From 17c184e720ee89957c0a195fa714b03f11bc46d8 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 31 Oct 2016 11:06:06 -0600 Subject: [PATCH 1/4] add AES-128-CBC to PKCS#7 Encode/DecodeEnvelopedData --- wolfcrypt/src/asn.c | 5 + wolfcrypt/src/pkcs7.c | 255 ++++++++++++++++++++++++++------------ wolfcrypt/test/test.c | 120 +++++++++++------- wolfssl/wolfcrypt/asn.h | 5 +- wolfssl/wolfcrypt/pkcs7.h | 23 +++- 5 files changed, 277 insertions(+), 131 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 8944d33d9..1e18861f8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -783,6 +783,7 @@ static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3}; #endif /* HAVE_ECC */ /* blkType */ +static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2}; static const byte blkDesCbcOid[] = {43, 14, 3, 2, 7}; static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7}; @@ -959,6 +960,10 @@ static const byte* OidFromId(word32 id, word32 type, word32* oidSz) case oidBlkType: switch (id) { + case AES128CBCb: + oid = blkAes128CbcOid; + *oidSz = sizeof(blkAes128CbcOid); + break; case DESb: oid = blkDesCbcOid; *oidSz = sizeof(blkDesCbcOid); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 68675572d..83056b56b 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1173,6 +1173,120 @@ WOLFSSL_LOCAL int wc_CreateRecipientInfo(const byte* cert, word32 certSz, } +int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz, + byte* iv, int ivSz, byte* in, int inSz, + byte* out) +{ + int ret; +#ifndef NO_AES + Aes aes; +#endif +#ifndef NO_DES3 + Des des; + Des3 des3; +#endif + + if (key == NULL || iv == NULL || in == NULL || out == NULL) + return BAD_FUNC_ARG; + + switch (encryptOID) { +#ifndef NO_AES + case AES128CBCb: + if (keySz != 16 || ivSz != AES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); + if (ret == 0) + ret = wc_AesCbcEncrypt(&aes, out, in, inSz); + + break; +#endif +#ifndef NO_DES3 + case DESb: + if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION); + if (ret == 0) + ret = wc_Des_CbcEncrypt(&des, out, in, inSz); + + break; + case DES3b: + if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION); + if (ret == 0) + ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz); + + break; +#endif + default: + WOLFSSL_MSG("Unsupported content cipher type"); + return ALGO_ID_E; + }; + + return ret; +} + + +int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz, + byte* iv, int ivSz, byte* in, int inSz, + byte* out) +{ + int ret; +#ifndef NO_AES + Aes aes; +#endif +#ifndef NO_DES3 + Des des; + Des3 des3; +#endif + + if (key == NULL || iv == NULL || in == NULL || out == NULL) + return BAD_FUNC_ARG; + + switch (encryptOID) { +#ifndef NO_AES + case AES128CBCb: + if (keySz != 16 || ivSz != AES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION); + if (ret == 0) + ret = wc_AesCbcDecrypt(&aes, out, in, inSz); + + break; +#endif +#ifndef NO_DES3 + case DESb: + if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION); + if (ret == 0) + ret = wc_Des_CbcDecrypt(&des, out, in, inSz); + + break; + case DES3b: + if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION); + if (ret == 0) + ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz); + + break; +#endif + default: + WOLFSSL_MSG("Unsupported content cipher type"); + return ALGO_ID_E; + }; + + return ret; +} + + /* build PKCS#7 envelopedData content type, return enveloped size */ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) { @@ -1189,7 +1303,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) byte ver[MAX_VERSION_SZ]; WC_RNG rng; - int contentKeyEncSz, blockKeySz; + int contentKeyEncSz, blockSz, blockKeySz; byte contentKeyPlain[MAX_CONTENT_KEY_LEN]; #ifdef WOLFSSL_SMALL_STACK byte* contentKeyEnc; @@ -1212,7 +1326,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) byte encContentSeq[MAX_SEQ_SZ]; byte contentType[MAX_ALGO_SZ]; byte contentEncAlgo[MAX_ALGO_SZ]; - byte tmpIv[DES_BLOCK_SIZE]; + byte tmpIv[MAX_CONTENT_IV_SIZE]; byte ivOctetString[MAX_OCTET_STR_SZ]; byte encContentOctet[MAX_OCTET_STR_SZ]; @@ -1223,14 +1337,21 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (output == NULL || outputSz == 0) return BAD_FUNC_ARG; - /* PKCS#7 only supports DES, 3DES for now */ + /* wolfCrypt PKCS#7 supports AES-128-CBC, DES, 3DES for now */ switch (pkcs7->encryptOID) { + case AES128CBCb: + blockKeySz = 16; + blockSz = AES_BLOCK_SIZE; + break; + case DESb: blockKeySz = DES_KEYLEN; + blockSz = DES_BLOCK_SIZE; break; case DES3b: blockKeySz = DES3_KEYLEN; + blockSz = DES_BLOCK_SIZE; break; default: @@ -1291,7 +1412,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) recipSetSz = SetSet(recipSz, recipSet); /* generate IV for block cipher */ - ret = wc_RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE); + ret = wc_RNG_GenerateBlock(&rng, tmpIv, blockSz); wc_FreeRng(&rng); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK @@ -1310,7 +1431,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* allocate encrypted content buffer and PKCS#7 padding */ - padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE); + padSz = blockSz - (pkcs7->contentSz % blockSz); desOutSz = pkcs7->contentSz + padSz; plain = (byte*)XMALLOC(desOutSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -1337,12 +1458,12 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* put together IV OCTET STRING */ - ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString); + ivOctetStringSz = SetOctetString(blockSz, ivOctetString); /* build up our ContentEncryptionAlgorithmIdentifier sequence, - * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */ + * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */ contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo, - oidBlkType, ivOctetStringSz + DES_BLOCK_SIZE); + oidBlkType, ivOctetStringSz + blockSz); if (contentEncAlgoSz == 0) { XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -1354,51 +1475,28 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) } /* encrypt content */ - if (pkcs7->encryptOID == DESb) { - Des des; + ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, contentKeyPlain, + blockKeySz, tmpIv, blockSz, plain, desOutSz, encryptedContent); - ret = wc_Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION); - - if (ret == 0) - wc_Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz); - - if (ret != 0) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ret != 0) { + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); #endif - return ret; - } - } - else if (pkcs7->encryptOID == DES3b) { - Des3 des3; - - ret = wc_Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION); - - if (ret == 0) - ret = wc_Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz); - - if (ret != 0) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); -#ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } + return ret; } encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, desOutSz, encContentOctet); encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + - ivOctetStringSz + DES_BLOCK_SIZE + + ivOctetStringSz + blockSz + encContentOctetSz + desOutSz, encContentSeq); /* keep track of sizes for outer wrapper layering */ totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + - contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE + + contentEncAlgoSz + ivOctetStringSz + blockSz + encContentOctetSz + desOutSz; /* EnvelopedData */ @@ -1446,8 +1544,8 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) idx += contentEncAlgoSz; XMEMCPY(output + idx, ivOctetString, ivOctetStringSz); idx += ivOctetStringSz; - XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE); - idx += DES_BLOCK_SIZE; + XMEMCPY(output + idx, tmpIv, blockSz); + idx += blockSz; XMEMCPY(output + idx, encContentOctet, encContentOctetSz); idx += encContentOctetSz; XMEMCPY(output + idx, encryptedContent, desOutSz); @@ -1476,8 +1574,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, word32 contentType, encOID; byte issuerHash[SHA_DIGEST_SIZE]; - int encryptedKeySz, keySz; - byte tmpIv[DES_BLOCK_SIZE]; + int encryptedKeySz, keySz, expBlockSz, blockKeySz; + byte tmpIv[MAX_CONTENT_IV_SIZE]; byte* decryptedKey = NULL; #ifdef WOLFSSL_SMALL_STACK @@ -1685,7 +1783,29 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, #endif return ASN_PARSE_E; } - + + /* wolfCrypt PKCS#7 supports AES-128-CBC, DES, 3DES for now */ + switch(encOID) { + case AES128CBCb: + blockKeySz = 16; + expBlockSz = AES_BLOCK_SIZE; + break; + + case DESb: + blockKeySz = DES_KEYLEN; + expBlockSz = DES_BLOCK_SIZE; + break; + + case DES3b: + blockKeySz = DES3_KEYLEN; + expBlockSz = DES_BLOCK_SIZE; + break; + + default: + WOLFSSL_MSG("Unsupported content cipher type"); + return ALGO_ID_E; + }; + /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */ if (pkiMsg[idx++] != ASN_OCTET_STRING) { #ifdef WOLFSSL_SMALL_STACK @@ -1701,8 +1821,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, return ASN_PARSE_E; } - if (length != DES_BLOCK_SIZE) { - WOLFSSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE"); + if (length != expBlockSz) { + WOLFSSL_MSG("Incorrect IV length, must be of content alg block size"); #ifdef WOLFSSL_SMALL_STACK XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -1743,7 +1863,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (privKey == NULL) { XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; + XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; } #endif @@ -1802,43 +1923,15 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, } /* decrypt encryptedContent */ - if (encOID == DESb) { - Des des; - ret = wc_Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); - - if (ret == 0) - wc_Des_CbcDecrypt(&des, encryptedContent, encryptedContent, - encryptedContentSz); - - if (ret != 0) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); -#ifdef WOLFSSL_SMALL_STACK - XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - } - else if (encOID == DES3b) { - Des3 des; - ret = wc_Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); - if (ret == 0) - ret = wc_Des3_CbcDecrypt(&des, encryptedContent, encryptedContent, - encryptedContentSz); - - if (ret != 0) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); -#ifdef WOLFSSL_SMALL_STACK - XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - } else { - WOLFSSL_MSG("Unsupported content encryption OID type"); + ret = wc_PKCS7_DecryptContent(encOID, decryptedKey, blockKeySz, + tmpIv, expBlockSz, encryptedContent, + encryptedContentSz, encryptedContent); + if (ret != 0) { XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ALGO_ID_E; + return ret; } padLen = encryptedContent[encryptedContentSz-1]; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index aec83b6c4..2d1c1f526 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8506,11 +8506,20 @@ int compress_test(void) #ifdef HAVE_PKCS7 +typedef struct { + const char* outFileName; + const byte* content; + word32 contentSz; + int contentOID; + int encryptOID; + byte* privateKey; + word32 privateKeySz; +} pkcs7EnvelopedVector; + int pkcs7enveloped_test(void) { int ret = 0; - int cipher = DES3b; int envelopedSz, decodedSz; PKCS7 pkcs7; byte* cert; @@ -8523,13 +8532,16 @@ int pkcs7enveloped_test(void) FILE* certFile; FILE* keyFile; FILE* pkcs7File; - const char* pkcs7OutFile = "pkcs7envelopedData.der"; const byte data[] = { /* Hello World */ 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f, 0x72,0x6c,0x64 }; + pkcs7EnvelopedVector a, b; + pkcs7EnvelopedVector test_pkcs7env[2]; + int times = sizeof(test_pkcs7env) / sizeof(pkcs7EnvelopedVector), i; + /* read client cert and key in DER format */ cert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cert == NULL) @@ -8566,49 +8578,73 @@ int pkcs7enveloped_test(void) fclose(keyFile); wc_PKCS7_InitWithCert(&pkcs7, cert, (word32)certSz); - pkcs7.content = (byte*)data; - pkcs7.contentSz = (word32)sizeof(data); - pkcs7.contentOID = DATA; - pkcs7.encryptOID = cipher; - pkcs7.privateKey = privKey; - pkcs7.privateKeySz = (word32)privKeySz; - /* encode envelopedData */ - envelopedSz = wc_PKCS7_EncodeEnvelopedData(&pkcs7, enveloped, - sizeof(enveloped)); - if (envelopedSz <= 0) { - XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -203; + /* set up test vectors */ + a.content = data; + a.contentSz = (word32)sizeof(data); + a.contentOID = DATA; + a.encryptOID = DES3b; + a.privateKey = privKey; + a.privateKeySz = (word32)privKeySz; + a.outFileName = "pkcs7envelopedDataDES3.der"; + + b.content = data; + b.contentSz = (word32)sizeof(data); + b.contentOID = DATA; + b.encryptOID = AES128CBCb; + b.privateKey = privKey; + b.privateKeySz = (word32)privKeySz; + b.outFileName = "pkcs7envelopedDataAES128CBC.der"; + + test_pkcs7env[0] = a; + test_pkcs7env[1] = b; + + for (i = 0; i < times; i++) { + pkcs7.content = (byte*)test_pkcs7env[i].content; + pkcs7.contentSz = test_pkcs7env[i].contentSz; + pkcs7.contentOID = test_pkcs7env[i].contentOID; + pkcs7.encryptOID = test_pkcs7env[i].encryptOID; + pkcs7.privateKey = test_pkcs7env[i].privateKey; + pkcs7.privateKeySz = test_pkcs7env[i].privateKeySz; + + /* encode envelopedData */ + envelopedSz = wc_PKCS7_EncodeEnvelopedData(&pkcs7, enveloped, + sizeof(enveloped)); + if (envelopedSz <= 0) { + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + printf("envelopedSz = %d\n", envelopedSz); + return -203; + } + + /* decode envelopedData */ + decodedSz = wc_PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz, + decoded, sizeof(decoded)); + if (decodedSz <= 0) { + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -204; + } + + /* test decode result */ + if (XMEMCMP(decoded, data, sizeof(data)) != 0) { + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -205; + } + + /* output pkcs7 envelopedData for external testing */ + pkcs7File = fopen(test_pkcs7env[i].outFileName, "wb"); + if (!pkcs7File) { + XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + return -206; + } + + ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File); + fclose(pkcs7File); } - /* decode envelopedData */ - decodedSz = wc_PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz, - decoded, sizeof(decoded)); - if (decodedSz <= 0) { - XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -204; - } - - /* test decode result */ - if (XMEMCMP(decoded, data, sizeof(data)) != 0) { - XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -205; - } - - /* output pkcs7 envelopedData for external testing */ - pkcs7File = fopen(pkcs7OutFile, "wb"); - if (!pkcs7File) { - XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -206; - } - - ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File); - fclose(pkcs7File); - XFREE(cert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(privKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(&pkcs7); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index bf8ab1248..4e6718637 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -227,8 +227,9 @@ enum Hash_Sum { enum Block_Sum { - DESb = 69, - DES3b = 652 + AES128CBCb = 414, + DESb = 69, + DES3b = 652 }; diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index c5d9766fd..7ba1408e2 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -32,6 +32,9 @@ #endif #include #include +#ifndef NO_AES + #include +#endif #ifndef NO_DES3 #include #endif @@ -52,12 +55,14 @@ enum PKCS7_TYPES { }; enum Pkcs7_Misc { - PKCS7_NONCE_SZ = 16, - MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */ - MAX_CONTENT_KEY_LEN = DES3_KEYLEN, /* highest current cipher is 3DES */ - MAX_RECIP_SZ = MAX_VERSION_SZ + - MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ + - MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ + PKCS7_NONCE_SZ = 16, + MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */ + MAX_CONTENT_KEY_LEN = DES3_KEYLEN, /* highest current cipher is 3DES */ + MAX_CONTENT_IV_SIZE = 16, /* highest current is AES128 */ + MAX_CONTENT_BLOCK_LEN = AES_BLOCK_SIZE, + MAX_RECIP_SZ = MAX_VERSION_SZ + + MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ + + MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ }; @@ -106,6 +111,12 @@ WOLFSSL_LOCAL int wc_CreateRecipientInfo(const byte* cert, word32 certSz, WC_RNG* rng, byte* contentKeyPlain, byte* contentKeyEnc, int* keyEncSz, byte* out, word32 outSz, void* heap); +WOLFSSL_LOCAL int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz, + byte* iv, int ivSz, byte* in, int inSz, + byte* out); +WOLFSSL_LOCAL int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz, + byte* iv, int ivSz, byte* in, int inSz, + byte* out); WOLFSSL_API int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz); WOLFSSL_API void wc_PKCS7_Free(PKCS7* pkcs7); From 8c23c3cdd0814955adafdf0fa2130af0bb8ce3c4 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 31 Oct 2016 11:22:49 -0600 Subject: [PATCH 2/4] add AES-192-CBC to PKCS#7 Encode/DecodeEnvelopedData --- wolfcrypt/src/asn.c | 5 +++++ wolfcrypt/src/pkcs7.c | 17 +++++++++++++++-- wolfcrypt/test/test.c | 13 +++++++++++-- wolfssl/wolfcrypt/asn.h | 1 + 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 1e18861f8..9e96bd149 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -784,6 +784,7 @@ static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3}; /* blkType */ static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2}; +static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22}; static const byte blkDesCbcOid[] = {43, 14, 3, 2, 7}; static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7}; @@ -964,6 +965,10 @@ static const byte* OidFromId(word32 id, word32 type, word32* oidSz) oid = blkAes128CbcOid; *oidSz = sizeof(blkAes128CbcOid); break; + case AES192CBCb: + oid = blkAes192CbcOid; + *oidSz = sizeof(blkAes192CbcOid); + break; case DESb: oid = blkDesCbcOid; *oidSz = sizeof(blkDesCbcOid); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 83056b56b..bca23a584 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1192,7 +1192,8 @@ int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz, switch (encryptOID) { #ifndef NO_AES case AES128CBCb: - if (keySz != 16 || ivSz != AES_BLOCK_SIZE) + case AES192CBCb: + if (ivSz != AES_BLOCK_SIZE) return BAD_FUNC_ARG; ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION); @@ -1211,6 +1212,7 @@ int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz, ret = wc_Des_CbcEncrypt(&des, out, in, inSz); break; + case DES3b: if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE) return BAD_FUNC_ARG; @@ -1249,7 +1251,8 @@ int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz, switch (encryptOID) { #ifndef NO_AES case AES128CBCb: - if (keySz != 16 || ivSz != AES_BLOCK_SIZE) + case AES192CBCb: + if (ivSz != AES_BLOCK_SIZE) return BAD_FUNC_ARG; ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION); @@ -1344,6 +1347,11 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) blockSz = AES_BLOCK_SIZE; break; + case AES192CBCb: + blockKeySz = 24; + blockSz = AES_BLOCK_SIZE; + break; + case DESb: blockKeySz = DES_KEYLEN; blockSz = DES_BLOCK_SIZE; @@ -1791,6 +1799,11 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, expBlockSz = AES_BLOCK_SIZE; break; + case AES192CBCb: + blockKeySz = 24; + expBlockSz = AES_BLOCK_SIZE; + break; + case DESb: blockKeySz = DES_KEYLEN; expBlockSz = DES_BLOCK_SIZE; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 2d1c1f526..9e5955af1 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8538,8 +8538,8 @@ int pkcs7enveloped_test(void) 0x72,0x6c,0x64 }; - pkcs7EnvelopedVector a, b; - pkcs7EnvelopedVector test_pkcs7env[2]; + pkcs7EnvelopedVector a, b, c; + pkcs7EnvelopedVector test_pkcs7env[3]; int times = sizeof(test_pkcs7env) / sizeof(pkcs7EnvelopedVector), i; /* read client cert and key in DER format */ @@ -8596,8 +8596,17 @@ int pkcs7enveloped_test(void) b.privateKeySz = (word32)privKeySz; b.outFileName = "pkcs7envelopedDataAES128CBC.der"; + c.content = data; + c.contentSz = (word32)sizeof(data); + c.contentOID = DATA; + c.encryptOID = AES192CBCb; + c.privateKey = privKey; + c.privateKeySz = (word32)privKeySz; + c.outFileName = "pkcs7envelopedDataAES192CBC.der"; + test_pkcs7env[0] = a; test_pkcs7env[1] = b; + test_pkcs7env[2] = c; for (i = 0; i < times; i++) { pkcs7.content = (byte*)test_pkcs7env[i].content; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 4e6718637..00bef121c 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -228,6 +228,7 @@ enum Hash_Sum { enum Block_Sum { AES128CBCb = 414, + AES192CBCb = 434, DESb = 69, DES3b = 652 }; From fa9a9175d0e537ba7671adfa7ddff77508adbd7c Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 31 Oct 2016 11:31:15 -0600 Subject: [PATCH 3/4] add AES-256-CBC to PKCS#7 Encode/DecodeEnvelopedData --- wolfcrypt/src/asn.c | 5 +++++ wolfcrypt/src/pkcs7.c | 14 +++++++++++++- wolfcrypt/test/test.c | 13 +++++++++++-- wolfssl/wolfcrypt/asn.h | 1 + wolfssl/wolfcrypt/pkcs7.h | 6 +++--- 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9e96bd149..afd924852 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -785,6 +785,7 @@ static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3}; /* blkType */ static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2}; static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22}; +static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42}; static const byte blkDesCbcOid[] = {43, 14, 3, 2, 7}; static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7}; @@ -969,6 +970,10 @@ static const byte* OidFromId(word32 id, word32 type, word32* oidSz) oid = blkAes192CbcOid; *oidSz = sizeof(blkAes192CbcOid); break; + case AES256CBCb: + oid = blkAes256CbcOid; + *oidSz = sizeof(blkAes256CbcOid); + break; case DESb: oid = blkDesCbcOid; *oidSz = sizeof(blkDesCbcOid); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index bca23a584..02ad3f661 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1193,6 +1193,7 @@ int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz, #ifndef NO_AES case AES128CBCb: case AES192CBCb: + case AES256CBCb: if (ivSz != AES_BLOCK_SIZE) return BAD_FUNC_ARG; @@ -1252,6 +1253,7 @@ int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz, #ifndef NO_AES case AES128CBCb: case AES192CBCb: + case AES256CBCb: if (ivSz != AES_BLOCK_SIZE) return BAD_FUNC_ARG; @@ -1340,7 +1342,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (output == NULL || outputSz == 0) return BAD_FUNC_ARG; - /* wolfCrypt PKCS#7 supports AES-128-CBC, DES, 3DES for now */ + /* wolfCrypt PKCS#7 supports AES-128/192/256-CBC, DES, 3DES for now */ switch (pkcs7->encryptOID) { case AES128CBCb: blockKeySz = 16; @@ -1352,6 +1354,11 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) blockSz = AES_BLOCK_SIZE; break; + case AES256CBCb: + blockKeySz = 32; + blockSz = AES_BLOCK_SIZE; + break; + case DESb: blockKeySz = DES_KEYLEN; blockSz = DES_BLOCK_SIZE; @@ -1804,6 +1811,11 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, expBlockSz = AES_BLOCK_SIZE; break; + case AES256CBCb: + blockKeySz = 32; + expBlockSz = AES_BLOCK_SIZE; + break; + case DESb: blockKeySz = DES_KEYLEN; expBlockSz = DES_BLOCK_SIZE; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 9e5955af1..31e89e575 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8538,8 +8538,8 @@ int pkcs7enveloped_test(void) 0x72,0x6c,0x64 }; - pkcs7EnvelopedVector a, b, c; - pkcs7EnvelopedVector test_pkcs7env[3]; + pkcs7EnvelopedVector a, b, c, d; + pkcs7EnvelopedVector test_pkcs7env[4]; int times = sizeof(test_pkcs7env) / sizeof(pkcs7EnvelopedVector), i; /* read client cert and key in DER format */ @@ -8604,9 +8604,18 @@ int pkcs7enveloped_test(void) c.privateKeySz = (word32)privKeySz; c.outFileName = "pkcs7envelopedDataAES192CBC.der"; + d.content = data; + d.contentSz = (word32)sizeof(data); + d.contentOID = DATA; + d.encryptOID = AES256CBCb; + d.privateKey = privKey; + d.privateKeySz = (word32)privKeySz; + d.outFileName = "pkcs7envelopedDataAES256CBC.der"; + test_pkcs7env[0] = a; test_pkcs7env[1] = b; test_pkcs7env[2] = c; + test_pkcs7env[3] = d; for (i = 0; i < times; i++) { pkcs7.content = (byte*)test_pkcs7env[i].content; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 00bef121c..a48a1de20 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -229,6 +229,7 @@ enum Hash_Sum { enum Block_Sum { AES128CBCb = 414, AES192CBCb = 434, + AES256CBCb = 454, DESb = 69, DES3b = 652 }; diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 7ba1408e2..d9eb2f45e 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -56,9 +56,9 @@ enum PKCS7_TYPES { enum Pkcs7_Misc { PKCS7_NONCE_SZ = 16, - MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */ - MAX_CONTENT_KEY_LEN = DES3_KEYLEN, /* highest current cipher is 3DES */ - MAX_CONTENT_IV_SIZE = 16, /* highest current is AES128 */ + MAX_ENCRYPTED_KEY_SZ = 512, /* max enc. key size, RSA <= 4096 */ + MAX_CONTENT_KEY_LEN = 32, /* highest current cipher is AES-256-CBC */ + MAX_CONTENT_IV_SIZE = 16, /* highest current is AES128 */ MAX_CONTENT_BLOCK_LEN = AES_BLOCK_SIZE, MAX_RECIP_SZ = MAX_VERSION_SZ + MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ + From 50464d4aefe745415b5fe1f6c5f943b2ea7db508 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 31 Oct 2016 11:36:23 -0600 Subject: [PATCH 4/4] gitignore PKCS#7 test files, delete on make clean --- .gitignore | 5 ++++- Makefile.am | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 03350bac4..891bf9881 100644 --- a/.gitignore +++ b/.gitignore @@ -85,7 +85,10 @@ certreq.der certreq.pem pkcs7cert.der pkcs7signedData.der -pkcs7envelopedData.der +pkcs7envelopedDataDES3.der +pkcs7envelopedDataAES128CBC.der +pkcs7envelopedDataAES192CBC.der +pkcs7envelopedDataAES256CBC.der diff sslSniffer/sslSnifferTest/tracefile.txt tracefile.txt diff --git a/Makefile.am b/Makefile.am index cb3248f73..09e1e7219 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,7 +38,10 @@ CLEANFILES+= cert.der \ othercert.der \ othercert.pem \ pkcs7cert.der \ - pkcs7envelopedData.der \ + pkcs7envelopedDataDES3.der \ + pkcs7envelopedDataAES128CBC.der \ + pkcs7envelopedDataAES192CBC.der \ + pkcs7envelopedDataAES256CBC.der \ pkcs7signedData.der exampledir = $(docdir)/example