mirror of https://github.com/acidanthera/audk.git
637 lines
19 KiB
C
637 lines
19 KiB
C
/** @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;
|
|
}
|
|
|
|
Buffer = NULL;
|
|
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;
|
|
}
|