internal.c: refactoring SendServerKeyExchange to reduce stack usage:

--- variable exportBuf moved to the heap (256 bytes saved)
--- indentation fixes
This commit is contained in:
Moisés Guimarães 2014-10-24 13:29:18 -03:00
parent 0e43240180
commit dc90935fc7

View File

@ -10017,6 +10017,8 @@ static void PickHashSigAlgo(CYASSL* ssl,
#else /* !NO_DH or HAVE_ECC */
return NOT_COMPILED_IN; /* not supported by build */
#endif /* !NO_DH or HAVE_ECC */
#undef ERROR_OUT
}
@ -11069,6 +11071,7 @@ int DoSessionTicket(CYASSL* ssl,
{
int ret = 0;
(void)ssl;
#define ERROR_OUT(err, exit) do { ret = err; goto exit; } while(0)
#ifndef NO_PSK
if (ssl->specs.kea == psk_kea)
@ -11080,7 +11083,9 @@ int DoSessionTicket(CYASSL* ssl,
/* include size part */
length = (word32)XSTRLEN(ssl->arrays->server_hint);
if (length > MAX_PSK_ID_LEN) return SERVER_HINT_ERROR;
if (length > MAX_PSK_ID_LEN)
return SERVER_HINT_ERROR;
length += HINT_LEN_SZ;
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
@ -11113,8 +11118,8 @@ int DoSessionTicket(CYASSL* ssl,
if (ssl->hsInfoOn)
AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
if (ssl->toInfoOn)
AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
output, sendSz, ssl->heap);
AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
sendSz, ssl->heap);
#endif
ssl->buffers.outputBuffer.length += sendSz;
@ -11187,6 +11192,7 @@ int DoSessionTicket(CYASSL* ssl,
idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
}
#endif
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -11234,8 +11240,8 @@ int DoSessionTicket(CYASSL* ssl,
if (ssl->hsInfoOn)
AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
if (ssl->toInfoOn)
AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
output, sendSz, ssl->heap);
AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
sendSz, ssl->heap);
#endif
ssl->buffers.outputBuffer.length += sendSz;
@ -11253,14 +11259,18 @@ int DoSessionTicket(CYASSL* ssl,
byte *output;
word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int sendSz;
byte exportBuf[MAX_EXPORT_ECC_SZ];
word32 expSz = sizeof(exportBuf);
word32 sigSz;
word32 preSigSz, preSigIdx;
#ifndef NO_RSA
RsaKey rsaKey;
#endif
ecc_key dsaKey;
#ifdef CYASSL_SMALL_STACK
byte* exportBuf = NULL;
#else
byte exportBuf[MAX_EXPORT_ECC_SZ];
#endif
word32 expSz = MAX_EXPORT_ECC_SZ;
if (ssl->specs.static_ecdh) {
CYASSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
@ -11281,8 +11291,15 @@ int DoSessionTicket(CYASSL* ssl,
ssl->eccTempKeyPresent = 1;
}
#ifdef CYASSL_SMALL_STACK
exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (exportBuf == NULL)
return MEMORY_E;
#endif
if (ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
return ECC_EXPORT_ERROR;
ERROR_OUT(ECC_EXPORT_ERROR, done_a);
length += expSz;
preSigSz = length;
@ -11290,8 +11307,10 @@ int DoSessionTicket(CYASSL* ssl,
#ifndef NO_RSA
ret = InitRsaKey(&rsaKey, ssl->heap);
if (ret != 0) return ret;
if (ret != 0)
goto done_a;
#endif
ecc_init(&dsaKey);
/* sig length */
@ -11302,7 +11321,7 @@ int DoSessionTicket(CYASSL* ssl,
FreeRsaKey(&rsaKey);
#endif
ecc_free(&dsaKey);
return NO_PRIVATE_KEY;
ERROR_OUT(NO_PRIVATE_KEY, done_a);
}
#ifndef NO_RSA
@ -11311,16 +11330,19 @@ int DoSessionTicket(CYASSL* ssl,
word32 i = 0;
ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
&rsaKey, ssl->buffers.key.length);
if (ret != 0) return ret;
if (ret != 0)
goto done_a;
sigSz = RsaEncryptSize(&rsaKey);
} else
#endif
if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
/* ecdsa sig size */
word32 i = 0;
ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
&dsaKey, ssl->buffers.key.length);
if (ret != 0) return ret;
if (ret != 0)
goto done_a;
sigSz = ecc_sig_size(&dsaKey); /* worst case estimate */
}
else {
@ -11328,7 +11350,7 @@ int DoSessionTicket(CYASSL* ssl,
FreeRsaKey(&rsaKey);
#endif
ecc_free(&dsaKey);
return ALGO_ID_E; /* unsupported type */
ERROR_OUT(ALGO_ID_E, done_a); /* unsupported type */
}
length += sigSz;
@ -11350,7 +11372,7 @@ int DoSessionTicket(CYASSL* ssl,
FreeRsaKey(&rsaKey);
#endif
ecc_free(&dsaKey);
return ret;
goto done_a;
}
/* get ouput buffer */
@ -11408,7 +11430,7 @@ int DoSessionTicket(CYASSL* ssl,
/* sha */
ret = InitSha(&sha);
if (ret != 0)
return ret;
goto done_a;
ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN);
ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN);
ShaUpdate(&sha, output + preSigIdx, preSigSz);
@ -11418,37 +11440,37 @@ int DoSessionTicket(CYASSL* ssl,
#ifndef NO_SHA256
ret = InitSha256(&sha256);
if (ret != 0)
return ret;
goto done_a;
ret = Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
if (ret != 0)
return ret;
goto done_a;
ret = Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
if (ret != 0)
return ret;
goto done_a;
ret = Sha256Update(&sha256, output + preSigIdx, preSigSz);
if (ret != 0)
return ret;
goto done_a;
ret = Sha256Final(&sha256, hash256);
if (ret != 0)
return ret;
goto done_a;
#endif
#ifdef CYASSL_SHA384
ret = InitSha384(&sha384);
if (ret != 0)
return ret;
goto done_a;
ret = Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
if (ret != 0)
return ret;
goto done_a;
ret = Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
if (ret != 0)
return ret;
goto done_a;
ret = Sha384Update(&sha384, output + preSigIdx, preSigSz);
if (ret != 0)
return ret;
goto done_a;
ret = Sha384Final(&sha384, hash384);
if (ret != 0)
return ret;
goto done_a;
#endif
#ifndef NO_RSA
if (ssl->suites->sigAlgo == rsa_sa_algo) {
@ -11494,25 +11516,23 @@ int DoSessionTicket(CYASSL* ssl,
#ifdef HAVE_PK_CALLBACKS
word32 ioLen = sigSz;
ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
output + idx,
&ioLen,
output + idx, &ioLen,
ssl->buffers.key.buffer,
ssl->buffers.key.length,
ssl->RsaSignCtx);
#endif /*HAVE_PK_CALLBACKS */
}
else {
else
ret = RsaSSL_Sign(signBuffer, signSz, output + idx,
sigSz, &rsaKey, ssl->rng);
if (ret > 0)
ret = 0; /* reset on success */
}
FreeRsaKey(&rsaKey);
ecc_free(&dsaKey);
if (ret < 0)
return ret;
goto done_a;
} else
#endif
if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
#ifndef NO_OLD_TLS
byte* digest = &hash[MD5_DIGEST_SIZE];
@ -11524,12 +11544,10 @@ int DoSessionTicket(CYASSL* ssl,
word32 sz = sigSz;
byte doUserEcc = 0;
#ifdef HAVE_PK_CALLBACKS
#ifdef HAVE_ECC
#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
if (ssl->ctx->EccSignCb)
doUserEcc = 1;
#endif /* HAVE_ECC */
#endif /*HAVE_PK_CALLBACKS */
#endif
if (IsAtLeastTLSv1_2(ssl)) {
if (ssl->suites->hashAlgo == sha_mac) {
@ -11553,15 +11571,13 @@ int DoSessionTicket(CYASSL* ssl,
}
if (doUserEcc) {
#ifdef HAVE_PK_CALLBACKS
#ifdef HAVE_ECC
#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
output + LENGTH_SZ + idx, &sz,
ssl->buffers.key.buffer,
ssl->buffers.key.length,
ssl->EccSignCtx);
#endif /* HAVE_ECC */
#endif /*HAVE_PK_CALLBACKS */
#endif
}
else {
ret = ecc_sign_hash(digest, digestSz,
@ -11571,7 +11587,8 @@ int DoSessionTicket(CYASSL* ssl,
FreeRsaKey(&rsaKey);
#endif
ecc_free(&dsaKey);
if (ret < 0) return ret;
if (ret < 0)
goto done_a;
/* Now that we know the real sig size, write it. */
c16toa((word16)sz, output + idx);
@ -11584,9 +11601,8 @@ int DoSessionTicket(CYASSL* ssl,
AddHeaders(output, length, server_key_exchange, ssl);
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
goto done_a;
#ifdef CYASSL_CALLBACKS
if (ssl->hsInfoOn)
@ -11602,6 +11618,13 @@ int DoSessionTicket(CYASSL* ssl,
else
ret = SendBuffered(ssl);
ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
done_a:
#ifdef CYASSL_SMALL_STACK
XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#endif /* HAVE_ECC */
@ -11691,6 +11714,7 @@ int DoSessionTicket(CYASSL* ssl,
preSigIdx = idx;
}
#endif
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
FreeRsaKey(&rsaKey);
@ -11811,14 +11835,14 @@ int DoSessionTicket(CYASSL* ssl,
#ifndef NO_RSA
if (ssl->suites->sigAlgo == rsa_sa_algo) {
byte* signBuffer = hash;
word32 signSz = sizeof(hash);
word32 signSz = FINISHED_SZ;
byte encodedSig[MAX_ENCODED_SIG_SZ];
byte doUserRsa = 0;
#ifdef HAVE_PK_CALLBACKS
if (ssl->ctx->RsaSignCb)
doUserRsa = 1;
#endif /*HAVE_PK_CALLBACKS */
#endif
if (IsAtLeastTLSv1_2(ssl)) {
byte* digest = &hash[MD5_DIGEST_SIZE];
@ -11848,33 +11872,31 @@ int DoSessionTicket(CYASSL* ssl,
#ifdef HAVE_PK_CALLBACKS
word32 ioLen = sigSz;
ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
output + idx,
&ioLen,
output + idx, &ioLen,
ssl->buffers.key.buffer,
ssl->buffers.key.length,
ssl->RsaSignCtx);
#endif /*HAVE_PK_CALLBACKS */
#endif
}
else {
else
ret = RsaSSL_Sign(signBuffer, signSz, output + idx,
sigSz, &rsaKey, ssl->rng);
}
FreeRsaKey(&rsaKey);
}
#endif
if (ret < 0)
return ret;
}
#endif
}
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
if (ssl->options.dtls)
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
return ret;
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
return ret;
#ifdef CYASSL_CALLBACKS
@ -11895,6 +11917,7 @@ int DoSessionTicket(CYASSL* ssl,
#endif /* NO_DH */
return ret;
#undef ERROR_OUT
}