Skip to content

Commit

Permalink
mbedtls: add PKCS7 parser patch for MBedTLS
Browse files Browse the repository at this point in the history
Added patch for MBedTLS PKCS7 parser to support MicroSoft
Authenticate Code with Authenticate Attributes.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
  • Loading branch information
raymo200915 committed Mar 1, 2024
1 parent 93e569e commit 25b0a46
Showing 1 changed file with 242 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
From 922c7a2bd87210df3a12669ef2f7366ff48892bb Mon Sep 17 00:00:00 2001
From: Raymond Mao <raymond.mao@linaro.org>
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 <raymond.mao@linaro.org>
---
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 <time.h>
#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

0 comments on commit 25b0a46

Please sign in to comment.