Skip to content

Commit 661eb46

Browse files
authored
Merge pull request #10117 from gasbytes/2025-03-31-dtls-and-tls-focused-fixes
Multiple DTLS and TLS focused fixes.
2 parents 3c87500 + c61f58d commit 661eb46

4 files changed

Lines changed: 93 additions & 16 deletions

File tree

src/dtls13.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ static int Dtls13SendFragmentedInternal(WOLFSSL* ssl)
10401040
fragLength + DTLS_HANDSHAKE_HEADER_SZ, isEncrypted);
10411041
if (outputSz < 0) {
10421042
Dtls13FreeFragmentsBuffer(ssl);
1043-
return recordLength;
1043+
return outputSz;
10441044
}
10451045

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

1105-
if (length < rlHeaderLength)
1105+
if (length < rlHeaderLength + DTLS_HANDSHAKE_HEADER_SZ)
11061106
return INCOMPLETE_DATA;
11071107

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

2215-
WOLFSSL_ENTER("Dtls13SetEpochKeys");
2215+
WOLFSSL_ENTER("Dtls13EpochCopyKeys");
22162216

22172217
clientWrite = serverWrite = 0;
22182218
enc = dec = 0;

src/tls13.c

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,13 @@ static const byte emptySHA512Hash[] = {
948948
0xF9, 0x27, 0xDA, 0x3E
949949
};
950950
#endif
951+
#ifdef WOLFSSL_SM3
952+
static const byte emptySM3Hash[] = {
953+
0x1A, 0xB2, 0x1D, 0x83, 0x55, 0xCF, 0xA1, 0x7F, 0x8E, 0x61, 0x19, 0x48,
954+
0x31, 0xE8, 0x1A, 0x8F, 0x22, 0xBE, 0xC8, 0xC7, 0x28, 0xFE, 0xFB, 0x74,
955+
0x7E, 0xD0, 0x35, 0xEB, 0x50, 0x82, 0xAA, 0x2B
956+
};
957+
#endif
951958
/**
952959
* Implement section 7.5 of RFC 8446
953960
* @return 0 on success
@@ -1003,6 +1010,17 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
10031010
emptyHash = emptySHA512Hash;
10041011
break;
10051012
#endif
1013+
1014+
#ifdef WOLFSSL_SM3
1015+
case sm3_mac:
1016+
hashType = WC_HASH_TYPE_SM3;
1017+
hashLen = WC_SM3_DIGEST_SIZE;
1018+
emptyHash = emptySM3Hash;
1019+
break;
1020+
#endif
1021+
1022+
default:
1023+
return BAD_FUNC_ARG;
10061024
}
10071025

10081026
/* Derive-Secret(Secret, label, "") */
@@ -2572,7 +2590,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
25722590
word16 sz, const byte* aad, word16 aadSz, int asyncOkay)
25732591
{
25742592
int ret = 0;
2575-
word16 dataSz = sz - ssl->specs.aead_mac_size;
2593+
word16 dataSz;
25762594
word16 macSz = ssl->specs.aead_mac_size;
25772595
word32 nonceSz = 0;
25782596
#ifdef WOLFSSL_ASYNC_CRYPT
@@ -2581,6 +2599,9 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
25812599
#endif
25822600

25832601
WOLFSSL_ENTER("EncryptTls13");
2602+
if (sz < ssl->specs.aead_mac_size)
2603+
return BUFFER_E;
2604+
dataSz = sz - ssl->specs.aead_mac_size;
25842605

25852606
(void)output;
25862607
(void)input;
@@ -4054,6 +4075,7 @@ static const WOLFSSL_EVP_MD* ssl_handshake_md(const byte mac_alg)
40544075
{
40554076
switch(mac_alg) {
40564077
case no_mac:
4078+
return NULL;
40574079
#ifndef NO_MD5
40584080
case md5_mac:
40594081
return wolfSSL_EVP_md5();
@@ -4161,6 +4183,8 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
41614183
#endif
41624184

41634185
/* Set the client identity to use. */
4186+
if (psk->identityLen > MAX_PSK_ID_LEN)
4187+
return PSK_KEY_ERROR;
41644188
XMEMSET(ssl->arrays->client_identity, 0,
41654189
sizeof(ssl->arrays->client_identity));
41664190
XMEMCPY(ssl->arrays->client_identity, psk->identity, psk->identityLen);
@@ -5997,7 +6021,7 @@ int FindPskSuite(const WOLFSSL* ssl, PreSharedKey* psk, byte* psk_key,
59976021
}
59986022
if (*found) {
59996023
if (*psk_keySz > MAX_PSK_KEY_LEN &&
6000-
*((int*)psk_keySz) != WC_NO_ERR_TRACE(USE_HW_PSK)) {
6024+
(int)*psk_keySz != WC_NO_ERR_TRACE(USE_HW_PSK)) {
60016025
WOLFSSL_MSG("Key len too long in FindPsk()");
60026026
ret = PSK_KEY_ERROR;
60036027
WOLFSSL_ERROR_VERBOSE(ret);
@@ -6337,6 +6361,8 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
63376361
client_hello, &bindersLen);
63386362
if (ret < 0)
63396363
return ret;
6364+
if (bindersLen > helloSz)
6365+
return BUFFER_ERROR;
63406366

63416367
/* Refine list for PSK processing. */
63426368
sslRefineSuites(ssl, clSuites);
@@ -6580,7 +6606,7 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
65806606
int ret;
65816607
byte sessIdSz;
65826608

6583-
ret = TlsCheckCookie(ssl, cookie->data, (byte)cookie->len);
6609+
ret = TlsCheckCookie(ssl, cookie->data, cookie->len);
65846610
if (ret < 0)
65856611
return ret;
65866612
cookieDataSz = (word16)ret;
@@ -9785,6 +9811,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
97859811
#ifndef NO_RSA
97869812
if (ssl->hsAltType == DYNAMIC_TYPE_RSA) {
97879813
/* build encoded signature buffer */
9814+
XFREE(rsaSigBuf->buffer, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
97889815
rsaSigBuf->length = WC_MAX_DIGEST_SIZE;
97899816
rsaSigBuf->buffer = (byte*)XMALLOC(rsaSigBuf->length,
97909817
ssl->heap,
@@ -11532,13 +11559,13 @@ static int SendTls13Finished(WOLFSSL* ssl)
1153211559
*/
1153311560
ret = DeriveFinishedSecret(ssl, ssl->clientSecret,
1153411561
ssl->keys.client_write_MAC_secret,
11535-
WOLFSSL_SERVER_END);
11562+
WOLFSSL_CLIENT_END);
1153611563
if (ret != 0)
1153711564
return ret;
1153811565

1153911566
ret = DeriveFinishedSecret(ssl, ssl->serverSecret,
1154011567
ssl->keys.server_write_MAC_secret,
11541-
WOLFSSL_CLIENT_END);
11568+
WOLFSSL_SERVER_END);
1154211569
if (ret != 0)
1154311570
return ret;
1154411571

@@ -11564,7 +11591,7 @@ static int SendTls13Finished(WOLFSSL* ssl)
1156411591
(word16)(Dtls13GetRlHeaderLength(ssl, 1) + headerSz + finishedSz), finished,
1156511592
1);
1156611593
if (dtlsRet != 0 && dtlsRet != WC_NO_ERR_TRACE(WANT_WRITE))
11567-
return ret;
11594+
return dtlsRet;
1156811595

1156911596
} else
1157011597
#endif /* WOLFSSL_DTLS13 */
@@ -12210,7 +12237,7 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
1221012237
word32 finishedSz = 0;
1221112238
byte mac[WC_MAX_DIGEST_SIZE];
1221212239
Digest digest;
12213-
static byte header[] = { 0x14, 0x00, 0x00, 0x00 };
12240+
byte header[] = { 0x14, 0x00, 0x00, 0x00 };
1221412241

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

@@ -12250,25 +12277,26 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl)
1225012277
ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret, mac,
1225112278
&finishedSz);
1225212279
if (ret != 0)
12253-
return ret;
12280+
goto restore;
1225412281
header[FINISHED_MSG_SIZE_OFFSET] = finishedSz;
1225512282
#ifdef WOLFSSL_EARLY_DATA
1225612283
if (ssl->earlyData != no_early_data) {
1225712284
static byte endOfEarlyData[] = { 0x05, 0x00, 0x00, 0x00 };
1225812285
ret = HashRaw(ssl, endOfEarlyData, sizeof(endOfEarlyData));
1225912286
if (ret != 0)
12260-
return ret;
12287+
goto restore;
1226112288
}
1226212289
#endif
1226312290
if ((ret = HashRaw(ssl, header, sizeof(header))) != 0)
12264-
return ret;
12291+
goto restore;
1226512292
if ((ret = HashRaw(ssl, mac, finishedSz)) != 0)
12266-
return ret;
12293+
goto restore;
1226712294

1226812295
if ((ret = DeriveResumptionSecret(ssl, ssl->session->masterSecret)) != 0)
12269-
return ret;
12296+
goto restore;
1227012297

1227112298
/* Restore the hash inline with currently seen messages. */
12299+
restore:
1227212300
switch (ssl->specs.mac_algorithm) {
1227312301
#ifndef NO_SHA256
1227412302
case sha256_mac:
@@ -13504,7 +13532,8 @@ int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1350413532
}
1350513533

1350613534
ret = EarlySanityCheckMsgReceived(ssl, type,
13507-
min(inputLength - HANDSHAKE_HEADER_SZ, size));
13535+
(inputLength > HANDSHAKE_HEADER_SZ) ?
13536+
min(inputLength - HANDSHAKE_HEADER_SZ, size) : 0);
1350813537
if (ret != 0) {
1350913538
WOLFSSL_ERROR(ret);
1351013539
return ret;
@@ -15352,6 +15381,8 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
1535215381
if (!IsAtLeastTLSv1_3(ssl->version))
1535315382
return BAD_FUNC_ARG;
1535415383

15384+
*outSz = 0;
15385+
1535515386
#ifndef NO_WOLFSSL_CLIENT
1535615387
if (ssl->options.side == WOLFSSL_SERVER_END)
1535715388
return SIDE_ERROR;

tests/api.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33047,6 +33047,46 @@ static int test_dtls13_missing_finished_server(void)
3304733047
return EXPECT_RESULT();
3304833048
}
3304933049

33050+
static int test_dtls13_finished_send_error_propagation(void)
33051+
{
33052+
EXPECT_DECLS;
33053+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
33054+
WOLFSSL_CTX *ctx_c = NULL;
33055+
WOLFSSL_CTX *ctx_s = NULL;
33056+
WOLFSSL *ssl_c = NULL;
33057+
WOLFSSL *ssl_s = NULL;
33058+
struct test_memio_ctx test_ctx;
33059+
33060+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
33061+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
33062+
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
33063+
33064+
/* CH1 */
33065+
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
33066+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
33067+
/* HRR */
33068+
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
33069+
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
33070+
/* CH2 */
33071+
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
33072+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
33073+
/* Server first flight with finished */
33074+
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
33075+
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
33076+
/* Client second flight with finished - block sends to force error */
33077+
test_ctx.s_len = TEST_MEMIO_BUF_SZ;
33078+
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
33079+
/* Verify the error is propagated, not silently swallowed as success */
33080+
ExpectIntNE(wolfSSL_get_error(ssl_c, -1), 0);
33081+
33082+
wolfSSL_free(ssl_c);
33083+
wolfSSL_free(ssl_s);
33084+
wolfSSL_CTX_free(ctx_c);
33085+
wolfSSL_CTX_free(ctx_s);
33086+
#endif
33087+
return EXPECT_RESULT();
33088+
}
33089+
3305033090

3305133091
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
3305233092
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
@@ -35390,6 +35430,7 @@ TEST_CASE testCases[] = {
3539035430
TEST_DECL(test_dtls12_missing_finished),
3539135431
TEST_DECL(test_dtls13_missing_finished_client),
3539235432
TEST_DECL(test_dtls13_missing_finished_server),
35433+
TEST_DECL(test_dtls13_finished_send_error_propagation),
3539335434
TEST_DTLS_DECLS,
3539435435
TEST_DECL(test_tls_multi_handshakes_one_record),
3539535436
TEST_DECL(test_write_dup),

tests/api/test_tls13.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,11 @@ int test_tls13_apis(void)
808808
/* invoking without session or psk cbs */
809809
ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
810810
sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(BAD_STATE_E));
811+
/* verify *outSz is initialized to 0 even on non-success paths */
812+
outSz = 42;
813+
ExpectIntEQ(wolfSSL_write_early_data(clientSsl, earlyData,
814+
sizeof(earlyData), &outSz), WC_NO_ERR_TRACE(BAD_STATE_E));
815+
ExpectIntEQ(outSz, 0);
811816
#endif
812817

813818
ExpectIntEQ(wolfSSL_read_early_data(NULL, earlyDataBuffer,

0 commit comments

Comments
 (0)