Additional TLS 1.3 return code checking.

This commit is contained in:
David Garske
2017-05-09 09:45:40 -07:00
parent e8cf4b5ff0
commit c47826cc8f

View File

@ -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,