OpenSSL_1_1_1b doesn't implement rand_pool_* functions for UEFI.\r
The file implement these functions.\r
\r
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <openssl/aes.h>\r
\r
#include <Uefi.h>\r
-#include <Library/TimerLib.h>\r
-\r
-#include "rand_pool_noise.h"\r
-\r
-/**\r
- Get some randomness from low-order bits of GetPerformanceCounter results.\r
- And combine them to the 64-bit value\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.\r
-**/\r
-STATIC\r
-BOOLEAN\r
-EFIAPI\r
-GetRandNoise64FromPerformanceCounter(\r
- OUT UINT64 *Rand\r
- )\r
-{\r
- UINT32 Index;\r
- UINT32 *RandPtr;\r
-\r
- if (NULL == Rand) {\r
- return FALSE;\r
- }\r
-\r
- RandPtr = (UINT32 *) Rand;\r
-\r
- for (Index = 0; Index < 2; Index ++) {\r
- *RandPtr = (UINT32) (GetPerformanceCounter () & 0xFF);\r
- MicroSecondDelay (10);\r
- RandPtr++;\r
- }\r
-\r
- return TRUE;\r
-}\r
+#include <Library/RngLib.h>\r
\r
/**\r
Calls RandomNumber64 to fill\r
a buffer of arbitrary size with random bytes.\r
+ This is a shim layer to RngLib.\r
\r
@param[in] Length Size of the buffer, in bytes, to fill with.\r
@param[out] RandBuffer Pointer to the buffer to store the random result.\r
\r
- @retval EFI_SUCCESS Random bytes generation succeeded.\r
- @retval EFI_NOT_READY Failed to request random bytes.\r
+ @retval TRUE Random bytes generation succeeded.\r
+ @retval FALSE Failed to request random bytes.\r
\r
**/\r
STATIC\r
EFIAPI\r
RandGetBytes (\r
IN UINTN Length,\r
- OUT UINT8 *RandBuffer\r
+ OUT UINT8 *RandBuffer\r
)\r
{\r
BOOLEAN Ret;\r
\r
Ret = FALSE;\r
\r
+ if (RandBuffer == NULL) {\r
+ DEBUG((DEBUG_ERROR, "[OPENSSL_RAND_POOL] NULL RandBuffer. No random numbers are generated and your system is not secure\n"));\r
+ ASSERT (RandBuffer != NULL); // Since we can't generate random numbers, we should assert. Otherwise we will just blow up later.\r
+ return Ret;\r
+ }\r
+\r
+\r
while (Length > 0) {\r
- //\r
- // Get random noise from platform.\r
- // If it failed, fallback to PerformanceCounter\r
- // If you really care about security, you must override\r
- // GetRandomNoise64FromPlatform.\r
- //\r
- Ret = GetRandomNoise64 (&TempRand);\r
- if (Ret == FALSE) {\r
- Ret = GetRandNoise64FromPerformanceCounter (&TempRand);\r
- }\r
+ // Use RngLib to get random number\r
+ Ret = GetRandomNumber64 (&TempRand);\r
+\r
if (!Ret) {\r
return Ret;\r
}\r
*((UINT64*) RandBuffer) = TempRand;\r
RandBuffer += sizeof (UINT64);\r
Length -= sizeof (TempRand);\r
- } else {\r
+ }\r
+ else {\r
CopyMem (RandBuffer, &TempRand, Length);\r
Length = 0;\r
}\r
return Ret;\r
}\r
\r
-/**\r
- Creates a 128bit random value that is fully forward and backward prediction resistant,\r
- suitable for seeding a NIST SP800-90 Compliant.\r
- This function takes multiple random numbers from PerformanceCounter to ensure reseeding\r
- and performs AES-CBC-MAC over the data to compute the seed value.\r
-\r
- @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed.\r
-\r
- @retval TRUE Random seed generation succeeded.\r
- @retval FALSE Failed to request random bytes.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-EFIAPI\r
-RandGetSeed128 (\r
- OUT UINT8 *SeedBuffer\r
- )\r
-{\r
- BOOLEAN Ret;\r
- UINT8 RandByte[16];\r
- UINT8 Key[16];\r
- UINT8 Ffv[16];\r
- UINT8 Xored[16];\r
- UINT32 Index;\r
- UINT32 Index2;\r
- AES_KEY AESKey;\r
-\r
- //\r
- // Chose an arbitrary key and zero the feed_forward_value (FFV)\r
- //\r
- for (Index = 0; Index < 16; Index++) {\r
- Key[Index] = (UINT8) Index;\r
- Ffv[Index] = 0;\r
- }\r
-\r
- AES_set_encrypt_key (Key, 16 * 8, &AESKey);\r
-\r
- //\r
- // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value\r
- // The 10us gaps will ensure multiple reseeds within the system time with a large\r
- // design margin.\r
- //\r
- for (Index = 0; Index < 32; Index++) {\r
- MicroSecondDelay (10);\r
- Ret = RandGetBytes (16, RandByte);\r
- if (!Ret) {\r
- return Ret;\r
- }\r
-\r
- //\r
- // Perform XOR operations on two 128-bit value.\r
- //\r
- for (Index2 = 0; Index2 < 16; Index2++) {\r
- Xored[Index2] = RandByte[Index2] ^ Ffv[Index2];\r
- }\r
-\r
- AES_encrypt (Xored, Ffv, &AESKey);\r
- }\r
-\r
- for (Index = 0; Index < 16; Index++) {\r
- SeedBuffer[Index] = Ffv[Index];\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-/**\r
- Generate high-quality entropy source.\r
-\r
- @param[in] Length Size of the buffer, in bytes, to fill with.\r
- @param[out] Entropy Pointer to the buffer to store the entropy data.\r
-\r
- @retval EFI_SUCCESS Entropy generation succeeded.\r
- @retval EFI_NOT_READY Failed to request random data.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-EFIAPI\r
-RandGenerateEntropy (\r
- IN UINTN Length,\r
- OUT UINT8 *Entropy\r
- )\r
-{\r
- BOOLEAN Ret;\r
- UINTN BlockCount;\r
- UINT8 Seed[16];\r
- UINT8 *Ptr;\r
-\r
- BlockCount = Length / 16;\r
- Ptr = (UINT8 *) Entropy;\r
-\r
- //\r
- // Generate high-quality seed for DRBG Entropy\r
- //\r
- while (BlockCount > 0) {\r
- Ret = RandGetSeed128 (Seed);\r
- if (!Ret) {\r
- return Ret;\r
- }\r
- CopyMem (Ptr, Seed, 16);\r
-\r
- BlockCount--;\r
- Ptr = Ptr + 16;\r
- }\r
-\r
- //\r
- // Populate the remained data as request.\r
- //\r
- Ret = RandGetSeed128 (Seed);\r
- if (!Ret) {\r
- return Ret;\r
- }\r
- CopyMem (Ptr, Seed, (Length % 16));\r
-\r
- return Ret;\r
-}\r
-\r
/*\r
* Add random bytes to the pool to acquire requested amount of entropy\r
*\r
*\r
* This is OpenSSL required interface.\r
*/\r
-size_t rand_pool_acquire_entropy(RAND_POOL *pool)\r
+size_t\r
+rand_pool_acquire_entropy (\r
+ RAND_POOL *pool\r
+ )\r
{\r
- BOOLEAN Ret;\r
- size_t bytes_needed;\r
- unsigned char * buffer;\r
+ BOOLEAN Ret;\r
+ size_t Bytes_needed;\r
+ unsigned char *Buffer;\r
\r
- bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);\r
- if (bytes_needed > 0) {\r
- buffer = rand_pool_add_begin(pool, bytes_needed);\r
+ Bytes_needed = rand_pool_bytes_needed (pool, 1 /*entropy_factor*/);\r
+ if (Bytes_needed > 0) {\r
+ Buffer = rand_pool_add_begin (pool, Bytes_needed);\r
\r
- if (buffer != NULL) {\r
- Ret = RandGenerateEntropy(bytes_needed, buffer);\r
+ if (Buffer != NULL) {\r
+ Ret = RandGetBytes (Bytes_needed, Buffer);\r
if (FALSE == Ret) {\r
- rand_pool_add_end(pool, 0, 0);\r
- } else {\r
- rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);\r
+ rand_pool_add_end (pool, 0, 0);\r
+ }\r
+ else {\r
+ rand_pool_add_end (pool, Bytes_needed, 8 * Bytes_needed);\r
}\r
}\r
}\r
\r
- return rand_pool_entropy_available(pool);\r
+ return rand_pool_entropy_available (pool);\r
}\r
\r
/*\r
*\r
* This is OpenSSL required interface.\r
*/\r
-int rand_pool_add_nonce_data(RAND_POOL *pool)\r
+int\r
+rand_pool_add_nonce_data (\r
+ RAND_POOL *pool\r
+ )\r
{\r
- struct {\r
- UINT64 Rand;\r
- UINT64 TimerValue;\r
- } data = { 0 };\r
-\r
- RandGetBytes(8, (UINT8 *)&(data.Rand));\r
- data.TimerValue = GetPerformanceCounter();\r
+ UINT8 data[16];\r
+ RandGetBytes (sizeof(data), data);\r
\r
- return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);\r
+ return rand_pool_add (pool, (unsigned char*)&data, sizeof(data), 0);\r
}\r
\r
/*\r
*\r
* This is OpenSSL required interface.\r
*/\r
-int rand_pool_add_additional_data(RAND_POOL *pool)\r
+int\r
+rand_pool_add_additional_data (\r
+ RAND_POOL *pool\r
+ )\r
{\r
- struct {\r
- UINT64 Rand;\r
- UINT64 TimerValue;\r
- } data = { 0 };\r
+ UINT8 data[16];\r
+ RandGetBytes (sizeof(data), data);\r
\r
- RandGetBytes(8, (UINT8 *)&(data.Rand));\r
- data.TimerValue = GetPerformanceCounter();\r
-\r
- return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);\r
+ return rand_pool_add (pool, (unsigned char*)&data, sizeof(data), 0);\r
}\r
\r
/*\r
*\r
* This is OpenSSL required interface.\r
*/\r
-int rand_pool_init(void)\r
+int\r
+rand_pool_init (\r
+ VOID\r
+ )\r
{\r
return 1;\r
}\r
*\r
* This is OpenSSL required interface.\r
*/\r
-void rand_pool_cleanup(void)\r
+VOID\r
+rand_pool_cleanup(\r
+ VOID\r
+ )\r
{\r
}\r
\r
*\r
* This is OpenSSL required interface.\r
*/\r
-void rand_pool_keep_random_devices_open(int keep)\r
+VOID\r
+rand_pool_keep_random_devices_open (\r
+ int keep\r
+ )\r
{\r
}\r
-\r