wolfCrypt PKCS#7 / CMS Expansion Customer: Mentor Graphics

This document summarizes the additions that wolfSSL has made to the wolfCrypt PKCS#7/CMS support on behalf of Mentor Graphics.

Compiling wolfSSL with PKCS#7 Support

To compile wolfSSL with PKCS#7 support using Autconf/configure run:

$ cd wolfssl $ ./configure --enable-pkcs7 --enable-hkdf $ make $ make check

To run only the wolfCrypt test app, after compiling the library, run the following from the root wolfSSL directory:

$ ./wolfcrypt/test/testwolfcrypt

CMS Encrypted-data Content Type wolfCrypt now supports the encrypted-data content type from RFC 5652, Section 8 with algorithm support for AES-128/192/256-CBC, DES, and 3DES. The following functions have been added:

#include int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, ​ ​ word32 outputSz); int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, ​ ​ word32 pkiMsgSz, byte* output, word32 outputSz);

Applications calling these functions must set the following members of the PKCS7 structure: typedef struct PKCS7 { … byte* content; /* data to be encrypted */ word32 contentSz; /* size of data to be encrypted */ int contentOID; /* OID of content */

Copyright © 2016 wolfSSL Inc. 1 int encryptOID; /* OID of encryption algorithm to use */ byte* encryptionKey; /* key to use for encryption */ word32 encryptionKeySz; /* size of key to use for encryption */ } contentOID will specify the PKCS#7/CMS contentType, for example “DATA”. encryptOID specifies the encryption algorithm to use and can be one of the following values:

AES128CBCb AES192CBCb AES256CBCb DESb DES3b

The following PKCS7 structure members are optional, and should be used when the user/application wants to create EncryptedData bundles that include the EncryptedData optional unprotected attributes. If not using unprotected attributes, these can be set to NULL and 0, ​ ​ ​ ​ respectively. typedef struct PKCS7 { … PKCS7Attrib* unprotectedAttribs; /* optional attributes */ Word32 unprotectedAttribsSz; /* sz of unprotectedAttribs */ }

If using the optional unprotected attributes, during decoding with wc_PKCS7_DecodeEncryptedData(), the decoded attributes will be placed into the following PKCS7 structure member as a linked list of PKCSDecodedAttrib structures. ​ ​ typedef struct PKCS7 { … PKCS7DecodedAttrib* decodedAttrib; /* linked list of decoded attribs */ }

The PKCSDecodedAttrib structure in looks like so: typedef struct PKCS7DecodedAttrib { byte* oid; word32 oidSz;

Copyright © 2016 wolfSSL Inc. 2 byte* value; word32 valueSz; struct PKCS7DecodedAttrib* next; } PKCS7DecodedAttrib;

Tests for encoding and decoding Encrypted-data content type bundles have been added to the wolfCrypt test application located in the /wolfcrypt/test/test. file. These new tests are located in the pkcs7encrypted_test() function and are run automatically when doing a “make check” or when running the wolfCrypt test app explicitly like so:

$ cd wolfssl $ ./configure --enable-pkcs7 $ make $ ./wolfcrypt/test/testwolfcrypt MD5 test passed! SHA test passed! ... PKCS7enveloped test passed! PKCS7signed test passed! PKCS7encrypted test passed!

The pkcs7encrypted_test() generates Encrypted-data buffers for several cases, including 3DES, AES-128-CBC, AES-192-CBC, and AES-256-CBC and dumps them to following DER-encoded files for external testing/validation: pkcs7encryptedDataAES128CBC.der pkcs7encryptedDataAES192CBC.der pkcs7encryptedDataAES256CBC.der pkcs7encryptedDataDES3.der

The OpenSSL “cms” command line utility can be used to externally verify the correctness of these EncryptedData bundles and verify interoperability with OpenSSL. For example, to verify the AES-128-CBC bundle:

$ cms -EncryptedData_decrypt -in pkcs7encryptedDataAES128CBC.der -inform DER -secretkey 01020304050607080102030405060708 Hello World

CMS Enveloped-data Content Type

Copyright © 2016 wolfSSL Inc. 3 wolfCrypt previously had support for the PKCS#7/CMS EnvelopedData content type using RSA certificates and either DES or 3DES. Support for RSA-AES128/192/256-CBC has been added to wolfCrypt’s EnvelopedData support.

The following functions are used to encode and decode EnvelopedData content type bundles.

#include int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz); ​ ​ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, ​ ​ word32 outputSz); int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, ​ ​ word32 pkiMsgSz, byte* output, word32 outputSz); void wc_PKCS7_Free(PKCS7* pkcs7); ​ ​

Applications calling these functions must set the following members of the PKCS7 structure: typedef struct PKCS7 { … byte* content; /* data to be enveloped */ word32 contentSz; /* size of data to be enveloped */ int contentOID; /* OID of content */ int encryptOID; /* OID of encryption algorithm to use */ byte* privateKey; /* sender private key, DER formatted */ word32 privateKeySz; /* size of privateKey, in bytes */ } contentOID will specify the PKCS#7/CMS contentType, for example “DATA”. encryptOID specifies the encryption algorithm to use and can be one of the following values:

AES128CBCb AES192CBCb AES256CBCb DESb DES3b

The wc_PKCS7_InitWithCert() function parses and loads the recipient certificate in DER ​ ​ format into the PKCS7 structure. wc_PKCS7_Free() will free resources used during the ​ ​ EnvelopedData procedure and should be called when the user/app is finished with PKCS#7/CMS operations.

Copyright © 2016 wolfSSL Inc. 4

Tests for encoding and decoding Enveloped-data content type bundles have been added to the wolfCrypt test application located in the /wolfcrypt/test/test.c file. These new tests are located in the pkcs7enveloped_test() function and are run automatically when doing a “make check” or when running the wolfCrypt test app.

The pkcs7enveloped_test() generates Enveloped-data buffers for several cases, including ​ ​ 3DES, AES-128-CBC, AES-192-CBC, and AES-256-CBC and dumps them to following DER-encoded files for external testing/validation: pkcs7envelopedDataAES128CBC.der pkcs7envelopedDataAES192CBC.der pkcs7envelopedDataAES256CBC.der pkcs7envelopedDataDES3.der

The OpenSSL “cms” command line utility can be used to externally verify the correctness of these EnvelopedData bundles and verify interoperability with OpenSSL. For example, to verify the AES-128-CBC bundle:

$ openssl cms -decrypt -inform DER -in pkcs7envelopedDataAES128CBC.der -recip ./certs/client-cert.pem -inkey ./certs/client-key.pem Hello World

EnvelopedData with ECC

Support for ECC-AES128/192/256 will be provided in the subsequent release, but the API’s from the above EnvelopedData section will be very similar. There will be two additional PKCS7 structure members which will need to be set in the case of EnvelopedData with ECC: typedef struct PKCS7 { … int keyWrapOID; /* key wrap algorithm OID */ int keyAgreeOID; /* key agreement algorithm OID */ } keyWrapOID represents the key wrap algorithm used during EnvelopedData generation using ECC. Possible values will be:

AES128_WRAP AES192_WRAP AES256_WRAP

Copyright © 2016 wolfSSL Inc. 5 keyAgreeOID specifies the key agreement algorithm used. Possible values may include: dhSinglePass_stdDH_sha1kdf_scheme dhSinglePass_stdDH_sha256kdf_scheme dhSinglePass_stdDH_sha384kdf_scheme dhSinglePass_stdDH_sha512kdf_scheme

Copyright © 2016 wolfSSL Inc. 6