forked from wolfSSL/wolfssl
keys: fixing DeriveKeys:
--- variables md5InputSz, shaInputSz and keyDataSz removed keys: refactoring MakeSslMasterSecret to reduce stack usage: --- variable shaOutput moved to the heap (20 bytes saved) --- variable md5Input moved to the heap (532 bytes saved) --- variable shaInput moved to the heap (579 bytes saved) --- variable md5 moved to the heap (sizeof(Md5) saved) --- variable sha moved to the heap (sizeof(Sha) saved)
This commit is contained in:
169
src/keys.c
169
src/keys.c
@ -2240,10 +2240,6 @@ int DeriveKeys(CYASSL* ssl)
|
|||||||
int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i;
|
int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
word32 md5InputSz = SECRET_LEN + SHA_DIGEST_SIZE;
|
|
||||||
word32 shaInputSz = KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN;
|
|
||||||
word32 keyDataSz = KEY_PREFIX * MD5_DIGEST_SIZE; /* max size */
|
|
||||||
|
|
||||||
#ifdef CYASSL_SMALL_STACK
|
#ifdef CYASSL_SMALL_STACK
|
||||||
byte* shaOutput;
|
byte* shaOutput;
|
||||||
byte* md5Input;
|
byte* md5Input;
|
||||||
@ -2253,9 +2249,9 @@ int DeriveKeys(CYASSL* ssl)
|
|||||||
Sha* sha;
|
Sha* sha;
|
||||||
#else
|
#else
|
||||||
byte shaOutput[SHA_DIGEST_SIZE];
|
byte shaOutput[SHA_DIGEST_SIZE];
|
||||||
byte md5Input[md5InputSz];
|
byte md5Input[SECRET_LEN + SHA_DIGEST_SIZE];
|
||||||
byte shaInput[shaInputSz];
|
byte shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN];
|
||||||
byte keyData[keyDataSz];
|
byte keyData[KEY_PREFIX * MD5_DIGEST_SIZE];
|
||||||
Md5 md5[1];
|
Md5 md5[1];
|
||||||
Sha sha[1];
|
Sha sha[1];
|
||||||
#endif
|
#endif
|
||||||
@ -2263,9 +2259,12 @@ int DeriveKeys(CYASSL* ssl)
|
|||||||
#ifdef CYASSL_SMALL_STACK
|
#ifdef CYASSL_SMALL_STACK
|
||||||
shaOutput = (byte*)XMALLOC(SHA_DIGEST_SIZE,
|
shaOutput = (byte*)XMALLOC(SHA_DIGEST_SIZE,
|
||||||
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
md5Input = (byte*)XMALLOC(md5InputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
md5Input = (byte*)XMALLOC(SECRET_LEN + SHA_DIGEST_SIZE,
|
||||||
shaInput = (byte*)XMALLOC(shaInputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
keyData = (byte*)XMALLOC(keyDataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
shaInput = (byte*)XMALLOC(KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN,
|
||||||
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
keyData = (byte*)XMALLOC(KEY_PREFIX * MD5_DIGEST_SIZE,
|
||||||
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
@ -2304,11 +2303,12 @@ int DeriveKeys(CYASSL* ssl)
|
|||||||
idx += RAN_LEN;
|
idx += RAN_LEN;
|
||||||
XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
|
XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
|
|
||||||
ShaUpdate(sha, shaInput, shaInputSz - KEY_PREFIX + j);
|
ShaUpdate(sha, shaInput, (KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN)
|
||||||
|
- KEY_PREFIX + j);
|
||||||
ShaFinal(sha, shaOutput);
|
ShaFinal(sha, shaOutput);
|
||||||
|
|
||||||
XMEMCPY(md5Input + SECRET_LEN, shaOutput, SHA_DIGEST_SIZE);
|
XMEMCPY(md5Input + SECRET_LEN, shaOutput, SHA_DIGEST_SIZE);
|
||||||
Md5Update(md5, md5Input, md5InputSz);
|
Md5Update(md5, md5Input, SECRET_LEN + SHA_DIGEST_SIZE);
|
||||||
Md5Final(md5, keyData + i * MD5_DIGEST_SIZE);
|
Md5Final(md5, keyData + i * MD5_DIGEST_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2350,15 +2350,23 @@ static int CleanPreMaster(CYASSL* ssl)
|
|||||||
/* Create and store the master secret see page 32, 6.1 */
|
/* Create and store the master secret see page 32, 6.1 */
|
||||||
static int MakeSslMasterSecret(CYASSL* ssl)
|
static int MakeSslMasterSecret(CYASSL* ssl)
|
||||||
{
|
{
|
||||||
byte shaOutput[SHA_DIGEST_SIZE];
|
|
||||||
byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
|
|
||||||
byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
|
|
||||||
int i, ret;
|
int i, ret;
|
||||||
word32 idx;
|
word32 idx;
|
||||||
word32 pmsSz = ssl->arrays->preMasterSz;
|
word32 pmsSz = ssl->arrays->preMasterSz;
|
||||||
|
|
||||||
Md5 md5;
|
#ifdef CYASSL_SMALL_STACK
|
||||||
Sha sha;
|
byte* shaOutput;
|
||||||
|
byte* md5Input;
|
||||||
|
byte* shaInput;
|
||||||
|
Md5* md5;
|
||||||
|
Sha* sha;
|
||||||
|
#else
|
||||||
|
byte shaOutput[SHA_DIGEST_SIZE];
|
||||||
|
byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
|
||||||
|
byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
|
||||||
|
Md5 md5[1];
|
||||||
|
Sha sha[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SHOW_SECRETS
|
#ifdef SHOW_SECRETS
|
||||||
{
|
{
|
||||||
@ -2369,58 +2377,91 @@ static int MakeSslMasterSecret(CYASSL* ssl)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InitMd5(&md5);
|
#ifdef CYASSL_SMALL_STACK
|
||||||
ret = InitSha(&sha);
|
shaOutput = (byte*)XMALLOC(SHA_DIGEST_SIZE,
|
||||||
if (ret != 0)
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
return ret;
|
md5Input = (byte*)XMALLOC(ENCRYPT_LEN + SHA_DIGEST_SIZE,
|
||||||
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XMEMCPY(md5Input, ssl->arrays->preMasterSecret, pmsSz);
|
shaInput = (byte*)XMALLOC(PREFIX + ENCRYPT_LEN + 2 * RAN_LEN,
|
||||||
|
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
for (i = 0; i < MASTER_ROUNDS; ++i) {
|
md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
byte prefix[KEY_PREFIX]; /* only need PREFIX bytes but static */
|
sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (!SetPrefix(prefix, i)) { /* analysis thinks will overrun */
|
|
||||||
return PREFIX_ERROR;
|
if (shaOutput == NULL || md5Input == NULL || shaInput == NULL ||
|
||||||
}
|
md5 == NULL || sha == NULL) {
|
||||||
|
if (shaOutput) XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
idx = 0;
|
if (md5Input) XFREE(md5Input, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XMEMCPY(shaInput, prefix, i + 1);
|
if (shaInput) XFREE(shaInput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
idx += i + 1;
|
if (md5) XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (sha) XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XMEMCPY(shaInput + idx, ssl->arrays->preMasterSecret, pmsSz);
|
|
||||||
idx += pmsSz;
|
return MEMORY_E;
|
||||||
XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
|
|
||||||
idx += RAN_LEN;
|
|
||||||
XMEMCPY(shaInput + idx, ssl->arrays->serverRandom, RAN_LEN);
|
|
||||||
idx += RAN_LEN;
|
|
||||||
ShaUpdate(&sha, shaInput, idx);
|
|
||||||
ShaFinal(&sha, shaOutput);
|
|
||||||
|
|
||||||
idx = pmsSz; /* preSz */
|
|
||||||
XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE);
|
|
||||||
idx += SHA_DIGEST_SIZE;
|
|
||||||
Md5Update(&md5, md5Input, idx);
|
|
||||||
Md5Final(&md5, &ssl->arrays->masterSecret[i * MD5_DIGEST_SIZE]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SHOW_SECRETS
|
|
||||||
{
|
|
||||||
word32 j;
|
|
||||||
printf("master secret: ");
|
|
||||||
for (j = 0; j < SECRET_LEN; j++)
|
|
||||||
printf("%02x", ssl->arrays->masterSecret[j]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = DeriveKeys(ssl);
|
InitMd5(md5);
|
||||||
if (ret != 0) {
|
|
||||||
/* always try to clean PreMaster */
|
ret = InitSha(sha);
|
||||||
CleanPreMaster(ssl);
|
|
||||||
return ret;
|
if (ret == 0) {
|
||||||
|
XMEMCPY(md5Input, ssl->arrays->preMasterSecret, pmsSz);
|
||||||
|
|
||||||
|
for (i = 0; i < MASTER_ROUNDS; ++i) {
|
||||||
|
byte prefix[KEY_PREFIX]; /* only need PREFIX bytes but static */
|
||||||
|
if (!SetPrefix(prefix, i)) { /* analysis thinks will overrun */
|
||||||
|
ret = PREFIX_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
XMEMCPY(shaInput, prefix, i + 1);
|
||||||
|
idx += i + 1;
|
||||||
|
|
||||||
|
XMEMCPY(shaInput + idx, ssl->arrays->preMasterSecret, pmsSz);
|
||||||
|
idx += pmsSz;
|
||||||
|
XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
|
idx += RAN_LEN;
|
||||||
|
XMEMCPY(shaInput + idx, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
idx += RAN_LEN;
|
||||||
|
ShaUpdate(sha, shaInput, idx);
|
||||||
|
ShaFinal(sha, shaOutput);
|
||||||
|
|
||||||
|
idx = pmsSz; /* preSz */
|
||||||
|
XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE);
|
||||||
|
idx += SHA_DIGEST_SIZE;
|
||||||
|
Md5Update(md5, md5Input, idx);
|
||||||
|
Md5Final(md5, &ssl->arrays->masterSecret[i * MD5_DIGEST_SIZE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SHOW_SECRETS
|
||||||
|
{
|
||||||
|
word32 j;
|
||||||
|
printf("master secret: ");
|
||||||
|
for (j = 0; j < SECRET_LEN; j++)
|
||||||
|
printf("%02x", ssl->arrays->masterSecret[j]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
ret = DeriveKeys(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CleanPreMaster(ssl);
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(shaOutput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(md5Input, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(shaInput, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
ret = CleanPreMaster(ssl);
|
||||||
|
else
|
||||||
|
CleanPreMaster(ssl);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user