diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index b7dbc9988..b222774e4 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -28,19 +28,19 @@ #ifndef NO_PWDBASED #ifdef WOLFSSL_PIC32MZ_HASH + #ifndef NO_MD5 + #define wc_InitMd5 wc_InitMd5_sw + #define wc_Md5Update wc_Md5Update_sw + #define wc_Md5Final wc_Md5Final_sw + #endif /* NO_MD5 */ -#define wc_InitMd5 wc_InitMd5_sw -#define wc_Md5Update wc_Md5Update_sw -#define wc_Md5Final wc_Md5Final_sw - -#define wc_InitSha wc_InitSha_sw -#define wc_ShaUpdate wc_ShaUpdate_sw -#define wc_ShaFinal wc_ShaFinal_sw - -#define wc_InitSha256 wc_InitSha256_sw -#define wc_Sha256Update wc_Sha256Update_sw -#define wc_Sha256Final wc_Sha256Final_sw + #define wc_InitSha wc_InitSha_sw + #define wc_ShaUpdate wc_ShaUpdate_sw + #define wc_ShaFinal wc_ShaFinal_sw + #define wc_InitSha256 wc_InitSha256_sw + #define wc_Sha256Update wc_Sha256Update_sw + #define wc_Sha256Final wc_Sha256Final_sw #endif #include @@ -57,7 +57,6 @@ #include #endif - #ifndef min static INLINE word32 min(word32 a, word32 b) @@ -68,48 +67,63 @@ #endif /* min */ +/* PBKDF1 needs at least SHA available */ int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType) { - Md5 md5; Sha sha; - int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; +#ifndef NO_MD5 + Md5 md5; +#endif + int hLen = (int)SHA_DIGEST_SIZE; int i, ret = 0; byte buffer[SHA_DIGEST_SIZE]; /* max size */ if (hashType != MD5 && hashType != SHA) return BAD_FUNC_ARG; +#ifndef NO_MD5 + if (hashType == MD5) + hLen = (int)MD5_DIGEST_SIZE; +#endif + if (kLen > hLen) return BAD_FUNC_ARG; if (iterations < 1) return BAD_FUNC_ARG; - if (hashType == MD5) { - wc_InitMd5(&md5); - wc_Md5Update(&md5, passwd, pLen); - wc_Md5Update(&md5, salt, sLen); - wc_Md5Final(&md5, buffer); - } - else { - ret = wc_InitSha(&sha); - if (ret != 0) - return ret; - wc_ShaUpdate(&sha, passwd, pLen); - wc_ShaUpdate(&sha, salt, sLen); - wc_ShaFinal(&sha, buffer); + switch (hashType) { +#ifndef NO_MD5 + case MD5: + wc_InitMd5(&md5); + wc_Md5Update(&md5, passwd, pLen); + wc_Md5Update(&md5, salt, sLen); + wc_Md5Final(&md5, buffer); + break; +#endif /* NO_MD5 */ + case SHA: + default: + ret = wc_InitSha(&sha); + if (ret != 0) + return ret; + wc_ShaUpdate(&sha, passwd, pLen); + wc_ShaUpdate(&sha, salt, sLen); + wc_ShaFinal(&sha, buffer); + break; } for (i = 1; i < iterations; i++) { - if (hashType == MD5) { - wc_Md5Update(&md5, buffer, hLen); - wc_Md5Final(&md5, buffer); - } - else { + if (hashType == SHA) { wc_ShaUpdate(&sha, buffer, hLen); wc_ShaFinal(&sha, buffer); } +#ifndef NO_MD5 + else { + wc_Md5Update(&md5, buffer, hLen); + wc_Md5Final(&md5, buffer); + } +#endif } XMEMCPY(output, buffer, kLen); @@ -117,6 +131,37 @@ int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, } +int GetDigestSize(int hashType) +{ + int hLen; + + switch (hashType) { +#ifndef NO_MD5 + case MD5: + hLen = MD5_DIGEST_SIZE; + break; +#endif + case SHA: + hLen = SHA_DIGEST_SIZE; + break; +#ifndef NO_SHA256 + case SHA256: + hLen = SHA256_DIGEST_SIZE; + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512: + hLen = SHA512_DIGEST_SIZE; + break; +#endif + default: + return BAD_FUNC_ARG; + } + + return hLen; +} + + int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType) { @@ -130,23 +175,8 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, byte buffer[MAX_DIGEST_SIZE]; #endif - if (hashType == MD5) { - hLen = MD5_DIGEST_SIZE; - } - else if (hashType == SHA) { - hLen = SHA_DIGEST_SIZE; - } -#ifndef NO_SHA256 - else if (hashType == SHA256) { - hLen = SHA256_DIGEST_SIZE; - } -#endif -#ifdef WOLFSSL_SHA512 - else if (hashType == SHA512) { - hLen = SHA512_DIGEST_SIZE; - } -#endif - else + hLen = GetDigestSize(hashType); + if (hLen < 0) return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK @@ -213,13 +243,155 @@ int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, } #ifdef WOLFSSL_SHA512 -#define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE + #define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE #elif !defined(NO_SHA256) -#define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE + #define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE #else -#define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE + #define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE #endif +/* helper for wc_PKCS12_PBKDF(), sets block and digest sizes */ +int GetPKCS12HashSizes(int hashType, word32* v, word32* u) +{ + if (!v || !u) + return BAD_FUNC_ARG; + + switch (hashType) { +#ifndef NO_MD5 + case MD5: + *v = MD5_BLOCK_SIZE; + *u = MD5_DIGEST_SIZE; + break; +#endif + case SHA: + *v = SHA_BLOCK_SIZE; + *u = SHA_DIGEST_SIZE; + break; +#ifndef NO_SHA256 + case SHA256: + *v = SHA256_BLOCK_SIZE; + *u = SHA256_DIGEST_SIZE; + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512: + *v = SHA512_BLOCK_SIZE; + *u = SHA512_DIGEST_SIZE; + break; +#endif + default: + return BAD_FUNC_ARG; + } + + return 0; +} + +/* helper for PKCS12_PBKDF(), does hash operation */ +int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen, + byte* Ai, word32 u, int iterations) +{ + int i; + int ret = 0; + + if (buffer == NULL || Ai == NULL) + return BAD_FUNC_ARG; + + switch (hashType) { +#ifndef NO_MD5 + case MD5: + { + Md5 md5; + wc_InitMd5(&md5); + wc_Md5Update(&md5, buffer, totalLen); + wc_Md5Final(&md5, Ai); + + for (i = 1; i < iterations; i++) { + wc_Md5Update(&md5, Ai, u); + wc_Md5Final(&md5, Ai); + } + } + break; +#endif /* NO_MD5 */ + case SHA: + { + Sha sha; + ret = wc_InitSha(&sha); + if (ret != 0) + break; + wc_ShaUpdate(&sha, buffer, totalLen); + wc_ShaFinal(&sha, Ai); + + for (i = 1; i < iterations; i++) { + wc_ShaUpdate(&sha, Ai, u); + wc_ShaFinal(&sha, Ai); + } + } + break; +#ifndef NO_SHA256 + case SHA256: + { + Sha256 sha256; + ret = wc_InitSha256(&sha256); + if (ret != 0) + break; + + ret = wc_Sha256Update(&sha256, buffer, totalLen); + if (ret != 0) + break; + + ret = wc_Sha256Final(&sha256, Ai); + if (ret != 0) + break; + + for (i = 1; i < iterations; i++) { + ret = wc_Sha256Update(&sha256, Ai, u); + if (ret != 0) + break; + + ret = wc_Sha256Final(&sha256, Ai); + if (ret != 0) + break; + } + } + break; +#endif /* NO_SHA256 */ +#ifdef WOLFSSL_SHA512 + case SHA512: + { + Sha512 sha512; + ret = wc_InitSha512(&sha512); + if (ret != 0) + break; + + ret = wc_Sha512Update(&sha512, buffer, totalLen); + if (ret != 0) + break; + + ret = wc_Sha512Final(&sha512, Ai); + if (ret != 0) + break; + + for (i = 1; i < iterations; i++) { + ret = wc_Sha512Update(&sha512, Ai, u); + if (ret != 0) + break; + + ret = wc_Sha512Final(&sha512, Ai); + if (ret != 0) + break; + } + } + break; +#endif /* WOLFSSL_SHA512 */ + + default: + ret = BAD_FUNC_ARG; + break; + } + + return ret; +} + int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, int saltLen, int iterations, int kLen, int hashType, int id) { @@ -247,27 +419,8 @@ int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* sa if (!iterations) iterations = 1; - if (hashType == MD5) { - v = MD5_BLOCK_SIZE; - u = MD5_DIGEST_SIZE; - } - else if (hashType == SHA) { - v = SHA_BLOCK_SIZE; - u = SHA_DIGEST_SIZE; - } -#ifndef NO_SHA256 - else if (hashType == SHA256) { - v = SHA256_BLOCK_SIZE; - u = SHA256_DIGEST_SIZE; - } -#endif -#ifdef WOLFSSL_SHA512 - else if (hashType == SHA512) { - v = SHA512_BLOCK_SIZE; - u = SHA512_DIGEST_SIZE; - } -#endif - else + ret = GetPKCS12HashSizes(hashType, &v, &u); + if (ret < 0) return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK @@ -282,6 +435,9 @@ int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* sa } #endif + XMEMSET(Ai, 0, PBKDF_DIGEST_SIZE); + XMEMSET(B, 0, PBKDF_DIGEST_SIZE); + dLen = v; sLen = v * ((saltLen + v - 1) / v); if (passLen) @@ -302,7 +458,7 @@ int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* sa return MEMORY_E; } dynamic = 1; - } + } D = buffer; S = D + dLen; @@ -320,86 +476,9 @@ int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* sa word32 currentLen; mp_int B1; - if (hashType == MD5) { - Md5 md5; - - wc_InitMd5(&md5); - wc_Md5Update(&md5, buffer, totalLen); - wc_Md5Final(&md5, Ai); - - for (i = 1; i < iterations; i++) { - wc_Md5Update(&md5, Ai, u); - wc_Md5Final(&md5, Ai); - } - } - else if (hashType == SHA) { - Sha sha; - - ret = wc_InitSha(&sha); - if (ret != 0) - break; - wc_ShaUpdate(&sha, buffer, totalLen); - wc_ShaFinal(&sha, Ai); - - for (i = 1; i < iterations; i++) { - wc_ShaUpdate(&sha, Ai, u); - wc_ShaFinal(&sha, Ai); - } - } -#ifndef NO_SHA256 - else if (hashType == SHA256) { - Sha256 sha256; - - ret = wc_InitSha256(&sha256); - if (ret != 0) - break; - - ret = wc_Sha256Update(&sha256, buffer, totalLen); - if (ret != 0) - break; - - ret = wc_Sha256Final(&sha256, Ai); - if (ret != 0) - break; - - for (i = 1; i < iterations; i++) { - ret = wc_Sha256Update(&sha256, Ai, u); - if (ret != 0) - break; - - ret = wc_Sha256Final(&sha256, Ai); - if (ret != 0) - break; - } - } -#endif -#ifdef WOLFSSL_SHA512 - else if (hashType == SHA512) { - Sha512 sha512; - - ret = wc_InitSha512(&sha512); - if (ret != 0) - break; - - ret = wc_Sha512Update(&sha512, buffer, totalLen); - if (ret != 0) - break; - - ret = wc_Sha512Final(&sha512, Ai); - if (ret != 0) - break; - - for (i = 1; i < iterations; i++) { - ret = wc_Sha512Update(&sha512, Ai, u); - if (ret != 0) - break; - - ret = wc_Sha512Final(&sha512, Ai); - if (ret != 0) - break; - } - } -#endif + ret = DoPKCS12Hash(hashType, buffer, totalLen, Ai, u, iterations); + if (ret < 0) + break; for (i = 0; i < (int)v; i++) B[i] = Ai[i % u]; diff --git a/wolfssl/wolfcrypt/pwdbased.h b/wolfssl/wolfcrypt/pwdbased.h index d9ff152e2..0173beef8 100644 --- a/wolfssl/wolfcrypt/pwdbased.h +++ b/wolfssl/wolfcrypt/pwdbased.h @@ -26,7 +26,10 @@ #ifndef NO_PWDBASED -#include /* for hash type */ +#ifndef NO_MD5 + #include /* for hash type */ +#endif + #include #ifdef __cplusplus @@ -47,6 +50,12 @@ WOLFSSL_API int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int typeH, int purpose); +/* helper functions */ +WOLFSSL_LOCAL int GetDigestSize(int hashType); +WOLFSSL_LOCAL int GetPKCS12HashSizes(int hashType, word32* v, word32* u); +WOLFSSL_LOCAL int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen, + byte* Ai, word32 u, int iterations); + #ifdef __cplusplus } /* extern "C" */