]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Library/OpensslLib/rand_pool.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / CryptoPkg / Library / OpensslLib / rand_pool.c
index 9d2a4ad1382331426b52896f21283a8d0a75f462..13e860a853d09772419b174dc82a9a6ce17630c4 100644 (file)
@@ -2,95 +2,60 @@
   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 "internal/rand_int.h"\r
+#include "crypto/rand.h"\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
 BOOLEAN\r
 EFIAPI\r
 RandGetBytes (\r
-  IN UINTN         Length,\r
-  OUT UINT8        *RandBuffer\r
+  IN UINTN   Length,\r
+  OUT UINT8  *RandBuffer\r
   )\r
 {\r
-  BOOLEAN     Ret;\r
-  UINT64      TempRand;\r
+  BOOLEAN  Ret;\r
+  UINT64   TempRand;\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
   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
+\r
     if (Length >= sizeof (TempRand)) {\r
-      *((UINT64*) RandBuffer) = TempRand;\r
-      RandBuffer += sizeof (UINT64);\r
-      Length -= sizeof (TempRand);\r
+      *((UINT64 *)RandBuffer) = TempRand;\r
+      RandBuffer             += sizeof (UINT64);\r
+      Length                 -= sizeof (TempRand);\r
     } else {\r
       CopyMem (RandBuffer, &TempRand, Length);\r
       Length = 0;\r
@@ -100,125 +65,6 @@ RandGetBytes (
   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 arbitary 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
@@ -227,27 +73,30 @@ RandGenerateEntropy (
  *\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
+        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, 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
@@ -255,17 +104,16 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
  *\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
+  UINT8  data[16];\r
 \r
-  RandGetBytes(8, (UINT8 *)&(data.Rand));\r
-  data.TimerValue = GetPerformanceCounter();\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
@@ -273,44 +121,51 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
  *\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
 \r
-  RandGetBytes(8, (UINT8 *)&(data.Rand));\r
-  data.TimerValue = GetPerformanceCounter();\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
- * Dummy Implememtation for UEFI\r
+ * Dummy Implementation for UEFI\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
 /*\r
- * Dummy Implememtation for UEFI\r
+ * Dummy Implementation for UEFI\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
- * Dummy Implememtation for UEFI\r
+ * Dummy Implementation for UEFI\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