From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web09.16025.1656530376328534640 for ; Wed, 29 Jun 2022 12:19:36 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: pierre.gondois@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 35FC2152B; Wed, 29 Jun 2022 12:19:36 -0700 (PDT) Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 067423F792; Wed, 29 Jun 2022 12:19:33 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [PATCH RESEND v1 5/9] MdePkg/DrbgLib: Add common wrappers Date: Wed, 29 Jun 2022 21:18:42 +0200 Message-Id: <20220629191848.2619317-6-Pierre.Gondois@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Pierre Gondois Add common wrappers around the TRNG and AES libraries: - GetEntropy() relies an Arm Trng - BlockEncrypt relies on Arm implementation of the AES library Signed-off-by: Pierre Gondois --- MdePkg/Library/DrbgLib/Common.c | 249 ++++++++++++++++++++++++++++++++ MdePkg/Library/DrbgLib/Common.h | 74 ++++++++++ 2 files changed, 323 insertions(+) create mode 100644 MdePkg/Library/DrbgLib/Common.c create mode 100644 MdePkg/Library/DrbgLib/Common.h diff --git a/MdePkg/Library/DrbgLib/Common.c b/MdePkg/Library/DrbgLib/Com= mon.c new file mode 100644 index 000000000000..0aa0459f0b0f --- /dev/null +++ b/MdePkg/Library/DrbgLib/Common.c @@ -0,0 +1,249 @@ +/** @file + Implementation of arch specific functions for the Drbg library. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommen= dation + for Random Number Generation Using Deterministic Random Bit Gene= rators. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/fina= l) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation = for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-= 5/final) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#include +#include +#include +#include +#include +#include + +#include "Common.h" +#include "CtrDrbg.h" + +/** GetEntropy implementation using Arm Trng. + + Cf. [3] 10.3.1.2 Condensing After Entropy Collection + + The min and max entropy length are in the DrbgHandle. + + @param [in] DrbgHandle The Drbg hanble. + @param [in] ReqEntropy Requested entropy. + @param [out] EntropyBitsStream Stream containing the generated entrop= y. + + @retval EFI_SUCCESS Success. + @retval EFI_ABORTED An error occured. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +GetEntropy ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN ReqEntropy, + OUT BIT_STREAM **EntropyBitsStream + ) +{ + EFI_STATUS Status; + UINTN TrngCollectedEntropy; + UINTN TrngReqBits; + UINTN TrngMaxBits; + UINTN TrngMaxBytes; + UINTN MinLen; + UINT8 *QueriedBitsBuff; + + if ((DrbgHandle =3D=3D NULL) || + (EntropyBitsStream =3D=3D NULL) || + (*EntropyBitsStream !=3D NULL)) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT (EntropyBitsStream !=3D NULL); + ASSERT (*EntropyBitsStream =3D=3D NULL); + return EFI_INVALID_PARAMETER; + } + + MinLen =3D 0; + TrngMaxBits =3D GetTrngMaxSupportedEntropyBits (); + TrngMaxBytes =3D BitsToUpperBytes (TrngMaxBits); + QueriedBitsBuff =3D NULL; + + // 1. If requested_entropy > max_length, return an error indication + // and a null value for the entropy_bitstring. + // + // Note: we also check for MinLen + if ((ReqEntropy > DrbgHandle->DrbgVal.MaxLen) || + (ReqEntropy < DrbgHandle->DrbgVal.MinLen)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // 2. collected_entropy =3D 0. + TrngCollectedEntropy =3D 0; + + // 3. entropy_bitstring =3D the Null string. + Status =3D BitStreamAlloc (ReqEntropy, EntropyBitsStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + QueriedBitsBuff =3D (UINT8 *)AllocateZeroPool (TrngMaxBytes); + if (QueriedBitsBuff =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // 4. While collected_entropy < requested_entropy + while (TrngCollectedEntropy < ReqEntropy) { + TrngReqBits =3D MIN ((MinLen - TrngCollectedEntropy), TrngMaxBits); + + // 4.1 Query one or more entropy sources to obtain queried_bits and = the + // assessed_entropy for those bits. + // + // Cf. Arm True Random Number Generator Firmware, Interface 1.0, + // s2.4.2 Usage, the number of bits requested to the TRNG equals the + // number of bits returned. So assessed_entropy =3D=3D #queried_bits + Status =3D GetTrngEntropy (TrngReqBits, TrngMaxBytes, QueriedBitsBuf= f); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // 4.2 entropy_bitstring =3D entropy_bitstring || queried_bits. + // + // We are concatenating the other way around. Since this is a TRNG a= nd + // the endianness of queried_bits is meaningless, this is the same. + Status =3D BitStreamWrite ( + QueriedBitsBuff, + TrngCollectedEntropy, + TrngReqBits, + *EntropyBitsStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // 4.3 collected_entropy =3D collected_entropy + assessed_entropy. + // + // Cf above, for Arm TRNG, assessed_entropy =3D=3D #queried_bits + TrngCollectedEntropy +=3D TrngReqBits; + } // while + + // 6. If (n > max_length), then + // entropy_bitstring =3D df(entropy_bitstring, max_length). + // + // Note: This cannot happen. + if (DrbgHandle->DrbgVal.MaxLen !=3D 0) { + Status =3D EFI_ABORTED; + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + FreePool (QueriedBitsBuff); + + // 7. Return (SUCCESS, entropy_bitstring). + return Status; + +ErrorHandler: + if (QueriedBitsBuff) { + FreePool (QueriedBitsBuff); + } + + BitStreamFree (EntropyBitsStream); + return Status; +} + +/** Block encryption (for AES). + + Cf. [1] s10.3.3 'BCC and Block_Encrypt'. + + @param [in] DrbgHandle The Drbg hanble. + @param [out] OutBlockStream Stream containing the encrypted block. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BlockEncrypt ( + IN DRBG_HANDLE DrbgHandle, + OUT BIT_STREAM **OutBlockStream + ) +{ + EFI_STATUS Status; + AES_CTX AesCtx; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + + if ((DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL) || + (OutBlockStream =3D=3D NULL) || + (*OutBlockStream !=3D NULL)) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + ASSERT (OutBlockStream !=3D NULL); + ASSERT (*OutBlockStream =3D=3D NULL); + return EFI_INVALID_PARAMETER; + } + + CtrVal =3D (CTR_VALUE_DEFINITIONS *)DrbgHandle->DrbgVal.DrbgAlgoV= al; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoInt= State; + if (IsBitStreamEmpty (CtrIntState->Key) || + IsBitStreamEmpty (CtrIntState->Val) + ) + { + ASSERT (!IsBitStreamEmpty (CtrIntState->Key)); + ASSERT (!IsBitStreamEmpty (CtrIntState->Val)); + return EFI_INVALID_PARAMETER; + } + + Status =3D AesInitCtx ( + BitStreamData (CtrIntState->Key), + BitStreamBitLen (CtrIntState->Key), + &AesCtx + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamAlloc (CtrVal->BlockLen, OutBlockStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AesEncrypt ( + &AesCtx, + BitStreamData (CtrIntState->Val), + BitStreamData (*OutBlockStream) + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + BitStreamFree (OutBlockStream); + // Fall through. + } + + return Status; +} diff --git a/MdePkg/Library/DrbgLib/Common.h b/MdePkg/Library/DrbgLib/Com= mon.h new file mode 100644 index 000000000000..f226528bc5c2 --- /dev/null +++ b/MdePkg/Library/DrbgLib/Common.h @@ -0,0 +1,74 @@ +/** @file + Implementation of arch specific functions for the Drbg library. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommen= dation + for Random Number Generation Using Deterministic Random Bit Gene= rators. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/fina= l) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation = for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-= 5/final) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#ifndef ARCH_IMPLEM_H_ +#define ARCH_IMPLEM_H_ + +#include "DrbgLibInternal.h" + +/** GetEntropy implementation using Arm Trng. + + Cf. [3] 10.3.1.2 Condensing After Entropy Collection + + The min and max entropy length are in the DrbgHandle. + + @param [in] DrbgHandle The Drbg hanble. + @param [in] ReqEntropy Requested entropy. + @param [out] EntropyBitsStream Stream containing the generated entrop= y. + + @retval EFI_SUCCESS Success. + @retval EFI_ABORTED An error occured. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +GetEntropy ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN ReqEntropy, + OUT BIT_STREAM **EntropyBitsStream + ); + +/** Block encryption (for AES). + + Cf. [1] s10.3.3 'BCC and Block_Encrypt'. + + @param [in] DrbgHandle The Drbg hanble. + @param [out] OutBlockStream Stream containing the encrypted block. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BlockEncrypt ( + IN DRBG_HANDLE DrbgHandle, + OUT BIT_STREAM **OutBlockStream + ); + +#endif // ARCH_IMPLEM_H_ --=20 2.25.1