From: "gaoliming" <gaoliming@byosoft.com.cn>
To: "'Rebecca Cran'" <rebecca@nuviainc.com>, <devel@edk2.groups.io>,
"'Jiewen Yao'" <jiewen.yao@intel.com>,
"'Jian J Wang'" <jian.j.wang@intel.com>,
"'Michael D Kinney'" <michael.d.kinney@intel.com>,
"'Zhiguang Liu'" <zhiguang.liu@intel.com>,
"'Ard Biesheuvel'" <ardb+tianocore@kernel.org>,
"'Sami Mujawar'" <sami.mujawar@arm.com>
Subject: 回复: [PATCH v2 2/2] SecurityPkg: Add support for RngDxe on AARCH64
Date: Sat, 8 May 2021 09:32:09 +0800 [thread overview]
Message-ID: <00c701d743a9$f67a6770$e36f3650$@byosoft.com.cn> (raw)
In-Reply-To: <20210507142315.679-3-rebecca@nuviainc.com>
Rebecca:
> -----邮件原件-----
> 发件人: Rebecca Cran <rebecca@nuviainc.com>
> 发送时间: 2021年5月7日 22:23
> 收件人: devel@edk2.groups.io; Jiewen Yao <jiewen.yao@intel.com>; Jian J
> Wang <jian.j.wang@intel.com>; Michael D Kinney
> <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> Zhiguang Liu <zhiguang.liu@intel.com>; Ard Biesheuvel
> <ardb+tianocore@kernel.org>; Sami Mujawar <sami.mujawar@arm.com>
> 抄送: Rebecca Cran <rebecca@nuviainc.com>
> 主题: [PATCH v2 2/2] SecurityPkg: Add support for RngDxe on AARCH64
>
> AARCH64 support has been added to BaseRngLib via the optional
> ARMv8.5 FEAT_RNG.
>
> Refactor RngDxe to support AARCH64, note support for it in the
> VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.
>
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
> SecurityPkg/SecurityPkg.dec |
> 2 +
> SecurityPkg/SecurityPkg.dsc |
> 11 +-
> SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf |
> 24 ++-
> SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |
> 0
> SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h |
> 17 --
> SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h |
> 117 ++++++++++++++
> SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c |
> 127 +++++++++++++++
> SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |
> 0
> SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c |
> 45 +-----
> SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c |
> 146 +++++++++++++++++
> SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c |
> 170 ++++++++------------
> 11 files changed, 483 insertions(+), 176 deletions(-)
>
> diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
> index dfbbb0365a2b..a45104fe3e6c 100644
> --- a/SecurityPkg/SecurityPkg.dec
> +++ b/SecurityPkg/SecurityPkg.dec
> @@ -297,6 +297,8 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
>
> gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationPass|0x0303100
> A|UINT32|0x00010030
>
> gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationFail|0x0303100B
> |UINT32|0x00010031
>
> +
> gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0}|VOID*|0
> x00010032
> +
This PCD value is GUID. So, its default value should be GUID (16 bytes)
instead of {0} (1 byte).
Thanks
Liming
> [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
> ## Image verification policy for OptionRom. Only following values are
> valid:<BR><BR>
> # NOTE: Do NOT use 0x5 and 0x2 since it violates the UEFI
specification
> and has been removed.<BR>
> diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
> index 12ccd1634941..bd4b810bce61 100644
> --- a/SecurityPkg/SecurityPkg.dsc
> +++ b/SecurityPkg/SecurityPkg.dsc
> @@ -259,6 +259,12 @@ [Components]
> [Components.IA32, Components.X64, Components.ARM,
> Components.AARCH64]
> SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
>
> +[Components.IA32, Components.X64, Components.AARCH64]
> + #
> + # Random Number Generator
> + #
> + SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> +
> [Components.IA32, Components.X64]
>
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigD
> xe.inf
>
> @@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
>
> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence
> Lib.inf
>
> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic
> alPresenceLib.inf
>
> - #
> - # Random Number Generator
> - #
> - SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> -
> #
> # Opal Password solution
> #
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> index 99d6f6b35fc2..f3300971993f 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> @@ -26,15 +26,22 @@ [Defines]
> #
> # The following information is for reference only and not required by the
> build tools.
> #
> -# VALID_ARCHITECTURES = IA32 X64
> +# VALID_ARCHITECTURES = IA32 X64 AARCH64
> #
>
> [Sources.common]
> RngDxe.c
> - RdRand.c
> - RdRand.h
> - AesCore.c
> - AesCore.h
> + RngDxeInternals.h
> +
> +[Sources.IA32, Sources.X64]
> + Rand/RngDxe.c
> + Rand/RdRand.c
> + Rand/RdRand.h
> + Rand/AesCore.c
> + Rand/AesCore.h
> +
> +[Sources.AARCH64]
> + AArch64/RngDxe.c
>
> [Packages]
> MdePkg/MdePkg.dec
> @@ -50,12 +57,19 @@ [LibraryClasses]
> RngLib
>
> [Guids]
> + gEfiRngAlgorithmSp80090Hash256Guid ## SOMETIMES_PRODUCES
> ## GUID # Unique ID of the algorithm for RNG
> + gEfiRngAlgorithmSp80090Hmac256Guid ## SOMETIMES_PRODUCES
> ## GUID # Unique ID of the algorithm for RNG
> gEfiRngAlgorithmSp80090Ctr256Guid ## SOMETIMES_PRODUCES
> ## GUID # Unique ID of the algorithm for RNG
> + 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
>
> [Protocols]
> gEfiRngProtocolGuid ## PRODUCES
>
> +[Pcd]
> + gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm ##
> CONSUMES
> +
> [Depex]
> TRUE
>
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> similarity index 72%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> index 12ab1f34ec6d..072378e062e7 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> @@ -23,23 +23,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Library/TimerLib.h>
> #include <Protocol/Rng.h>
>
> -/**
> - Calls RDRAND to fill a buffer of arbitrary size with random bytes.
> -
> - @param[in] Length Size of the buffer, in bytes, to fill with.
> - @param[out] RandBuffer Pointer to the buffer to store the random
> result.
> -
> - @retval EFI_SUCCESS Random bytes generation succeeded.
> - @retval EFI_NOT_READY Failed to request random bytes.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RdRandGetBytes (
> - IN UINTN Length,
> - OUT UINT8 *RandBuffer
> - );
> -
> /**
> Generate high-quality entropy source through RDRAND.
>
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> new file mode 100644
> index 000000000000..2660ed5875e0
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> @@ -0,0 +1,117 @@
> +/** @file
> + Function prototypes for UEFI Random Number Generator protocol
> support.
> +
> + Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RNGDXE_INTERNALS_H_
> +#define RNGDXE_INTERNALS_H_
> +
> +/**
> + Returns information about the random number generation
> implementation.
> +
> + @param[in] This A pointer to the
> EFI_RNG_PROTOCOL instance.
> + @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 The services is not supported
> by this driver.
> + @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.
> + @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
> is too small to hold the result.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetInfo (
> + IN EFI_RNG_PROTOCOL *This,
> + IN OUT UINTN *RNGAlgorithmListSize,
> + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
> + );
> +
> +/**
> + 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
> + );
> +
> +/**
> + 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_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
> is too small to hold the result.
> +
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithms (
> + IN OUT UINTN *RNGAlgorithmListSize,
> + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
> + );
> +
> +/**
> + Runs CPU RNG instruction to fill a buffer of arbitrary size with random
> bytes.
> +
> + @param[in] Length Size of the buffer, in bytes, to fill with.
> + @param[out] RandBuffer Pointer to the buffer to store the random
> result.
> +
> + @retval EFI_SUCCESS Random bytes generation succeeded.
> + @retval EFI_NOT_READY Failed to request random bytes.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetBytes (
> + IN UINTN Length,
> + OUT UINT8 *RandBuffer
> + );
> +
> +#endif // RNGDXE_INTERNALS_H_
> diff --git
> a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> new file mode 100644
> index 000000000000..2810a9eb94ad
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> @@ -0,0 +1,127 @@
> +/** @file
> + RNG Driver to produce the UEFI Random Number Generator protocol.
> +
> + The driver will use the RNDR instruction to produce random numbers.
> +
> + RNG Algorithms defined in UEFI 2.4:
> + - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
> + - EFI_RNG_ALGORITHM_RAW - Unsupported
> + - 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, 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>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/TimerLib.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;
> +
> + if ((RNGValueLength == 0) || (RNGValue == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (RNGAlgorithm == NULL) {
> + //
> + // Use the default RNG algorithm if RNGAlgorithm is NULL.
> + //
> + RNGAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
> + }
> +
> + if (CompareGuid (RNGAlgorithm, PcdGetPtr
> (PcdCpuRngSupportedAlgorithm))) {
> + Status = RngGetBytes (RNGValueLength, RNGValue);
> + return Status;
> + }
> +
> + //
> + // 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_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
> is too small to hold the result.
> +
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithms (
> + IN OUT UINTN *RNGAlgorithmListSize,
> + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
> + )
> +{
> + UINTN RequiredSize;
> + EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
> +
> + RequiredSize = sizeof (EFI_RNG_ALGORITHM);
> +
> + if (*RNGAlgorithmListSize < RequiredSize) {
> + *RNGAlgorithmListSize = RequiredSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
> +
> + CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof
> (EFI_RNG_ALGORITHM));
> +
> + *RNGAlgorithmListSize = RequiredSize;
> + return EFI_SUCCESS;
> +}
> +
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
> similarity index 71%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
> index e7dd5ab18111..83025a47d43d 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
> @@ -8,48 +8,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> **/
> #include <Library/RngLib.h>
>
> -#include "RdRand.h"
> #include "AesCore.h"
> -
> -/**
> - Calls RDRAND to fill a buffer of arbitrary size with random bytes.
> -
> - @param[in] Length Size of the buffer, in bytes, to fill with.
> - @param[out] RandBuffer Pointer to the buffer to store the random
> result.
> -
> - @retval EFI_SUCCESS Random bytes generation succeeded.
> - @retval EFI_NOT_READY Failed to request random bytes.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RdRandGetBytes (
> - IN UINTN Length,
> - OUT UINT8 *RandBuffer
> - )
> -{
> - BOOLEAN IsRandom;
> - UINT64 TempRand[2];
> -
> - while (Length > 0) {
> - IsRandom = GetRandomNumber128 (TempRand);
> - if (!IsRandom) {
> - return EFI_NOT_READY;
> - }
> - if (Length >= sizeof (TempRand)) {
> - WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);
> - RandBuffer += sizeof (UINT64);
> - WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);
> - RandBuffer += sizeof (UINT64);
> - Length -= sizeof (TempRand);
> - } else {
> - CopyMem (RandBuffer, TempRand, Length);
> - Length = 0;
> - }
> - }
> -
> - return EFI_SUCCESS;
> -}
> +#include "RdRand.h"
> +#include "RngDxeInternals.h"
>
> /**
> Creates a 128bit random value that is fully forward and backward
> prediction resistant,
> @@ -92,7 +53,7 @@ RdRandGetSeed128 (
> //
> for (Index = 0; Index < 32; Index++) {
> MicroSecondDelay (10);
> - Status = RdRandGetBytes (16, RandByte);
> + Status = RngGetBytes (16, RandByte);
> if (EFI_ERROR (Status)) {
> return Status;
> }
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
> new file mode 100644
> index 000000000000..6b628a9f8bc6
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
> @@ -0,0 +1,146 @@
> +/** @file
> + RNG Driver to produce the UEFI Random Number Generator protocol.
> +
> + The driver will use the new RDRAND instruction to produce high-quality,
> high-performance
> + entropy and random number.
> +
> + RNG Algorithms defined in UEFI 2.4:
> + - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
> + (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based
> DRBG)
> + - EFI_RNG_ALGORITHM_RAW - Supported
> + (Structuring RDRAND invocation can be guaranteed as high-quality
> entropy source)
> + - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
> + - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
> + - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
> + - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
> +
> + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RdRand.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;
> +
> + if ((RNGValueLength == 0) || (RNGValue == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = EFI_UNSUPPORTED;
> + if (RNGAlgorithm == NULL) {
> + //
> + // Use the default RNG algorithm if RNGAlgorithm is NULL.
> + //
> + RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
> + }
> +
> + //
> + // NIST SP800-90-AES-CTR-256 supported by RDRAND
> + //
> + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid))
> {
> + Status = RngGetBytes (RNGValueLength, RNGValue);
> + return Status;
> + }
> +
> + //
> + // The "raw" algorithm is intended to provide entropy directly
> + //
> + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
> + //
> + // When a DRBG is used on the output of a entropy source,
> + // its security level must be at least 256 bits according to UEFI
Spec.
> + //
> + if (RNGValueLength < 32) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
> + return Status;
> + }
> +
> + //
> + // Other algorithms were unsupported by this driver.
> + //
> + return Status;
> +}
> +
> +/**
> + 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_BUFFER_TOO_SMALL The buffer RNGAlgorithmList
> is too small to hold the result.
> +
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithms (
> + IN OUT UINTN *RNGAlgorithmListSize,
> + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
> + )
> +{
> + UINTN RequiredSize;
> + EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
> +
> + RequiredSize = 2 * sizeof (EFI_RNG_ALGORITHM);
> +
> + if (*RNGAlgorithmListSize < RequiredSize) {
> + *RNGAlgorithmListSize = RequiredSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
> +
> + CopyMem(&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof
> (EFI_RNG_ALGORITHM));
> +
> + // x86 platforms also support EFI_RNG_ALGORITHM_RAW via RDSEED
> + CopyMem(&RNGAlgorithmList[1], &gEfiRngAlgorithmRaw, sizeof
> (EFI_RNG_ALGORITHM));
> +
> + *RNGAlgorithmListSize = RequiredSize;
> + return EFI_SUCCESS;
> +}
> +
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> index 13d3dbd0bfbe..b959c70536ea 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> @@ -1,34 +1,32 @@
> /** @file
> RNG Driver to produce the UEFI Random Number Generator protocol.
>
> - The driver will use the new RDRAND instruction to produce high-quality,
> high-performance
> - entropy and random number.
> + The driver uses CPU RNG instructions to produce high-quality,
> + high-performance entropy and random number.
>
> RNG Algorithms defined in UEFI 2.4:
> - - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
> - (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based
> DRBG)
> - - EFI_RNG_ALGORITHM_RAW - Supported
> - (Structuring RDRAND invocation can be guaranteed as high-quality
> entropy source)
> - - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
> - - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
> - - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
> - - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
> + - 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
> + - EFI_RNG_ALGORITHM_X9_31_AES_GUID
>
> Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> SPDX-License-Identifier: BSD-2-Clause-Patent
>
> **/
>
> -#include "RdRand.h"
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/RngLib.h>
> +#include <Library/TimerLib.h>
> +#include <Protocol/Rng.h>
>
> -//
> -// Supported RNG Algorithms list by this driver.
> -//
> -EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
> - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
> - EFI_RNG_ALGORITHM_RAW
> -};
> +#include "RngDxeInternals.h"
>
> /**
> Returns information about the random number generation
> implementation.
> @@ -62,106 +60,23 @@ RngGetInfo (
> )
> {
> EFI_STATUS Status;
> - UINTN RequiredSize;
>
> if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {
> return EFI_INVALID_PARAMETER;
> }
>
> - RequiredSize = sizeof (mSupportedRngAlgorithms);
> - if (*RNGAlgorithmListSize < RequiredSize) {
> - Status = EFI_BUFFER_TOO_SMALL;
> + //
> + // Return algorithm list supported by driver.
> + //
> + if (RNGAlgorithmList != NULL) {
> + Status = ArchGetSupportedRngAlgorithms (RNGAlgorithmListSize,
> RNGAlgorithmList);
> } else {
> - //
> - // Return algorithm list supported by driver.
> - //
> - if (RNGAlgorithmList != NULL) {
> - CopyMem (RNGAlgorithmList, mSupportedRngAlgorithms,
> RequiredSize);
> - Status = EFI_SUCCESS;
> - } else {
> - Status = EFI_INVALID_PARAMETER;
> - }
> + Status = EFI_INVALID_PARAMETER;
> }
> - *RNGAlgorithmListSize = RequiredSize;
>
> return Status;
> }
>
> -/**
> - 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;
> -
> - if ((RNGValueLength == 0) || (RNGValue == NULL)) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - Status = EFI_UNSUPPORTED;
> - if (RNGAlgorithm == NULL) {
> - //
> - // Use the default RNG algorithm if RNGAlgorithm is NULL.
> - //
> - RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
> - }
> -
> - //
> - // NIST SP800-90-AES-CTR-256 supported by RDRAND
> - //
> - if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
> - Status = RdRandGetBytes (RNGValueLength, RNGValue);
> - return Status;
> - }
> -
> - //
> - // The "raw" algorithm is intended to provide entropy directly
> - //
> - if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
> - //
> - // When a DRBG is used on the output of a entropy source,
> - // its security level must be at least 256 bits according to UEFI
Spec.
> - //
> - if (RNGValueLength < 32) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
> - return Status;
> - }
> -
> - //
> - // Other algorithms were unsupported by this driver.
> - //
> - return Status;
> -}
> -
> //
> // The Random Number Generator (RNG) protocol
> //
> @@ -204,3 +119,44 @@ RngDriverEntry (
>
> return Status;
> }
> +
> +
> +/**
> + Calls RDRAND to fill a buffer of arbitrary size with random bytes.
> +
> + @param[in] Length Size of the buffer, in bytes, to fill with.
> + @param[out] RandBuffer Pointer to the buffer to store the random
> result.
> +
> + @retval EFI_SUCCESS Random bytes generation succeeded.
> + @retval EFI_NOT_READY Failed to request random bytes.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetBytes (
> + IN UINTN Length,
> + OUT UINT8 *RandBuffer
> + )
> +{
> + BOOLEAN IsRandom;
> + UINT64 TempRand[2];
> +
> + while (Length > 0) {
> + IsRandom = GetRandomNumber128 (TempRand);
> + if (!IsRandom) {
> + return EFI_NOT_READY;
> + }
> + if (Length >= sizeof (TempRand)) {
> + WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[0]);
> + RandBuffer += sizeof (UINT64);
> + WriteUnaligned64 ((UINT64*)RandBuffer, TempRand[1]);
> + RandBuffer += sizeof (UINT64);
> + Length -= sizeof (TempRand);
> + } else {
> + CopyMem (RandBuffer, TempRand, Length);
> + Length = 0;
> + }
> + }
> +
> + return EFI_SUCCESS;
> +}
> --
> 2.26.2
next prev parent reply other threads:[~2021-05-08 1:32 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-07 14:23 [PATCH v2 0/2] MdePkg,SecurityPkg: Add support to RngDxe and BaseRngLib for AARCH64 RNDR Rebecca Cran
2021-05-07 14:23 ` [PATCH v2 1/2] MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
2021-05-08 1:35 ` 回复: " gaoliming
2021-05-07 14:23 ` [PATCH v2 2/2] SecurityPkg: Add support for RngDxe on AARCH64 Rebecca Cran
2021-05-08 1:32 ` gaoliming [this message]
2021-05-07 17:28 ` [PATCH v2 0/2] MdePkg,SecurityPkg: Add support to RngDxe and BaseRngLib for AARCH64 RNDR Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='00c701d743a9$f67a6770$e36f3650$@byosoft.com.cn' \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox