[edk2-devel] [PATCH v3 2/2] SecurityPkg: Add support for RngDxe on AARCH64

Yao, Jiewen jiewen.yao at intel.com
Tue May 11 14:45:48 UTC 2021


Acked-by: Jiewen Yao <Jiewen.yao at intel.com>

Need ARM expert to double confirm.

> -----Original Message-----
> From: devel at edk2.groups.io <devel at edk2.groups.io> On Behalf Of Ard
> Biesheuvel
> Sent: Tuesday, May 11, 2021 10:44 PM
> To: Rebecca Cran <rebecca at nuviainc.com>; Yao, Jiewen
> <jiewen.yao at intel.com>; Wang, Jian J <jian.j.wang at intel.com>
> Cc: edk2-devel-groups-io <devel at edk2.groups.io>; Kinney, Michael D
> <michael.d.kinney at intel.com>; Liming Gao <gaoliming at byosoft.com.cn>; Liu,
> Zhiguang <zhiguang.liu at intel.com>; Ard Biesheuvel
> <ardb+tianocore at kernel.org>; Sami Mujawar <sami.mujawar at arm.com>
> Subject: Re: [edk2-devel] [PATCH v3 2/2] SecurityPkg: Add support for RngDxe
> on AARCH64
> 
> On Mon, 10 May 2021 at 23:53, Rebecca Cran <rebecca at nuviainc.com> wrote:
> >
> > 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 at nuviainc.com>
> 
> I'm happy to take these and merge them if I can get an ack from a
> SecurityPkg maintainer.
> 
> 
> > ---
> >  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..4001650fa28e 100644
> > --- a/SecurityPkg/SecurityPkg.dec
> > +++ b/SecurityPkg/SecurityPkg.dec
> > @@ -297,6 +297,8 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationPass|0x0303100A|
> UINT32|0x00010030
> >
> gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeFvVerificationFail|0x0303100B|
> UINT32|0x00010031
> >
> > +
> gEfiSecurityPkgTokenSpaceGuid.PcdCpuRngSupportedAlgorithm|{0x00,0x00,0x0
> 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}|VOID
> *|0x00010032
> > +
> >  [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/SecureBootConfigDx
> e.inf
> >
> > @@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
> >
> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib
> .inf
> >
> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalP
> resenceLib.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
> >
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#75013): https://edk2.groups.io/g/devel/message/75013
Mute This Topic: https://groups.io/mt/82732213/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list