summaryrefslogtreecommitdiff
path: root/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
diff options
context:
space:
mode:
Diffstat (limited to 'CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c')
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c635
1 files changed, 635 insertions, 0 deletions
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
new file mode 100644
index 0000000..e3283da
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
@@ -0,0 +1,635 @@
+/** @file
+ PKCS#7 SignedData Sign Wrapper and PKCS#7 SignedData Verification Wrapper
+ Implementation over mbedtls.
+
+ RFC 8422 - Elliptic Curve Cryptography (ECC) Cipher Suites
+ FIPS 186-4 - Digital Signature Standard (DSS)
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CryptPkcs7Internal.h"
+#include <mbedtls/ecdh.h>
+
+///
+/// Enough to store any signature generated by PKCS7
+///
+#define MAX_SIGNATURE_SIZE 1024
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 MbedtlsOidDigestAlgSha256[] = MBEDTLS_OID_DIGEST_ALG_SHA256;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 MbedtlsOidPkcs1Rsa[] = MBEDTLS_OID_PKCS1_RSA;
+
+/**
+ Write DigestAlgorithmIdentifier.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] DigestType Digest Type
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteDigestAlgorithm (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ mbedtls_md_type_t DigestType
+ )
+{
+ UINT8 *OidPtr;
+ UINTN OidLen;
+ INT32 Ret;
+
+ Ret = mbedtls_oid_get_oid_by_md (DigestType, (CONST CHAR8 **)&OidPtr, &OidLen);
+ if (Ret == 0) {
+ return mbedtls_asn1_write_oid (Ptr, (CONST UINT8 *)Start, (CONST CHAR8 *)OidPtr, OidLen);
+ }
+
+ return 0;
+}
+
+/**
+ DigestAlgorithmIdentifiers ::=
+ SET OF DigestAlgorithmIdentifier.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] DigestTypes Digest Type array.
+ @param[in] Count The index for Digest Type.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteDigestAlgorithmSet (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ mbedtls_md_type_t *DigestTypes,
+ INTN Count
+ )
+{
+ INTN Idx;
+ INT32 Len;
+ INT32 Ret;
+
+ Len = 0;
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_null (Ptr, Start));
+
+ for (Idx = 0; Idx < Count; Idx++) {
+ EDKII_ASN1_CHK_ADD (
+ Len,
+ MbedTlsPkcs7WriteDigestAlgorithm (Ptr, Start, DigestTypes[Idx])
+ );
+ }
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));
+
+ EDKII_ASN1_CHK_ADD (
+ Len,
+ mbedtls_asn1_write_tag (
+ Ptr,
+ Start,
+ (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)
+ )
+ );
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));
+
+ EDKII_ASN1_CHK_ADD (
+ Len,
+ mbedtls_asn1_write_tag (
+ Ptr,
+ Start,
+ (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)
+ )
+ );
+
+ return Len;
+}
+
+/**
+ ContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ content
+ [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] Content ContentInfo.
+ @param[in] ContentLen Size of ContentInfo.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteContentInfo (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ UINT8 *Content,
+ INTN ContentLen
+ )
+{
+ INT32 Ret;
+ INT32 Len;
+
+ Len = 0;
+ if (Content != NULL) {
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, Content, ContentLen));
+ }
+
+ EDKII_ASN1_CHK_ADD (
+ Len,
+ mbedtls_asn1_write_oid (
+ Ptr,
+ Start,
+ MBEDTLS_OID_PKCS7_DATA,
+ sizeof (MBEDTLS_OID_PKCS7_DATA) - 1
+ )
+ );
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
+
+ return Len;
+}
+
+/**
+ certificates :: SET OF ExtendedCertificateOrCertificate,
+ ExtendedCertificateOrCertificate ::= CHOICE {
+ certificate Certificate -- x509,
+ extendedCertificate[0] IMPLICIT ExtendedCertificate }.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] Cert Certificate.
+ @param[in] OtherCerts Ohter Certificate.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteCertificates (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ mbedtls_x509_crt *Cert,
+ mbedtls_x509_crt *OtherCerts
+ )
+{
+ INT32 Ret;
+ INT32 Len;
+ mbedtls_x509_crt *TmpCert;
+
+ Len = 0;
+
+ /// Write OtherCerts
+ TmpCert = OtherCerts;
+ while (TmpCert != NULL) {
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, TmpCert->raw.p, TmpCert->raw.len));
+ TmpCert = TmpCert->next;
+ }
+
+ /// Write Cert
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, Cert->raw.p, Cert->raw.len));
+
+ /// Write NextContext
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
+ return Len;
+}
+
+/**
+ write Pkcs7 Int.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] SerialRaw SerialRaw.
+ @param[in] SerialRawLen Size of SerialRaw.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteInt (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ UINT8 *SerialRaw,
+ INTN SerialRawLen
+ )
+{
+ INT32 Ret;
+ UINT8 *Pt;
+ INT32 Len;
+
+ Len = 0;
+ Pt = SerialRaw + SerialRawLen;
+ while (Pt > SerialRaw) {
+ *--(*Ptr) = *--Pt;
+ Len++;
+ }
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_INTEGER));
+
+ return Len;
+}
+
+/**
+ write Pkcs7 Issuer And SerialNumber.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] Serial Serial.
+ @param[in] SerialLen Size of Serial.
+ @param[in] IssuerRaw IssuerRawLen.
+ @param[in] IssuerRawLen Size of IssuerRawLen.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteIssuerAndSerialNumber (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ UINT8 *Serial,
+ INTN SerialLen,
+ UINT8 *IssuerRaw,
+ INTN IssuerRawLen
+ )
+{
+ INT32 Ret;
+ INT32 Len;
+
+ Len = 0;
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteInt (Ptr, Start, Serial, SerialLen));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, IssuerRaw, IssuerRawLen));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
+
+ return Len;
+}
+
+/**
+ SignerInfo ::= SEQUENCE {
+ version Version;
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ digestAlgorithm DigestAlgorithmIdentifier,
+ authenticatedAttributes
+ [0] IMPLICIT Attributes OPTIONAL,
+ digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ encryptedDigest EncryptedDigest,
+ unauthenticatedAttributes
+ [1] IMPLICIT Attributes OPTIONAL.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] SignerInfo SignerInfo.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteSignerInfo (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ MbedtlsPkcs7SignerInfo *SignerInfo
+ )
+{
+ INT32 Ret;
+ INT32 Len;
+
+ Len = 0;
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, SignerInfo->Sig.p, SignerInfo->Sig.len));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->SigAlgIdentifier.p, SignerInfo->SigAlgIdentifier.len, 0));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->AlgIdentifier.p, SignerInfo->AlgIdentifier.len, 0));
+
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteIssuerAndSerialNumber (Ptr, Start, SignerInfo->Serial.p, SignerInfo->Serial.len, SignerInfo->IssuerRaw.p, SignerInfo->IssuerRaw.len));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, SignerInfo->Version));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
+
+ return Len;
+}
+
+/**
+ write Pkcs7 Signers Info Set.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] SignersSet SignerInfo Set.
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteSignersInfoSet (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ MbedtlsPkcs7SignerInfo *SignersSet
+ )
+{
+ MbedtlsPkcs7SignerInfo *SignerInfo;
+ INT32 Ret;
+ INT32 Len;
+
+ SignerInfo = SignersSet;
+ Len = 0;
+
+ while (SignerInfo != NULL) {
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignerInfo (Ptr, Start, SignerInfo));
+ // move to next
+ SignerInfo = SignerInfo->Next;
+ }
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET));
+
+ return Len;
+}
+
+/**
+ Signed Data Type
+ SignedData ::= SEQUENCE {
+ version Version,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ contentInfo ContentInfo,
+ certificates
+ [0] IMPLICIT ExtendedCertificatesAndCertificates
+ OPTIONAL,
+ crls
+ [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ signerInfos SignerInfos }
+
+ DigestAlgorithmIdentifiers ::=
+ SET OF DigestAlgorithmIdentifier
+
+ SignerInfos ::= SET OF SignerInfo.
+
+ @param[in, out] Ptr The reference to the current position pointer.
+ @param[in] Start The start of the buffer, for bounds-checking.
+ @param[in] Pkcs7 MbedtlsPkcs7
+
+ @retval number The number of bytes written to p on success.
+ @retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
+**/
+STATIC
+INT32
+MbedTlsPkcs7WriteDer (
+ UINT8 **Ptr,
+ UINT8 *Start,
+ MbedtlsPkcs7 *Pkcs7
+ )
+{
+ INT32 Ret;
+ INT32 Len;
+ mbedtls_md_type_t DigestAlg[1];
+
+ DigestAlg[0] = MBEDTLS_MD_SHA256;
+ Len = 0;
+
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignersInfoSet (Ptr, Start, &(Pkcs7->SignedData.SignerInfos)));
+
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteCertificates (Ptr, Start, &(Pkcs7->SignedData.Certificates), Pkcs7->SignedData.Certificates.next));
+
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteContentInfo (Ptr, Start, NULL, 0));
+
+ EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteDigestAlgorithmSet (Ptr, Start, DigestAlg, 1));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, Pkcs7->SignedData.Version));
+
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
+ EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
+
+ return Len;
+}
+
+/**
+ Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
+ Syntax Standard, version 1.5". This interface is only intended to be used for
+ application to perform PKCS#7 functionality validation.
+
+ If this interface is not supported, then return FALSE.
+
+ @param[in] PrivateKey Pointer to the PEM-formatted private key data for
+ data signing.
+ @param[in] PrivateKeySize Size of the PEM private key data in bytes.
+ @param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM
+ key data.
+ @param[in] InData Pointer to the content to be signed.
+ @param[in] InDataSize Size of InData in bytes.
+ @param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.
+ @param[in] OtherCerts Pointer to an optional additional set of certificates to
+ include in the PKCS#7 signedData (e.g. any intermediate
+ CAs in the chain).
+ @param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's
+ responsibility to free the buffer with FreePool().
+ @param[out] SignedDataSize Size of SignedData in bytes.
+
+ @retval TRUE PKCS#7 data signing succeeded.
+ @retval FALSE PKCS#7 data signing failed.
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+Pkcs7Sign (
+ IN CONST UINT8 *PrivateKey,
+ IN UINTN PrivateKeySize,
+ IN CONST UINT8 *KeyPassword,
+ IN UINT8 *InData,
+ IN UINTN InDataSize,
+ IN UINT8 *SignCert,
+ IN UINT8 *OtherCerts OPTIONAL,
+ OUT UINT8 **SignedData,
+ OUT UINTN *SignedDataSize
+ )
+{
+ BOOLEAN Status;
+ INT32 Ret;
+ mbedtls_pk_context Pkey;
+ UINT8 HashValue[SHA256_DIGEST_SIZE];
+ UINT8 Signature[MAX_SIGNATURE_SIZE];
+ UINTN SignatureLen;
+ UINT8 *NewPrivateKey;
+ mbedtls_x509_crt *Crt;
+
+ MbedtlsPkcs7 Pkcs7;
+ MbedtlsPkcs7SignerInfo SignerInfo;
+ UINT8 *Buffer;
+ INTN BufferSize;
+ UINT8 *Ptr;
+ INT32 Len;
+
+ //
+ // Check input parameters.
+ //
+ if ((PrivateKey == NULL) || (KeyPassword == NULL) || (InData == NULL) ||
+ (SignCert == NULL) || (SignedData == NULL) || (SignedDataSize == NULL) || (InDataSize > INT_MAX))
+ {
+ return FALSE;
+ }
+
+ BufferSize = 4096;
+
+ SignatureLen = MAX_SIGNATURE_SIZE;
+ Crt = (mbedtls_x509_crt *)SignCert;
+
+ NewPrivateKey = NULL;
+ if (PrivateKey[PrivateKeySize - 1] != 0) {
+ NewPrivateKey = AllocateZeroPool (PrivateKeySize + 1);
+ if (NewPrivateKey == NULL) {
+ return FALSE;
+ }
+
+ CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
+ NewPrivateKey[PrivateKeySize] = 0;
+ PrivateKeySize++;
+ } else {
+ NewPrivateKey = AllocateZeroPool (PrivateKeySize);
+ if (NewPrivateKey == NULL) {
+ return FALSE;
+ }
+
+ CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
+ }
+
+ mbedtls_pk_init (&Pkey);
+ Ret = mbedtls_pk_parse_key (
+ &Pkey,
+ NewPrivateKey,
+ PrivateKeySize,
+ KeyPassword,
+ KeyPassword == NULL ? 0 : AsciiStrLen ((CONST CHAR8 *)KeyPassword),
+ NULL,
+ NULL
+ );
+ if (Ret != 0) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+
+ /// Calculate InData Digest
+ ZeroMem (HashValue, SHA256_DIGEST_SIZE);
+ Status = Sha256HashAll (InData, InDataSize, HashValue);
+ if (!Status) {
+ goto Cleanup;
+ }
+
+ /// Pk Sign
+ ZeroMem (Signature, MAX_SIGNATURE_SIZE);
+ Ret = mbedtls_pk_sign (
+ &Pkey,
+ MBEDTLS_MD_SHA256,
+ HashValue,
+ SHA256_DIGEST_SIZE,
+ Signature,
+ MAX_SIGNATURE_SIZE,
+ &SignatureLen,
+ MbedtlsRand,
+ NULL
+ );
+ if (Ret != 0) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+
+ ZeroMem (&Pkcs7, sizeof (MbedtlsPkcs7));
+ Pkcs7.SignedData.Version = 1;
+
+ Crt->next = (mbedtls_x509_crt *)OtherCerts;
+ Pkcs7.SignedData.Certificates = *Crt;
+
+ SignerInfo.Next = NULL;
+ SignerInfo.Sig.p = Signature;
+ SignerInfo.Sig.len = SignatureLen;
+ SignerInfo.Version = 1;
+ SignerInfo.AlgIdentifier.p = MbedtlsOidDigestAlgSha256;
+ SignerInfo.AlgIdentifier.len = sizeof (MBEDTLS_OID_DIGEST_ALG_SHA256) - 1;
+ if (mbedtls_pk_get_type (&Pkey) == MBEDTLS_PK_RSA) {
+ SignerInfo.SigAlgIdentifier.p = MbedtlsOidPkcs1Rsa;
+ SignerInfo.SigAlgIdentifier.len = sizeof (MBEDTLS_OID_PKCS1_RSA) - 1;
+ } else {
+ Ret = mbedtls_oid_get_oid_by_sig_alg (MBEDTLS_PK_ECDSA, MBEDTLS_MD_SHA256, (CONST CHAR8 **)&SignerInfo.SigAlgIdentifier.p, &SignerInfo.SigAlgIdentifier.len);
+ if (Ret != 0) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+ }
+
+ SignerInfo.Serial = ((mbedtls_x509_crt *)SignCert)->serial;
+ SignerInfo.IssuerRaw = ((mbedtls_x509_crt *)SignCert)->issuer_raw;
+ Pkcs7.SignedData.SignerInfos = SignerInfo;
+
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+
+ Ptr = Buffer + BufferSize;
+ Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
+
+ /// Enlarge buffer if buffer is too small
+ while (Len == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
+ BufferSize = BufferSize * 2;
+ Ptr = Buffer + BufferSize;
+ FreePool (Buffer);
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+
+ Ptr = Buffer + BufferSize;
+ Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
+ }
+
+ if (Len <= 0) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+
+ *SignedData = AllocateZeroPool (Len);
+ if (*SignedData == NULL) {
+ Status = FALSE;
+ goto Cleanup;
+ }
+
+ *SignedDataSize = Len;
+ CopyMem (*SignedData, Ptr, Len);
+ Status = TRUE;
+
+Cleanup:
+ if (&Pkey != NULL) {
+ mbedtls_pk_free (&Pkey);
+ }
+
+ if (NewPrivateKey != NULL) {
+ memset (NewPrivateKey, 0, PrivateKeySize);
+ FreePool (NewPrivateKey);
+ }
+
+ if (Buffer != NULL) {
+ memset (Buffer, 0, BufferSize);
+ FreePool (Buffer);
+ }
+
+ return Status;
+}