Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/dtls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ static int Dtls13SendFragmentedInternal(WOLFSSL* ssl)
fragLength + DTLS_HANDSHAKE_HEADER_SZ, isEncrypted);
if (outputSz < 0) {
Dtls13FreeFragmentsBuffer(ssl);
return recordLength;
return outputSz;
}

ret = CheckAvailableSize(ssl, outputSz);
Expand Down Expand Up @@ -1102,7 +1102,7 @@ static int Dtls13SendFragmented(WOLFSSL* ssl, byte* message, word16 length,
isEncrypted = Dtls13TypeIsEncrypted(handshake_type);
rlHeaderLength = Dtls13GetRlHeaderLength(ssl, isEncrypted);

if (length < rlHeaderLength)
if (length < rlHeaderLength + DTLS_HANDSHAKE_HEADER_SZ)
return INCOMPLETE_DATA;

/* DTLSv1.3 do not consider fragmentation for hash transcript. Build the
Expand Down Expand Up @@ -2212,7 +2212,7 @@ static void Dtls13EpochCopyKeys(WOLFSSL* ssl, Dtls13Epoch* e, Keys* k, int side)
byte clientWrite, serverWrite;
byte enc, dec;

WOLFSSL_ENTER("Dtls13SetEpochKeys");
WOLFSSL_ENTER("Dtls13EpochCopyKeys");

clientWrite = serverWrite = 0;
enc = dec = 0;
Expand Down
57 changes: 44 additions & 13 deletions src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,13 @@ static const byte emptySHA512Hash[] = {
0xF9, 0x27, 0xDA, 0x3E
};
#endif
#ifdef WOLFSSL_SM3
static const byte emptySM3Hash[] = {
0x1A, 0xB2, 0x1D, 0x83, 0x55, 0xCF, 0xA1, 0x7F, 0x8E, 0x61, 0x19, 0x48,
0x31, 0xE8, 0x1A, 0x8F, 0x22, 0xBE, 0xC8, 0xC7, 0x28, 0xFE, 0xFB, 0x74,
0x7E, 0xD0, 0x35, 0xEB, 0x50, 0x82, 0xAA, 0x2B
};
#endif
/**
* Implement section 7.5 of RFC 8446
* @return 0 on success
Expand Down Expand Up @@ -1003,6 +1010,17 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
emptyHash = emptySHA512Hash;
break;
#endif

#ifdef WOLFSSL_SM3
case sm3_mac:
hashType = WC_HASH_TYPE_SM3;
hashLen = WC_SM3_DIGEST_SIZE;
emptyHash = emptySM3Hash;
break;
#endif

default:
return BAD_FUNC_ARG;
}

/* Derive-Secret(Secret, label, "") */
Expand Down Expand Up @@ -2572,7 +2590,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
word16 sz, const byte* aad, word16 aadSz, int asyncOkay)
{
int ret = 0;
word16 dataSz = sz - ssl->specs.aead_mac_size;
word16 dataSz;
word16 macSz = ssl->specs.aead_mac_size;
word32 nonceSz = 0;
#ifdef WOLFSSL_ASYNC_CRYPT
Expand All @@ -2581,6 +2599,9 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
#endif

WOLFSSL_ENTER("EncryptTls13");
if (sz < ssl->specs.aead_mac_size)
return BUFFER_E;
dataSz = sz - ssl->specs.aead_mac_size;

(void)output;
(void)input;
Expand Down Expand Up @@ -4054,6 +4075,7 @@ static const WOLFSSL_EVP_MD* ssl_handshake_md(const byte mac_alg)
{
switch(mac_alg) {
case no_mac:
return NULL;
#ifndef NO_MD5
case md5_mac:
return wolfSSL_EVP_md5();
Expand Down Expand Up @@ -4161,6 +4183,8 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
#endif

/* Set the client identity to use. */
if (psk->identityLen > MAX_PSK_ID_LEN)
return PSK_KEY_ERROR;
XMEMSET(ssl->arrays->client_identity, 0,
sizeof(ssl->arrays->client_identity));
XMEMCPY(ssl->arrays->client_identity, psk->identity, psk->identityLen);
Expand Down Expand Up @@ -5982,7 +6006,7 @@ int FindPskSuite(const WOLFSSL* ssl, PreSharedKey* psk, byte* psk_key,
}
if (*found) {
if (*psk_keySz > MAX_PSK_KEY_LEN &&
*((int*)psk_keySz) != WC_NO_ERR_TRACE(USE_HW_PSK)) {
(int)*psk_keySz != WC_NO_ERR_TRACE(USE_HW_PSK)) {
WOLFSSL_MSG("Key len too long in FindPsk()");
ret = PSK_KEY_ERROR;
WOLFSSL_ERROR_VERBOSE(ret);
Expand Down Expand Up @@ -6322,6 +6346,8 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
client_hello, &bindersLen);
if (ret < 0)
return ret;
if (bindersLen > helloSz)
return BUFFER_ERROR;

/* Refine list for PSK processing. */
sslRefineSuites(ssl, clSuites);
Expand Down Expand Up @@ -6564,7 +6590,7 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
int keyShareExt = 0;
int ret;

ret = TlsCheckCookie(ssl, cookie->data, (byte)cookie->len);
ret = TlsCheckCookie(ssl, cookie->data, cookie->len);
if (ret < 0)
return ret;
cookieDataSz = (word16)ret;
Expand Down Expand Up @@ -9741,6 +9767,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
#ifndef NO_RSA
if (ssl->hsAltType == DYNAMIC_TYPE_RSA) {
/* build encoded signature buffer */
XFREE(rsaSigBuf->buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
rsaSigBuf->length = WC_MAX_DIGEST_SIZE;
rsaSigBuf->buffer = (byte*)XMALLOC(rsaSigBuf->length,
ssl->heap,
Expand Down Expand Up @@ -11488,13 +11515,13 @@ static int SendTls13Finished(WOLFSSL* ssl)
*/
ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
ssl->keys.client_write_MAC_secret,
WOLFSSL_SERVER_END);
WOLFSSL_CLIENT_END);
if (ret != 0)
return ret;

ret = DeriveFinishedSecret(ssl, ssl->serverSecret,
ssl->keys.server_write_MAC_secret,
WOLFSSL_CLIENT_END);
WOLFSSL_SERVER_END);
if (ret != 0)
return ret;

Expand All @@ -11520,7 +11547,7 @@ static int SendTls13Finished(WOLFSSL* ssl)
(word16)(Dtls13GetRlHeaderLength(ssl, 1) + headerSz + finishedSz), finished,
1);
if (dtlsRet != 0 && dtlsRet != WC_NO_ERR_TRACE(WANT_WRITE))
return ret;
return dtlsRet;

} else
#endif /* WOLFSSL_DTLS13 */
Expand Down Expand Up @@ -12166,7 +12193,7 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
word32 finishedSz = 0;
byte mac[WC_MAX_DIGEST_SIZE];
Digest digest;
static byte header[] = { 0x14, 0x00, 0x00, 0x00 };
byte header[] = { 0x14, 0x00, 0x00, 0x00 };

XMEMSET(&digest, 0, sizeof(Digest));

Expand Down Expand Up @@ -12206,25 +12233,26 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret, mac,
&finishedSz);
if (ret != 0)
return ret;
goto restore;
header[FINISHED_MSG_SIZE_OFFSET] = finishedSz;
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData != no_early_data) {
static byte endOfEarlyData[] = { 0x05, 0x00, 0x00, 0x00 };
ret = HashRaw(ssl, endOfEarlyData, sizeof(endOfEarlyData));
if (ret != 0)
return ret;
goto restore;
}
#endif
if ((ret = HashRaw(ssl, header, sizeof(header))) != 0)
return ret;
goto restore;
if ((ret = HashRaw(ssl, mac, finishedSz)) != 0)
return ret;
goto restore;

if ((ret = DeriveResumptionSecret(ssl, ssl->session->masterSecret)) != 0)
return ret;
goto restore;

/* Restore the hash inline with currently seen messages. */
restore:
switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256
case sha256_mac:
Expand Down Expand Up @@ -13460,7 +13488,8 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
}

ret = EarlySanityCheckMsgReceived(ssl, type,
min(inputLength - HANDSHAKE_HEADER_SZ, size));
(inputLength > HANDSHAKE_HEADER_SZ) ?
min(inputLength - HANDSHAKE_HEADER_SZ, size) : 0);
if (ret != 0) {
WOLFSSL_ERROR(ret);
return ret;
Expand Down Expand Up @@ -15308,6 +15337,8 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
if (!IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;

*outSz = 0;

#ifndef NO_WOLFSSL_CLIENT
if (ssl->options.side == WOLFSSL_SERVER_END)
return SIDE_ERROR;
Expand Down
41 changes: 41 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -33050,6 +33050,46 @@ static int test_dtls13_missing_finished_server(void)
return EXPECT_RESULT();
}

static int test_dtls13_finished_send_error_propagation(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;

XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);

/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HRR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client second flight with finished - block sends to force error */
test_ctx.s_len = TEST_MEMIO_BUF_SZ;
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
/* Verify the error is propagated, not silently swallowed as success */
ExpectIntNE(wolfSSL_get_error(ssl_c, -1), 0);

wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}


#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
Expand Down Expand Up @@ -35393,6 +35433,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_dtls12_missing_finished),
TEST_DECL(test_dtls13_missing_finished_client),
TEST_DECL(test_dtls13_missing_finished_server),
TEST_DECL(test_dtls13_finished_send_error_propagation),
TEST_DTLS_DECLS,
TEST_DECL(test_tls_multi_handshakes_one_record),
TEST_DECL(test_write_dup),
Expand Down
5 changes: 5 additions & 0 deletions tests/api/test_tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,11 @@ int test_tls13_apis(void)
/* invoking without session or psk cbs */
ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(BAD_STATE_E));
/* verify *outSz is initialized to 0 even on non-success paths */
outSz = 42;
ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(BAD_STATE_E));
ExpectIntEQ(outSz, 0);
#endif

ExpectIntEQ(wolfSSL_read_early_data(NULL, earlyDataBuffer,
Expand Down
Loading