SecurityPkg/RngDxe: Add AArch64 RawAlgorithm support through ArmTrngLib

Bugzilla: 3668 (https://bugzilla.tianocore.org/show_bug.cgi?id=3668)

RawAlgorithm is used to provide access to entropy that is suitable
for cryptographic applications. Therefore, add RawAlgorithm support
that provides access to entropy using the ArmTrngLib.

Also remove unused UefiBootServicesTableLib library inclusion
and Status variable.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Acked-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Sami Mujawar 2022-10-28 17:32:55 +02:00 committed by mergify[bot]
parent 4b3e9d80be
commit 863fe9e191
4 changed files with 103 additions and 4 deletions

View File

@ -1,11 +1,13 @@
/** @file
RNG Driver to produce the UEFI Random Number Generator protocol.
The driver will use the RNDR instruction to produce random numbers.
The driver can use RNDR instruction (through the RngLib and if FEAT_RNG is
present) to produce random numbers. It also uses the Arm FW-TRNG interface
to implement EFI_RNG_ALGORITHM_RAW.
RNG Algorithms defined in UEFI 2.4:
- EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
- EFI_RNG_ALGORITHM_RAW - Unsupported
- EFI_RNG_ALGORITHM_RAW
- EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
- EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
- EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
@ -26,12 +28,14 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/RngLib.h>
#include <Library/DebugLib.h>
#include <Library/ArmTrngLib.h>
#include <Protocol/Rng.h>
#include "RngDxeInternals.h"
// Maximum number of Rng algorithms.
#define RNG_AVAILABLE_ALGO_MAX 1
#define RNG_AVAILABLE_ALGO_MAX 2
/** Allocate and initialize mAvailableAlgoArray with the available
Rng algorithms. Also update mAvailableAlgoArrayCount.
@ -46,8 +50,9 @@ GetAvailableAlgorithms (
)
{
UINT64 DummyRand;
UINT16 MajorRevision;
UINT16 MinorRevision;
// Allocate RNG_AVAILABLE_ALGO_MAX entries to avoid evaluating
// Rng algorithms 2 times, one for the allocation, one to populate.
mAvailableAlgoArray = AllocateZeroPool (RNG_AVAILABLE_ALGO_MAX);
if (mAvailableAlgoArray == NULL) {
@ -64,6 +69,16 @@ GetAvailableAlgorithms (
mAvailableAlgoArrayCount++;
}
// Raw algorithm (Trng)
if (!EFI_ERROR (GetArmTrngVersion (&MajorRevision, &MinorRevision))) {
CopyMem (
&mAvailableAlgoArray[mAvailableAlgoArrayCount],
&gEfiRngAlgorithmRaw,
sizeof (EFI_RNG_ALGORITHM)
);
mAvailableAlgoArrayCount++;
}
return EFI_SUCCESS;
}
@ -141,6 +156,11 @@ FoundAlgo:
return Status;
}
// Raw algorithm (Trng)
if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
return GenerateEntropy (RNGValueLength, RNGValue);
}
//
// Other algorithms are unsupported by this driver.
//

View File

@ -0,0 +1,71 @@
/** @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.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/ArmTrngLib.h>
#include <Protocol/Rng.h>
#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;
}

View File

@ -43,8 +43,10 @@
[Sources.AARCH64]
AArch64/RngDxe.c
ArmTrng.c
[Packages]
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
@ -57,6 +59,9 @@
TimerLib
RngLib
[LibraryClasses.AARCH64]
ArmTrngLib
[Guids]
gEfiRngAlgorithmSp80090Hash256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG
gEfiRngAlgorithmSp80090Hmac256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG

View File

@ -4,6 +4,7 @@
# Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP<BR>
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
# Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@ -89,6 +90,8 @@
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
[LibraryClasses.ARM]
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf