/** @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
#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
\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
\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
\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
{\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