From ee5d78f84fabba97a54b92b25a04eefc724a2280 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 16 Mar 2018 09:08:37 -0700 Subject: [PATCH 1/2] Added new `wc_OidGetHash` API for getting the hash type from a hash OID. Refactor PKCS7 and PKCS12 to use new API and reduce duplicate ocde. Updated `wc_GetCTC_HashOID` to use `wc_HashGetOID` and maintain back compat. --- wolfcrypt/src/asn.c | 40 +++++------------------ wolfcrypt/src/hash.c | 50 +++++++++++++++++++++++++++-- wolfcrypt/src/pkcs12.c | 41 ++++++------------------ wolfcrypt/src/pkcs7.c | 68 ++++++---------------------------------- wolfssl/wolfcrypt/hash.h | 1 + 5 files changed, 77 insertions(+), 123 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index aac691823..c6aac170f 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4897,38 +4897,14 @@ word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz, int wc_GetCTC_HashOID(int type) { - switch (type) { -#ifdef WOLFSSL_MD2 - case MD2: - return MD2h; -#endif -#ifndef NO_MD5 - case WC_MD5: - return MD5h; -#endif -#ifndef NO_SHA - case WC_SHA: - return SHAh; -#endif -#ifdef WOLFSSL_SHA224 - case WC_SHA224: - return SHA224h; -#endif -#ifndef NO_SHA256 - case WC_SHA256: - return SHA256h; -#endif -#ifdef WOLFSSL_SHA384 - case WC_SHA384: - return SHA384h; -#endif -#ifdef WOLFSSL_SHA512 - case WC_SHA512: - return SHA512h; -#endif - default: - return 0; - }; + int ret; + + /* hash type is same as enum HashType (ex WC_SHA is WC_HASH_TYPE_SHA) */ + ret = wc_HashGetOID((enum wc_HashType)type); + if (ret < 0) + ret = 0; /* backwards compatibility */ + + return ret; } void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index bcc3e282c..bd17034bb 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -126,7 +126,7 @@ int wc_HashGetOID(enum wc_HashType hash_type) #endif break; case WC_HASH_TYPE_SHA224: - #if defined(WOLFSSL_SHA224) + #ifdef WOLFSSL_SHA224 oid = SHA224h; #endif break; @@ -136,7 +136,7 @@ int wc_HashGetOID(enum wc_HashType hash_type) #endif break; case WC_HASH_TYPE_SHA384: - #if defined(WOLFSSL_SHA512) && defined(WOLFSSL_SHA384) + #ifdef WOLFSSL_SHA384 oid = SHA384h; #endif break; @@ -160,6 +160,52 @@ int wc_HashGetOID(enum wc_HashType hash_type) } return oid; } + +enum wc_HashType wc_OidGetHash(int oid) +{ + enum wc_HashType hash_type = WC_HASH_TYPE_NONE; + switch (oid) + { + case MD2h: + #ifdef WOLFSSL_MD2 + hash_type = WC_HASH_TYPE_MD2; + #endif + break; + case MD5h: + #ifndef NO_MD5 + hash_type = WC_HASH_TYPE_MD5; + #endif + break; + case SHAh: + #ifndef NO_SHA + hash_type = WC_HASH_TYPE_SHA; + #endif + break; + case SHA224h: + #if defined(WOLFSSL_SHA224) + hash_type = WC_HASH_TYPE_SHA224; + #endif + break; + case SHA256h: + #ifndef NO_SHA256 + hash_type = WC_HASH_TYPE_SHA256; + #endif + break; + case SHA384h: + #ifdef WOLFSSL_SHA384 + hash_type = WC_HASH_TYPE_SHA384; + #endif + break; + case SHA512h: + #ifdef WOLFSSL_SHA512 + hash_type = WC_HASH_TYPE_SHA512; + #endif + break; + default: + break; + } + return hash_type; +} #endif /* !NO_ASN || !NO_DH || HAVE_ECC */ diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 681994757..b49968e36 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -41,6 +41,7 @@ #endif #include #include +#include #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } @@ -480,7 +481,8 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, { Hmac hmac; MacData* mac; - int ret, typeH, kLen; + int ret, kLen; + enum wc_HashType hashT; int idx = 0; int id = 3; /* value from RFC 7292 indicating key is used for MAC */ word32 i; @@ -509,35 +511,12 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, unicodePasswd[idx++] = 0x00; /* get hash type used and resulting size of HMAC key */ - switch (mac->oid) { - #ifndef NO_SHA - case SHAh: /* 88 */ - typeH = WC_SHA; - kLen = WC_SHA_DIGEST_SIZE; - break; - #endif - #ifndef NO_SHA256 - case SHA256h: /* 414 */ - typeH = WC_SHA256; - kLen = WC_SHA256_DIGEST_SIZE; - break; - #endif - #ifdef WOLFSSL_SHA384 - case SHA384h: /* 415 */ - typeH = WC_SHA384; - kLen = WC_SHA384_DIGEST_SIZE; - break; - #endif - #ifdef WOLFSSL_SHA512 - case SHA512h: /* 416 */ - typeH = WC_SHA512; - kLen = WC_SHA512_DIGEST_SIZE; - break; - #endif - default: /* May be SHA224 or was just not built in */ - WOLFSSL_MSG("Unsupported hash used"); - return BAD_FUNC_ARG; + hashT = wc_OidGetHash(mac->oid); + if (hashT == WC_HASH_TYPE_NONE) { + WOLFSSL_MSG("Unsupported hash used"); + return BAD_FUNC_ARG; } + kLen = wc_HashGetDigestSize(hashT); /* check out buffer is large enough */ if (kLen < 0 || outSz < (word32)kLen) { @@ -546,7 +525,7 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, /* idx contains size of unicodePasswd */ if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt, - mac->saltSz, mac->itt, kLen, typeH, id, pkcs12->heap)) < 0) { + mac->saltSz, mac->itt, kLen, (int)hashT, id, pkcs12->heap)) < 0) { return ret; } @@ -554,7 +533,7 @@ static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz, if ((ret = wc_HmacInit(&hmac, pkcs12->heap, INVALID_DEVID)) != 0) { return ret; } - ret = wc_HmacSetKey(&hmac, typeH, key, kLen); + ret = wc_HmacSetKey(&hmac, (int)hashT, key, kLen); if (ret == 0) ret = wc_HmacUpdate(&hmac, data, dataSz); if (ret == 0) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 1991834fe..b5b6d842d 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -994,58 +994,6 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7, return ret; } - -/* sets the wc_HashType in ESD struct based on pkcs7->hashOID - * - * pkcs7 - pointer to initialized PKCS7 struct - * type - [OUT] pointer to wc_HashType for output - * - * returns hash digest size on success, negative on error */ -static int wc_PKCS7_SetHashType(PKCS7* pkcs7, enum wc_HashType* type) -{ - if (pkcs7 == NULL || type == NULL) - return BAD_FUNC_ARG; - - switch (pkcs7->hashOID) { - -#ifndef NO_MD5 - case MD5h: - *type = WC_HASH_TYPE_MD5; - break; -#endif -#ifndef NO_SHA - case SHAh: - *type = WC_HASH_TYPE_SHA; - break; -#endif -#ifdef WOLFSSL_SHA224 - case SHA224h: - *type = WC_HASH_TYPE_SHA224; - break; -#endif -#ifndef NO_SHA256 - case SHA256h: - *type = WC_HASH_TYPE_SHA256; - break; -#endif -#ifdef WOLFSSL_SHA384 - case SHA384h: - *type = WC_HASH_TYPE_SHA384; - break; -#endif -#ifdef WOLFSSL_SHA512 - case SHA512h: - *type = WC_HASH_TYPE_SHA512; - break; -#endif - default: - return BAD_FUNC_ARG; - } - - return wc_HashGetDigestSize(*type); -} - - /* build PKCS#7 signedData content type */ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) { @@ -1097,13 +1045,15 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) XMEMSET(esd, 0, sizeof(ESD)); - hashSz = wc_PKCS7_SetHashType(pkcs7, &esd->hashType); - if (hashSz < 0) { + esd->hashType = wc_OidGetHash(pkcs7->hashOID); + ret = wc_HashGetDigestSize(esd->hashType); + if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return hashSz; + return ret; } + hashSz = ret; ret = wc_HashInit(&esd->hash, esd->hashType); if (ret != 0) { @@ -1521,13 +1471,15 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib, XMEMSET(digest, 0, WC_MAX_DIGEST_SIZE); XMEMSET(digestInfo, 0, MAX_PKCS7_DIGEST_SZ); - hashSz = wc_PKCS7_SetHashType(pkcs7, &hashType); - if (hashSz < 0) { + hashType = wc_OidGetHash(pkcs7->hashOID); + ret = wc_HashGetDigestSize(hashType); + if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return hashSz; + return ret; } + hashSz = ret; /* calculate digest */ ret = wc_HashInit(&hash, hashType); diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index e7e2afed6..fef7dc725 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -117,6 +117,7 @@ typedef union { #if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) WOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type); +WOLFSSL_API enum wc_HashType wc_OidGetHash(int oid); #endif WOLFSSL_API enum wc_HashType wc_HashTypeConvert(int hashType); From 1f7b954d47609d280a7977883dbc8a76604b2fda Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 12 Apr 2018 06:51:23 -0700 Subject: [PATCH 2/2] Fix for `wc_GetCTC_HashOID` in FIPS mode. Uses the new `wc_HashTypeConvert` to handle conversion from unique WC_ALGO (`int`) to WC_HASH_TYPE_ALGO (`enum wc_HashType`). --- wolfcrypt/src/asn.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c6aac170f..a7d7615b5 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4898,9 +4898,10 @@ word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz, int wc_GetCTC_HashOID(int type) { int ret; + enum wc_HashType hType; - /* hash type is same as enum HashType (ex WC_SHA is WC_HASH_TYPE_SHA) */ - ret = wc_HashGetOID((enum wc_HashType)type); + hType = wc_HashTypeConvert(type); + ret = wc_HashGetOID(hType); if (ret < 0) ret = 0; /* backwards compatibility */