From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.byosoft.com.cn (mail.byosoft.com.cn [58.240.74.242]) by mx.groups.io with SMTP id smtpd.web11.1484.1620437539196480173 for ; Fri, 07 May 2021 18:32:20 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=none, err=permanent DNS error (domain: byosoft.com.cn, ip: 58.240.74.242, mailfrom: gaoliming@byosoft.com.cn) Received: from DESKTOPS6D0PVI ([58.246.60.130]) (envelope-sender ) by 192.168.6.13 with ESMTP for ; Sat, 08 May 2021 09:32:09 +0800 X-WM-Sender: gaoliming@byosoft.com.cn X-Originating-IP: 58.246.60.130 X-WM-AuthFlag: YES X-WM-AuthUser: gaoliming@byosoft.com.cn From: "gaoliming" To: "'Rebecca Cran'" , , "'Jiewen Yao'" , "'Jian J Wang'" , "'Michael D Kinney'" , "'Zhiguang Liu'" , "'Ard Biesheuvel'" , "'Sami Mujawar'" References: <20210507142315.679-1-rebecca@nuviainc.com> <20210507142315.679-3-rebecca@nuviainc.com> In-Reply-To: <20210507142315.679-3-rebecca@nuviainc.com> Subject: =?UTF-8?B?5Zue5aSNOiBbUEFUQ0ggdjIgMi8yXSBTZWN1cml0eVBrZzogQWRkIHN1cHBvcnQgZm9yIFJuZ0R4ZSBvbiBBQVJDSDY0?= Date: Sat, 8 May 2021 09:32:09 +0800 Message-ID: <00c701d743a9$f67a6770$e36f3650$@byosoft.com.cn> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQG2M0EqFAh6EFqwMovONduGnDbE6AMC/xiVqwLVGFA= Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: quoted-printable Content-Language: zh-cn Rebecca: > -----=D3=CA=BC=FE=D4=AD=BC=FE----- > =B7=A2=BC=FE=C8=CB: Rebecca Cran > =B7=A2=CB=CD=CA=B1=BC=E4: 2021=C4=EA5=D4=C27=C8=D5 22:23 > =CA=D5=BC=FE=C8=CB: devel@edk2.groups.io; Jiewen Yao = ; Jian J > Wang ; Michael D Kinney > ; Liming Gao ; > Zhiguang Liu ; Ard Biesheuvel > ; Sami Mujawar > =B3=AD=CB=CD: Rebecca Cran > =D6=F7=CC=E2: [PATCH v2 2/2] SecurityPkg: Add support for RngDxe on = AARCH64 >=20 > AARCH64 support has been added to BaseRngLib via the optional > ARMv8.5 FEAT_RNG. >=20 > Refactor RngDxe to support AARCH64, note support for it in the > VALID_ARCHITECTURES line of RngDxe.inf and enable it in = SecurityPkg.dsc. >=20 > Signed-off-by: Rebecca Cran > --- > SecurityPkg/SecurityPkg.dec | > 2 + > SecurityPkg/SecurityPkg.dsc | > 11 +- > SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | > 24 ++- > SecurityPkg/RandomNumberGenerator/RngDxe/{ =3D> Rand}/AesCore.h | > 0 > SecurityPkg/RandomNumberGenerator/RngDxe/{ =3D> Rand}/RdRand.h | > 17 -- > SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | > 117 ++++++++++++++ > SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | > 127 +++++++++++++++ > SecurityPkg/RandomNumberGenerator/RngDxe/{ =3D> Rand}/AesCore.c | > 0 > SecurityPkg/RandomNumberGenerator/RngDxe/{ =3D> Rand}/RdRand.c | > 45 +----- > SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c | > 146 +++++++++++++++++ > SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | > 170 ++++++++------------ > 11 files changed, 483 insertions(+), 176 deletions(-) >=20 > diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec > index dfbbb0365a2b..a45104fe3e6c 100644 > --- a/SecurityPkg/SecurityPkg.dec > +++ b/SecurityPkg/SecurityPkg.dec > @@ -297,6 +297,8 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] >=20 > = gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationPass|0x0303100 > A|UINT32|0x00010030 >=20 > = gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationFail|0x0303100B > |UINT32|0x00010031 >=20 > + > gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0}|VOID*|0 > x00010032 > + This PCD value is GUID. So, its default value should be GUID (16 bytes) instead of {0} (1 byte). Thanks Liming > [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] > ## Image verification policy for OptionRom. Only following values = are > valid:

> # NOTE: Do NOT use 0x5 and 0x2 since it violates the UEFI specification > and has been removed.
> 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 >=20 > +[Components.IA32, Components.X64, Components.AARCH64] > + # > + # Random Number Generator > + # > + SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf > + > [Components.IA32, Components.X64] >=20 > = SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigD > xe.inf >=20 > @@ -334,11 +340,6 @@ [Components.IA32, Components.X64] >=20 > SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence > Lib.inf >=20 > SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic > alPresenceLib.inf >=20 > - # > - # 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 =3D IA32 X64 > +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64 > # >=20 > [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 >=20 > [Packages] > MdePkg/MdePkg.dec > @@ -50,12 +57,19 @@ [LibraryClasses] > RngLib >=20 > [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 >=20 > [Protocols] > gEfiRngProtocolGuid ## PRODUCES >=20 > +[Pcd] > + gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm ## > CONSUMES > + > [Depex] > TRUE >=20 > 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 > #include >=20 > -/** > - 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. >=20 > 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.
> + > + 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.
> + Copyright (c) 2013 - 2018, Intel Corporation. All rights = reserved.
> + (C) Copyright 2015 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > + > +#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 =3D=3D 0) || (RNGValue =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (RNGAlgorithm =3D=3D NULL) { > + // > + // Use the default RNG algorithm if RNGAlgorithm is NULL. > + // > + RNGAlgorithm =3D PcdGetPtr (PcdCpuRngSupportedAlgorithm); > + } > + > + if (CompareGuid (RNGAlgorithm, PcdGetPtr > (PcdCpuRngSupportedAlgorithm))) { > + Status =3D 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 =3D sizeof (EFI_RNG_ALGORITHM); > + > + if (*RNGAlgorithmListSize < RequiredSize) { > + *RNGAlgorithmListSize =3D RequiredSize; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + CpuRngSupportedAlgorithm =3D PcdGetPtr = (PcdCpuRngSupportedAlgorithm); > + > + CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof > (EFI_RNG_ALGORITHM)); > + > + *RNGAlgorithmListSize =3D 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 >=20 > -#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 =3D GetRandomNumber128 (TempRand); > - if (!IsRandom) { > - return EFI_NOT_READY; > - } > - if (Length >=3D sizeof (TempRand)) { > - WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]); > - RandBuffer +=3D sizeof (UINT64); > - WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]); > - RandBuffer +=3D sizeof (UINT64); > - Length -=3D sizeof (TempRand); > - } else { > - CopyMem (RandBuffer, TempRand, Length); > - Length =3D 0; > - } > - } > - > - return EFI_SUCCESS; > -} > +#include "RdRand.h" > +#include "RngDxeInternals.h" >=20 > /** > Creates a 128bit random value that is fully forward and backward > prediction resistant, > @@ -92,7 +53,7 @@ RdRandGetSeed128 ( > // > for (Index =3D 0; Index < 32; Index++) { > MicroSecondDelay (10); > - Status =3D RdRandGetBytes (16, RandByte); > + Status =3D 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.
> + (C) Copyright 2015 Hewlett Packard Enterprise Development LP
> + 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 =3D=3D 0) || (RNGValue =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status =3D EFI_UNSUPPORTED; > + if (RNGAlgorithm =3D=3D NULL) { > + // > + // Use the default RNG algorithm if RNGAlgorithm is NULL. > + // > + RNGAlgorithm =3D &gEfiRngAlgorithmSp80090Ctr256Guid; > + } > + > + // > + // NIST SP800-90-AES-CTR-256 supported by RDRAND > + // > + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) > { > + Status =3D 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 =3D 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 =3D 2 * sizeof (EFI_RNG_ALGORITHM); > + > + if (*RNGAlgorithmListSize < RequiredSize) { > + *RNGAlgorithmListSize =3D RequiredSize; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + CpuRngSupportedAlgorithm =3D 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 =3D 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. >=20 > - 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. >=20 > 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 >=20 > Copyright (c) 2013 - 2018, Intel Corporation. All rights = reserved.
> (C) Copyright 2015 Hewlett Packard Enterprise Development LP
> + > SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > **/ >=20 > -#include "RdRand.h" > +#include > +#include > +#include > +#include > +#include > +#include >=20 > -// > -// Supported RNG Algorithms list by this driver. > -// > -EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] =3D { > - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID, > - EFI_RNG_ALGORITHM_RAW > -}; > +#include "RngDxeInternals.h" >=20 > /** > Returns information about the random number generation > implementation. > @@ -62,106 +60,23 @@ RngGetInfo ( > ) > { > EFI_STATUS Status; > - UINTN RequiredSize; >=20 > if ((This =3D=3D NULL) || (RNGAlgorithmListSize =3D=3D NULL)) { > return EFI_INVALID_PARAMETER; > } >=20 > - RequiredSize =3D sizeof (mSupportedRngAlgorithms); > - if (*RNGAlgorithmListSize < RequiredSize) { > - Status =3D EFI_BUFFER_TOO_SMALL; > + // > + // Return algorithm list supported by driver. > + // > + if (RNGAlgorithmList !=3D NULL) { > + Status =3D ArchGetSupportedRngAlgorithms (RNGAlgorithmListSize, > RNGAlgorithmList); > } else { > - // > - // Return algorithm list supported by driver. > - // > - if (RNGAlgorithmList !=3D NULL) { > - CopyMem (RNGAlgorithmList, mSupportedRngAlgorithms, > RequiredSize); > - Status =3D EFI_SUCCESS; > - } else { > - Status =3D EFI_INVALID_PARAMETER; > - } > + Status =3D EFI_INVALID_PARAMETER; > } > - *RNGAlgorithmListSize =3D RequiredSize; >=20 > return Status; > } >=20 > -/** > - 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 =3D=3D 0) || (RNGValue =3D=3D NULL)) { > - return EFI_INVALID_PARAMETER; > - } > - > - Status =3D EFI_UNSUPPORTED; > - if (RNGAlgorithm =3D=3D NULL) { > - // > - // Use the default RNG algorithm if RNGAlgorithm is NULL. > - // > - RNGAlgorithm =3D &gEfiRngAlgorithmSp80090Ctr256Guid; > - } > - > - // > - // NIST SP800-90-AES-CTR-256 supported by RDRAND > - // > - if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) = { > - Status =3D 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 =3D 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 ( >=20 > 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 =3D GetRandomNumber128 (TempRand); > + if (!IsRandom) { > + return EFI_NOT_READY; > + } > + if (Length >=3D sizeof (TempRand)) { > + WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]); > + RandBuffer +=3D sizeof (UINT64); > + WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]); > + RandBuffer +=3D sizeof (UINT64); > + Length -=3D sizeof (TempRand); > + } else { > + CopyMem (RandBuffer, TempRand, Length); > + Length =3D 0; > + } > + } > + > + return EFI_SUCCESS; > +} > -- > 2.26.2