]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c
SecurityPkg/RngDxe: Add AArch64 RawAlgorithm support through ArmTrngLib
[mirror_edk2.git] / SecurityPkg / RandomNumberGenerator / RngDxe / ArmTrng.c
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c b/SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c
new file mode 100644 (file)
index 0000000..ffe557b
--- /dev/null
@@ -0,0 +1,71 @@
+/** @file\r
+  RNG Driver to produce the UEFI Random Number Generator protocol.\r
+\r
+  The driver implements the EFI_RNG_ALGORITHM_RAW using the FW-TRNG\r
+  interface to provide entropy.\r
+\r
+  Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ArmTrngLib.h>\r
+#include <Protocol/Rng.h>\r
+\r
+#include "RngDxeInternals.h"\r
+\r
+/**\r
+  Generate high-quality entropy source using a TRNG or through RDRAND.\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  RETURN_SUCCESS            The function completed successfully.\r
+  @retval  RETURN_INVALID_PARAMETER  Invalid parameter.\r
+  @retval  RETURN_UNSUPPORTED        Function not implemented.\r
+  @retval  RETURN_BAD_BUFFER_SIZE    Buffer size is too small.\r
+  @retval  RETURN_NOT_READY          No Entropy available.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GenerateEntropy (\r
+  IN  UINTN  Length,\r
+  OUT UINT8  *Entropy\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       CollectedEntropyBits;\r
+  UINTN       RequiredEntropyBits;\r
+  UINTN       EntropyBits;\r
+  UINTN       Index;\r
+  UINTN       MaxBits;\r
+\r
+  ZeroMem (Entropy, Length);\r
+\r
+  RequiredEntropyBits  = (Length << 3);\r
+  Index                = 0;\r
+  CollectedEntropyBits = 0;\r
+  MaxBits              = GetArmTrngMaxSupportedEntropyBits ();\r
+  while (CollectedEntropyBits < RequiredEntropyBits) {\r
+    EntropyBits = MIN ((RequiredEntropyBits - CollectedEntropyBits), MaxBits);\r
+    Status      = GetArmTrngEntropy (\r
+                    EntropyBits,\r
+                    (Length - Index),\r
+                    &Entropy[Index]\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      // Discard the collected bits.\r
+      ZeroMem (Entropy, Length);\r
+      return Status;\r
+    }\r
+\r
+    CollectedEntropyBits += EntropyBits;\r
+    Index                += (EntropyBits >> 3);\r
+  } // while\r
+\r
+  return Status;\r
+}\r