]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseRngLib/BaseRng.c
MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions
[mirror_edk2.git] / MdePkg / Library / BaseRngLib / BaseRng.c
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