Make BaseRngLib more generic by moving x86 specific functionality from BaseRng.c into Rand/RdRand.c, and adding AArch64/Rndr.c, which supports the optional ARMv8.5 RNG instructions RNDR and RNDRRS that are a part of FEAT_RNG.
Signed-off-by: Rebecca Cran <rebe...@nuviainc.com> --- MdePkg/MdePkg.dec | 9 +- MdePkg/MdePkg.dsc | 4 +- MdePkg/Library/BaseRngLib/BaseRngLib.inf | 16 ++- MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 31 +++++ MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 121 ++++++++++++++++++++ MdePkg/Library/BaseRngLib/BaseRng.c | 55 +++------ MdePkg/Library/BaseRngLib/Rand/RdRand.c | 103 +++++++++++++++++ MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +- 8 files changed, 291 insertions(+), 54 deletions(-) diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 8965e903e093..b49f88d8e18f 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -267,6 +267,11 @@ [LibraryClasses] # RegisterFilterLib|Include/Library/RegisterFilterLib.h +[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] + ## @libraryclass Provides services to generate random number. + # + RngLib|Include/Library/RngLib.h + [LibraryClasses.IA32, LibraryClasses.X64] ## @libraryclass Abstracts both S/W SMI generation and detection. ## @@ -288,10 +293,6 @@ [LibraryClasses.IA32, LibraryClasses.X64] # SmmPeriodicSmiLib|Include/Library/SmmPeriodicSmiLib.h - ## @libraryclass Provides services to generate random number. - # - RngLib|Include/Library/RngLib.h - ## @libraryclass Provides services to log the SMI handler registration. SmiHandlerProfileLib|Include/Library/SmiHandlerProfileLib.h diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index d363419006ea..a94959169b2f 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -145,6 +145,9 @@ [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf +[Components.IA32, Components.X64, Components.AARCH64] + MdePkg/Library/BaseRngLib/BaseRngLib.inf + [Components.IA32, Components.X64] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf @@ -168,7 +171,6 @@ [Components.IA32, Components.X64] MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf MdePkg/Library/SmmMemLib/SmmMemLib.inf MdePkg/Library/SmmIoLib/SmmIoLib.inf - MdePkg/Library/BaseRngLib/BaseRngLib.inf MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf b/MdePkg/Library/BaseRngLib/BaseRngLib.inf index 31740751c69c..1dc3249a8c20 100644 --- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf +++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -1,9 +1,10 @@ ## @file # Instance of RNG (Random Number Generator) Library. # -# BaseRng Library that uses CPU RdRand instruction access to provide -# high-quality random numbers. +# BaseRng Library that uses CPU RNG instructions (e.g. RdRand) to +# provide high-quality random numbers. # +# Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR> # Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -22,11 +23,18 @@ [Defines] CONSTRUCTOR = BaseRngLibConstructor # -# VALID_ARCHITECTURES = IA32 X64 +# VALID_ARCHITECTURES = IA32 X64 AARCH64 # -[Sources.Ia32, Sources.X64] +[Sources] BaseRng.c + BaseRngLibInternals.h + +[Sources.Ia32, Sources.X64] + Rand/RdRand.c + +[Sources.AARCH64] + AArch64/Rndr.c [Packages] MdePkg/MdePkg.dec diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h new file mode 100644 index 000000000000..44fda69c9eec --- /dev/null +++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h @@ -0,0 +1,31 @@ +/** @file + + Architecture specific interface to RNG functionality. + +Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef BASE_RNGLIB_INTERNALS_H_ + +BOOLEAN +EFIAPI +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ); + +BOOLEAN +EFIAPI +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ); + +BOOLEAN +EFIAPI +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ); + +#endif // BASE_RNGLIB_INTERNALS_H_ diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c new file mode 100644 index 000000000000..19643237923a --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c @@ -0,0 +1,121 @@ +/** @file + Random number generator service that uses the RNDR instruction + to provide high-quality random numbers. + + Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR> + Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> + +#include <Library/RngLib.h> + +#include "BaseRngLibInternals.h" + +// +// Bit mask used to determine if RNDR instruction is supported. +// +#define RNDR_MASK ((UINT64)MAX_UINT16 << 60U) + +/** + The constructor function checks whether or not RNDR instruction is supported + by the host hardware. + + The constructor function checks whether or not RNDR instruction is supported. + It will ASSERT() if RNDR instruction is not supported. + It will always return RETURN_SUCCESS. + + @retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +RETURN_STATUS +EFIAPI +BaseRngLibConstructor ( + VOID + ) +{ + UINT64 Isar0; + // + // Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by + // MSR. A non-zero value indicates that the processor supports the RNDR instruction. + // + Isar0 = ArmReadIdIsar0 (); + ASSERT ((Isar0 & RNDR_MASK) != 0); + (void)Isar0; + + return RETURN_SUCCESS; +} + + +/** + Generates a 16-bit random number. + + @param[out] Rand Buffer pointer to store the 16-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + +**/ +BOOLEAN +EFIAPI +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ) +{ + UINT64 Rand64; + + if (ArchGetRandomNumber64 (&Rand64)) { + *Rand = Rand64 & MAX_UINT16; + return TRUE; + } + + return FALSE; +} + +/** + Generates a 32-bit random number. + + @param[out] Rand Buffer pointer to store the 32-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + +**/ +BOOLEAN +EFIAPI +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ) +{ + UINT64 Rand64; + + if (ArchGetRandomNumber64 (&Rand64)) { + *Rand = Rand64 & MAX_UINT32; + return TRUE; + } + + return FALSE; +} + +/** + Generates a 64-bit random number. + + @param[out] Rand Buffer pointer to store the 64-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + +**/ +BOOLEAN +EFIAPI +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ) +{ + return ArmRndr (Rand); +} + diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c b/MdePkg/Library/BaseRngLib/BaseRng.c index 7ad7aec9d38f..072fa37d3394 100644 --- a/MdePkg/Library/BaseRngLib/BaseRng.c +++ b/MdePkg/Library/BaseRngLib/BaseRng.c @@ -1,8 +1,10 @@ /** @file - Random number generator services that uses RdRand instruction access - to provide high-quality random numbers. + Random number generator services that uses CPU RNG instructions to + provide high-quality random numbers. +Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR> Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Library/BaseLib.h> #include <Library/DebugLib.h> -// -// Bit mask used to determine if RdRand instruction is supported. -// -#define RDRAND_MASK BIT30 +#include "BaseRngLibInternals.h" // // Limited retry number when valid random data is returned. // Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32 -// Architectures Software Developer's Mannual". +// Architectures Software Developer's Manual". // -#define RDRAND_RETRY_LIMIT 10 +#define GETRANDOM_RETRY_LIMIT 10 -/** - The constructor function checks whether or not RDRAND instruction is supported - by the host hardware. - - The constructor function checks whether or not RDRAND instruction is supported. - It will ASSERT() if RDRAND instruction is not supported. - It will always return RETURN_SUCCESS. - - @retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -RETURN_STATUS -EFIAPI -BaseRngLibConstructor ( - VOID - ) -{ - UINT32 RegEcx; - - // - // Determine RDRAND support by examining bit 30 of the ECX register returned by - // CPUID. A value of 1 indicates that processor support RDRAND instruction. - // - AsmCpuid (1, 0, 0, &RegEcx, 0); - ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK); - - return RETURN_SUCCESS; -} /** Generates a 16-bit random number. @@ -75,8 +46,8 @@ GetRandomNumber16 ( // // A loop to fetch a 16 bit random value with a retry count limit. // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand16 (Rand)) { + for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) { + if (ArchGetRandomNumber16 (Rand)) { return TRUE; } } @@ -108,8 +79,8 @@ GetRandomNumber32 ( // // A loop to fetch a 32 bit random value with a retry count limit. // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand32 (Rand)) { + for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) { + if (ArchGetRandomNumber32 (Rand)) { return TRUE; } } @@ -141,8 +112,8 @@ GetRandomNumber64 ( // // A loop to fetch a 64 bit random value with a retry count limit. // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand64 (Rand)) { + for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) { + if (ArchGetRandomNumber64 (Rand)) { return TRUE; } } diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c new file mode 100644 index 000000000000..3f1378064b4c --- /dev/null +++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c @@ -0,0 +1,103 @@ +/** @file + Random number generator services that uses RdRand instruction access + to provide high-quality random numbers. + +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> + +#include "BaseRngLibInternals.h" + +// +// Bit mask used to determine if RdRand instruction is supported. +// +#define RDRAND_MASK BIT30 + +/** + The constructor function checks whether or not RDRAND instruction is supported + by the host hardware. + + The constructor function checks whether or not RDRAND instruction is supported. + It will ASSERT() if RDRAND instruction is not supported. + It will always return RETURN_SUCCESS. + + @retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +RETURN_STATUS +EFIAPI +BaseRngLibConstructor ( + VOID + ) +{ + UINT32 RegEcx; + + // + // Determine RDRAND support by examining bit 30 of the ECX register returned by + // CPUID. A value of 1 indicates that processor support RDRAND instruction. + // + AsmCpuid (1, 0, 0, &RegEcx, 0); + ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK); + + return RETURN_SUCCESS; +} + +/** + Generates a 16-bit random number. + + @param[out] Rand Buffer pointer to store the 16-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + +**/ +BOOLEAN +EFIAPI +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ) +{ + return AsmRdRand16 (Rand); +} + +/** + Generates a 32-bit random number. + + @param[out] Rand Buffer pointer to store the 32-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + +**/ +BOOLEAN +EFIAPI +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ) +{ + return AsmRdRand32 (Rand); +} + +/** + Generates a 64-bit random number. + + @param[out] Rand Buffer pointer to store the 64-bit random value. + + @retval TRUE Random number generated successfully. + @retval FALSE Failed to generate the random number. + +**/ +BOOLEAN +EFIAPI +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ) +{ + return AsmRdRand64 (Rand); +} + diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni b/MdePkg/Library/BaseRngLib/BaseRngLib.uni index f3ed954c5209..8c7fe1219450 100644 --- a/MdePkg/Library/BaseRngLib/BaseRngLib.uni +++ b/MdePkg/Library/BaseRngLib/BaseRngLib.uni @@ -1,8 +1,8 @@ // /** @file // Instance of RNG (Random Number Generator) Library. // -// BaseRng Library that uses CPU RdRand instruction access to provide -// high-quality random numbers. +// BaseRng Library that uses CPU RNG instructions to provide high-quality +// random numbers. // // Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> // @@ -13,5 +13,5 @@ #string STR_MODULE_ABSTRACT #language en-US "Instance of RNG Library" -#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RdRand instruction access to provide high-quality random numbers" +#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RNG instructions to provide high-quality random numbers" -- 2.26.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#74580): https://edk2.groups.io/g/devel/message/74580 Mute This Topic: https://groups.io/mt/82440612/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-