From 25b0a46fa5bf971f980c3a1e30622bf4553eb917 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Fri, 1 Mar 2024 13:11:46 -0800 Subject: [PATCH] mbedtls: add PKCS7 parser patch for MBedTLS Added patch for MBedTLS PKCS7 parser to support MicroSoft Authenticate Code with Authenticate Attributes. Signed-off-by: Raymond Mao --- ...oft-authentication-code-in-PKCS7-lib.patch | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 lib/mbedtls/patch/0002-support-MicroSoft-authentication-code-in-PKCS7-lib.patch diff --git a/lib/mbedtls/patch/0002-support-MicroSoft-authentication-code-in-PKCS7-lib.patch b/lib/mbedtls/patch/0002-support-MicroSoft-authentication-code-in-PKCS7-lib.patch new file mode 100644 index 00000000000..5484acf7648 --- /dev/null +++ b/lib/mbedtls/patch/0002-support-MicroSoft-authentication-code-in-PKCS7-lib.patch @@ -0,0 +1,242 @@ +From 922c7a2bd87210df3a12669ef2f7366ff48892bb Mon Sep 17 00:00:00 2001 +From: Raymond Mao +Date: Fri, 1 Mar 2024 12:49:32 -0800 +Subject: [PATCH] support MicroSoft authentication code in PKCS7 lib + +Decode MicroSoft authentication code and its authenticate attributes +if they exist in a PKCS7 message, and save them into PKCS7 and +signer's info respectively. + +Signed-off-by: Raymond Mao +--- + include/mbedtls/oid.h | 16 ++++++++ + include/mbedtls/pkcs7.h | 21 +++++++++++ + library/pkcs7.c | 81 +++++++++++++++++++++++++++++++++++------ + 3 files changed, 107 insertions(+), 11 deletions(-) + +diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h +index e48817d68..b8b9cffb5 100644 +--- a/include/mbedtls/oid.h ++++ b/include/mbedtls/oid.h +@@ -347,6 +347,22 @@ + #define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */ + #define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */ + ++/* ++ * MicroSoft Authenticate Code OIDs ++ */ ++#define MBEDTLS_OID_PRIVATE_ENTERPRISE MBEDTLS_OID_INTERNET "\x04\x01" /* {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) */ ++#define MBEDTLS_OID_MICROSOFT "\x82\x37" /* {microsoft(311)} */ ++/* ++ * OID_msIndirectData: (1.3.6.1.4.1.311.2.1.4) ++ * {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) microsoft(311) 2(2) 1(1) 4(4)} ++ */ ++#define MBEDTLS_OID_MICROSOFT_INDIRECTDATA MBEDTLS_OID_PRIVATE_ENTERPRISE MBEDTLS_OID_MICROSOFT "\x02\x01\x04" ++/* ++ * OID_msPeImageDataObjId: (1.3.6.1.4.1.311.2.1.15) ++ * {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) microsoft(311) 2(2) 1(1) 15(15)} ++ */ ++#define MBEDTLS_OID_MICROSOFT_PEIMAGEDATA MBEDTLS_OID_PRIVATE_ENTERPRISE MBEDTLS_OID_MICROSOFT "\x02\x01\x0f" ++ + /* + * EC key algorithms from RFC 5480 + */ +diff --git a/include/mbedtls/pkcs7.h b/include/mbedtls/pkcs7.h +index 70b25a9c6..811483b0c 100644 +--- a/include/mbedtls/pkcs7.h ++++ b/include/mbedtls/pkcs7.h +@@ -103,6 +103,16 @@ typedef enum { + } + mbedtls_pkcs7_type; + ++/* ++ * Authenticate Attributes for MicroSoft Authentication Code using in U-Boot ++ * Secure Boot ++ */ ++typedef struct mbedtls_pkcs7_authattrs { ++ size_t data_len; ++ void *data; ++} ++mbedtls_pkcs7_authattrs; ++ + /** + * Structure holding PKCS #7 signer info + */ +@@ -114,6 +124,7 @@ typedef struct mbedtls_pkcs7_signer_info { + mbedtls_x509_buf MBEDTLS_PRIVATE(alg_identifier); + mbedtls_x509_buf MBEDTLS_PRIVATE(sig_alg_identifier); + mbedtls_x509_buf MBEDTLS_PRIVATE(sig); ++ mbedtls_pkcs7_authattrs authattrs; + struct mbedtls_pkcs7_signer_info *MBEDTLS_PRIVATE(next); + } + mbedtls_pkcs7_signer_info; +@@ -133,12 +144,22 @@ typedef struct mbedtls_pkcs7_signed_data { + } + mbedtls_pkcs7_signed_data; + ++/* Content Data for MicroSoft Authentication Code using in U-Boot Secure Boot */ ++typedef struct mbedtls_pkcs7_conten_data { ++ int data_type; /* Type of Data */ ++ size_t data_len; /* Length of Data */ ++ size_t data_hdrlen; /* Length of Data ASN.1 header */ ++ void *data; /* Content Data */ ++} ++mbedtls_pkcs7_conten_data; ++ + /** + * Structure holding PKCS #7 structure, only signed data for now + */ + typedef struct mbedtls_pkcs7 { + mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw); + mbedtls_pkcs7_signed_data MBEDTLS_PRIVATE(signed_data); ++ mbedtls_pkcs7_conten_data content_data; + } + mbedtls_pkcs7; + +diff --git a/library/pkcs7.c b/library/pkcs7.c +index 36b49f53b..526943473 100644 +--- a/library/pkcs7.c ++++ b/library/pkcs7.c +@@ -29,6 +29,13 @@ + #include + #endif + ++enum OID { ++ /* PKCS#7 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)} */ ++ OID_data = 13, /* 1.2.840.113549.1.7.1 */ ++ /* Microsoft Authenticode & Software Publishing */ ++ OID_msIndirectData = 24, /* 1.3.6.1.4.1.311.2.1.4 */ ++}; ++ + /** + * Initializes the mbedtls_pkcs7 structure. + */ +@@ -281,6 +288,7 @@ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end, + unsigned char *end_signer, *end_issuer_and_sn; + int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; ++ unsigned char *tmp_p; + + asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED + | MBEDTLS_ASN1_SEQUENCE); +@@ -342,6 +350,27 @@ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end, + goto out; + } + ++ /* Save authenticatedAttributes if present */ ++ if (*p < end_signer && ++ **p == (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0)) { ++ tmp_p = *p + 1; ++ ++ ret = mbedtls_asn1_get_tag(p, end_signer, &len, ++ MBEDTLS_ASN1_CONTEXT_SPECIFIC | ++ MBEDTLS_ASN1_CONSTRUCTED | 0); ++ if (ret != 0) { ++ goto out; ++ } ++ ++ /* ++ * Only skip the leading tag byte ++ * (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0) ++ */ ++ signer->authattrs.data = tmp_p; ++ signer->authattrs.data_len = len + *p - tmp_p; ++ ++ *p += len; ++ } + /* Assume authenticatedAttributes is nonexistent */ + ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier); + if (ret != 0) { +@@ -449,7 +478,7 @@ cleanup: + * signerInfos SignerInfos } + */ + static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, +- mbedtls_pkcs7_signed_data *signed_data) ++ mbedtls_pkcs7 *pkcs7) + { + unsigned char *p = buf; + unsigned char *end = buf + buflen; +@@ -457,6 +486,7 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, + size_t len = 0; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_md_type_t md_alg; ++ mbedtls_pkcs7_signed_data *signed_data = &pkcs7->signed_data; + + ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED + | MBEDTLS_ASN1_SEQUENCE); +@@ -493,25 +523,54 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, + if (ret != 0) { + return ret; + } +- if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) { ++ ++ /* ++ * We should only support 1.2.840.113549.1.7.1 (PKCS7 DATA) and ++ * 1.3.6.1.4.1.311.2.1.4 (MicroSoft Authentication Code) that is for ++ * U-Boot Secure Boot ++ */ ++ if (!MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) { ++ pkcs7->content_data.data_type = OID_data; ++ } else if (!MBEDTLS_OID_CMP(MBEDTLS_OID_MICROSOFT_INDIRECTDATA, ++ &content_type)) { ++ pkcs7->content_data.data_type = OID_msIndirectData; ++ } else { + return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO; + } + + if (p != end_content_info) { ++ unsigned char *tmp_p = p; ++ + /* Determine if valid content is present */ + ret = mbedtls_asn1_get_tag(&p, + end_content_info, + &len, +- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC); +- if (ret != 0) { +- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); ++ MBEDTLS_ASN1_CONSTRUCTED | ++ MBEDTLS_ASN1_CONTEXT_SPECIFIC); ++ if (ret != 0 || p + len != end_content_info) { ++ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ++ ret); + } +- p += len; +- if (p != end_content_info) { +- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); ++ ++ /* ++ * U-Boot Secure Boot needs to calculate the digest of MicroSoft ++ * Authentication Code during verifying an EFI image. ++ * Thus we need to save the context of Content Data. ++ * See U-Boot function efi_signature_verify() for reference. ++ */ ++ pkcs7->content_data.data_hdrlen = p - tmp_p; ++ /* Parse the content data from a sequence */ ++ ret = mbedtls_asn1_get_tag(&p, end_content_info, &len, ++ MBEDTLS_ASN1_CONSTRUCTED | ++ MBEDTLS_ASN1_SEQUENCE); ++ if (ret != 0 || p + len != end_content_info) { ++ return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ++ ret); + } +- /* Valid content is present - this is not supported */ +- return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; ++ pkcs7->content_data.data = p; ++ pkcs7->content_data.data_len = len; ++ ++ p += len; + } + + /* Look for certificates, there may or may not be any */ +@@ -624,7 +683,7 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf, + } + + try_data: +- ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data); ++ ret = pkcs7_get_signed_data(p, len, pkcs7); + if (ret != 0) { + goto out; + } +-- +2.25.1 +