]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
SecurityPkg: Fix spelling errors
[mirror_edk2.git] / SecurityPkg / RandomNumberGenerator / RngDxe / RdRand.c
index 7e618dc91f2349b1da8c0b674c9dd844a940fabf..e7dd5ab1811117f0af5064994641aaa6d9d586ee 100644 (file)
 /** @file\r
   Support routines for RDRAND instruction access.\r
 \r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
+#include <Library/RngLib.h>\r
 \r
 #include "RdRand.h"\r
 #include "AesCore.h"\r
 \r
-//\r
-// Bit mask used to determine if RdRand instruction is supported.\r
-//\r
-#define RDRAND_MASK    0x40000000\r
-\r
-/**\r
-  Determines whether or not RDRAND instruction is supported by the host hardware.\r
-\r
-  @retval EFI_SUCCESS          RDRAND instruction supported.\r
-  @retval EFI_UNSUPPORTED      RDRAND instruction not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsRdRandSupported (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT32      RegEax;\r
-  UINT32      RegEbx;\r
-  UINT32      RegEcx;\r
-  UINT32      RegEdx;\r
-  BOOLEAN     IsIntelCpu;\r
-\r
-  Status     = EFI_UNSUPPORTED;\r
-  IsIntelCpu = FALSE;\r
-  \r
-  //\r
-  // Checks whether the current processor is an Intel product by CPUID.\r
-  //\r
-  AsmCpuid (0, &RegEax, &RegEbx, &RegEcx, &RegEdx);\r
-  if ((CompareMem ((CHAR8 *)(&RegEbx), "Genu", 4) == 0) &&\r
-      (CompareMem ((CHAR8 *)(&RegEdx), "ineI", 4) == 0) &&\r
-      (CompareMem ((CHAR8 *)(&RegEcx), "ntel", 4) == 0)) {\r
-    IsIntelCpu = TRUE;\r
-  }\r
-\r
-  if (IsIntelCpu) {\r
-    //\r
-    // Determine RDRAND support by examining bit 30 of the ECX register returned by CPUID.\r
-    // A value of 1 indicates that processor supports RDRAND instruction.\r
-    //\r
-    AsmCpuid (1, 0, 0, &RegEcx, 0);\r
-\r
-    if ((RegEcx & RDRAND_MASK) == RDRAND_MASK) {\r
-      Status = EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Calls RDRAND to obtain a 16-bit random number.\r
-\r
-  @param[out]  Rand          Buffer pointer to store the random result.\r
-  @param[in]   NeedRetry     Determine whether or not to loop retry.\r
-\r
-  @retval EFI_SUCCESS        RDRAND call was successful.\r
-  @retval EFI_NOT_READY      Failed attempts to call RDRAND.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RdRand16 (\r
-  OUT UINT16       *Rand,\r
-  IN BOOLEAN       NeedRetry\r
-  )\r
-{\r
-  UINT32      Index;\r
-  UINT32      RetryCount;\r
-\r
-  if (NeedRetry) {\r
-    RetryCount = RETRY_LIMIT;\r
-  } else {\r
-    RetryCount = 1;\r
-  }\r
-\r
-  //\r
-  // Perform a single call to RDRAND, or enter a loop call until RDRAND succeeds.\r
-  //\r
-  for (Index = 0; Index < RetryCount; Index++) {\r
-    if (RdRand16Step (Rand)) {\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-  \r
-  return EFI_NOT_READY;\r
-}\r
-\r
-/**\r
-  Calls RDRAND to obtain a 32-bit random number.\r
-\r
-  @param[out]  Rand          Buffer pointer to store the random result.\r
-  @param[in]   NeedRetry     Determine whether or not to loop retry.\r
-\r
-  @retval EFI_SUCCESS        RDRAND call was successful.\r
-  @retval EFI_NOT_READY      Failed attempts to call RDRAND.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RdRand32 (\r
-  OUT UINT32       *Rand,\r
-  IN BOOLEAN       NeedRetry\r
-  )\r
-{\r
-  UINT32      Index;\r
-  UINT32      RetryCount;\r
-\r
-  if (NeedRetry) {\r
-    RetryCount = RETRY_LIMIT;\r
-  } else {\r
-    RetryCount = 1;\r
-  }\r
-\r
-  //\r
-  // Perform a single call to RDRAND, or enter a loop call until RDRAND succeeds.\r
-  //\r
-  for (Index = 0; Index < RetryCount; Index++) {\r
-    if (RdRand32Step (Rand)) {\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-  \r
-  return EFI_NOT_READY;\r
-}\r
-\r
-/**\r
-  Calls RDRAND to obtain a 64-bit random number.\r
-\r
-  @param[out]  Rand          Buffer pointer to store the random result.\r
-  @param[in]   NeedRetry     Determine whether or not to loop retry.\r
-\r
-  @retval EFI_SUCCESS        RDRAND call was successful.\r
-  @retval EFI_NOT_READY      Failed attempts to call RDRAND.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RdRand64 (\r
-  OUT UINT64       *Rand,\r
-  IN BOOLEAN       NeedRetry\r
-  )\r
-{\r
-  UINT32      Index;\r
-  UINT32      RetryCount;\r
-\r
-  if (NeedRetry) {\r
-    RetryCount = RETRY_LIMIT;\r
-  } else {\r
-    RetryCount = 1;\r
-  }\r
-\r
-  //\r
-  // Perform a single call to RDRAND, or enter a loop call until RDRAND succeeds.\r
-  //\r
-  for (Index = 0; Index < RetryCount; Index++) {\r
-    if (RdRand64Step (Rand)) {\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-  \r
-  return EFI_NOT_READY;\r
-}\r
-\r
 /**\r
   Calls RDRAND to fill a buffer of arbitrary size with random bytes.\r
 \r
@@ -199,80 +28,23 @@ RdRandGetBytes (
   OUT UINT8        *RandBuffer\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT8       *Start;\r
-  UINT8       *ResidualStart;\r
-  UINTN       *BlockStart;\r
-  UINTN       TempRand;\r
-  UINTN       Count;\r
-  UINTN       Residual;\r
-  UINTN       StartLen;\r
-  UINTN       BlockNum;\r
-  UINTN       Index;\r
-\r
-  ResidualStart = NULL;\r
-  TempRand      = 0;\r
-\r
-  //\r
-  // Compute the address of the first word aligned (32/64-bit) block in the \r
-  // destination buffer, depending on whether we are in 32- or 64-bit mode.\r
-  //\r
-  Start = RandBuffer;\r
-  if (((UINT32)(UINTN)Start % (UINT32)sizeof(UINTN)) == 0) {\r
-    BlockStart = (UINTN *)Start;\r
-    Count      = Length;\r
-    StartLen   = 0;\r
-  } else {\r
-    BlockStart = (UINTN *)(((UINTN)Start & ~(UINTN)(sizeof(UINTN) - 1)) + (UINTN)sizeof(UINTN));\r
-    Count      = Length - (sizeof (UINTN) - (UINT32)((UINTN)Start % sizeof (UINTN)));\r
-    StartLen   = (UINT32)((UINTN)BlockStart - (UINTN)Start);\r
-  }\r
-\r
-  //\r
-  // Compute the number of word blocks and the remaining number of bytes.\r
-  //\r
-  Residual = Count % sizeof (UINTN);\r
-  BlockNum = Count / sizeof (UINTN);\r
-  if (Residual != 0) {\r
-    ResidualStart = (UINT8 *) (BlockStart + BlockNum);\r
-  }\r
-\r
-  //\r
-  // Obtain a temporary random number for use in the residuals. Failout if retry fails.\r
-  //\r
-  if (StartLen > 0) {\r
-    Status = RdRandWord ((UINTN *) &TempRand, TRUE);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
+  BOOLEAN     IsRandom;\r
+  UINT64      TempRand[2];\r
 \r
-  //\r
-  // Populate the starting mis-aligned block.\r
-  //\r
-  for (Index = 0; Index < StartLen; Index++) {\r
-    Start[Index] = (UINT8)(TempRand & 0xff);\r
-    TempRand     = TempRand >> 8;\r
-  }\r
-\r
-  //\r
-  // Populate the central aligned block. Fail out if retry fails.\r
-  //\r
-  Status = RdRandGetWords (BlockNum, (UINTN *)(BlockStart));\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Populate the final mis-aligned block.\r
-  //\r
-  if (Residual > 0) {\r
-    Status = RdRandWord ((UINTN *)&TempRand, TRUE);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
+  while (Length > 0) {\r
+    IsRandom = GetRandomNumber128 (TempRand);\r
+    if (!IsRandom) {\r
+      return EFI_NOT_READY;\r
     }\r
-    for (Index = 0; Index < Residual; Index++) {\r
-      ResidualStart[Index] = (UINT8)(TempRand & 0xff);\r
-      TempRand             = TempRand >> 8;\r
+    if (Length >= sizeof (TempRand)) {\r
+      WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);\r
+      RandBuffer += sizeof (UINT64);\r
+      WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);\r
+      RandBuffer += sizeof (UINT64);\r
+      Length -= sizeof (TempRand);\r
+    } else {\r
+      CopyMem (RandBuffer, TempRand, Length);\r
+      Length = 0;\r
     }\r
   }\r
 \r
@@ -285,7 +57,7 @@ RdRandGetBytes (
   This function takes multiple random numbers through RDRAND without intervening\r
   delays to ensure reseeding and performs AES-CBC-MAC over the data to compute the\r
   seed value.\r
-  \r
+\r
   @param[out]  SeedBuffer    Pointer to a 128bit buffer to store the random seed.\r
 \r
   @retval EFI_SUCCESS        Random seed generation succeeded.\r
@@ -307,7 +79,7 @@ RdRandGetSeed128 (
   UINT32      Index2;\r
 \r
   //\r
-  // Chose an arbitary key and zero the feed_forward_value (FFV)\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