forked from wolfSSL/wolfssl
Additional TLS 1.3 return code checking.
This commit is contained in:
136
src/tls13.c
136
src/tls13.c
@ -741,7 +741,8 @@ static int DeriveMasterSecret(WOLFSSL* ssl)
|
|||||||
* hash The hash result - verify data.
|
* hash The hash result - verify data.
|
||||||
* returns length of verify data generated.
|
* returns length of verify data generated.
|
||||||
*/
|
*/
|
||||||
static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash)
|
static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
|
||||||
|
word32* pHashSz)
|
||||||
{
|
{
|
||||||
Hmac verifyHmac;
|
Hmac verifyHmac;
|
||||||
int hashType = SHA256;
|
int hashType = SHA256;
|
||||||
@ -785,10 +786,11 @@ static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash)
|
|||||||
ret = wc_HmacFinal(&verifyHmac, hash);
|
ret = wc_HmacFinal(&verifyHmac, hash);
|
||||||
wc_HmacFree(&verifyHmac);
|
wc_HmacFree(&verifyHmac);
|
||||||
}
|
}
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return hashSz;
|
if (pHashSz)
|
||||||
|
*pHashSz = hashSz;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The length of the label to use when deriving keys. */
|
/* The length of the label to use when deriving keys. */
|
||||||
@ -1149,7 +1151,7 @@ end:
|
|||||||
*/
|
*/
|
||||||
static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
|
static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = BAD_FUNC_ARG;
|
||||||
|
|
||||||
#ifndef NO_OLD_TLS
|
#ifndef NO_OLD_TLS
|
||||||
#ifndef NO_SHA
|
#ifndef NO_SHA
|
||||||
@ -1751,9 +1753,13 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
|
|||||||
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
|
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
|
||||||
ssl->arrays->psk_keySz);
|
ssl->arrays->psk_keySz);
|
||||||
/* Derive the early secret using the PSK. */
|
/* Derive the early secret using the PSK. */
|
||||||
DeriveEarlySecret(ssl);
|
ret = DeriveEarlySecret(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
/* Derive the binder key to use to with HMAC. */
|
/* Derive the binder key to use to with HMAC. */
|
||||||
DeriveBinderKeyResume(ssl, binderKey);
|
ret = DeriveBinderKeyResume(ssl, binderKey);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* TODO: [TLS13] Support non-ticket PSK. */
|
/* TODO: [TLS13] Support non-ticket PSK. */
|
||||||
@ -1762,16 +1768,25 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
|
|||||||
(char *)current->identity, ssl->arrays->client_identity,
|
(char *)current->identity, ssl->arrays->client_identity,
|
||||||
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
|
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
|
||||||
/* Derive the early secret using the PSK. */
|
/* Derive the early secret using the PSK. */
|
||||||
DeriveEarlySecret(ssl);
|
ret = DeriveEarlySecret(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
/* Derive the binder key to use to with HMAC. */
|
/* Derive the binder key to use to with HMAC. */
|
||||||
DeriveBinderKey(ssl, binderKey);
|
ret = DeriveBinderKey(ssl, binderKey);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Finished message secret. */
|
/* Derive the Finished message secret. */
|
||||||
DeriveFinishedSecret(ssl, binderKey, ssl->keys.client_write_MAC_secret);
|
ret = DeriveFinishedSecret(ssl, binderKey, ssl->keys.client_write_MAC_secret);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Build the HMAC of the handshake message data = binder. */
|
/* Build the HMAC of the handshake message data = binder. */
|
||||||
current->binderLen = BuildTls13HandshakeHmac(ssl,
|
ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret,
|
||||||
ssl->keys.client_write_MAC_secret, current->binder);
|
current->binder, current->binderLen);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
@ -2288,9 +2303,13 @@ static int DoPreSharedKeys(WOLFSSL *ssl, const byte* input, word32 helloSz,
|
|||||||
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
|
XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
|
||||||
ssl->specs.hash_size);
|
ssl->specs.hash_size);
|
||||||
/* Derive the early secret using the PSK. */
|
/* Derive the early secret using the PSK. */
|
||||||
DeriveEarlySecret(ssl);
|
ret = DeriveEarlySecret(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
/* Derive the binder key to use to with HMAC. */
|
/* Derive the binder key to use to with HMAC. */
|
||||||
DeriveBinderKeyResume(ssl, binderKey);
|
ret = DeriveBinderKeyResume(ssl, binderKey);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* PSK age is always zero. */
|
/* PSK age is always zero. */
|
||||||
@ -2302,16 +2321,26 @@ static int DoPreSharedKeys(WOLFSSL *ssl, const byte* input, word32 helloSz,
|
|||||||
(char*)current->identity, ssl->arrays->client_identity,
|
(char*)current->identity, ssl->arrays->client_identity,
|
||||||
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
|
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
|
||||||
/* Derive the early secret using the PSK. */
|
/* Derive the early secret using the PSK. */
|
||||||
DeriveEarlySecret(ssl);
|
ret = DeriveEarlySecret(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
/* Derive the binder key to use to with HMAC. */
|
/* Derive the binder key to use to with HMAC. */
|
||||||
DeriveBinderKey(ssl, binderKey);
|
ret = DeriveBinderKey(ssl, binderKey);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derive the Finished message secret. */
|
/* Derive the Finished message secret. */
|
||||||
DeriveFinishedSecret(ssl, binderKey, ssl->keys.client_write_MAC_secret);
|
ret = DeriveFinishedSecret(ssl, binderKey,
|
||||||
|
ssl->keys.client_write_MAC_secret);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Derive the binder and compare with the one in the extension. */
|
/* Derive the binder and compare with the one in the extension. */
|
||||||
binderLen = BuildTls13HandshakeHmac(ssl,
|
ret = BuildTls13HandshakeHmac(ssl,
|
||||||
ssl->keys.client_write_MAC_secret, binder);
|
ssl->keys.client_write_MAC_secret, binder, &binderLen);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
if (binderLen != current->binderLen ||
|
if (binderLen != current->binderLen ||
|
||||||
XMEMCMP(binder, current->binder, binderLen) != 0) {
|
XMEMCMP(binder, current->binder, binderLen) != 0) {
|
||||||
return BAD_BINDER;
|
return BAD_BINDER;
|
||||||
@ -3048,38 +3077,51 @@ static int CreateECCEncodedSig(byte* sigData, int sigDataSz, int hashAlgo)
|
|||||||
{
|
{
|
||||||
Digest digest;
|
Digest digest;
|
||||||
int hashSz = 0;
|
int hashSz = 0;
|
||||||
|
int ret = BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* Digest the signature data. */
|
/* Digest the signature data. */
|
||||||
switch (hashAlgo) {
|
switch (hashAlgo) {
|
||||||
#ifndef NO_WOLFSSL_SHA256
|
#ifndef NO_WOLFSSL_SHA256
|
||||||
case sha256_mac:
|
case sha256_mac:
|
||||||
wc_InitSha256(&digest.sha256);
|
ret = wc_InitSha256(&digest.sha256);
|
||||||
wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
|
if (ret == 0) {
|
||||||
wc_Sha256Final(&digest.sha256, sigData);
|
ret = wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
|
||||||
wc_Sha256Free(&digest.sha256);
|
if (ret == 0)
|
||||||
|
ret = wc_Sha256Final(&digest.sha256, sigData);
|
||||||
|
wc_Sha256Free(&digest.sha256);
|
||||||
|
}
|
||||||
hashSz = SHA256_DIGEST_SIZE;
|
hashSz = SHA256_DIGEST_SIZE;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_SHA384
|
#ifdef WOLFSSL_SHA384
|
||||||
case sha384_mac:
|
case sha384_mac:
|
||||||
wc_InitSha384(&digest.sha384);
|
ret = wc_InitSha384(&digest.sha384);
|
||||||
wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
|
if (ret == 0) {
|
||||||
wc_Sha384Final(&digest.sha384, sigData);
|
ret = wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
|
||||||
wc_Sha384Free(&digest.sha384);
|
if (ret == 0)
|
||||||
|
ret = wc_Sha384Final(&digest.sha384, sigData);
|
||||||
|
wc_Sha384Free(&digest.sha384);
|
||||||
|
}
|
||||||
hashSz = SHA384_DIGEST_SIZE;
|
hashSz = SHA384_DIGEST_SIZE;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_SHA512
|
#ifdef WOLFSSL_SHA512
|
||||||
case sha512_mac:
|
case sha512_mac:
|
||||||
wc_InitSha512(&digest.sha512);
|
ret = wc_InitSha512(&digest.sha512);
|
||||||
wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
|
if (ret == 0) {
|
||||||
wc_Sha512Final(&digest.sha512, sigData);
|
ret = wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
|
||||||
wc_Sha512Free(&digest.sha512);
|
if (ret == 0)
|
||||||
|
ret = wc_Sha512Final(&digest.sha512, sigData);
|
||||||
|
wc_Sha512Free(&digest.sha512);
|
||||||
|
}
|
||||||
hashSz = SHA512_DIGEST_SIZE;
|
hashSz = SHA512_DIGEST_SIZE;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return hashSz;
|
return hashSz;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -3520,12 +3562,17 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
|
|||||||
sig->length = MAX_ENCODED_SIG_SZ;
|
sig->length = MAX_ENCODED_SIG_SZ;
|
||||||
sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap,
|
sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap,
|
||||||
DYNAMIC_TYPE_TMP_BUFFER);
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (sig->buffer == NULL)
|
if (sig->buffer == NULL) {
|
||||||
return MEMORY_E;
|
ERROR_OUT(MEMORY_E, exit_scv);
|
||||||
|
}
|
||||||
|
|
||||||
/* Digest the signature data and encode. Used in verify too. */
|
/* Digest the signature data and encode. Used in verify too. */
|
||||||
sig->length = CreateRSAEncodedSig(sig->buffer, args->sigData,
|
ret = CreateRSAEncodedSig(sig->buffer, args->sigData,
|
||||||
args->sigDataSz, ssl->suites->hashAlgo);
|
args->sigDataSz, ssl->suites->hashAlgo);
|
||||||
|
if (ret < 0)
|
||||||
|
goto exit_scv;
|
||||||
|
sig->length = ret;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
/* Maximum size of RSA Signature. */
|
/* Maximum size of RSA Signature. */
|
||||||
args->sigLen = args->length;
|
args->sigLen = args->length;
|
||||||
@ -3535,8 +3582,12 @@ int SendTls13CertificateVerify(WOLFSSL* ssl)
|
|||||||
if (ssl->hsType == DYNAMIC_TYPE_ECC) {
|
if (ssl->hsType == DYNAMIC_TYPE_ECC) {
|
||||||
sig->length = args->sendSz - args->idx - HASH_SIG_SIZE -
|
sig->length = args->sendSz - args->idx - HASH_SIG_SIZE -
|
||||||
VERIFY_HEADER;
|
VERIFY_HEADER;
|
||||||
args->sigDataSz = CreateECCEncodedSig(args->sigData,
|
ret = CreateECCEncodedSig(args->sigData,
|
||||||
args->sigDataSz, ssl->suites->hashAlgo);
|
args->sigDataSz, ssl->suites->hashAlgo);
|
||||||
|
if (ret < 0)
|
||||||
|
goto exit_scv;
|
||||||
|
args->sigDataSz = ret;
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_ECC */
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
@ -3845,8 +3896,12 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
|
CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
|
||||||
args->sigDataSz = CreateECCEncodedSig(args->sigData,
|
ret = CreateECCEncodedSig(args->sigData,
|
||||||
args->sigDataSz, args->hashAlgo);
|
args->sigDataSz, args->hashAlgo);
|
||||||
|
if (ret < 0)
|
||||||
|
goto exit_dcv;
|
||||||
|
args->sigDataSz = ret;
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4003,7 +4058,10 @@ static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
secret = ssl->keys.client_write_MAC_secret;
|
secret = ssl->keys.client_write_MAC_secret;
|
||||||
finishedSz = BuildTls13HandshakeHmac(ssl, secret, mac);
|
|
||||||
|
ret = BuildTls13HandshakeHmac(ssl, secret, mac, &finishedSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
if (size != finishedSz)
|
if (size != finishedSz)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
@ -4097,7 +4155,9 @@ int SendTls13Finished(WOLFSSL* ssl)
|
|||||||
|
|
||||||
secret = ssl->keys.server_write_MAC_secret;
|
secret = ssl->keys.server_write_MAC_secret;
|
||||||
}
|
}
|
||||||
BuildTls13HandshakeHmac(ssl, secret, &input[headerSz]);
|
ret = BuildTls13HandshakeHmac(ssl, secret, &input[headerSz], NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* This message is always encrypted. */
|
/* This message is always encrypted. */
|
||||||
sendSz = BuildTls13Message(ssl, output, outputSz, input,
|
sendSz = BuildTls13Message(ssl, output, outputSz, input,
|
||||||
|
Reference in New Issue
Block a user