/** @file
RNG Driver to produce the UEFI Random Number Generator protocol.
The driver implements the EFI_RNG_ALGORITHM_RAW using the FW-TRNG
interface to provide entropy.
Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include "RngDxeInternals.h"
/**
Generate high-quality entropy source using a TRNG or through RDRAND.
@param[in] Length Size of the buffer, in bytes, to fill with.
@param[out] Entropy Pointer to the buffer to store the entropy data.
@retval RETURN_SUCCESS The function completed successfully.
@retval RETURN_INVALID_PARAMETER Invalid parameter.
@retval RETURN_UNSUPPORTED Function not implemented.
@retval RETURN_BAD_BUFFER_SIZE Buffer size is too small.
@retval RETURN_NOT_READY No Entropy available.
**/
EFI_STATUS
EFIAPI
GenerateEntropy (
IN UINTN Length,
OUT UINT8 *Entropy
)
{
EFI_STATUS Status;
UINTN CollectedEntropyBits;
UINTN RequiredEntropyBits;
UINTN EntropyBits;
UINTN Index;
UINTN MaxBits;
ZeroMem (Entropy, Length);
RequiredEntropyBits = (Length << 3);
Index = 0;
CollectedEntropyBits = 0;
MaxBits = GetArmTrngMaxSupportedEntropyBits ();
while (CollectedEntropyBits < RequiredEntropyBits) {
EntropyBits = MIN ((RequiredEntropyBits - CollectedEntropyBits), MaxBits);
Status = GetArmTrngEntropy (
EntropyBits,
(Length - Index),
&Entropy[Index]
);
if (EFI_ERROR (Status)) {
// Discard the collected bits.
ZeroMem (Entropy, Length);
return Status;
}
CollectedEntropyBits += EntropyBits;
Index += (EntropyBits >> 3);
} // while
return Status;
}