public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Nhi Pham via groups.io" <nhi=os.amperecomputing.com@groups.io>
To: "Hou, Wenxing" <wenxing.hou@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Tam Chi Nguyen <tamnguyenchi@os.amperecomputing.com>,
	"Yao, Jiewen" <jiewen.yao@intel.com>,
	"Li, Yi1" <yi1.li@intel.com>
Subject: Re: [edk2-devel] [PATCH 1/1] CryptoPkg: Add new API to get PKCS7 Signature
Date: Tue, 30 Jan 2024 16:48:55 +0700	[thread overview]
Message-ID: <32f064a1-f435-4173-92e0-9dfd7e708317@os.amperecomputing.com> (raw)
In-Reply-To: <PH0PR11MB50462F1190FC972E7356634CF77D2@PH0PR11MB5046.namprd11.prod.outlook.com>

Thanks Wenxing. I'll do that.

Regards,
Nhi

On 1/30/2024 4:46 PM, Hou, Wenxing wrote:
> Hi Pham,
> 
> Thanks for your contribution.
> 
> I think there are two works you need to do:
> Firstly, submit an EDKII PR to ensure the patch can pass the CI.
> Secondly,  add unit-test to test the new API(such as: get signature then compare).
> 
> 
> Thanks
> Wenxing
> 
> 
> -----Original Message-----
> From: Nhi Pham <nhi@os.amperecomputing.com>
> Sent: Tuesday, January 30, 2024 1:44 PM
> To: devel@edk2.groups.io
> Cc: Tam Chi Nguyen <tamnguyenchi@os.amperecomputing.com>; Yao, Jiewen <jiewen.yao@intel.com>; Hou, Wenxing <wenxing.hou@intel.com>; Li, Yi1 <yi1.li@intel.com>; Nhi Pham <nhi@os.amperecomputing.com>
> Subject: [PATCH 1/1] CryptoPkg: Add new API to get PKCS7 Signature
> 
> From: Tam Chi Nguyen <tamnguyenchi@os.amperecomputing.com>
> 
> This patch adds a new Pkcs7GetSignature() API to support extracting the signature data from PKCS7 certificate.
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Wenxing Hou <wenxing.hou@intel.com>
> Cc: Yi Li <yi1.li@intel.com>
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
>   CryptoPkg/Include/Library/BaseCryptLib.h                   |  29 +++++
>   CryptoPkg/Private/Protocol/Crypto.h                        |  29 +++++
>   CryptoPkg/Driver/Crypto.c                                  |  33 ++++++
>   CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c | 120 ++++++++++++++++++++
>   CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c   |  33 ++++++
>   CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c     |  32 ++++++
>   6 files changed, 276 insertions(+)
> 
> diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
> index a52bd91ad664..d52a91244482 100644
> --- a/CryptoPkg/Include/Library/BaseCryptLib.h
> +++ b/CryptoPkg/Include/Library/BaseCryptLib.h
> @@ -5,6 +5,7 @@
>     functionality enabling.
>   
>   Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
>   SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -2471,6 +2472,34 @@ ImageTimestampVerify (
>     OUT EFI_TIME     *SigningTime
>     );
>   
> +/**
> +  Get the data signature from PKCS#7 signed data as described in "PKCS #7:
> +  Cryptographic Message Syntax Standard". The input signed data could
> +be wrapped
> +  in a ContentInfo structure.
> +
> +  If P7Data, Signature, SignatureLength is NULL, then return FALSE.
> +  If P7Length overflow, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
> +  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
> +  @param[out] Signature    Pointer to Signature data
> +  @param[out] SignatureLength  Length of signature in bytes.
> +
> +  @retval  TRUE            The operation is finished successfully.
> +  @retval  FALSE           Error occurs during the operation.
> +  @retval  FALSE           This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Pkcs7GetSignature (
> +  IN  CONST UINT8  *P7Data,
> +  IN  UINTN        P7Length,
> +  OUT UINT8        **Signature,
> +  OUT UINTN        *SignatureLength
> +  );
> +
>   /**
>     Retrieve the version from one X.509 certificate.
>   
> diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
> index 0e0b1d94018d..d228cea0453b 100644
> --- a/CryptoPkg/Private/Protocol/Crypto.h
> +++ b/CryptoPkg/Private/Protocol/Crypto.h
> @@ -3,6 +3,7 @@
>   
>     Copyright (C) Microsoft Corporation. All rights reserved.
>     Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
>     SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -1036,6 +1037,34 @@ BOOLEAN
>     OUT EFI_TIME     *SigningTime
>     );
>   
> +/**
> +  Get the data signature from PKCS#7 signed data as described in "PKCS #7:
> +  Cryptographic Message Syntax Standard". The input signed data could
> +be wrapped
> +  in a ContentInfo structure.
> +
> +  If P7Data, Signature, SignatureLength is NULL, then return FALSE.
> +  If P7Length overflow, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
> +  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
> +  @param[out] Signature    Pointer to Signature data
> +  @param[out] SignatureLength  Length of signature in bytes.
> +
> +  @retval  TRUE            The operation is finished successfully.
> +  @retval  FALSE           Error occurs during the operation.
> +  @retval  FALSE           This interface is not supported.
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *EDKII_CRYPTO_PKCS7_GET_SIGNATURE) (
> +  IN  CONST UINT8  *P7Data,
> +  IN  UINTN        P7Length,
> +  OUT UINT8        **Signature,
> +  OUT UINTN        *SignatureLength
> +  );
> +
>   // =====================================================================================
>   //    DH Key Exchange Primitive
>   // =====================================================================================
> diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index bdbb4863a97e..83094e73c33a 100644
> --- a/CryptoPkg/Driver/Crypto.c
> +++ b/CryptoPkg/Driver/Crypto.c
> @@ -4,6 +4,7 @@
>   
>     Copyright (C) Microsoft Corporation. All rights reserved.
>     Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
>     SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -3910,6 +3911,37 @@ CryptoServiceImageTimestampVerify (
>     return CALL_BASECRYPTLIB (Pkcs.Services.ImageTimestampVerify, ImageTimestampVerify, (AuthData, DataSize, TsaCert, CertSize, SigningTime), FALSE);  }
>   
> +/**
> +  Get the data signature from PKCS#7 signed data as described in "PKCS #7:
> +  Cryptographic Message Syntax Standard". The input signed data could
> +be wrapped
> +  in a ContentInfo structure.
> +
> +  If P7Data, Signature, SignatureLength is NULL, then return FALSE.
> +  If P7Length overflow, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
> +  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
> +  @param[out] Signature    Pointer to Signature data
> +  @param[out] SignatureLength  Length of signature in bytes.
> +
> +  @retval  TRUE            The operation is finished successfully.
> +  @retval  FALSE           Error occurs during the operation.
> +  @retval  FALSE           This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +CryptoServicePkcs7GetSignature (
> +  IN  CONST UINT8  *P7Data,
> +  IN  UINTN        P7Length,
> +  OUT UINT8        **Signature,
> +  OUT UINTN        *SignatureLength
> +  )
> +{
> +  return CALL_BASECRYPTLIB (Pkcs.Services.Pkcs7GetSignature,
> +Pkcs7GetSignature, (P7Data, P7Length, Signature, SignatureLength),
> +FALSE); }
> +
>   // =====================================================================================
>   //    DH Key Exchange Primitive
>   // =====================================================================================
> @@ -6748,6 +6780,7 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
>     CryptoServicePkcs7GetCertificatesList,
>     CryptoServiceAuthenticodeVerify,
>     CryptoServiceImageTimestampVerify,
> +  CryptoServicePkcs7GetSignature,
>     /// DH
>     CryptoServiceDhNew,
>     CryptoServiceDhFree,
> diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
> index 4e5a14e35210..9e3fccf1bb4e 100644
> --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
> +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
> @@ -11,6 +11,7 @@
>     Variable and will do basic check for data structure.
>   
>   Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
>   SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -926,3 +927,122 @@ _Exit:
>   
>     return Status;
>   }
> +
> +/**
> +  Get the data signature from PKCS#7 signed data as described in "PKCS #7:
> +  Cryptographic Message Syntax Standard". The input signed data could
> +be wrapped
> +  in a ContentInfo structure.
> +
> +  If P7Data, Signature, SignatureLength is NULL, then return FALSE.
> +  If P7Length overflow, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
> +  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
> +  @param[out] Signature    Pointer to Signature data
> +  @param[out] SignatureLength  Length of signature in bytes.
> +
> +  @retval  TRUE            The operation is finished successfully.
> +  @retval  FALSE           Error occurs during the operation.
> +  @retval  FALSE           This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Pkcs7GetSignature (
> +  IN  CONST UINT8  *P7Data,
> +  IN  UINTN        P7Length,
> +  OUT UINT8        **Signature,
> +  OUT UINTN        *SignatureLength
> +  )
> +{
> +  PKCS7                         *Pkcs7;
> +  BOOLEAN                       Wrapped;
> +  BOOLEAN                       Status;
> +  UINT8                         *SignedData;
> +  UINT8                         *Temp;
> +  UINTN                         SignedDataSize;
> +  STACK_OF (PKCS7_SIGNER_INFO)  *SignerInfos;
> +  PKCS7_SIGNER_INFO             *SignInfo;
> +  ASN1_OCTET_STRING             *EncDigest;
> +
> +  if ((P7Data == NULL) || (P7Length > INT_MAX) ||
> +      (Signature == NULL && SignatureLength == NULL)) {
> +    return FALSE;
> +  }
> +
> +  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData,
> + &SignedDataSize);  if (!Status) {
> +    return Status;
> +  }
> +
> +  Status     = FALSE;
> +  Pkcs7      = NULL;
> +  //
> +  // Retrieve PKCS#7 Data (DER encoding)  //  if (SignedDataSize >
> + INT_MAX) {
> +    goto _Exit;
> +  }
> +
> +  Temp = SignedData;
> +  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int)
> + SignedDataSize);  if (Pkcs7 == NULL) {
> +    goto _Exit;
> +  }
> +
> +  //
> +  // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)  //
> + if (!PKCS7_type_is_signed (Pkcs7)) {
> +    goto _Exit;
> +  }
> +
> +  //
> +  // Check if there is one and only one signer.
> +  //
> +  SignerInfos = PKCS7_get_signer_info (Pkcs7);  if (!SignerInfos ||
> + (sk_PKCS7_SIGNER_INFO_num (SignerInfos) != 1)) {
> +    goto _Exit;
> +  }
> +
> +  //
> +  // Locate the TimeStamp CounterSignature.
> +  //
> +  SignInfo = sk_PKCS7_SIGNER_INFO_value (SignerInfos, 0);  if (SignInfo
> + == NULL) {
> +    goto _Exit;
> +  }
> +
> +  //
> +  // Locate Message Digest which will be the data to be time-stamped.
> +  //
> +  EncDigest = SignInfo->enc_digest;
> +  if (EncDigest == NULL) {
> +    goto _Exit;
> +  }
> +
> +  *SignatureLength = EncDigest->length;  if (Signature != NULL)  {
> +    if (*Signature == NULL) {
> +      Status = FALSE;
> +      goto _Exit;
> +    }
> +    CopyMem ((VOID *)*Signature, EncDigest->data, EncDigest->length);
> +    Status = TRUE;
> +  }
> +
> +_Exit:
> +  //
> +  // Release Resources
> +  //
> +  if (!Wrapped) {
> +    free (SignedData);
> +  }
> +  if (Pkcs7 != NULL) {
> +    PKCS7_free (Pkcs7);
> +  }
> +
> +  return Status;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c
> index b9b7960126de..a080bbfc4237 100644
> --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c
> +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c
> @@ -3,6 +3,7 @@
>     real capabilities.
>   
>   Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
>   SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -161,3 +162,35 @@ Pkcs7GetAttachedContent (
>     ASSERT (FALSE);
>     return FALSE;
>   }
> +
> +/**
> +  Get the data signature from PKCS#7 signed data as described in "PKCS #7:
> +  Cryptographic Message Syntax Standard". The input signed data could
> +be wrapped
> +  in a ContentInfo structure.
> +
> +  If P7Data, Signature, SignatureLength is NULL, then return FALSE.
> +  If P7Length overflow, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
> +  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
> +  @param[out] Signature    Pointer to Signature data
> +  @param[out] SignatureLength  Length of signature in bytes.
> +
> +  @retval  TRUE            The operation is finished successfully.
> +  @retval  FALSE           Error occurs during the operation.
> +  @retval  FALSE           This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Pkcs7GetSignature (
> +  IN  CONST UINT8  *P7Data,
> +  IN  UINTN        P7Length,
> +  OUT UINT8        **Signature,
> +  OUT UINTN        *SignatureLength
> +  )
> +{
> +  ASSERT (FALSE);
> +  return FALSE;
> +}
> diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
> index 4e31bc278e0f..55d7b17688a0 100644
> --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
> +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
> @@ -4,6 +4,7 @@
>   
>     Copyright (C) Microsoft Corporation. All rights reserved.
>     Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
>     SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -3146,6 +3147,37 @@ ImageTimestampVerify (
>     CALL_CRYPTO_SERVICE (ImageTimestampVerify, (AuthData, DataSize, TsaCert, CertSize, SigningTime), FALSE);  }
>   
> +/**
> +  Get the data signature from PKCS#7 signed data as described in "PKCS #7:
> +  Cryptographic Message Syntax Standard". The input signed data could
> +be wrapped
> +  in a ContentInfo structure.
> +
> +  If P7Data, Signature, SignatureLength is NULL, then return FALSE.
> +  If P7Length overflow, then return FALSE.
> +  If this interface is not supported, then return FALSE.
> +
> +  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
> +  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
> +  @param[out] Signature    Pointer to Signature data
> +  @param[out] SignatureLength  Length of signature in bytes.
> +
> +  @retval  TRUE            The operation is finished successfully.
> +  @retval  FALSE           Error occurs during the operation.
> +  @retval  FALSE           This interface is not supported.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +Pkcs7GetSignature (
> +  IN  CONST UINT8  *P7Data,
> +  IN  UINTN        P7Length,
> +  OUT UINT8        **Signature,
> +  OUT UINTN        *SignatureLength
> +  )
> +{
> +  CALL_CRYPTO_SERVICE (Pkcs7GetSignature, (P7Data, P7Length, Signature,
> +SignatureLength), FALSE); }
> +
>   // =====================================================================================
>   //    DH Key Exchange Primitive
>   // =====================================================================================
> --
> 2.25.1
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114769): https://edk2.groups.io/g/devel/message/114769
Mute This Topic: https://groups.io/mt/104048629/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  reply	other threads:[~2024-01-30  9:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-30  5:44 [edk2-devel] [PATCH 1/1] CryptoPkg: Add new API to get PKCS7 Signature Nhi Pham via groups.io
2024-01-30  9:46 ` Wenxing Hou
2024-01-30  9:48   ` Nhi Pham via groups.io [this message]
2024-02-01  2:09     ` Yao, Jiewen
2024-02-19  3:31       ` Nhi Pham via groups.io

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=32f064a1-f435-4173-92e0-9dfd7e708317@os.amperecomputing.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