public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
	"Xu, Min M" <min.m.xu@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: "Yao, Jiewen" <jiewen.yao@intel.com>,
	"Wang, Jian J" <jian.j.wang@intel.com>,
	"Lu, Xiaoyu1" <xiaoyu1.lu@intel.com>,
	"Jiang, Guomin" <guomin.jiang@intel.com>,
	Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [edk2-devel] [PATCH V3 2/9] CryptoPkg: Add SecCryptLib
Date: Mon, 18 Apr 2022 15:31:46 +0000	[thread overview]
Message-ID: <CO1PR11MB4929F716BEF3EB15FE12F17FD2F39@CO1PR11MB4929.namprd11.prod.outlook.com> (raw)
In-Reply-To: <a40534fcd7892bc6448c748513b61b2de638cb45.1650239544.git.min.m.xu@intel.com>

Hi,

Did you evaluate the use of the following PCD to make an SEC version?

  ## Enable/Disable the families and individual services produced by the
  #  EDK II Crypto Protocols/PPIs.  The default is all services disabled.
  #  This Structured PCD is associated with PCD_CRYPTO_SERVICE_FAMILY_ENABLE
  #  structure that is defined in Include/Pcd/PcdCryptoServiceFamilyEnable.h.
  # @Prompt Enable/Disable EDK II Crypto Protocol/PPI services
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable|{0x00}|PCD_CRYPTO_SERVICE_FAMILY_ENABLE|0x00000002 {
    <Packages>
      CryptoPkg/CryptoPkg.dec
    <HeaderFiles>
      Pcd/PcdCryptoServiceFamilyEnable.h
  }


CryptoPkg.dsc has different PCD settings for different FW phases to configure
only the crypto services required in each phase.  You can extend for SEC. Here
is the setting for the minimum for PEI phase.

!if $(CRYPTO_SERVICES) == MIN_PEI
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.HmacSha256.Family               | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Sha1.Family                     | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Sha256.Family                   | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Sha384.Family                   | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Sha512.Family                   | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Sm3.Family                      | PCD_CRYPTO_SERVICE_ENABLE_FAMILY
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.Pkcs1Verify        | TRUE
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.New                | TRUE
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.Free               | TRUE
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Rsa.Services.SetKey             | TRUE
  gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Pkcs.Services.Pkcs5HashPassword | TRUE
!endif

The complete set of settings is isn the PCD_CRYPTO_SERVICE_FAMILY_ENABLE structure:

	https://github.com/tianocore/edk2/blob/master/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Min Xu
> Sent: Sunday, April 17, 2022 5:00 PM
> To: devel@edk2.groups.io
> Cc: Xu, Min M <min.m.xu@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>; Gerd Hoffmann <kraxel@redhat.com>
> Subject: [edk2-devel] [PATCH V3 2/9] CryptoPkg: Add SecCryptLib
> 
> RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3853
> 
> This is the Cryptographic library instance for SEC. The motivation of
> this library is to support SHA384 in SEC phase for Td guest. So only
> Hash/CryptSha512.c is included which supports SHA384 and SHA512. Other
> cryptographics are added with the null version, such as CryptMd5Null.c.
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> Cc: Guomin Jiang <guomin.jiang@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
> ---
>  CryptoPkg/CryptoPkg.dsc                       |   4 +
>  .../Library/BaseCryptLib/Hash/CryptMd5Null.c  | 163 +++++++++++++++++
>  .../Library/BaseCryptLib/Hash/CryptSha1Null.c | 166 ++++++++++++++++++
>  .../BaseCryptLib/Hash/CryptSha256Null.c       | 162 +++++++++++++++++
>  .../Library/BaseCryptLib/Hash/CryptSm3Null.c  | 164 +++++++++++++++++
>  .../BaseCryptLib/Pk/CryptPkcs7VerifyEkuNull.c | 152 ++++++++++++++++
>  .../BaseCryptLib/Pk/CryptRsaBasicNull.c       | 121 +++++++++++++
>  .../Library/BaseCryptLib/SecCryptLib.inf      |  91 ++++++++++
>  8 files changed, 1023 insertions(+)
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5Null.c
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1Null.c
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256Null.c
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3Null.c
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEkuNull.c
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaBasicNull.c
>  create mode 100644 CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
> 
> diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
> index 0aa72ed87846..b814e9616454 100644
> --- a/CryptoPkg/CryptoPkg.dsc
> +++ b/CryptoPkg/CryptoPkg.dsc
> @@ -109,6 +109,9 @@
>  [LibraryClasses.ARM]
>    ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
> 
> +[LibraryClasses.common.SEC]
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
> +
>  [LibraryClasses.common.PEIM]
>    PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>    ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> @@ -236,6 +239,7 @@
>  !if $(CRYPTO_SERVICES) == PACKAGE
>  [Components]
>    CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +  CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
>    CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
>    CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
>    CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5Null.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5Null.c
> new file mode 100644
> index 000000000000..893a2302a6de
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5Null.c
> @@ -0,0 +1,163 @@
> +/** @file
> +
> +MD5 Digest Wrapper Null Implementation.
> +
> +Copyright (c) Microsoft Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalCryptLib.h"
> +
> +/**
> +  Retrieves the size, in bytes, of the context buffer required for MD5 hash operations.
> +
> +  @return  The size, in bytes, of the context buffer required for MD5 hash operations.
> +
> +**/
> +UINTN
> +EFIAPI
> +Md5GetContextSize (
> +  VOID
> +  )
> +{
> +  ASSERT (FALSE);
> +  return 0;
> +}
> +
> +/**
> +  Initializes user-supplied memory pointed by Md5Context as MD5 hash context for
> +  subsequent use.
> +
> +  If Md5Context is NULL, then return FALSE.
> +
> +  @param[out]  Md5Context  Pointer to MD5 context being initialized.
> +
> +  @retval TRUE   MD5 context initialization succeeded.
> +  @retval FALSE  MD5 context initialization failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Md5Init (
> +  OUT  VOID  *Md5Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Makes a copy of an existing MD5 context.
> +
> +  If Md5Context is NULL, then return FALSE.
> +  If NewMd5Context is NULL, then return FALSE.
> +
> +  @param[in]  Md5Context     Pointer to MD5 context being copied.
> +  @param[out] NewMd5Context  Pointer to new MD5 context.
> +
> +  @retval TRUE   MD5 context copy succeeded.
> +  @retval FALSE  MD5 context copy failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Md5Duplicate (
> +  IN   CONST VOID  *Md5Context,
> +  OUT  VOID        *NewMd5Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Digests the input data and updates MD5 context.
> +
> +  This function performs MD5 digest on a data buffer of the specified size.
> +  It can be called multiple times to compute the digest of long or discontinuous data streams.
> +  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized
> +  by Md5Final(). Behavior with invalid context is undefined.
> +
> +  If Md5Context is NULL, then return FALSE.
> +
> +  @param[in, out]  Md5Context  Pointer to the MD5 context.
> +  @param[in]       Data        Pointer to the buffer containing the data to be hashed.
> +  @param[in]       DataSize    Size of Data buffer in bytes.
> +
> +  @retval TRUE   MD5 data digest succeeded.
> +  @retval FALSE  MD5 data digest failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Md5Update (
> +  IN OUT  VOID        *Md5Context,
> +  IN      CONST VOID  *Data,
> +  IN      UINTN       DataSize
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Completes computation of the MD5 digest value.
> +
> +  This function completes MD5 hash computation and retrieves the digest value into
> +  the specified memory. After this function has been called, the MD5 context cannot
> +  be used again.
> +  MD5 context should be already correctly intialized by Md5Init(), and should not be
> +  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.
> +
> +  If Md5Context is NULL, then return FALSE.
> +  If HashValue is NULL, then return FALSE.
> +
> +  @param[in, out]  Md5Context  Pointer to the MD5 context.
> +  @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest
> +                               value (16 bytes).
> +
> +  @retval TRUE   MD5 digest computation succeeded.
> +  @retval FALSE  MD5 digest computation failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Md5Final (
> +  IN OUT  VOID   *Md5Context,
> +  OUT     UINT8  *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +Computes the MD5 message digest of a input data buffer.
> +
> +This function performs the MD5 message digest of a given data buffer, and places
> +the digest value into the specified memory.
> +
> +If this interface is not supported, then return FALSE.
> +
> +@param[in]   Data        Pointer to the buffer containing the data to be hashed.
> +@param[in]   DataSize    Size of Data buffer in bytes.
> +@param[out]  HashValue   Pointer to a buffer that receives the MD5 digest
> +value (16 bytes).
> +
> +@retval TRUE   MD5 digest computation succeeded.
> +@retval FALSE  MD5 digest computation failed.
> +@retval FALSE  This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Md5HashAll (
> +  IN   CONST VOID  *Data,
> +  IN   UINTN       DataSize,
> +  OUT  UINT8       *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1Null.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1Null.c
> new file mode 100644
> index 000000000000..d9b4610af0e0
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1Null.c
> @@ -0,0 +1,166 @@
> +/** @file
> +  SHA-1 Digest Wrapper Null Implementation.
> +
> +Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalCryptLib.h"
> +
> +/**
> +  Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations.
> +
> +  @return  The size, in bytes, of the context buffer required for SHA-1 hash operations.
> +
> +**/
> +UINTN
> +EFIAPI
> +Sha1GetContextSize (
> +  VOID
> +  )
> +{
> +  //
> +  // Retrieves SHA Context Size
> +  //
> +  ASSERT (FALSE);
> +  return 0;
> +}
> +
> +/**
> +  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for
> +  subsequent use.
> +
> +  If Sha1Context is NULL, then return FALSE.
> +
> +  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.
> +
> +  @retval TRUE   SHA-1 context initialization succeeded.
> +  @retval FALSE  SHA-1 context initialization failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha1Init (
> +  OUT  VOID  *Sha1Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Makes a copy of an existing SHA-1 context.
> +
> +  If Sha1Context is NULL, then return FALSE.
> +  If NewSha1Context is NULL, then return FALSE.
> +
> +  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.
> +  @param[out] NewSha1Context  Pointer to new SHA-1 context.
> +
> +  @retval TRUE   SHA-1 context copy succeeded.
> +  @retval FALSE  SHA-1 context copy failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha1Duplicate (
> +  IN   CONST VOID  *Sha1Context,
> +  OUT  VOID        *NewSha1Context
> +  )
> +{
> +  ASSERT (FALSE);
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Digests the input data and updates SHA-1 context.
> +
> +  This function performs SHA-1 digest on a data buffer of the specified size.
> +  It can be called multiple times to compute the digest of long or discontinuous data streams.
> +  SHA-1 context should be already correctly initialized by Sha1Init(), and should not be finalized
> +  by Sha1Final(). Behavior with invalid context is undefined.
> +
> +  If Sha1Context is NULL, then return FALSE.
> +
> +  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.
> +  @param[in]       Data         Pointer to the buffer containing the data to be hashed.
> +  @param[in]       DataSize     Size of Data buffer in bytes.
> +
> +  @retval TRUE   SHA-1 data digest succeeded.
> +  @retval FALSE  SHA-1 data digest failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha1Update (
> +  IN OUT  VOID        *Sha1Context,
> +  IN      CONST VOID  *Data,
> +  IN      UINTN       DataSize
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Completes computation of the SHA-1 digest value.
> +
> +  This function completes SHA-1 hash computation and retrieves the digest value into
> +  the specified memory. After this function has been called, the SHA-1 context cannot
> +  be used again.
> +  SHA-1 context should be already correctly initialized by Sha1Init(), and should not be
> +  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.
> +
> +  If Sha1Context is NULL, then return FALSE.
> +  If HashValue is NULL, then return FALSE.
> +
> +  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.
> +  @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest
> +                                value (20 bytes).
> +
> +  @retval TRUE   SHA-1 digest computation succeeded.
> +  @retval FALSE  SHA-1 digest computation failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha1Final (
> +  IN OUT  VOID   *Sha1Context,
> +  OUT     UINT8  *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Computes the SHA-1 message digest of a input data buffer.
> +
> +  This function performs the SHA-1 message digest of a given data buffer, and places
> +  the digest value into the specified memory.
> +
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]   Data        Pointer to the buffer containing the data to be hashed.
> +  @param[in]   DataSize    Size of Data buffer in bytes.
> +  @param[out]  HashValue   Pointer to a buffer that receives the SHA-1 digest
> +                           value (20 bytes).
> +
> +  @retval TRUE   SHA-1 digest computation succeeded.
> +  @retval FALSE  SHA-1 digest computation failed.
> +  @retval FALSE  This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha1HashAll (
> +  IN   CONST VOID  *Data,
> +  IN   UINTN       DataSize,
> +  OUT  UINT8       *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256Null.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256Null.c
> new file mode 100644
> index 000000000000..cf994e8e0664
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256Null.c
> @@ -0,0 +1,162 @@
> +/** @file
> +  SHA-256 Digest Wrapper Null Implementation.
> +
> +Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalCryptLib.h"
> +
> +/**
> +  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.
> +
> +  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.
> +
> +**/
> +UINTN
> +EFIAPI
> +Sha256GetContextSize (
> +  VOID
> +  )
> +{
> +  ASSERT (FALSE);
> +  return 0;
> +}
> +
> +/**
> +  Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for
> +  subsequent use.
> +
> +  If Sha256Context is NULL, then return FALSE.
> +
> +  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.
> +
> +  @retval TRUE   SHA-256 context initialization succeeded.
> +  @retval FALSE  SHA-256 context initialization failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha256Init (
> +  OUT  VOID  *Sha256Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Makes a copy of an existing SHA-256 context.
> +
> +  If Sha256Context is NULL, then return FALSE.
> +  If NewSha256Context is NULL, then return FALSE.
> +
> +  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.
> +  @param[out] NewSha256Context  Pointer to new SHA-256 context.
> +
> +  @retval TRUE   SHA-256 context copy succeeded.
> +  @retval FALSE  SHA-256 context copy failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha256Duplicate (
> +  IN   CONST VOID  *Sha256Context,
> +  OUT  VOID        *NewSha256Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Digests the input data and updates SHA-256 context.
> +
> +  This function performs SHA-256 digest on a data buffer of the specified size.
> +  It can be called multiple times to compute the digest of long or discontinuous data streams.
> +  SHA-256 context should be already correctly initialized by Sha256Init(), and should not be finalized
> +  by Sha256Final(). Behavior with invalid context is undefined.
> +
> +  If Sha256Context is NULL, then return FALSE.
> +
> +  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.
> +  @param[in]       Data           Pointer to the buffer containing the data to be hashed.
> +  @param[in]       DataSize       Size of Data buffer in bytes.
> +
> +  @retval TRUE   SHA-256 data digest succeeded.
> +  @retval FALSE  SHA-256 data digest failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha256Update (
> +  IN OUT  VOID        *Sha256Context,
> +  IN      CONST VOID  *Data,
> +  IN      UINTN       DataSize
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Completes computation of the SHA-256 digest value.
> +
> +  This function completes SHA-256 hash computation and retrieves the digest value into
> +  the specified memory. After this function has been called, the SHA-256 context cannot
> +  be used again.
> +  SHA-256 context should be already correctly initialized by Sha256Init(), and should not be
> +  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.
> +
> +  If Sha256Context is NULL, then return FALSE.
> +  If HashValue is NULL, then return FALSE.
> +
> +  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.
> +  @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest
> +                                  value (32 bytes).
> +
> +  @retval TRUE   SHA-256 digest computation succeeded.
> +  @retval FALSE  SHA-256 digest computation failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha256Final (
> +  IN OUT  VOID   *Sha256Context,
> +  OUT     UINT8  *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Computes the SHA-256 message digest of a input data buffer.
> +
> +  This function performs the SHA-256 message digest of a given data buffer, and places
> +  the digest value into the specified memory.
> +
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]   Data        Pointer to the buffer containing the data to be hashed.
> +  @param[in]   DataSize    Size of Data buffer in bytes.
> +  @param[out]  HashValue   Pointer to a buffer that receives the SHA-256 digest
> +                           value (32 bytes).
> +
> +  @retval TRUE   SHA-256 digest computation succeeded.
> +  @retval FALSE  SHA-256 digest computation failed.
> +  @retval FALSE  This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sha256HashAll (
> +  IN   CONST VOID  *Data,
> +  IN   UINTN       DataSize,
> +  OUT  UINT8       *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3Null.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3Null.c
> new file mode 100644
> index 000000000000..0f3c89b46517
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSm3Null.c
> @@ -0,0 +1,164 @@
> +/** @file
> +  SM3 Digest Wrapper Null Implementation.
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalCryptLib.h"
> +
> +/**
> +  Retrieves the size, in bytes, of the context buffer required for SM3 hash operations.
> +
> +  @return  The size, in bytes, of the context buffer required for SM3 hash operations.
> +
> +**/
> +UINTN
> +EFIAPI
> +Sm3GetContextSize (
> +  VOID
> +  )
> +{
> +  ASSERT (FALSE);
> +  return 0;
> +}
> +
> +/**
> +  Initializes user-supplied memory pointed by Sm3Context as SM3 hash context for
> +  subsequent use.
> +
> +  If Sm3Context is NULL, then return FALSE.
> +
> +  @param[out]  Sm3Context  Pointer to SM3 context being initialized.
> +
> +  @retval TRUE   SM3 context initialization succeeded.
> +  @retval FALSE  SM3 context initialization failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sm3Init (
> +  OUT  VOID  *Sm3Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Makes a copy of an existing SM3 context.
> +
> +  If Sm3Context is NULL, then return FALSE.
> +  If NewSm3Context is NULL, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  Sm3Context     Pointer to SM3 context being copied.
> +  @param[out] NewSm3Context  Pointer to new SM3 context.
> +
> +  @retval TRUE   SM3 context copy succeeded.
> +  @retval FALSE  SM3 context copy failed.
> +  @retval FALSE  This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sm3Duplicate (
> +  IN   CONST VOID  *Sm3Context,
> +  OUT  VOID        *NewSm3Context
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Digests the input data and updates SM3 context.
> +
> +  This function performs SM3 digest on a data buffer of the specified size.
> +  It can be called multiple times to compute the digest of long or discontinuous data streams.
> +  SM3 context should be already correctly initialized by Sm3Init(), and should not be finalized
> +  by Sm3Final(). Behavior with invalid context is undefined.
> +
> +  If Sm3Context is NULL, then return FALSE.
> +
> +  @param[in, out]  Sm3Context     Pointer to the SM3 context.
> +  @param[in]       Data           Pointer to the buffer containing the data to be hashed.
> +  @param[in]       DataSize       Size of Data buffer in bytes.
> +
> +  @retval TRUE   SM3 data digest succeeded.
> +  @retval FALSE  SM3 data digest failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sm3Update (
> +  IN OUT  VOID        *Sm3Context,
> +  IN      CONST VOID  *Data,
> +  IN      UINTN       DataSize
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Completes computation of the SM3 digest value.
> +
> +  This function completes SM3 hash computation and retrieves the digest value into
> +  the specified memory. After this function has been called, the SM3 context cannot
> +  be used again.
> +  SM3 context should be already correctly initialized by Sm3Init(), and should not be
> +  finalized by Sm3Final(). Behavior with invalid SM3 context is undefined.
> +
> +  If Sm3Context is NULL, then return FALSE.
> +  If HashValue is NULL, then return FALSE.
> +
> +  @param[in, out]  Sm3Context     Pointer to the SM3 context.
> +  @param[out]      HashValue      Pointer to a buffer that receives the SM3 digest
> +                                  value (32 bytes).
> +
> +  @retval TRUE   SM3 digest computation succeeded.
> +  @retval FALSE  SM3 digest computation failed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sm3Final (
> +  IN OUT  VOID   *Sm3Context,
> +  OUT     UINT8  *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Computes the SM3 message digest of a input data buffer.
> +
> +  This function performs the SM3 message digest of a given data buffer, and places
> +  the digest value into the specified memory.
> +
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]   Data        Pointer to the buffer containing the data to be hashed.
> +  @param[in]   DataSize    Size of Data buffer in bytes.
> +  @param[out]  HashValue   Pointer to a buffer that receives the SM3 digest
> +                           value (32 bytes).
> +
> +  @retval TRUE   SM3 digest computation succeeded.
> +  @retval FALSE  SM3 digest computation failed.
> +  @retval FALSE  This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Sm3HashAll (
> +  IN   CONST VOID  *Data,
> +  IN   UINTN       DataSize,
> +  OUT  UINT8       *HashValue
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEkuNull.c
> b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEkuNull.c
> new file mode 100644
> index 000000000000..c1d9837c5129
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyEkuNull.c
> @@ -0,0 +1,152 @@
> +/** @file
> +  PKCS7 Verify Null implementation.
> +
> +  Copyright (C) Microsoft Corporation. All Rights Reserved.
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalCryptLib.h"
> +
> +/**
> +  This function will return the leaf signer certificate in a chain.  This is
> +  required because certificate chains are not guaranteed to have the
> +  certificates in the order that they were issued.
> +
> +  A typical certificate chain looks like this:
> +
> +
> +                 ----------------------------
> +                |            Root            |
> +                 ----------------------------
> +                               ^
> +                               |
> +                 ----------------------------
> +                |          Policy CA         | <-- Typical Trust Anchor.
> +                 ----------------------------
> +                               ^
> +                               |
> +                 ----------------------------
> +                |         Issuing CA         |
> +                 ----------------------------
> +                               ^
> +                               |
> +                 -----------------------------
> +                /  End-Entity (leaf) signer  / <-- Bottom certificate.
> +                -----------------------------  EKU: "1.3.6.1.4.1.311.76.9.21.1"
> +                                                    (Firmware Signing)
> +
> +
> +  @param[in]   CertChain            Certificate chain.
> +
> +  @param[out]  SignerCert           Last certificate in the chain.  For PKCS7 signatures,
> +                                    this will be the end-entity (leaf) signer cert.
> +
> +  @retval EFI_SUCCESS               The required EKUs were found in the signature.
> +  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
> +  @retval EFI_NOT_FOUND             The number of signers found was not 1.
> +
> +**/
> +EFI_STATUS
> +GetSignerCertificate (
> +  IN CONST VOID  *CertChain,
> +  OUT VOID       **SignerCert
> +  )
> +{
> +  ASSERT (FALSE);
> +  return EFI_NOT_READY;
> +}
> +
> +/**
> +  Determines if the specified EKU represented in ASN1 form is present
> +  in a given certificate.
> +
> +  @param[in]  Cert                  The certificate to check.
> +
> +  @param[in]  Asn1ToFind            The EKU to look for.
> +
> +  @retval EFI_SUCCESS               We successfully identified the signing type.
> +  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
> +  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.
> +
> +**/
> +EFI_STATUS
> +IsEkuInCertificate (
> +  IN CONST VOID  *Cert,
> +  IN VOID        *Asn1ToFind
> +  )
> +{
> +  ASSERT (FALSE);
> +  return EFI_NOT_READY;
> +}
> +
> +/**
> +  Determines if the specified EKUs are present in a signing certificate.
> +
> +  @param[in]  SignerCert            The certificate to check.
> +  @param[in]  RequiredEKUs          The EKUs to look for.
> +  @param[in]  RequiredEKUsSize      The number of EKUs
> +  @param[in]  RequireAllPresent     If TRUE, then all the specified EKUs
> +                                    must be present in the certificate.
> +
> +  @retval EFI_SUCCESS               We successfully identified the signing type.
> +  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
> +  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.
> +**/
> +EFI_STATUS
> +CheckEKUs (
> +  IN CONST VOID    *SignerCert,
> +  IN CONST CHAR8   *RequiredEKUs[],
> +  IN CONST UINT32  RequiredEKUsSize,
> +  IN BOOLEAN       RequireAllPresent
> +  )
> +{
> +  ASSERT (FALSE);
> +  return EFI_NOT_READY;
> +}
> +
> +/**
> +  This function receives a PKCS#7 formatted signature blob,
> +  looks for the EKU SEQUENCE blob, and if found then looks
> +  for all the required EKUs. This function was created so that
> +  the Surface team can cut down on the number of Certificate
> +  Authorities (CA's) by checking EKU's on leaf signers for
> +  a specific product. This prevents one product's certificate
> +  from signing another product's firmware or unlock blobs.
> +
> +  Note that this function does not validate the certificate chain.
> +  That needs to be done before using this function.
> +
> +  @param[in]  Pkcs7Signature       The PKCS#7 signed information content block. An array
> +                                   containing the content block with both the signature,
> +                                   the signer's certificate, and any necessary intermediate
> +                                   certificates.
> +  @param[in]  Pkcs7SignatureSize   Number of bytes in Pkcs7Signature.
> +  @param[in]  RequiredEKUs         Array of null-terminated strings listing OIDs of
> +                                   required EKUs that must be present in the signature.
> +  @param[in]  RequiredEKUsSize     Number of elements in the RequiredEKUs string array.
> +  @param[in]  RequireAllPresent    If this is TRUE, then all of the specified EKU's
> +                                   must be present in the leaf signer.  If it is
> +                                   FALSE, then we will succeed if we find any
> +                                   of the specified EKU's.
> +
> +  @retval EFI_SUCCESS              The required EKUs were found in the signature.
> +  @retval EFI_INVALID_PARAMETER    A parameter was invalid.
> +  @retval EFI_NOT_FOUND            One or more EKU's were not found in the signature.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VerifyEKUsInPkcs7Signature (
> +  IN CONST UINT8   *Pkcs7Signature,
> +  IN CONST UINT32  SignatureSize,
> +  IN CONST CHAR8   *RequiredEKUs[],
> +  IN CONST UINT32  RequiredEKUsSize,
> +  IN BOOLEAN       RequireAllPresent
> +  )
> +{
> +  ASSERT (FALSE);
> +  return EFI_NOT_READY;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaBasicNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaBasicNull.c
> new file mode 100644
> index 000000000000..fd352e32dd93
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsaBasicNull.c
> @@ -0,0 +1,121 @@
> +/** @file
> +  RSA Asymmetric Cipher Wrapper Null Implementation.
> +
> +  This file implements following APIs which provide basic capabilities for RSA:
> +  1) RsaNew
> +  2) RsaFree
> +  3) RsaSetKey
> +  4) RsaPkcs1Verify
> +
> +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "InternalCryptLib.h"
> +
> +/**
> +  Allocates and initializes one RSA context for subsequent use.
> +
> +  @return  Pointer to the RSA context that has been initialized.
> +           If the allocations fails, RsaNew() returns NULL.
> +
> +**/
> +VOID *
> +EFIAPI
> +RsaNew (
> +  VOID
> +  )
> +{
> +  //
> +  // Allocates & Initializes RSA Context
> +  //
> +  ASSERT (FALSE);
> +  return NULL;
> +}
> +
> +/**
> +  Release the specified RSA context.
> +
> +  @param[in]  RsaContext  Pointer to the RSA context to be released.
> +
> +**/
> +VOID
> +EFIAPI
> +RsaFree (
> +  IN  VOID  *RsaContext
> +  )
> +{
> +  //
> +  // Free RSA Context
> +  //
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  Sets the tag-designated key component into the established RSA context.
> +
> +  This function sets the tag-designated RSA key component into the established
> +  RSA context from the user-specified non-negative integer (octet string format
> +  represented in RSA PKCS#1).
> +  If BigNumber is NULL, then the specified key component in RSA context is cleared.
> +
> +  If RsaContext is NULL, then return FALSE.
> +
> +  @param[in, out]  RsaContext  Pointer to RSA context being set.
> +  @param[in]       KeyTag      Tag of RSA key component being set.
> +  @param[in]       BigNumber   Pointer to octet integer buffer.
> +                               If NULL, then the specified key component in RSA
> +                               context is cleared.
> +  @param[in]       BnSize      Size of big number buffer in bytes.
> +                               If BigNumber is NULL, then it is ignored.
> +
> +  @retval  TRUE   RSA key component was set successfully.
> +  @retval  FALSE  Invalid RSA key component tag.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +RsaSetKey (
> +  IN OUT  VOID         *RsaContext,
> +  IN      RSA_KEY_TAG  KeyTag,
> +  IN      CONST UINT8  *BigNumber,
> +  IN      UINTN        BnSize
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> +
> +/**
> +  Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
> +  RSA PKCS#1.
> +
> +  If RsaContext is NULL, then return FALSE.
> +  If MessageHash is NULL, then return FALSE.
> +  If Signature is NULL, then return FALSE.
> +  If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.
> +
> +  @param[in]  RsaContext   Pointer to RSA context for signature verification.
> +  @param[in]  MessageHash  Pointer to octet message hash to be checked.
> +  @param[in]  HashSize     Size of the message hash in bytes.
> +  @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.
> +  @param[in]  SigSize      Size of signature in bytes.
> +
> +  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.
> +  @retval  FALSE  Invalid signature or invalid RSA context.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +RsaPkcs1Verify (
> +  IN  VOID         *RsaContext,
> +  IN  CONST UINT8  *MessageHash,
> +  IN  UINTN        HashSize,
> +  IN  CONST UINT8  *Signature,
> +  IN  UINTN        SigSize
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
> new file mode 100644
> index 000000000000..070b44447e74
> --- /dev/null
> +++ b/CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
> @@ -0,0 +1,91 @@
> +## @file
> +#  Cryptographic Library Instance for SEC.
> +#
> +#  Caution: This module requires additional review when modified.
> +#  This library will have external input - signature.
> +#  This external input must be validated carefully to avoid security issues such as
> +#  buffer overflow or integer overflow.
> +#
> +#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SecCryptLib
> +  FILE_GUID                      = 3689D343-0D32-4284-8053-BF10537990E8
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = BaseCryptLib|SEC
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  InternalCryptLib.h
> +  Hash/CryptSha512.c
> +
> +  Hash/CryptMd5Null.c
> +  Hash/CryptSha1Null.c
> +  Hash/CryptSha256Null.c
> +  Hash/CryptSm3Null.c
> +  Hash/CryptParallelHashNull.c
> +  Hmac/CryptHmacSha256Null.c
> +  Kdf/CryptHkdfNull.c
> +  Cipher/CryptAesNull.c
> +  Pk/CryptRsaBasicNull.c
> +  Pk/CryptRsaExtNull.c
> +  Pk/CryptPkcs1OaepNull.c
> +  Pk/CryptPkcs5Pbkdf2Null.c
> +  Pk/CryptPkcs7SignNull.c
> +  Pk/CryptPkcs7VerifyNull.c
> +  Pk/CryptPkcs7VerifyEkuNull.c
> +  Pk/CryptDhNull.c
> +  Pk/CryptX509Null.c
> +  Pk/CryptAuthenticodeNull.c
> +  Pk/CryptTsNull.c
> +  Pem/CryptPemNull.c
> +  Rand/CryptRandNull.c
> +  Pk/CryptRsaPssNull.c
> +  Pk/CryptRsaPssSignNull.c
> +
> +  SysCall/CrtWrapper.c
> +  SysCall/ConstantTimeClock.c
> +  SysCall/BaseMemAllocation.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CryptoPkg/CryptoPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  DebugLib
> +  OpensslLib
> +  IntrinsicLib
> +
> +#
> +# Remove these [BuildOptions] after this library is cleaned up
> +#
> +[BuildOptions]
> +  #
> +  # suppress the following warnings so we do not break the build with warnings-as-errors:
> +  # C4090: 'function' : different 'const' qualifiers
> +  # C4718: 'function call' : recursive call has no side effects, deleting
> +  #
> +  MSFT:*_*_*_CC_FLAGS = /wd4090 /wd4718
> +
> +  # -JCryptoPkg/Include : To disable the use of the system includes provided by RVCT
> +  # --diag_remark=1     : Reduce severity of "#1-D: last line of file ends without a newline"
> +  RVCT:*_*_ARM_CC_FLAGS = -JCryptoPkg/Include --diag_remark=1
> +
> +  GCC:*_CLANG35_*_CC_FLAGS = -std=c99
> +  GCC:*_CLANG38_*_CC_FLAGS = -std=c99
> +  GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
> +
> +  XCODE:*_*_*_CC_FLAGS = -std=c99
> --
> 2.29.2.windows.2
> 
> 
> 
> 
> 


  reply	other threads:[~2022-04-18 15:32 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-17 23:59 [PATCH V3 0/9] Enable RTMR based measurement and measure boot for Td guest Min Xu
2022-04-17 23:59 ` [PATCH V3 1/9] Security: Add HashLibTdx Min Xu
2022-04-17 23:59 ` [PATCH V3 2/9] CryptoPkg: Add SecCryptLib Min Xu
2022-04-18 15:31   ` Michael D Kinney [this message]
2022-04-19 11:45     ` [edk2-devel] " Min Xu
2022-04-17 23:59 ` [PATCH V3 3/9] SecurityPkg: Add definition of EFI_CC_EVENT_HOB_GUID Min Xu
2022-04-17 23:59 ` [PATCH V3 4/9] OvmfPkg: Introduce SecMeasurementLib Min Xu
2022-04-17 23:59 ` [PATCH V3 5/9] OvmfPkg/IntelTdx: Measure Td HobList and Configuration FV Min Xu
2022-04-19  6:58   ` Gerd Hoffmann
2022-04-19 11:12     ` Min Xu
2022-04-19 12:49       ` [edk2-devel] " Gerd Hoffmann
2022-04-19 14:06         ` Yao, Jiewen
2022-04-20  8:16           ` Gerd Hoffmann
2022-04-20  9:46             ` Yao, Jiewen
2022-04-20 16:05               ` Gerd Hoffmann
2022-04-20 14:25             ` James Bottomley
2022-04-20 16:29               ` Gerd Hoffmann
2022-04-20 22:29                 ` Yao, Jiewen
2022-04-21  9:14                   ` Gerd Hoffmann
2022-04-21  9:24                     ` Yao, Jiewen
2022-04-17 23:59 ` [PATCH V3 6/9] OvmfPkg: Add PCDs for LAML/LASA field in CC EVENTLOG ACPI table Min Xu
2022-04-17 23:59 ` [PATCH V3 7/9] MdePkg: Define CC Measure EventLog ACPI Table Min Xu
2022-04-18  1:23   ` Yao, Jiewen
2022-04-18  2:02     ` Min Xu
2022-04-17 23:59 ` [PATCH V3 8/9] OvmfPkg/IntelTdx: Add TdTcg2Dxe Min Xu
2022-04-18  0:00 ` [PATCH V3 9/9] OvmfPkg/IntelTdx: Enable RTMR based measurement and measure boot Min Xu
2022-04-18  1:43 ` [edk2-devel] [PATCH V3 0/9] Enable RTMR based measurement and measure boot for Td guest Yao, Jiewen

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=CO1PR11MB4929F716BEF3EB15FE12F17FD2F39@CO1PR11MB4929.namprd11.prod.outlook.com \
    --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