Acked-by: Jiewen Yao <jiewen....@intel.com> Need ARM expert to double confirm.
> -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ard > Biesheuvel > Sent: Tuesday, May 11, 2021 10:44 PM > To: Rebecca Cran <rebe...@nuviainc.com>; Yao, Jiewen > <jiewen....@intel.com>; Wang, Jian J <jian.j.w...@intel.com> > Cc: edk2-devel-groups-io <devel@edk2.groups.io>; Kinney, Michael D > <michael.d.kin...@intel.com>; Liming Gao <gaolim...@byosoft.com.cn>; Liu, > Zhiguang <zhiguang....@intel.com>; Ard Biesheuvel > <ardb+tianoc...@kernel.org>; Sami Mujawar <sami.muja...@arm.com> > Subject: Re: [edk2-devel] [PATCH v3 2/2] SecurityPkg: Add support for RngDxe > on AARCH64 > > On Mon, 10 May 2021 at 23:53, Rebecca Cran <rebe...@nuviainc.com> wrote: > > > > AARCH64 support has been added to BaseRngLib via the optional > > ARMv8.5 FEAT_RNG. > > > > Refactor RngDxe to support AARCH64, note support for it in the > > VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc. > > > > Signed-off-by: Rebecca Cran <rebe...@nuviainc.com> > > I'm happy to take these and merge them if I can get an ack from a > SecurityPkg maintainer. > > > > --- > > SecurityPkg/SecurityPkg.dec | 2 + > > SecurityPkg/SecurityPkg.dsc | 11 +- > > SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | 24 ++- > > SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h | 0 > > SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h | 17 -- > > SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | 117 > ++++++++++++++ > > SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | 127 > +++++++++++++++ > > SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c | 0 > > SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c | 45 +- > ---- > > SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | 146 > +++++++++++++++++ > > SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | 170 > ++++++++------------ > > 11 files changed, 483 insertions(+), 176 deletions(-) > > > > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec > > index dfbbb0365a2b..4001650fa28e 100644 > > --- a/SecurityPkg/SecurityPkg.dec > > +++ b/SecurityPkg/SecurityPkg.dec > > @@ -297,6 +297,8 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] > > > gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationPass|0x0303100A| > UINT32|0x00010030 > > > gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationFail|0x0303100B| > UINT32|0x00010031 > > > > + > gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0x00,0x00,0x0 > 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}|VOID > *|0x00010032 > > + > > [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] > > ## Image verification policy for OptionRom. Only following values are > valid:<BR><BR> > > # NOTE: Do NOT use 0x5 and 0x2 since it violates the UEFI specification > > and > has been removed.<BR> > > diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc > > index 12ccd1634941..bd4b810bce61 100644 > > --- a/SecurityPkg/SecurityPkg.dsc > > +++ b/SecurityPkg/SecurityPkg.dsc > > @@ -259,6 +259,12 @@ [Components] > > [Components.IA32, Components.X64, Components.ARM, > Components.AARCH64] > > SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf > > > > +[Components.IA32, Components.X64, Components.AARCH64] > > + # > > + # Random Number Generator > > + # > > + SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > > + > > [Components.IA32, Components.X64] > > > SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDx > e.inf > > > > @@ -334,11 +340,6 @@ [Components.IA32, Components.X64] > > > SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib > .inf > > > SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalP > resenceLib.inf > > > > - # > > - # Random Number Generator > > - # > > - SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > > - > > # > > # Opal Password solution > > # > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > > index 99d6f6b35fc2..f3300971993f 100644 > > --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > > @@ -26,15 +26,22 @@ [Defines] > > # > > # The following information is for reference only and not required by the > > build > tools. > > # > > -# VALID_ARCHITECTURES = IA32 X64 > > +# VALID_ARCHITECTURES = IA32 X64 AARCH64 > > # > > > > [Sources.common] > > RngDxe.c > > - RdRand.c > > - RdRand.h > > - AesCore.c > > - AesCore.h > > + RngDxeInternals.h > > + > > +[Sources.IA32, Sources.X64] > > + Rand/RngDxe.c > > + Rand/RdRand.c > > + Rand/RdRand.h > > + Rand/AesCore.c > > + Rand/AesCore.h > > + > > +[Sources.AARCH64] > > + AArch64/RngDxe.c > > > > [Packages] > > MdePkg/MdePkg.dec > > @@ -50,12 +57,19 @@ [LibraryClasses] > > RngLib > > > > [Guids] > > + gEfiRngAlgorithmSp80090Hash256Guid ## SOMETIMES_PRODUCES ## > GUID # Unique ID of the algorithm for RNG > > + gEfiRngAlgorithmSp80090Hmac256Guid ## SOMETIMES_PRODUCES ## > GUID # Unique ID of the algorithm for RNG > > gEfiRngAlgorithmSp80090Ctr256Guid ## SOMETIMES_PRODUCES ## GUID > # Unique ID of the algorithm for RNG > > + gEfiRngAlgorithmX9313DesGuid ## SOMETIMES_PRODUCES ## GUID > # Unique ID of the algorithm for RNG > > + gEfiRngAlgorithmX931AesGuid ## SOMETIMES_PRODUCES ## GUID > # Unique ID of the algorithm for RNG > > gEfiRngAlgorithmRaw ## SOMETIMES_PRODUCES ## GUID > > # > Unique ID of the algorithm for RNG > > > > [Protocols] > > gEfiRngProtocolGuid ## PRODUCES > > > > +[Pcd] > > + gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm ## > CONSUMES > > + > > [Depex] > > TRUE > > > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h > b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h > > similarity index 100% > > rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h > > rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h > b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h > > similarity index 72% > > rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h > > rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h > > index 12ab1f34ec6d..072378e062e7 100644 > > --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h > > @@ -23,23 +23,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > #include <Library/TimerLib.h> > > #include <Protocol/Rng.h> > > > > -/** > > - Calls RDRAND to fill a buffer of arbitrary size with random bytes. > > - > > - @param[in] Length Size of the buffer, in bytes, to fill with. > > - @param[out] RandBuffer Pointer to the buffer to store the random > > result. > > - > > - @retval EFI_SUCCESS Random bytes generation succeeded. > > - @retval EFI_NOT_READY Failed to request random bytes. > > - > > -**/ > > -EFI_STATUS > > -EFIAPI > > -RdRandGetBytes ( > > - IN UINTN Length, > > - OUT UINT8 *RandBuffer > > - ); > > - > > /** > > Generate high-quality entropy source through RDRAND. > > > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h > b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h > > new file mode 100644 > > index 000000000000..2660ed5875e0 > > --- /dev/null > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h > > @@ -0,0 +1,117 @@ > > +/** @file > > + Function prototypes for UEFI Random Number Generator protocol support. > > + > > + Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#ifndef RNGDXE_INTERNALS_H_ > > +#define RNGDXE_INTERNALS_H_ > > + > > +/** > > + Returns information about the random number generation implementation. > > + > > + @param[in] This A pointer to the EFI_RNG_PROTOCOL > > instance. > > + @param[in,out] RNGAlgorithmListSize On input, the size in bytes of > RNGAlgorithmList. > > + On output with a return code of > > EFI_SUCCESS, the size > > + in bytes of the data returned in > > RNGAlgorithmList. On > output > > + with a return code of > > EFI_BUFFER_TOO_SMALL, > > + the size of RNGAlgorithmList > > required to obtain the list. > > + @param[out] RNGAlgorithmList A caller-allocated memory buffer > > filled > by the driver > > + with one EFI_RNG_ALGORITHM element > > for each > supported > > + RNG algorithm. The list must not > > change across multiple > > + calls to the same driver. The first > > algorithm in the list > > + is the default algorithm for the > > driver. > > + > > + @retval EFI_SUCCESS The RNG algorithm list was returned > successfully. > > + @retval EFI_UNSUPPORTED The services is not supported by this > driver. > > + @retval EFI_DEVICE_ERROR The list of algorithms could not be > retrieved due to a > > + hardware or firmware error. > > + @retval EFI_INVALID_PARAMETER One or more of the parameters are > incorrect. > > + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too > small to hold the result. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +RngGetInfo ( > > + IN EFI_RNG_PROTOCOL *This, > > + IN OUT UINTN *RNGAlgorithmListSize, > > + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList > > + ); > > + > > +/** > > + Produces and returns an RNG value using either the default or specified > > RNG > algorithm. > > + > > + @param[in] This A pointer to the EFI_RNG_PROTOCOL > > instance. > > + @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM > that identifies the RNG > > + algorithm to use. May be NULL in > > which case the > function will > > + use its default RNG algorithm. > > + @param[in] RNGValueLength The length in bytes of the memory > buffer pointed to by > > + RNGValue. The driver shall return > > exactly this numbers > of bytes. > > + @param[out] RNGValue A caller-allocated memory buffer > > filled by > the driver with the > > + resulting RNG value. > > + > > + @retval EFI_SUCCESS The RNG value was returned > > successfully. > > + @retval EFI_UNSUPPORTED The algorithm specified by > RNGAlgorithm is not supported by > > + this driver. > > + @retval EFI_DEVICE_ERROR An RNG value could not be retrieved > > due > to a hardware or > > + firmware error. > > + @retval EFI_NOT_READY There is not enough random data > > available > to satisfy the length > > + requested by RNGValueLength. > > + @retval EFI_INVALID_PARAMETER RNGValue is NULL or > RNGValueLength is zero. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +RngGetRNG ( > > + IN EFI_RNG_PROTOCOL *This, > > + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL > > + IN UINTN RNGValueLength, > > + OUT UINT8 *RNGValue > > + ); > > + > > +/** > > + Returns information about the random number generation implementation. > > + > > + @param[in,out] RNGAlgorithmListSize On input, the size in bytes of > RNGAlgorithmList. > > + On output with a return code of > > EFI_SUCCESS, the size > > + in bytes of the data returned in > > RNGAlgorithmList. On > output > > + with a return code of > > EFI_BUFFER_TOO_SMALL, > > + the size of RNGAlgorithmList > > required to obtain the list. > > + @param[out] RNGAlgorithmList A caller-allocated memory buffer > > filled > by the driver > > + with one EFI_RNG_ALGORITHM element > > for each > supported > > + RNG algorithm. The list must not > > change across multiple > > + calls to the same driver. The first > > algorithm in the list > > + is the default algorithm for the > > driver. > > + > > + @retval EFI_SUCCESS The RNG algorithm list was returned > successfully. > > + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too > small to hold the result. > > + > > +**/ > > +UINTN > > +EFIAPI > > +ArchGetSupportedRngAlgorithms ( > > + IN OUT UINTN *RNGAlgorithmListSize, > > + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList > > + ); > > + > > +/** > > + Runs CPU RNG instruction to fill a buffer of arbitrary size with random > > bytes. > > + > > + @param[in] Length Size of the buffer, in bytes, to fill with. > > + @param[out] RandBuffer Pointer to the buffer to store the random > > result. > > + > > + @retval EFI_SUCCESS Random bytes generation succeeded. > > + @retval EFI_NOT_READY Failed to request random bytes. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +RngGetBytes ( > > + IN UINTN Length, > > + OUT UINT8 *RandBuffer > > + ); > > + > > +#endif // RNGDXE_INTERNALS_H_ > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c > b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c > > new file mode 100644 > > index 000000000000..2810a9eb94ad > > --- /dev/null > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c > > @@ -0,0 +1,127 @@ > > +/** @file > > + RNG Driver to produce the UEFI Random Number Generator protocol. > > + > > + The driver will use the RNDR instruction to produce random numbers. > > + > > + RNG Algorithms defined in UEFI 2.4: > > + - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID > > + - EFI_RNG_ALGORITHM_RAW - Unsupported > > + - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID > > + - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID > > + - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported > > + - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported > > + > > + Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR> > > + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> > > + (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include <Library/BaseLib.h> > > +#include <Library/BaseMemoryLib.h> > > +#include <Library/UefiBootServicesTableLib.h> > > +#include <Library/TimerLib.h> > > +#include <Protocol/Rng.h> > > + > > +#include "RngDxeInternals.h" > > + > > +/** > > + Produces and returns an RNG value using either the default or specified > > RNG > algorithm. > > + > > + @param[in] This A pointer to the EFI_RNG_PROTOCOL > > instance. > > + @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM > that identifies the RNG > > + algorithm to use. May be NULL in > > which case the > function will > > + use its default RNG algorithm. > > + @param[in] RNGValueLength The length in bytes of the memory > buffer pointed to by > > + RNGValue. The driver shall return > > exactly this numbers > of bytes. > > + @param[out] RNGValue A caller-allocated memory buffer > > filled by > the driver with the > > + resulting RNG value. > > + > > + @retval EFI_SUCCESS The RNG value was returned > > successfully. > > + @retval EFI_UNSUPPORTED The algorithm specified by > RNGAlgorithm is not supported by > > + this driver. > > + @retval EFI_DEVICE_ERROR An RNG value could not be retrieved > > due > to a hardware or > > + firmware error. > > + @retval EFI_NOT_READY There is not enough random data > > available > to satisfy the length > > + requested by RNGValueLength. > > + @retval EFI_INVALID_PARAMETER RNGValue is NULL or > RNGValueLength is zero. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +RngGetRNG ( > > + IN EFI_RNG_PROTOCOL *This, > > + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL > > + IN UINTN RNGValueLength, > > + OUT UINT8 *RNGValue > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + if ((RNGValueLength == 0) || (RNGValue == NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + if (RNGAlgorithm == NULL) { > > + // > > + // Use the default RNG algorithm if RNGAlgorithm is NULL. > > + // > > + RNGAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm); > > + } > > + > > + if (CompareGuid (RNGAlgorithm, PcdGetPtr > (PcdCpuRngSupportedAlgorithm))) { > > + Status = RngGetBytes (RNGValueLength, RNGValue); > > + return Status; > > + } > > + > > + // > > + // Other algorithms are unsupported by this driver. > > + // > > + return EFI_UNSUPPORTED; > > +} > > + > > +/** > > + Returns information about the random number generation implementation. > > + > > + @param[in,out] RNGAlgorithmListSize On input, the size in bytes of > RNGAlgorithmList. > > + On output with a return code of > > EFI_SUCCESS, the size > > + in bytes of the data returned in > > RNGAlgorithmList. On > output > > + with a return code of > > EFI_BUFFER_TOO_SMALL, > > + the size of RNGAlgorithmList > > required to obtain the list. > > + @param[out] RNGAlgorithmList A caller-allocated memory buffer > > filled > by the driver > > + with one EFI_RNG_ALGORITHM element > > for each > supported > > + RNG algorithm. The list must not > > change across multiple > > + calls to the same driver. The first > > algorithm in the list > > + is the default algorithm for the > > driver. > > + > > + @retval EFI_SUCCESS The RNG algorithm list was returned > successfully. > > + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too > small to hold the result. > > + > > +**/ > > +UINTN > > +EFIAPI > > +ArchGetSupportedRngAlgorithms ( > > + IN OUT UINTN *RNGAlgorithmListSize, > > + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList > > + ) > > +{ > > + UINTN RequiredSize; > > + EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm; > > + > > + RequiredSize = sizeof (EFI_RNG_ALGORITHM); > > + > > + if (*RNGAlgorithmListSize < RequiredSize) { > > + *RNGAlgorithmListSize = RequiredSize; > > + return EFI_BUFFER_TOO_SMALL; > > + } > > + > > + CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm); > > + > > + CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof > (EFI_RNG_ALGORITHM)); > > + > > + *RNGAlgorithmListSize = RequiredSize; > > + return EFI_SUCCESS; > > +} > > + > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c > b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c > > similarity index 100% > > rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c > > rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c > b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c > > similarity index 71% > > rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c > > rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c > > index e7dd5ab18111..83025a47d43d 100644 > > --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c > > @@ -8,48 +8,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > > #include <Library/RngLib.h> > > > > -#include "RdRand.h" > > #include "AesCore.h" > > - > > -/** > > - Calls RDRAND to fill a buffer of arbitrary size with random bytes. > > - > > - @param[in] Length Size of the buffer, in bytes, to fill with. > > - @param[out] RandBuffer Pointer to the buffer to store the random > > result. > > - > > - @retval EFI_SUCCESS Random bytes generation succeeded. > > - @retval EFI_NOT_READY Failed to request random bytes. > > - > > -**/ > > -EFI_STATUS > > -EFIAPI > > -RdRandGetBytes ( > > - IN UINTN Length, > > - OUT UINT8 *RandBuffer > > - ) > > -{ > > - BOOLEAN IsRandom; > > - UINT64 TempRand[2]; > > - > > - while (Length > 0) { > > - IsRandom = GetRandomNumber128 (TempRand); > > - if (!IsRandom) { > > - return EFI_NOT_READY; > > - } > > - if (Length >= sizeof (TempRand)) { > > - WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]); > > - RandBuffer += sizeof (UINT64); > > - WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]); > > - RandBuffer += sizeof (UINT64); > > - Length -= sizeof (TempRand); > > - } else { > > - CopyMem (RandBuffer, TempRand, Length); > > - Length = 0; > > - } > > - } > > - > > - return EFI_SUCCESS; > > -} > > +#include "RdRand.h" > > +#include "RngDxeInternals.h" > > > > /** > > Creates a 128bit random value that is fully forward and backward > > prediction > resistant, > > @@ -92,7 +53,7 @@ RdRandGetSeed128 ( > > // > > for (Index = 0; Index < 32; Index++) { > > MicroSecondDelay (10); > > - Status = RdRandGetBytes (16, RandByte); > > + Status = RngGetBytes (16, RandByte); > > if (EFI_ERROR (Status)) { > > return Status; > > } > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c > b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c > > new file mode 100644 > > index 000000000000..6b628a9f8bc6 > > --- /dev/null > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c > > @@ -0,0 +1,146 @@ > > +/** @file > > + RNG Driver to produce the UEFI Random Number Generator protocol. > > + > > + The driver will use the new RDRAND instruction to produce high-quality, > high-performance > > + entropy and random number. > > + > > + RNG Algorithms defined in UEFI 2.4: > > + - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported > > + (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based > DRBG) > > + - EFI_RNG_ALGORITHM_RAW - Supported > > + (Structuring RDRAND invocation can be guaranteed as high-quality > > entropy > source) > > + - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported > > + - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported > > + - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported > > + - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported > > + > > + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> > > + (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "RdRand.h" > > +#include "RngDxeInternals.h" > > + > > +/** > > + Produces and returns an RNG value using either the default or specified > > RNG > algorithm. > > + > > + @param[in] This A pointer to the EFI_RNG_PROTOCOL > > instance. > > + @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM > that identifies the RNG > > + algorithm to use. May be NULL in > > which case the > function will > > + use its default RNG algorithm. > > + @param[in] RNGValueLength The length in bytes of the memory > buffer pointed to by > > + RNGValue. The driver shall return > > exactly this numbers > of bytes. > > + @param[out] RNGValue A caller-allocated memory buffer > > filled by > the driver with the > > + resulting RNG value. > > + > > + @retval EFI_SUCCESS The RNG value was returned > > successfully. > > + @retval EFI_UNSUPPORTED The algorithm specified by > RNGAlgorithm is not supported by > > + this driver. > > + @retval EFI_DEVICE_ERROR An RNG value could not be retrieved > > due > to a hardware or > > + firmware error. > > + @retval EFI_NOT_READY There is not enough random data > > available > to satisfy the length > > + requested by RNGValueLength. > > + @retval EFI_INVALID_PARAMETER RNGValue is NULL or > RNGValueLength is zero. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +RngGetRNG ( > > + IN EFI_RNG_PROTOCOL *This, > > + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL > > + IN UINTN RNGValueLength, > > + OUT UINT8 *RNGValue > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + if ((RNGValueLength == 0) || (RNGValue == NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Status = EFI_UNSUPPORTED; > > + if (RNGAlgorithm == NULL) { > > + // > > + // Use the default RNG algorithm if RNGAlgorithm is NULL. > > + // > > + RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid; > > + } > > + > > + // > > + // NIST SP800-90-AES-CTR-256 supported by RDRAND > > + // > > + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) { > > + Status = RngGetBytes (RNGValueLength, RNGValue); > > + return Status; > > + } > > + > > + // > > + // The "raw" algorithm is intended to provide entropy directly > > + // > > + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) { > > + // > > + // When a DRBG is used on the output of a entropy source, > > + // its security level must be at least 256 bits according to UEFI Spec. > > + // > > + if (RNGValueLength < 32) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Status = RdRandGenerateEntropy (RNGValueLength, RNGValue); > > + return Status; > > + } > > + > > + // > > + // Other algorithms were unsupported by this driver. > > + // > > + return Status; > > +} > > + > > +/** > > + Returns information about the random number generation implementation. > > + > > + @param[in,out] RNGAlgorithmListSize On input, the size in bytes of > RNGAlgorithmList. > > + On output with a return code of > > EFI_SUCCESS, the size > > + in bytes of the data returned in > > RNGAlgorithmList. On > output > > + with a return code of > > EFI_BUFFER_TOO_SMALL, > > + the size of RNGAlgorithmList > > required to obtain the list. > > + @param[out] RNGAlgorithmList A caller-allocated memory buffer > > filled > by the driver > > + with one EFI_RNG_ALGORITHM element > > for each > supported > > + RNG algorithm. The list must not > > change across multiple > > + calls to the same driver. The first > > algorithm in the list > > + is the default algorithm for the > > driver. > > + > > + @retval EFI_SUCCESS The RNG algorithm list was returned > successfully. > > + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too > small to hold the result. > > + > > +**/ > > +UINTN > > +EFIAPI > > +ArchGetSupportedRngAlgorithms ( > > + IN OUT UINTN *RNGAlgorithmListSize, > > + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList > > + ) > > +{ > > + UINTN RequiredSize; > > + EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm; > > + > > + RequiredSize = 2 * sizeof (EFI_RNG_ALGORITHM); > > + > > + if (*RNGAlgorithmListSize < RequiredSize) { > > + *RNGAlgorithmListSize = RequiredSize; > > + return EFI_BUFFER_TOO_SMALL; > > + } > > + > > + CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm); > > + > > + CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof > (EFI_RNG_ALGORITHM)); > > + > > + // x86 platforms also support EFI_RNG_ALGORITHM_RAW via RDSEED > > + CopyMem(&RNGAlgorithmList[1], &gEfiRngAlgorithmRaw, sizeof > (EFI_RNG_ALGORITHM)); > > + > > + *RNGAlgorithmListSize = RequiredSize; > > + return EFI_SUCCESS; > > +} > > + > > diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c > b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c > > index 13d3dbd0bfbe..b959c70536ea 100644 > > --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c > > +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c > > @@ -1,34 +1,32 @@ > > /** @file > > RNG Driver to produce the UEFI Random Number Generator protocol. > > > > - The driver will use the new RDRAND instruction to produce high-quality, > high-performance > > - entropy and random number. > > + The driver uses CPU RNG instructions to produce high-quality, > > + high-performance entropy and random number. > > > > RNG Algorithms defined in UEFI 2.4: > > - - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported > > - (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based DRBG) > > - - EFI_RNG_ALGORITHM_RAW - Supported > > - (Structuring RDRAND invocation can be guaranteed as high-quality > > entropy > source) > > - - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported > > - - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported > > - - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported > > - - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported > > + - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID > > + - EFI_RNG_ALGORITHM_RAW > > + - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID > > + - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID > > + - EFI_RNG_ALGORITHM_X9_31_3DES_GUID > > + - EFI_RNG_ALGORITHM_X9_31_AES_GUID > > > > Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> > > (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> > > + > > SPDX-License-Identifier: BSD-2-Clause-Patent > > > > **/ > > > > -#include "RdRand.h" > > +#include <Library/BaseLib.h> > > +#include <Library/BaseMemoryLib.h> > > +#include <Library/UefiBootServicesTableLib.h> > > +#include <Library/RngLib.h> > > +#include <Library/TimerLib.h> > > +#include <Protocol/Rng.h> > > > > -// > > -// Supported RNG Algorithms list by this driver. > > -// > > -EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = { > > - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID, > > - EFI_RNG_ALGORITHM_RAW > > -}; > > +#include "RngDxeInternals.h" > > > > /** > > Returns information about the random number generation implementation. > > @@ -62,106 +60,23 @@ RngGetInfo ( > > ) > > { > > EFI_STATUS Status; > > - UINTN RequiredSize; > > > > if ((This == NULL) || (RNGAlgorithmListSize == NULL)) { > > return EFI_INVALID_PARAMETER; > > } > > > > - RequiredSize = sizeof (mSupportedRngAlgorithms); > > - if (*RNGAlgorithmListSize < RequiredSize) { > > - Status = EFI_BUFFER_TOO_SMALL; > > + // > > + // Return algorithm list supported by driver. > > + // > > + if (RNGAlgorithmList != NULL) { > > + Status = ArchGetSupportedRngAlgorithms (RNGAlgorithmListSize, > RNGAlgorithmList); > > } else { > > - // > > - // Return algorithm list supported by driver. > > - // > > - if (RNGAlgorithmList != NULL) { > > - CopyMem (RNGAlgorithmList, mSupportedRngAlgorithms, RequiredSize); > > - Status = EFI_SUCCESS; > > - } else { > > - Status = EFI_INVALID_PARAMETER; > > - } > > + Status = EFI_INVALID_PARAMETER; > > } > > - *RNGAlgorithmListSize = RequiredSize; > > > > return Status; > > } > > > > -/** > > - Produces and returns an RNG value using either the default or specified > > RNG > algorithm. > > - > > - @param[in] This A pointer to the EFI_RNG_PROTOCOL > > instance. > > - @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM > that identifies the RNG > > - algorithm to use. May be NULL in > > which case the > function will > > - use its default RNG algorithm. > > - @param[in] RNGValueLength The length in bytes of the memory > > buffer > pointed to by > > - RNGValue. The driver shall return > > exactly this numbers of > bytes. > > - @param[out] RNGValue A caller-allocated memory buffer > > filled by > the driver with the > > - resulting RNG value. > > - > > - @retval EFI_SUCCESS The RNG value was returned > > successfully. > > - @retval EFI_UNSUPPORTED The algorithm specified by > > RNGAlgorithm > is not supported by > > - this driver. > > - @retval EFI_DEVICE_ERROR An RNG value could not be retrieved > > due > to a hardware or > > - firmware error. > > - @retval EFI_NOT_READY There is not enough random data > > available > to satisfy the length > > - requested by RNGValueLength. > > - @retval EFI_INVALID_PARAMETER RNGValue is NULL or > RNGValueLength is zero. > > - > > -**/ > > -EFI_STATUS > > -EFIAPI > > -RngGetRNG ( > > - IN EFI_RNG_PROTOCOL *This, > > - IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL > > - IN UINTN RNGValueLength, > > - OUT UINT8 *RNGValue > > - ) > > -{ > > - EFI_STATUS Status; > > - > > - if ((RNGValueLength == 0) || (RNGValue == NULL)) { > > - return EFI_INVALID_PARAMETER; > > - } > > - > > - Status = EFI_UNSUPPORTED; > > - if (RNGAlgorithm == NULL) { > > - // > > - // Use the default RNG algorithm if RNGAlgorithm is NULL. > > - // > > - RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid; > > - } > > - > > - // > > - // NIST SP800-90-AES-CTR-256 supported by RDRAND > > - // > > - if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) { > > - Status = RdRandGetBytes (RNGValueLength, RNGValue); > > - return Status; > > - } > > - > > - // > > - // The "raw" algorithm is intended to provide entropy directly > > - // > > - if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) { > > - // > > - // When a DRBG is used on the output of a entropy source, > > - // its security level must be at least 256 bits according to UEFI Spec. > > - // > > - if (RNGValueLength < 32) { > > - return EFI_INVALID_PARAMETER; > > - } > > - > > - Status = RdRandGenerateEntropy (RNGValueLength, RNGValue); > > - return Status; > > - } > > - > > - // > > - // Other algorithms were unsupported by this driver. > > - // > > - return Status; > > -} > > - > > // > > // The Random Number Generator (RNG) protocol > > // > > @@ -204,3 +119,44 @@ RngDriverEntry ( > > > > return Status; > > } > > + > > + > > +/** > > + Calls RDRAND to fill a buffer of arbitrary size with random bytes. > > + > > + @param[in] Length Size of the buffer, in bytes, to fill with. > > + @param[out] RandBuffer Pointer to the buffer to store the random > > result. > > + > > + @retval EFI_SUCCESS Random bytes generation succeeded. > > + @retval EFI_NOT_READY Failed to request random bytes. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +RngGetBytes ( > > + IN UINTN Length, > > + OUT UINT8 *RandBuffer > > + ) > > +{ > > + BOOLEAN IsRandom; > > + UINT64 TempRand[2]; > > + > > + while (Length > 0) { > > + IsRandom = GetRandomNumber128 (TempRand); > > + if (!IsRandom) { > > + return EFI_NOT_READY; > > + } > > + if (Length >= sizeof (TempRand)) { > > + WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]); > > + RandBuffer += sizeof (UINT64); > > + WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]); > > + RandBuffer += sizeof (UINT64); > > + Length -= sizeof (TempRand); > > + } else { > > + CopyMem (RandBuffer, TempRand, Length); > > + Length = 0; > > + } > > + } > > + > > + return EFI_SUCCESS; > > +} > > -- > > 2.26.2 > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#75013): https://edk2.groups.io/g/devel/message/75013 Mute This Topic: https://groups.io/mt/82732213/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-