pwdbased: PBKDF2 refactory to reduce stack usage: (up to 64 bytes - pointer size) moved to the heap.

--- buffer variable moved to the heap; (up to 64 bytes)
--- returns changed to breaks

pwdbased: PKCS12_PBKDF refactory to reduce stack usage: (up to 1023 + 128 bytes - pointer sizes) moved to the heap.
--- staticBuffer variable changed to have size = 1 byte (1023 bytes saved)
--- Ai variable moved to the heap; (up to 64 bytes)
--- B variable moved to the heap; (up to 64 bytes)

hmac: HKDF refactory to restore previous behavior inside while loop.
This commit is contained in:
Moisés Guimarães
2014-04-21 14:45:07 -03:00
parent 6d0fbfe7e9
commit eaaf0a7c28
2 changed files with 105 additions and 30 deletions

View File

@ -767,19 +767,36 @@ int HKDF(int type, const byte* inKey, word32 inKeySz,
saltSz = hashSz; saltSz = hashSz;
} }
if ((ret = HmacSetKey(&myHmac, type, localSalt, saltSz)) == 0) do {
if ((ret = HmacUpdate(&myHmac, inKey, inKeySz)) == 0) ret = HmacSetKey(&myHmac, type, localSalt, saltSz);
ret = HmacFinal(&myHmac, prk); if (ret != 0)
break;
ret = HmacUpdate(&myHmac, inKey, inKeySz);
if (ret != 0)
break;
ret = HmacFinal(&myHmac, prk);
} while (0);
while (ret == 0 && outIdx < outSz) { if (ret == 0) {
while (outIdx < outSz) {
int tmpSz = (n == 1) ? 0 : hashSz; int tmpSz = (n == 1) ? 0 : hashSz;
word32 left = outSz - outIdx; word32 left = outSz - outIdx;
if ((ret = HmacSetKey(&myHmac, type, prk, hashSz)) == 0) ret = HmacSetKey(&myHmac, type, prk, hashSz);
if ((ret = HmacUpdate(&myHmac, tmp, tmpSz)) == 0) if (ret != 0)
if ((ret = HmacUpdate(&myHmac, info, infoSz)) == 0) break;
if ((ret = HmacUpdate(&myHmac, &n, 1)) == 0) ret = HmacUpdate(&myHmac, tmp, tmpSz);
ret = HmacFinal(&myHmac, tmp); if (ret != 0)
break;
ret = HmacUpdate(&myHmac, info, infoSz);
if (ret != 0)
break;
ret = HmacUpdate(&myHmac, &n, 1);
if (ret != 0)
break;
ret = HmacFinal(&myHmac, tmp);
if (ret != 0)
break;
left = min(left, (word32)hashSz); left = min(left, (word32)hashSz);
XMEMCPY(out+outIdx, tmp, left); XMEMCPY(out+outIdx, tmp, left);
@ -787,6 +804,7 @@ int HKDF(int type, const byte* inKey, word32 inKeySz,
outIdx += hashSz; outIdx += hashSz;
n++; n++;
} }
}
#ifdef CYASSL_SMALL_STACK #ifdef CYASSL_SMALL_STACK
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);

View File

@ -124,7 +124,11 @@ int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
int hLen; int hLen;
int j, ret; int j, ret;
Hmac hmac; Hmac hmac;
#ifdef CYASSL_SMALL_STACK
byte* buffer;
#else
byte buffer[MAX_DIGEST_SIZE]; byte buffer[MAX_DIGEST_SIZE];
#endif
if (hashType == MD5) { if (hashType == MD5) {
hLen = MD5_DIGEST_SIZE; hLen = MD5_DIGEST_SIZE;
@ -145,16 +149,21 @@ int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
else else
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
ret = HmacSetKey(&hmac, hashType, passwd, pLen); #ifdef CYASSL_SMALL_STACK
if (ret != 0) buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret; if (buffer == NULL)
return MEMORY_E;
#endif
ret = HmacSetKey(&hmac, hashType, passwd, pLen);
if (ret == 0) {
while (kLen) { while (kLen) {
int currentLen; int currentLen;
ret = HmacUpdate(&hmac, salt, sLen); ret = HmacUpdate(&hmac, salt, sLen);
if (ret != 0) if (ret != 0)
return ret; break;
/* encode i */ /* encode i */
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
@ -162,12 +171,16 @@ int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
ret = HmacUpdate(&hmac, &b, 1); ret = HmacUpdate(&hmac, &b, 1);
if (ret != 0) if (ret != 0)
return ret; break;
} }
/* check ret from inside for loop */
if (ret != 0)
break;
ret = HmacFinal(&hmac, buffer); ret = HmacFinal(&hmac, buffer);
if (ret != 0) if (ret != 0)
return ret; break;
currentLen = min(kLen, hLen); currentLen = min(kLen, hLen);
XMEMCPY(output, buffer, currentLen); XMEMCPY(output, buffer, currentLen);
@ -175,21 +188,37 @@ int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
for (j = 1; j < iterations; j++) { for (j = 1; j < iterations; j++) {
ret = HmacUpdate(&hmac, buffer, hLen); ret = HmacUpdate(&hmac, buffer, hLen);
if (ret != 0) if (ret != 0)
return ret; break;
ret = HmacFinal(&hmac, buffer); ret = HmacFinal(&hmac, buffer);
if (ret != 0) if (ret != 0)
return ret; break;
xorbuf(output, buffer, currentLen); xorbuf(output, buffer, currentLen);
} }
/* check ret from inside for loop */
if (ret != 0)
break;
output += currentLen; output += currentLen;
kLen -= currentLen; kLen -= currentLen;
i++; i++;
} }
}
return 0; #ifdef CYASSL_SMALL_STACK
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
} }
#ifdef CYASSL_SHA512
#define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE
#elif !defined(NO_SHA256)
#define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE
#else
#define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE
#endif
int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
int saltLen, int iterations, int kLen, int hashType, int id) int saltLen, int iterations, int kLen, int hashType, int id)
@ -200,17 +229,19 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
int ret = 0; int ret = 0;
int i; int i;
byte *D, *S, *P, *I; byte *D, *S, *P, *I;
byte staticBuffer[1024]; #ifdef CYASSL_SMALL_STACK
byte* buffer = staticBuffer; byte staticBuffer[1]; /* force dynamic usage */
#ifdef CYASSL_SHA512
byte Ai[SHA512_DIGEST_SIZE];
byte B[SHA512_BLOCK_SIZE];
#elif !defined(NO_SHA256)
byte Ai[SHA256_DIGEST_SIZE];
byte B[SHA256_BLOCK_SIZE];
#else #else
byte Ai[SHA_DIGEST_SIZE]; byte staticBuffer[1024];
byte B[SHA_BLOCK_SIZE]; #endif
byte* buffer = staticBuffer;
#ifdef CYASSL_SMALL_STACK
byte* Ai;
byte* B;
#else
byte Ai[PBKDF_DIGEST_SIZE];
byte B[PBKDF_DIGEST_SIZE];
#endif #endif
if (!iterations) if (!iterations)
@ -237,7 +268,19 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
} }
#endif #endif
else else
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
#ifdef CYASSL_SMALL_STACK
Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (Ai == NULL)
return MEMORY_E;
B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (B == NULL) {
XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E;
}
#endif
dLen = v; dLen = v;
sLen = v * ((saltLen + v - 1) / v); sLen = v * ((saltLen + v - 1) / v);
@ -251,7 +294,13 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
if (totalLen > sizeof(staticBuffer)) { if (totalLen > sizeof(staticBuffer)) {
buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
if (buffer == NULL) return MEMORY_E; if (buffer == NULL) {
#ifdef CYASSL_SMALL_STACK
XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MEMORY_E;
}
dynamic = 1; dynamic = 1;
} }
@ -410,8 +459,16 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
} }
if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
#ifdef CYASSL_SMALL_STACK
XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret; return ret;
} }
#undef PBKDF_DIGEST_SIZE
#endif /* NO_PWDBASED */ #endif /* NO_PWDBASED */