--- /dev/null
+/** @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