diff --git a/ctaocrypt/include/pwdbased.h b/ctaocrypt/include/pwdbased.h index 431948975..4c9817278 100644 --- a/ctaocrypt/include/pwdbased.h +++ b/ctaocrypt/include/pwdbased.h @@ -36,6 +36,8 @@ int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType); +int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, + int sLen, int iterations, int kLen, int hashType); diff --git a/ctaocrypt/src/pwdbased.c b/ctaocrypt/src/pwdbased.c index 2cd380f08..8585e5b22 100644 --- a/ctaocrypt/src/pwdbased.c +++ b/ctaocrypt/src/pwdbased.c @@ -23,6 +23,26 @@ #ifndef NO_PWDBASED #include "pwdbased.h" +#include "ctc_hmac.h" +#ifdef CYASSL_SHA512 + #include "sha512.h" +#endif +#ifdef NO_INLINE + #include "misc.h" +#else + #include "misc.c" +#endif + + + +#ifndef min + + static INLINE word32 min(word32 a, word32 b) + { + return a > b ? b : a; + } + +#endif /* min */ int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, @@ -72,5 +92,61 @@ int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, } +int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, + int sLen, int iterations, int kLen, int hashType) +{ + word32 i = 1; + int hLen; + int j; + Hmac hmac; + byte buffer[INNER_HASH_SIZE]; /* max size */ + + if (hashType == MD5) { + hLen = MD5_DIGEST_SIZE; + } + else if (hashType == SHA) { + hLen = SHA_DIGEST_SIZE; + } + else if (hashType == SHA256) { + hLen = SHA256_DIGEST_SIZE; + } +#ifdef CYASSL_SHA512 + else if (hashType == SHA512) { + hLen = SHA512_DIGEST_SIZE; + } +#endif + else + return -1; /* bad HMAC hashType */ + + HmacSetKey(&hmac, hashType, passwd, pLen); + + while (kLen) { + int currentLen; + HmacUpdate(&hmac, salt, sLen); + + /* encode i */ + for (j = 0; j < 4; j++) { + byte b = i >> ((3-j) * 8); + HmacUpdate(&hmac, &b, 1); + } + HmacFinal(&hmac, buffer); + + currentLen = min(kLen, hLen); + XMEMCPY(output, buffer, currentLen); + + for (j = 1; j < iterations; j++) { + HmacUpdate(&hmac, buffer, hLen); + HmacFinal(&hmac, buffer); + xorbuf(output, buffer, currentLen); + } + + output += currentLen; + kLen -= currentLen; + i++; + } + + return 0; +} + #endif /* NO_PWDBASED */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 50fecd38c..46ca1032a 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -1653,6 +1653,7 @@ int pbkdf2_test() const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 }; int iterations = 2048; int kLen = 24; + byte derived[64]; const byte verify[] = { 0xBF, 0xDE, 0x6B, 0xE9, 0x4D, 0xF7, 0xE1, 0x1D, 0xD4, 0x09, 0xBC, 0xE2, @@ -1660,6 +1661,12 @@ int pbkdf2_test() }; + PBKDF2(derived, (byte*)passwd, strlen(passwd), salt, 8, iterations, kLen, + SHA); + + if (memcmp(derived, verify, sizeof(verify)) != 0) + return -101; + return 0; } @@ -1689,7 +1696,8 @@ int pbkdf1_test() int pwdbased_test() { - return pbkdf1_test(); + int ret = pbkdf1_test(); + return ret + pbkdf2_test(); } #endif /* NO_PWDBASED */