Fix for issue with unique hash types on ctoacrypt FIPS using different values than WC_HASH_TYPE_*. Add new API wc_HashTypeConvert to handle the conversion between enum wc_HashType and int. For FIPS it uses a switch() to convert and for non-FIPS it uses a simple cast. Changed the pwdbased_test to return actual ret instead of adding values (made it difficult to track down error location).

This commit is contained in:
David Garske
2018-04-11 09:20:19 -07:00
parent 3f3e332a3a
commit 83bfdb1594
4 changed files with 85 additions and 23 deletions

View File

@@ -48,6 +48,62 @@ enum Hash_Sum {
}; };
#endif /* !NO_ASN */ #endif /* !NO_ASN */
/* function converts int hash type to enum */
enum wc_HashType wc_HashTypeConvert(int hashType)
{
/* Default to hash type none as error */
enum wc_HashType eHashType = WC_HASH_TYPE_NONE;
#ifdef HAVE_FIPS
/* original FIPSv1 requires a mapping for unique hash type to wc_HashType */
switch (hashType) {
#ifndef NO_MD5
case WC_MD5:
eHashType = WC_HASH_TYPE_MD5;
break;
#endif /* !NO_MD5 */
#ifndef NO_SHA
case WC_SHA:
eHashType = WC_HASH_TYPE_SHA;
break;
#endif /* !NO_SHA */
#ifdef WOLFSSL_SHA224
case WC_SHA224:
eHashType = WC_HASH_TYPE_SHA224;
break;
#endif /* WOLFSSL_SHA224 */
#ifndef NO_SHA256
case WC_SHA256:
eHashType = WC_HASH_TYPE_SHA256;
break;
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_SHA384
case WC_SHA384:
eHashType = WC_HASH_TYPE_SHA384;
break;
#endif /* WOLFSSL_SHA384 */
case WC_SHA512:
eHashType = WC_HASH_TYPE_SHA512;
break;
#endif /* WOLFSSL_SHA512 */
default:
eHashType = WC_HASH_TYPE_NONE;
break;
}
#else
/* current master uses same unique types as wc_HashType */
if (hashType > 0 && hashType <= WC_HASH_TYPE_MAX) {
eHashType = (enum wc_HashType)hashType;
}
#endif
return eHashType;
}
int wc_HashGetOID(enum wc_HashType hash_type) int wc_HashGetOID(enum wc_HashType hash_type)
{ {
int oid = HASH_TYPE_E; /* Default to hash type error */ int oid = HASH_TYPE_E; /* Default to hash type error */

View File

@@ -62,15 +62,14 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
(void)heap; (void)heap;
if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || ivLen < 0){
ivLen < 0 || hashType < 0 || hashType > WC_HASH_TYPE_MAX) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
if (iterations <= 0) if (iterations <= 0)
iterations = 1; iterations = 1;
hashT = (enum wc_HashType)hashType; hashT = wc_HashTypeConvert(hashType);
err = wc_HashGetDigestSize(hashT); err = wc_HashGetDigestSize(hashT);
if (err < 0) if (err < 0)
return err; return err;
@@ -180,16 +179,14 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
#endif #endif
enum wc_HashType hashT; enum wc_HashType hashT;
if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0 || if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0) {
hashType < 0 || hashType > WC_HASH_TYPE_MAX) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
if (iterations <= 0) if (iterations <= 0)
iterations = 1; iterations = 1;
hashT = (enum wc_HashType)hashType; hashT = wc_HashTypeConvert(hashType);
hLen = wc_HashGetDigestSize(hashT); hLen = wc_HashGetDigestSize(hashT);
if (hLen < 0) if (hLen < 0)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@@ -205,7 +202,8 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
ret = wc_HmacInit(hmac, NULL, INVALID_DEVID); ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
if (ret == 0) { if (ret == 0) {
ret = wc_HmacSetKey(hmac, hashT, passwd, pLen); /* use int hashType here, since HMAC FIPS uses the old unique value */
ret = wc_HmacSetKey(hmac, hashType, passwd, pLen);
while (ret == 0 && kLen) { while (ret == 0 && kLen) {
int currentLen; int currentLen;
@@ -276,12 +274,11 @@ static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
#endif #endif
enum wc_HashType hashT; enum wc_HashType hashT;
if (buffer == NULL || Ai == NULL || hashType < 0 || if (buffer == NULL || Ai == NULL) {
hashType > WC_HASH_TYPE_MAX) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
hashT = (enum wc_HashType)hashType; hashT = wc_HashTypeConvert(hashType);
/* initialize hash */ /* initialize hash */
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
@@ -356,16 +353,15 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
enum wc_HashType hashT; enum wc_HashType hashT;
(void)heap; (void)heap;
if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0 || if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0) {
hashType < 0 || hashType > WC_HASH_TYPE_MAX) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
if (iterations <= 0) if (iterations <= 0)
iterations = 1; iterations = 1;
hashT = (enum wc_HashType)hashType; hashT = wc_HashTypeConvert(hashType);
ret = wc_HashGetDigestSize(hashT); ret = wc_HashGetDigestSize(hashT);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@@ -13147,15 +13147,23 @@ int pbkdf1_test(void)
int pwdbased_test(void) int pwdbased_test(void)
{ {
int ret = 0; int ret = 0;
#ifndef NO_SHA
ret += pbkdf1_test();
#endif
ret += pbkdf2_test();
ret += pkcs12_test();
#ifdef HAVE_SCRYPT
ret += scrypt_test();
#endif
#ifndef NO_SHA
ret = pbkdf1_test();
if (ret != 0)
return ret;
#endif
ret = pbkdf2_test();
if (ret != 0)
return ret;
ret = pkcs12_test();
if (ret != 0)
return ret;
#ifdef HAVE_SCRYPT
ret = scrypt_test();
if (ret != 0)
return ret;
#endif
return ret; return ret;
} }

View File

@@ -119,6 +119,8 @@ typedef union {
WOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type); WOLFSSL_API int wc_HashGetOID(enum wc_HashType hash_type);
#endif #endif
WOLFSSL_API enum wc_HashType wc_HashTypeConvert(int hashType);
WOLFSSL_API int wc_HashGetDigestSize(enum wc_HashType hash_type); WOLFSSL_API int wc_HashGetDigestSize(enum wc_HashType hash_type);
WOLFSSL_API int wc_HashGetBlockSize(enum wc_HashType hash_type); WOLFSSL_API int wc_HashGetBlockSize(enum wc_HashType hash_type);
WOLFSSL_API int wc_Hash(enum wc_HashType hash_type, WOLFSSL_API int wc_Hash(enum wc_HashType hash_type,