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 TRNG library interface. Signed-off-by: Sami Mujawar <sami.muja...@arm.com> --- Notes: v2: - MdeModulePkg\Include\Guid\ZeroGuid.h has defined [LIMING] gZeroGuid. You don't define it again. - Replaced use of gNullGuid with gZeroGuid. [SAMI] SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c | 79 ++++++++-- SecurityPkg/RandomNumberGenerator/RngDxe/Arm/RngDxe.c | 163 ++++++++++++++++++++ SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c | 61 ++++++++ SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c | 2 +- SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf | 13 +- SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h | 1 + SecurityPkg/SecurityPkg.dsc | 8 +- 7 files changed, 314 insertions(+), 13 deletions(-) diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c index 282fdca9d334b77e02ca47734df08729e0f4fd31..d1c8f4c69b4d65c10141da320d44cd8f01bb0c74 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c @@ -1,11 +1,12 @@ /** @file RNG Driver to produce the UEFI Random Number Generator protocol. - The driver will use the RNDR instruction to produce random numbers. + The driver will use the RNDR instruction 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 @@ -14,15 +15,17 @@ Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR> Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> + Copyright (c) 2021, Arm Limited. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include <Guid/ZeroGuid.h> #include <Library/BaseLib.h> #include <Library/BaseMemoryLib.h> -#include <Library/UefiBootServicesTableLib.h> -#include <Library/TimerLib.h> +#include <Library/DebugLib.h> +#include <Library/TrngLib.h> #include <Protocol/Rng.h> #include "RngDxeInternals.h" @@ -58,7 +61,9 @@ RngGetRNG ( OUT UINT8 *RNGValue ) { - EFI_STATUS Status; + EFI_STATUS Status; + UINT16 MajorRevision; + UINT16 MinorRevision; if ((RNGValueLength == 0) || (RNGValue == NULL)) { return EFI_INVALID_PARAMETER; @@ -76,6 +81,17 @@ RngGetRNG ( return Status; } + // + // The "raw" algorithm is intended to provide entropy directly + // + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) { + Status = GetTrngVersion (&MajorRevision, &MinorRevision); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + return GenerateEntropy (RNGValueLength, RNGValue); + } + // // Other algorithms are unsupported by this driver. // @@ -97,8 +113,9 @@ RngGetRNG ( is the default algorithm for the driver. @retval EFI_SUCCESS The RNG algorithm list was returned successfully. + @retval EFI_UNSUPPORTED No supported algorithms found. @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result. - + @retval EFI_INVALID_PARAMETER The pointer to the buffer RNGAlgorithmList is invalid. **/ UINTN EFIAPI @@ -107,19 +124,61 @@ ArchGetSupportedRngAlgorithms ( OUT EFI_RNG_ALGORITHM *RNGAlgorithmList ) { - UINTN RequiredSize; + EFI_STATUS Status; + UINT16 MajorRevision; + UINT16 MinorRevision; + UINTN RequiredSize; + BOOLEAN CpuRngAlgorithmSupported; + BOOLEAN RawAlgorithmSupported; + UINTN Index; EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm; - RequiredSize = sizeof (EFI_RNG_ALGORITHM); + RequiredSize = 0; + CpuRngAlgorithmSupported = FALSE; + RawAlgorithmSupported = FALSE; + + CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm); + if (!CompareGuid (CpuRngSupportedAlgorithm, &gZeroGuid)) { + CpuRngAlgorithmSupported = TRUE; + RequiredSize += sizeof (EFI_RNG_ALGORITHM); + } + + Status = GetTrngVersion (&MajorRevision, &MinorRevision); + if (!EFI_ERROR (Status)) { + RawAlgorithmSupported = TRUE; + RequiredSize += sizeof (EFI_RNG_ALGORITHM); + } if (*RNGAlgorithmListSize < RequiredSize) { *RNGAlgorithmListSize = RequiredSize; return EFI_BUFFER_TOO_SMALL; } - CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm); + if (RequiredSize == 0) { + // No supported algorithms found. + return EFI_UNSUPPORTED; + } - CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof (EFI_RNG_ALGORITHM)); + if (RNGAlgorithmList == NULL) { + return EFI_INVALID_PARAMETER; + } + + Index = 0; + if (CpuRngAlgorithmSupported) { + CopyMem ( + &RNGAlgorithmList[Index++], + CpuRngSupportedAlgorithm, + sizeof (EFI_RNG_ALGORITHM) + ); + } + + if (RawAlgorithmSupported) { + CopyMem ( + &RNGAlgorithmList[Index++], + &gEfiRngAlgorithmRaw, + sizeof (EFI_RNG_ALGORITHM) + ); + } *RNGAlgorithmListSize = RequiredSize; return EFI_SUCCESS; diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Arm/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Arm/RngDxe.c new file mode 100644 index 0000000000000000000000000000000000000000..cba9883e50cefbb22495190d17de99bfeab33cf3 --- /dev/null +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Arm/RngDxe.c @@ -0,0 +1,163 @@ +/** @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. + + RNG Algorithms defined in UEFI 2.4: + - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID + - 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 + - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported + + Copyright (c) 2021, 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/TrngLib.h> +#include <Protocol/Rng.h> + +#include "RngDxeInternals.h" + +/** + Produces and returns an RNG value using either the default or specified + RNG algorithm. + + @param[in] This A pointer to the EFI_RNG_PROTOCOL instance. + @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that + identifies the RNG algorithm to use. May be + NULL in which case the function will use its + default RNG algorithm. + @param[in] RNGValueLength The length in bytes of the memory buffer + pointed to by RNGValue. The driver shall + return exactly this numbers of bytes. + @param[out] RNGValue A caller-allocated memory buffer filled by + the driver with the resulting RNG value. + + @retval EFI_SUCCESS The RNG value was returned successfully. + @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is + not supported by this driver. + @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to + a hardware or firmware error. + @retval EFI_NOT_READY There is not enough random data available + to satisfy the length requested by + RNGValueLength. + @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero. + +**/ +EFI_STATUS +EFIAPI +RngGetRNG ( + IN EFI_RNG_PROTOCOL *This, + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ) +{ + EFI_STATUS Status; + UINT16 MajorRevision; + UINT16 MinorRevision; + + if ((RNGValueLength == 0) || (RNGValue == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (RNGAlgorithm == NULL) { + // + // Use the default RNG algorithm if RNGAlgorithm is NULL. + // + RNGAlgorithm = &gEfiRngAlgorithmRaw; + } + + // + // The "raw" algorithm is intended to provide entropy directly + // + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) { + Status = GetTrngVersion (&MajorRevision, &MinorRevision); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + return GenerateEntropy (RNGValueLength, RNGValue); + } + + // + // Other algorithms are unsupported by this driver. + // + return EFI_UNSUPPORTED; +} + +/** + Returns information about the random number generation implementation. + + @param[in,out] RNGAlgorithmListSize On input, the size in bytes of + RNGAlgorithmList. + On output with a return code of + EFI_SUCCESS, the size in bytes of the + data returned in RNGAlgorithmList. + On output with a return code of + EFI_BUFFER_TOO_SMALL, the size of + RNGAlgorithmList required to obtain the + list. + @param[out] RNGAlgorithmList A caller-allocated memory buffer filled + by the driver with one EFI_RNG_ALGORITHM + element for each supported RNG algorithm. + The list must not change across multiple + calls to the same driver. The first + algorithm in the list is the default + algorithm for the driver. + + @retval EFI_SUCCESS The RNG algorithm list was returned + successfully. + @retval EFI_UNSUPPORTED No supported algorithms found. + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small + to hold the result. + @retval EFI_INVALID_PARAMETER The pointer to the buffer RNGAlgorithmList + is invalid. +**/ +UINTN +EFIAPI +ArchGetSupportedRngAlgorithms ( + IN OUT UINTN *RNGAlgorithmListSize, + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList + ) +{ + EFI_STATUS Status; + UINTN RequiredSize; + UINT16 MajorRevision; + UINT16 MinorRevision; + + RequiredSize = 0; + + Status = GetTrngVersion (&MajorRevision, &MinorRevision); + if (EFI_ERROR (Status)) { + // No supported algorithms found. + return EFI_UNSUPPORTED; + } + + RequiredSize += sizeof (EFI_RNG_ALGORITHM); + + if (*RNGAlgorithmListSize < RequiredSize) { + *RNGAlgorithmListSize = RequiredSize; + return EFI_BUFFER_TOO_SMALL; + } + + if (RNGAlgorithmList == NULL) { + return EFI_INVALID_PARAMETER; + } + + CopyMem ( + &RNGAlgorithmList[0], + &gEfiRngAlgorithmRaw, + sizeof (EFI_RNG_ALGORITHM) + ); + + *RNGAlgorithmListSize = RequiredSize; + return EFI_SUCCESS; +} diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c b/SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c new file mode 100644 index 0000000000000000000000000000000000000000..8df37d82e2051854f74816711a14ee23472f6b41 --- /dev/null +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c @@ -0,0 +1,61 @@ +/** @file + Arm FW-TRNG interface helper common for AArch32 and AArch64. + + Copyright (c) 2021, Arm Limited. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/TrngLib.h> + +/** + Generate high-quality entropy source using a TRNG. + + @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 EFI_SUCCESS Entropy generation succeeded. + @retval EFI_NOT_READY Failed to request random data. + +**/ +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 = GetTrngMaxSupportedEntropyBits (); + while (CollectedEntropyBits < RequiredEntropyBits) { + EntropyBits = MIN ((RequiredEntropyBits - CollectedEntropyBits), MaxBits); + Status = GetEntropy ( + EntropyBits, + &Entropy[Index], + (Length - Index) + ); + if (EFI_ERROR (Status)) { + // Discard the collected bits. + ZeroMem (Entropy, Length); + return Status; + } + CollectedEntropyBits += EntropyBits; + Index += (EntropyBits >> 3); + } // while + + return Status; +} diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c index 2e3b714bc691e4e517866369c034b721fbccfa24..b7ac0baf3f8216c9a86029b3037bfe4fd59269f6 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c @@ -45,7 +45,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent is the default algorithm for the driver. @retval EFI_SUCCESS The RNG algorithm list was returned successfully. - @retval EFI_UNSUPPORTED The services is not supported by this driver. + @retval EFI_UNSUPPORTED No supported algorithms found. @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a hardware or firmware error. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf index ef5cd73273e68c67bec7411279bb8433c45ab2d4..9f2e92512bfa48bd772c7f887a23453756421b80 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf @@ -10,6 +10,7 @@ # # Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> # (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> +# Copyright (c) 2021, Arm Limited. All rights reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -26,7 +27,7 @@ [Defines] # # The following information is for reference only and not required by the build tools. # -# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# VALID_ARCHITECTURES = IA32 X64 AARCH64 ARM # [Sources.common] @@ -41,8 +42,14 @@ [Sources.IA32, Sources.X64] [Sources.AARCH64] AArch64/RngDxe.c + ArmTrng.c + +[Sources.ARM] + Arm/RngDxe.c + ArmTrng.c [Packages] + MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec SecurityPkg/SecurityPkg.dec @@ -55,6 +62,9 @@ [LibraryClasses] TimerLib RngLib +[LibraryClasses.AARCH64, LibraryClasses.ARM] + TrngLib + [Guids] gEfiRngAlgorithmSp80090Hash256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG gEfiRngAlgorithmSp80090Hmac256Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG @@ -62,6 +72,7 @@ [Guids] gEfiRngAlgorithmX9313DesGuid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG gEfiRngAlgorithmX931AesGuid ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG gEfiRngAlgorithmRaw ## SOMETIMES_PRODUCES ## GUID # Unique ID of the algorithm for RNG + gZeroGuid ## CONSUMES [Protocols] gEfiRngProtocolGuid ## PRODUCES diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h index 37c27c4094e5302dfe2e7d9bbeef33a24b0c73ea..8978d54f51d4e72ad881ee584e16dcdda72a66ae 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h @@ -89,6 +89,7 @@ RngGetRNG ( is the default algorithm for the driver. @retval EFI_SUCCESS The RNG algorithm list was returned successfully. + @retval EFI_UNSUPPORTED No supported algorithms found. @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result. @retval EFI_INVALID_PARAMETER The pointer to the buffer RNGAlgorithmList is invalid. **/ diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 73a93c2285b13a2e0ce45b08a1230a766e0d759a..63da3d8c92e5a2c559b7731dd6dc0654caab30b8 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -3,6 +3,7 @@ # # Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR> # (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP<BR> +# Copyright (c) 2021, Arm Limited. All rights reserved.<BR> # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -86,6 +87,11 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf + # Arm FW-TRNG interface library. + TrngLib|ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf + ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf + [LibraryClasses.ARM] RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf @@ -277,7 +283,7 @@ [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.inf SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf -[Components.IA32, Components.X64, Components.AARCH64] +[Components.IA32, Components.X64, Components.AARCH64, Components.ARM] # # Random Number Generator # -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#83778): https://edk2.groups.io/g/devel/message/83778 Mute This Topic: https://groups.io/mt/87092737/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-