]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions
authorRebecca Cran <rebecca@nuviainc.com>
Mon, 10 May 2021 21:53:07 +0000 (15:53 -0600)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 11 May 2021 16:26:05 +0000 (16:26 +0000)
Make BaseRngLib more generic by moving x86-specific functionality into
'Rand' and adding files under 'AArch64' to support the optional ARMv8.5
RNG instruction RNDR that is a part of FEAT_RNG.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
13 files changed:
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S [new file with mode: 0644]
MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm [new file with mode: 0644]
MdePkg/Library/BaseRngLib/AArch64/ArmRng.S [new file with mode: 0644]
MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm [new file with mode: 0644]
MdePkg/Library/BaseRngLib/AArch64/ArmRng.h [new file with mode: 0644]
MdePkg/Library/BaseRngLib/AArch64/Rndr.c [new file with mode: 0644]
MdePkg/Library/BaseRngLib/BaseRng.c
MdePkg/Library/BaseRngLib/BaseRngLib.inf
MdePkg/Library/BaseRngLib/BaseRngLib.uni
MdePkg/Library/BaseRngLib/BaseRngLibInternals.h [new file with mode: 0644]
MdePkg/Library/BaseRngLib/Rand/RdRand.c [new file with mode: 0644]
MdePkg/MdePkg.dec
MdePkg/MdePkg.dsc

diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
new file mode 100644 (file)
index 0000000..82a00d3
--- /dev/null
@@ -0,0 +1,31 @@
+#------------------------------------------------------------------------------\r
+#\r
+# ArmReadIdIsar0() for AArch64\r
+#\r
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+.text\r
+.p2align 2\r
+GCC_ASM_EXPORT(ArmReadIdIsar0)\r
+\r
+#/**\r
+#  Reads the ID_AA64ISAR0 Register.\r
+#\r
+#  @return The contents of the ID_AA64ISAR0 register.\r
+#\r
+#**/\r
+#UINT64\r
+#EFIAPI\r
+#ArmReadIdIsar0 (\r
+#  VOID\r
+#  );\r
+#\r
+ASM_PFX(ArmReadIdIsar0):\r
+  mrs  x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register\r
+  ret\r
+\r
+\r
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
new file mode 100644 (file)
index 0000000..1d9f9a8
--- /dev/null
@@ -0,0 +1,30 @@
+;------------------------------------------------------------------------------\r
+;\r
+; ArmReadIdIsar0() for AArch64\r
+;\r
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+;\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+  EXPORT ArmReadIdIsar0\r
+  AREA BaseLib_LowLevel, CODE, READONLY\r
+\r
+;/**\r
+;  Reads the ID_AA64ISAR0 Register.\r
+;\r
+; @return The contents of the ID_AA64ISAR0 register.\r
+;\r
+;**/\r
+;UINT64\r
+;EFIAPI\r
+;ArmReadIdIsar0 (\r
+;  VOID\r
+;  );\r
+;\r
+ArmReadIdIsar0\r
+  mrs  x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register\r
+  ret\r
+\r
+  END\r
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S
new file mode 100644 (file)
index 0000000..5159f46
--- /dev/null
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------\r
+#\r
+# ArmRndr() for AArch64\r
+#\r
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#include "BaseRngLibInternals.h"\r
+\r
+.text\r
+.p2align 2\r
+GCC_ASM_EXPORT(ArmRndr)\r
+\r
+#/**\r
+#  Generates a random number using RNDR.\r
+#  Returns TRUE on success; FALSE on failure.\r
+#\r
+#  @param[out] Rand     Buffer pointer to store the 64-bit random value.\r
+#\r
+#  @retval TRUE         Random number generated successfully.\r
+#  @retval FALSE        Failed to generate the random number.\r
+#\r
+#**/\r
+#BOOLEAN\r
+#EFIAPI\r
+#ArmRndr (\r
+#  OUT UINT64 *Rand\r
+#  );\r
+#\r
+ASM_PFX(ArmRndr):\r
+  mrs  x1, RNDR\r
+  str  x1, [x0]\r
+  cset x0, ne    // RNDR sets NZCV to 0b0100 on failure\r
+  ret\r
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm
new file mode 100644 (file)
index 0000000..3314419
--- /dev/null
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------\r
+;\r
+; ArmRndr() for AArch64\r
+;\r
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+;\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+#include "BaseRngLibInternals.h"\r
+\r
+  EXPORT ArmRndr\r
+  AREA BaseLib_LowLevel, CODE, READONLY\r
+\r
+\r
+;/**\r
+;  Generates a random number using RNDR.\r
+;  Returns TRUE on success; FALSE on failure.\r
+;\r
+;  @param[out] Rand     Buffer pointer to store the 64-bit random value.\r
+;\r
+;  @retval TRUE         Random number generated successfully.\r
+;  @retval FALSE        Failed to generate the random number.\r
+;\r
+;**/\r
+;BOOLEAN\r
+;EFIAPI\r
+;ArmRndr (\r
+;  OUT UINT64 *Rand\r
+;  );\r
+;\r
+ArmRndr\r
+  mrs  x1, RNDR\r
+  str  x1, [x0]\r
+  cset x0, ne    // RNDR sets NZCV to 0b0100 on failure\r
+  ret\r
+\r
+  END\r
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
new file mode 100644 (file)
index 0000000..e0a5673
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+  Random number generator service that uses the RNDR instruction\r
+  to provide pseudorandom numbers.\r
+\r
+  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef ARM_RNG_H_\r
+#define ARM_RNG_H_\r
+\r
+/**\r
+  Generates a random number using RNDR.\r
+  Returns TRUE on success; FALSE on failure.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArmRndr (\r
+  OUT UINT64 *Rand\r
+  );\r
+\r
+/**\r
+  Reads the ID_AA64ISAR0 Register.\r
+\r
+  @return The contents of the ID_AA64ISAR0 register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+ArmReadIdIsar0 (\r
+  VOID\r
+  );\r
+\r
+#endif /* ARM_RNG_H_ */\r
diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
new file mode 100644 (file)
index 0000000..c9f8c81
--- /dev/null
@@ -0,0 +1,139 @@
+/** @file\r
+  Random number generator service that uses the RNDR instruction\r
+  to provide pseudorandom numbers.\r
+\r
+  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/RngLib.h>\r
+\r
+#include "ArmRng.h"\r
+#include "BaseRngLibInternals.h"\r
+\r
+STATIC BOOLEAN mRndrSupported;\r
+\r
+//\r
+// Bit mask used to determine if RNDR instruction is supported.\r
+//\r
+#define RNDR_MASK                  ((UINT64)MAX_UINT16 << 60U)\r
+\r
+/**\r
+  The constructor function checks whether or not RNDR instruction is supported\r
+  by the host hardware.\r
+\r
+  The constructor function checks whether or not RNDR instruction is supported.\r
+  It will ASSERT() if RNDR instruction is not supported.\r
+  It will always return EFI_SUCCESS.\r
+\r
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseRngLibConstructor (\r
+  VOID\r
+  )\r
+{\r
+  UINT64 Isar0;\r
+  //\r
+  // Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by\r
+  // MSR. A non-zero value indicates that the processor supports the RNDR instruction.\r
+  //\r
+  Isar0 = ArmReadIdIsar0 ();\r
+  ASSERT ((Isar0 & RNDR_MASK) != 0);\r
+\r
+  mRndrSupported = ((Isar0 & RNDR_MASK) != 0);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Generates a 16-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 16-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber16 (\r
+  OUT     UINT16                    *Rand\r
+  )\r
+{\r
+  UINT64 Rand64;\r
+\r
+  if (ArchGetRandomNumber64 (&Rand64)) {\r
+    *Rand = Rand64 & MAX_UINT16;\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Generates a 32-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 32-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber32 (\r
+  OUT     UINT32                    *Rand\r
+  )\r
+{\r
+  UINT64 Rand64;\r
+\r
+  if (ArchGetRandomNumber64 (&Rand64)) {\r
+    *Rand = Rand64 & MAX_UINT32;\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Generates a 64-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber64 (\r
+  OUT     UINT64                    *Rand\r
+  )\r
+{\r
+  return ArmRndr (Rand);\r
+}\r
+\r
+/**\r
+  Checks whether RNDR is supported.\r
+\r
+  @retval TRUE         RNDR is supported.\r
+  @retval FALSE        RNDR is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchIsRngSupported (\r
+  VOID\r
+  )\r
+{\r
+  return mRndrSupported;\r
+}\r
index 7ad7aec9d38f1949a9eea33193aa742f16d99886..5b63d8f7146b2ba8d42b692688b6d567fc256d00 100644 (file)
@@ -1,8 +1,10 @@
 /** @file\r
-  Random number generator services that uses RdRand instruction access\r
-  to provide high-quality random numbers.\r
+  Random number generator services that uses CPU RNG instructions to\r
+  provide random numbers.\r
 \r
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
-//\r
-// Bit mask used to determine if RdRand instruction is supported.\r
-//\r
-#define RDRAND_MASK                  BIT30\r
+#include "BaseRngLibInternals.h"\r
 \r
 //\r
 // Limited retry number when valid random data is returned.\r
 // Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32\r
-// Architectures Software Developer's Mannual".\r
+// Architectures Software Developer's Manual".\r
 //\r
-#define RDRAND_RETRY_LIMIT           10\r
-\r
-/**\r
-  The constructor function checks whether or not RDRAND instruction is supported\r
-  by the host hardware.\r
-\r
-  The constructor function checks whether or not RDRAND instruction is supported.\r
-  It will ASSERT() if RDRAND instruction is not supported.\r
-  It will always return RETURN_SUCCESS.\r
-\r
-  @retval RETURN_SUCCESS   The constructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-RETURN_STATUS\r
-EFIAPI\r
-BaseRngLibConstructor (\r
-  VOID\r
-  )\r
-{\r
-  UINT32  RegEcx;\r
-\r
-  //\r
-  // Determine RDRAND support by examining bit 30 of the ECX register returned by\r
-  // CPUID. A value of 1 indicates that processor support RDRAND instruction.\r
-  //\r
-  AsmCpuid (1, 0, 0, &RegEcx, 0);\r
-  ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);\r
+#define GETRANDOM_RETRY_LIMIT           10\r
 \r
-  return RETURN_SUCCESS;\r
-}\r
 \r
 /**\r
   Generates a 16-bit random number.\r
@@ -72,11 +43,19 @@ GetRandomNumber16 (
 \r
   ASSERT (Rand != NULL);\r
 \r
+  if (Rand == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (!ArchIsRngSupported ()) {\r
+    return FALSE;\r
+  }\r
+\r
   //\r
   // A loop to fetch a 16 bit random value with a retry count limit.\r
   //\r
-  for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {\r
-    if (AsmRdRand16 (Rand)) {\r
+  for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {\r
+    if (ArchGetRandomNumber16 (Rand)) {\r
       return TRUE;\r
     }\r
   }\r
@@ -105,11 +84,19 @@ GetRandomNumber32 (
 \r
   ASSERT (Rand != NULL);\r
 \r
+  if (Rand == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (!ArchIsRngSupported ()) {\r
+    return FALSE;\r
+  }\r
+\r
   //\r
   // A loop to fetch a 32 bit random value with a retry count limit.\r
   //\r
-  for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {\r
-    if (AsmRdRand32 (Rand)) {\r
+  for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {\r
+    if (ArchGetRandomNumber32 (Rand)) {\r
       return TRUE;\r
     }\r
   }\r
@@ -138,11 +125,19 @@ GetRandomNumber64 (
 \r
   ASSERT (Rand != NULL);\r
 \r
+  if (Rand == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (!ArchIsRngSupported ()) {\r
+    return FALSE;\r
+  }\r
+\r
   //\r
   // A loop to fetch a 64 bit random value with a retry count limit.\r
   //\r
-  for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) {\r
-    if (AsmRdRand64 (Rand)) {\r
+  for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {\r
+    if (ArchGetRandomNumber64 (Rand)) {\r
       return TRUE;\r
     }\r
   }\r
@@ -169,6 +164,14 @@ GetRandomNumber128 (
 {\r
   ASSERT (Rand != NULL);\r
 \r
+  if (Rand == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (!ArchIsRngSupported ()) {\r
+    return FALSE;\r
+  }\r
+\r
   //\r
   // Read first 64 bits\r
   //\r
index 31740751c69ce205dfe0f0bf5a9ade6159689298..1fcceb941495f32528a166f2fe58cac4fb2eb954 100644 (file)
@@ -1,9 +1,10 @@
 ## @file\r
 #  Instance of RNG (Random Number Generator) Library.\r
 #\r
-#  BaseRng Library that uses CPU RdRand instruction access to provide\r
-#  high-quality random numbers.\r
+#  BaseRng Library that uses CPU RNG instructions (e.g. RdRand) to\r
+#  provide random numbers.\r
 #\r
+#  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
 #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
   CONSTRUCTOR                    = BaseRngLibConstructor\r
 \r
 #\r
-#  VALID_ARCHITECTURES           = IA32 X64\r
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64\r
 #\r
 \r
-[Sources.Ia32, Sources.X64]\r
+[Sources]\r
   BaseRng.c\r
+  BaseRngLibInternals.h\r
+\r
+[Sources.Ia32, Sources.X64]\r
+  Rand/RdRand.c\r
+\r
+[Sources.AARCH64]\r
+  AArch64/Rndr.c\r
+  AArch64/ArmRng.h\r
+\r
+  AArch64/ArmReadIdIsar0.S   | GCC\r
+  AArch64/ArmRng.S           | GCC\r
+\r
+  AArch64/ArmReadIdIsar0.asm | MSFT\r
+  AArch64/ArmRng.asm         | MSFT\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
index f3ed954c5209ee8b18034d6ed709a1232f89bc5c..4e1fbfb0e40e2a843f0dc400b8adc9d6032ed977 100644 (file)
@@ -1,8 +1,8 @@
 // /** @file\r
 // Instance of RNG (Random Number Generator) Library.\r
 //\r
-// BaseRng Library that uses CPU RdRand instruction access to provide\r
-// high-quality random numbers.\r
+// BaseRng Library that uses CPU RNG instructions to provide\r
+// random numbers.\r
 //\r
 // Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
 //\r
@@ -13,5 +13,4 @@
 \r
 #string STR_MODULE_ABSTRACT             #language en-US "Instance of RNG Library"\r
 \r
-#string STR_MODULE_DESCRIPTION          #language en-US "BaseRng Library that uses CPU RdRand instruction access to provide high-quality random numbers"\r
-\r
+#string STR_MODULE_DESCRIPTION          #language en-US "BaseRng Library that uses CPU RNG instructions to provide random numbers"\r
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
new file mode 100644 (file)
index 0000000..b6b4e9e
--- /dev/null
@@ -0,0 +1,78 @@
+/** @file\r
+\r
+  Architecture specific interface to RNG functionality.\r
+\r
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef BASE_RNGLIB_INTERNALS_H_\r
+\r
+/**\r
+  Generates a 16-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 16-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber16 (\r
+  OUT UINT16 *Rand\r
+  );\r
+\r
+/**\r
+  Generates a 32-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 32-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber32 (\r
+  OUT UINT32 *Rand\r
+  );\r
+\r
+/**\r
+  Generates a 64-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber64 (\r
+  OUT UINT64 *Rand\r
+  );\r
+\r
+/**\r
+  Checks whether the RNG instruction is supported.\r
+\r
+  @retval TRUE         RNG instruction is supported.\r
+  @retval FALSE        RNG instruction is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchIsRngSupported (\r
+  VOID\r
+  );\r
+\r
+#if defined (MDE_CPU_AARCH64)\r
+\r
+// RNDR, Random Number\r
+#define RNDR      S3_3_C2_C4_0\r
+\r
+#endif\r
+\r
+#endif    // BASE_RNGLIB_INTERNALS_H_\r
diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
new file mode 100644 (file)
index 0000000..09fb875
--- /dev/null
@@ -0,0 +1,131 @@
+/** @file\r
+  Random number generator services that uses RdRand instruction access\r
+  to provide high-quality random numbers.\r
+\r
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#include "BaseRngLibInternals.h"\r
+\r
+//\r
+// Bit mask used to determine if RdRand instruction is supported.\r
+//\r
+#define RDRAND_MASK                  BIT30\r
+\r
+\r
+STATIC BOOLEAN mRdRandSupported;\r
+\r
+/**\r
+  The constructor function checks whether or not RDRAND instruction is supported\r
+  by the host hardware.\r
+\r
+  The constructor function checks whether or not RDRAND instruction is supported.\r
+  It will ASSERT() if RDRAND instruction is not supported.\r
+  It will always return EFI_SUCCESS.\r
+\r
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseRngLibConstructor (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  RegEcx;\r
+\r
+  //\r
+  // Determine RDRAND support by examining bit 30 of the ECX register returned by\r
+  // CPUID. A value of 1 indicates that processor support RDRAND instruction.\r
+  //\r
+  AsmCpuid (1, 0, 0, &RegEcx, 0);\r
+  ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK);\r
+\r
+  mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Generates a 16-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 16-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber16 (\r
+  OUT     UINT16                    *Rand\r
+  )\r
+{\r
+  return AsmRdRand16 (Rand);\r
+}\r
+\r
+/**\r
+  Generates a 32-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 32-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber32 (\r
+  OUT     UINT32                    *Rand\r
+  )\r
+{\r
+  return AsmRdRand32 (Rand);\r
+}\r
+\r
+/**\r
+  Generates a 64-bit random number.\r
+\r
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.\r
+\r
+  @retval TRUE         Random number generated successfully.\r
+  @retval FALSE        Failed to generate the random number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchGetRandomNumber64 (\r
+  OUT     UINT64                    *Rand\r
+  )\r
+{\r
+  return AsmRdRand64 (Rand);\r
+}\r
+\r
+/**\r
+  Checks whether RDRAND is supported.\r
+\r
+  @retval TRUE         RDRAND is supported.\r
+  @retval FALSE        RDRAND is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+ArchIsRngSupported (\r
+  VOID\r
+  )\r
+{\r
+  /*\r
+     Existing software depends on this always returning TRUE, so for\r
+     now hard-code it.\r
+\r
+     return mRdRandSupported;\r
+  */\r
+  return TRUE;\r
+}\r
index 8965e903e0939c3a732f176f11fc19294378251e..b49f88d8e18f8a5fc4c25277763b4bf4c43f2463 100644 (file)
   #\r
   RegisterFilterLib|Include/Library/RegisterFilterLib.h\r
 \r
+[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]\r
+  ##  @libraryclass  Provides services to generate random number.\r
+  #\r
+  RngLib|Include/Library/RngLib.h\r
+\r
 [LibraryClasses.IA32, LibraryClasses.X64]\r
   ##  @libraryclass  Abstracts both S/W SMI generation and detection.\r
   ##\r
   #\r
   SmmPeriodicSmiLib|Include/Library/SmmPeriodicSmiLib.h\r
 \r
-  ##  @libraryclass  Provides services to generate random number.\r
-  #\r
-  RngLib|Include/Library/RngLib.h\r
-\r
   ##  @libraryclass  Provides services to log the SMI handler registration.\r
   SmiHandlerProfileLib|Include/Library/SmiHandlerProfileLib.h\r
 \r
index d363419006ea465f57134ef8872a2417df8bc53a..a94959169b2fd9d4b5bf7ad903bf5ce06566c60e 100644 (file)
   MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf\r
   MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf\r
 \r
+[Components.IA32, Components.X64, Components.AARCH64]\r
+  MdePkg/Library/BaseRngLib/BaseRngLib.inf\r
+\r
 [Components.IA32, Components.X64]\r
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf\r
   MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf\r
   MdePkg/Library/SmmMemLib/SmmMemLib.inf\r
   MdePkg/Library/SmmIoLib/SmmIoLib.inf\r
-  MdePkg/Library/BaseRngLib/BaseRngLib.inf\r
   MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf\r
   MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf\r
   MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf\r