From 32b70dd56ce8f9b3c1f4fcc6441692348faf364f Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 15 Aug 2018 11:15:31 -0600 Subject: [PATCH] add support for FirmwarePkgData in CMS SignedData EncapsulatedContentInfo --- Makefile.am | 2 ++ wolfcrypt/src/asn.c | 2 +- wolfcrypt/src/pkcs7.c | 70 ++++++++++++++++++++++++++++----------- wolfcrypt/test/test.c | 51 ++++++++++++++++++---------- wolfssl/wolfcrypt/asn.h | 1 + wolfssl/wolfcrypt/pkcs7.h | 15 +++++---- 6 files changed, 95 insertions(+), 46 deletions(-) diff --git a/Makefile.am b/Makefile.am index 320115dbb..875dffc50 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,6 +59,7 @@ CLEANFILES+= cert.der \ pkcs7signedData_RSA_SHA_noattr.der \ pkcs7signedData_RSA_SHA224.der \ pkcs7signedData_RSA_SHA256.der \ + pkcs7signedData_RSA_SHA256_firmwarePkgData.der \ pkcs7signedData_RSA_SHA256_custom_contentType.der \ pkcs7signedData_RSA_SHA256_SKID.der \ pkcs7signedData_RSA_SHA384.der \ @@ -67,6 +68,7 @@ CLEANFILES+= cert.der \ pkcs7signedData_ECDSA_SHA_noattr.der \ pkcs7signedData_ECDSA_SHA224.der \ pkcs7signedData_ECDSA_SHA256.der \ + pkcs7signedData_ECDSA_SHA256_firmwarePkgData.der \ pkcs7signedData_ECDSA_SHA256_custom_contentType.der \ pkcs7signedData_ECDSA_SHA256_SKID.der \ pkcs7signedData_ECDSA_SHA384.der \ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 8743e7ecb..44278d32f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1966,7 +1966,7 @@ int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, * output Buffer to write into. * returns the number of bytes added to the buffer. */ -static int SetObjectId(int len, byte* output) +int SetObjectId(int len, byte* output) { int idx = 0; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index da38e586e..3c3866ef0 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -58,7 +58,7 @@ typedef enum { /* placed ASN.1 contentType OID into *output, return idx on success, * 0 upon failure */ -static int wc_SetContentType(int pkcs7TypeOID, byte* output) +static int wc_SetContentType(int pkcs7TypeOID, byte* output, word32 outputSz) { /* PKCS#7 content types, RFC 2315, section 14 */ const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, @@ -73,14 +73,16 @@ static int wc_SetContentType(int pkcs7TypeOID, byte* output) 0x0D, 0x01, 0x07, 0x04 }; const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05 }; - #ifndef NO_PKCS7_ENCRYPTED_DATA const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 }; #endif + /* FirmwarePkgData (1.2.840.113549.1.9.16.1.16), from RFC 4108 */ + const byte firmwarePkgData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x10, 0x01, 0x10 }; - int idSz; - int typeSz = 0, idx = 0; + int idSz, idx = 0; + word32 typeSz = 0; const byte* typeName = 0; byte ID_Length[MAX_LENGTH_SZ]; @@ -121,12 +123,19 @@ static int wc_SetContentType(int pkcs7TypeOID, byte* output) typeName = encryptedData; break; #endif + case FIRMWARE_PKG_DATA: + typeSz = sizeof(firmwarePkgData); + typeName = firmwarePkgData; + break; default: WOLFSSL_MSG("Unknown PKCS#7 Type"); return 0; }; + if (outputSz < (MAX_LENGTH_SZ + 1 + typeSz)) + return BAD_FUNC_ARG; + idSz = SetLength(typeSz, ID_Length); output[idx++] = ASN_OBJECT_ID; XMEMCPY(output + idx, ID_Length, idSz); @@ -1046,11 +1055,6 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; - /* default id-data OID (1.2.840.113549.1.7.1), user can override */ - const byte innerOid[] = - { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x07, 0x01 }; - /* contentType OID (1.2.840.113549.1.9.3) */ const byte contentTypeOid[] = { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, @@ -1087,10 +1091,21 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, XMEMSET(esd, 0, sizeof(ESD)); - /* use default DATA contentType if not set by user */ + /* set content type based on contentOID, unless user has set custom one + with wc_PKCS7_SetContentType() */ if (pkcs7->contentTypeSz == 0) { - XMEMCPY(pkcs7->contentType, innerOid, sizeof(innerOid)); - pkcs7->contentTypeSz = sizeof(innerOid); + + /* default to DATA content type if user has not set */ + if (pkcs7->contentOID == 0) { + pkcs7->contentOID = DATA; + } + + ret = wc_SetContentType(pkcs7->contentOID, pkcs7->contentType, + sizeof(pkcs7->contentType)); + if (ret < 0) + return ret; + + pkcs7->contentTypeSz = ret; } esd->hashType = wc_OidGetHash(pkcs7->hashOID); @@ -3784,7 +3799,12 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return blockSz; /* outer content type */ - outerContentTypeSz = wc_SetContentType(ENVELOPED_DATA, outerContentType); + ret = wc_SetContentType(ENVELOPED_DATA, outerContentType, + sizeof(outerContentType)); + if (ret < 0) + return ret; + + outerContentTypeSz = ret; /* version, defined as 0 in RFC 2315 */ #ifdef HAVE_ECC @@ -3877,13 +3897,15 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* EncryptedContentInfo */ - contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType); - if (contentTypeSz == 0) { + ret = wc_SetContentType(pkcs7->contentOID, contentType, + sizeof(contentType)); + if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - return BAD_FUNC_ARG; + return ret; } + contentTypeSz = ret; /* allocate encrypted content buffer and PKCS#7 padding */ padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz); @@ -5081,7 +5103,12 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) return BAD_FUNC_ARG; /* outer content type */ - outerContentTypeSz = wc_SetContentType(ENCRYPTED_DATA, outerContentType); + ret = wc_SetContentType(ENCRYPTED_DATA, outerContentType, + sizeof(outerContentType)); + if (ret < 0) + return ret; + + outerContentTypeSz = ret; /* version, 2 if unprotectedAttrs present, 0 if absent */ if (pkcs7->unprotectedAttribsSz > 0) { @@ -5091,9 +5118,12 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* EncryptedContentInfo */ - contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType); - if (contentTypeSz == 0) - return BAD_FUNC_ARG; + contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType, + sizeof(contentType)); + if (ret < 0) + return ret; + + contentTypeSz = ret; /* allocate encrypted content buffer, do PKCS#7 padding */ blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 1a9efe39a..c550d3c34 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -19298,6 +19298,7 @@ typedef struct { PKCS7Attrib* signedAttribs; word32 signedAttribsSz; const char* outFileName; + int contentOID; byte* contentType; word32 contentTypeSz; int sidType; @@ -19363,48 +19364,54 @@ static int pkcs7signed_run_vectors(byte* rsaCert, word32 rsaCertSz, /* RSA with SHA */ {data, (word32)sizeof(data), SHAh, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA.der", NULL, 0, 0}, + "pkcs7signedData_RSA_SHA.der", 0, NULL, 0, 0}, /* RSA with SHA, no signed attributes */ {data, (word32)sizeof(data), SHAh, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, NULL, 0, - "pkcs7signedData_RSA_SHA_noattr.der", NULL, 0, 0}, + "pkcs7signedData_RSA_SHA_noattr.der", 0, NULL, 0, 0}, #endif #ifdef WOLFSSL_SHA224 /* RSA with SHA224 */ {data, (word32)sizeof(data), SHA224h, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA224.der", NULL, 0, 0}, + "pkcs7signedData_RSA_SHA224.der", 0, NULL, 0, 0}, #endif #ifndef NO_SHA256 /* RSA with SHA256 */ {data, (word32)sizeof(data), SHA256h, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA256.der", NULL, 0, 0}, + "pkcs7signedData_RSA_SHA256.der", 0, NULL, 0, 0}, /* RSA with SHA256 and SubjectKeyIdentifier in SignerIdentifier */ {data, (word32)sizeof(data), SHA256h, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA256_SKID.der", NULL, 0, + "pkcs7signedData_RSA_SHA256_SKID.der", 0, NULL, 0, SID_SUBJECT_KEY_IDENTIFIER}, /* RSA with SHA256 and custom contentType */ {data, (word32)sizeof(data), SHA256h, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA256_custom_contentType.der", customContentType, - sizeof(customContentType), 0}, + "pkcs7signedData_RSA_SHA256_custom_contentType.der", 0, + customContentType, sizeof(customContentType), 0}, + + /* RSA with SHA256 and FirmwarePkgData contentType */ + {data, (word32)sizeof(data), SHA256h, RSAk, rsaPrivKey, rsaPrivKeySz, + rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), + "pkcs7signedData_RSA_SHA256_firmwarePkgData.der", + FIRMWARE_PKG_DATA, NULL, 0, 0}, #endif #if defined(WOLFSSL_SHA384) /* RSA with SHA384 */ {data, (word32)sizeof(data), SHA384h, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA384.der", NULL, 0, 0}, + "pkcs7signedData_RSA_SHA384.der", 0, NULL, 0, 0}, #endif #if defined(WOLFSSL_SHA512) /* RSA with SHA512 */ {data, (word32)sizeof(data), SHA512h, RSAk, rsaPrivKey, rsaPrivKeySz, rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_RSA_SHA512.der", NULL, 0, 0}, + "pkcs7signedData_RSA_SHA512.der", 0, NULL, 0, 0}, #endif #endif /* NO_RSA */ @@ -19413,48 +19420,54 @@ static int pkcs7signed_run_vectors(byte* rsaCert, word32 rsaCertSz, /* ECDSA with SHA */ {data, (word32)sizeof(data), SHAh, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA.der", NULL, 0, 0}, + "pkcs7signedData_ECDSA_SHA.der", 0, NULL, 0, 0}, /* ECDSA with SHA, no signed attributes */ {data, (word32)sizeof(data), SHAh, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, NULL, 0, - "pkcs7signedData_ECDSA_SHA_noattr.der", NULL, 0, 0}, + "pkcs7signedData_ECDSA_SHA_noattr.der", 0, NULL, 0, 0}, #endif #ifdef WOLFSSL_SHA224 /* ECDSA with SHA224 */ {data, (word32)sizeof(data), SHA224h, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA224.der", NULL, 0, 0}, + "pkcs7signedData_ECDSA_SHA224.der", 0, NULL, 0, 0}, #endif #ifndef NO_SHA256 /* ECDSA with SHA256 */ {data, (word32)sizeof(data), SHA256h, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA256.der", NULL, 0, 0}, + "pkcs7signedData_ECDSA_SHA256.der", 0, NULL, 0, 0}, /* ECDSA with SHA256 and SubjectKeyIdentifier in SigherIdentifier */ {data, (word32)sizeof(data), SHA256h, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA256_SKID.der", NULL, 0, + "pkcs7signedData_ECDSA_SHA256_SKID.der", 0, NULL, 0, SID_SUBJECT_KEY_IDENTIFIER}, /* ECDSA with SHA256 and custom contentType */ {data, (word32)sizeof(data), SHA256h, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA256_custom_contentType.der", + "pkcs7signedData_ECDSA_SHA256_custom_contentType.der", 0, customContentType, sizeof(customContentType), 0}, + + /* ECDSA with SHA256 and FirmwarePkgData contentType */ + {data, (word32)sizeof(data), SHA256h, ECDSAk, eccPrivKey, eccPrivKeySz, + eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), + "pkcs7signedData_ECDSA_SHA256_firmwarePkgData.der", + FIRMWARE_PKG_DATA, NULL, 0, 0}, #endif #ifdef WOLFSSL_SHA384 /* ECDSA with SHA384 */ {data, (word32)sizeof(data), SHA384h, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA384.der", NULL, 0, 0}, + "pkcs7signedData_ECDSA_SHA384.der", 0, NULL, 0, 0}, #endif #ifdef WOLFSSL_SHA512 /* ECDSA with SHA512 */ {data, (word32)sizeof(data), SHA512h, ECDSAk, eccPrivKey, eccPrivKeySz, eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)), - "pkcs7signedData_ECDSA_SHA512.der", NULL, 0, 0}, + "pkcs7signedData_ECDSA_SHA512.der", 0, NULL, 0, 0}, #endif #endif /* HAVE_ECC */ }; @@ -19503,12 +19516,14 @@ static int pkcs7signed_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7->contentSz = testVectors[i].contentSz; pkcs7->hashOID = testVectors[i].hashOID; pkcs7->encryptOID = testVectors[i].encryptOID; + pkcs7->contentOID = testVectors[i].contentOID; pkcs7->privateKey = testVectors[i].privateKey; pkcs7->privateKeySz = testVectors[i].privateKeySz; pkcs7->signedAttribs = testVectors[i].signedAttribs; pkcs7->signedAttribsSz = testVectors[i].signedAttribsSz; - /* optional custom contentType, default is DATA */ + /* optional custom contentType, default is DATA, + overrides contentOID if set */ if (testVectors[i].contentType != NULL) { ret = wc_PKCS7_SetContentType(pkcs7, testVectors[i].contentType, testVectors[i].contentTypeSz); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 4eeea1ceb..009c9f501 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1015,6 +1015,7 @@ WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, #endif WOLFSSL_LOCAL int GetASNObjectId(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); +WOLFSSL_LOCAL int SetObjectId(int len, byte* output); WOLFSSL_LOCAL int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, word32 oidType, word32 maxIdx); WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 6353e14de..8d6fd0c32 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -53,13 +53,14 @@ /* PKCS#7 content types, ref RFC 2315 (Section 14) */ enum PKCS7_TYPES { - PKCS7_MSG = 650, /* 1.2.840.113549.1.7 */ - DATA = 651, /* 1.2.840.113549.1.7.1 */ - SIGNED_DATA = 652, /* 1.2.840.113549.1.7.2 */ - ENVELOPED_DATA = 653, /* 1.2.840.113549.1.7.3 */ - SIGNED_AND_ENVELOPED_DATA = 654, /* 1.2.840.113549.1.7.4 */ - DIGESTED_DATA = 655, /* 1.2.840.113549.1.7.5 */ - ENCRYPTED_DATA = 656 /* 1.2.840.113549.1.7.6 */ + PKCS7_MSG = 650, /* 1.2.840.113549.1.7 */ + DATA = 651, /* 1.2.840.113549.1.7.1 */ + SIGNED_DATA = 652, /* 1.2.840.113549.1.7.2 */ + ENVELOPED_DATA = 653, /* 1.2.840.113549.1.7.3 */ + SIGNED_AND_ENVELOPED_DATA = 654, /* 1.2.840.113549.1.7.4 */ + DIGESTED_DATA = 655, /* 1.2.840.113549.1.7.5 */ + ENCRYPTED_DATA = 656, /* 1.2.840.113549.1.7.6 */ + FIRMWARE_PKG_DATA = 685 /* 1.2.840.113549.1.9.16.1.16, RFC 4108 */ }; enum Pkcs7_Misc {