Skip to content

Commit 0fa0fd2

Browse files
committed
(d)tls: refactor wolfSSL_GetMaxFragSize(), simplify length computations
1 parent e9f3bd5 commit 0fa0fd2

File tree

6 files changed

+133
-92
lines changed

6 files changed

+133
-92
lines changed

src/dtls13.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -979,31 +979,35 @@ static int Dtls13SendFragmentedInternal(WOLFSSL* ssl)
979979
{
980980
int fragLength, rlHeaderLength;
981981
int remainingSize, maxFragment;
982-
int recordLength;
982+
int recordLength, outputSz;
983983
byte isEncrypted;
984984
byte* output;
985985
int ret;
986986

987987
isEncrypted = Dtls13TypeIsEncrypted(
988988
(enum HandShakeType)ssl->dtls13FragHandshakeType);
989989
rlHeaderLength = Dtls13GetRlHeaderLength(ssl, isEncrypted);
990-
maxFragment = wolfSSL_GetMaxFragSize(ssl, MAX_RECORD_SIZE);
990+
maxFragment = wolfSSL_GetMaxPlaintextSize(ssl);
991991

992992
remainingSize = ssl->dtls13MessageLength - ssl->dtls13FragOffset;
993993

994994
while (remainingSize > 0) {
995995

996-
fragLength = maxFragment - rlHeaderLength - DTLS_HANDSHAKE_HEADER_SZ;
997-
998-
recordLength = maxFragment;
996+
fragLength = maxFragment - DTLS_HANDSHAKE_HEADER_SZ;
999997

1000998
if (fragLength > remainingSize) {
1001999
fragLength = remainingSize;
1002-
recordLength =
1003-
fragLength + rlHeaderLength + DTLS_HANDSHAKE_HEADER_SZ;
10041000
}
10051001

1006-
ret = CheckAvailableSize(ssl, recordLength + MAX_MSG_EXTRA);
1002+
recordLength = fragLength + rlHeaderLength + DTLS_HANDSHAKE_HEADER_SZ;
1003+
outputSz = wolfSSL_GetRecordSize(ssl,
1004+
fragLength + DTLS_HANDSHAKE_HEADER_SZ, isEncrypted);
1005+
if (outputSz < 0) {
1006+
Dtls13FreeFragmentsBuffer(ssl);
1007+
return recordLength;
1008+
}
1009+
1010+
ret = CheckAvailableSize(ssl, outputSz);
10071011
if (ret != 0) {
10081012
Dtls13FreeFragmentsBuffer(ssl);
10091013
return ret;
@@ -1025,7 +1029,7 @@ static int Dtls13SendFragmentedInternal(WOLFSSL* ssl)
10251029

10261030
ret = Dtls13SendOneFragmentRtx(ssl,
10271031
(enum HandShakeType)ssl->dtls13FragHandshakeType,
1028-
(word16)recordLength + MAX_MSG_EXTRA, output, (word32)recordLength, 0);
1032+
(word16)outputSz, output, (word32)recordLength, 0);
10291033
if (ret == WC_NO_ERR_TRACE(WANT_WRITE)) {
10301034
ssl->dtls13FragOffset += fragLength;
10311035
return ret;
@@ -2018,7 +2022,7 @@ int Dtls13HandshakeSend(WOLFSSL* ssl, byte* message, word16 outputSize,
20182022
return ret;
20192023
}
20202024

2021-
maxFrag = wolfSSL_GetMaxFragSize(ssl, MAX_RECORD_SIZE);
2025+
maxFrag = wolfSSL_GetMaxPlaintextSize(ssl);
20222026
maxLen = length;
20232027

20242028
if (handshakeType == key_update)

src/internal.c

Lines changed: 109 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10745,7 +10745,13 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
1074510745
inputSz += HANDSHAKE_HEADER_SZ;
1074610746
rHdrSz = RECORD_HEADER_SZ;
1074710747
}
10748-
maxFrag = wolfSSL_GetMaxFragSize(ssl, (int)inputSz);
10748+
maxFrag = wolfSSL_GetMaxPlaintextSize(ssl);
10749+
#ifdef WOLFSSL_DTLS
10750+
if (ssl->options.dtls) {
10751+
/* In DTLS the handshake header is per fragment */
10752+
maxFrag -= DTLS_HANDSHAKE_HEADER_SZ;
10753+
}
10754+
#endif
1074910755

1075010756
/* Make sure input is not the ssl output buffer as this
1075110757
* function doesn't handle that */
@@ -24793,9 +24799,12 @@ int SendCertificate(WOLFSSL* ssl)
2479324799
if (ssl->fragOffset != 0)
2479424800
length -= (ssl->fragOffset + headerSz);
2479524801

24796-
maxFragment = MAX_RECORD_SIZE;
2479724802

24798-
maxFragment = (word32)wolfSSL_GetMaxFragSize(ssl, (int)maxFragment);
24803+
maxFragment = (word32)wolfSSL_GetMaxPlaintextSize(ssl);
24804+
if (ssl->options.dtls)
24805+
maxFragment -= DTLS_HANDSHAKE_HEADER_SZ;
24806+
else
24807+
maxFragment -= HANDSHAKE_HEADER_SZ;
2479924808

2480024809
while (length > 0 && ret == 0) {
2480124810
byte* output = NULL;
@@ -25572,27 +25581,6 @@ int IsSCR(WOLFSSL* ssl)
2557225581
}
2557325582

2557425583

25575-
#ifdef WOLFSSL_DTLS
25576-
static int ModifyForMTU(WOLFSSL* ssl, int buffSz, int outputSz, int mtuSz)
25577-
{
25578-
int recordExtra = outputSz - buffSz;
25579-
25580-
(void)ssl;
25581-
25582-
if (recordExtra > 0 && outputSz > mtuSz) {
25583-
buffSz = mtuSz - recordExtra;
25584-
#ifndef WOLFSSL_AEAD_ONLY
25585-
/* Subtract a block size to be certain that returned fragment
25586-
* size won't get more padding. */
25587-
if (ssl->specs.cipher_type == block)
25588-
buffSz -= ssl->specs.block_size;
25589-
#endif
25590-
}
25591-
25592-
return buffSz;
25593-
}
25594-
#endif /* WOLFSSL_DTLS */
25595-
2559625584
#if !defined(NO_TLS) && defined(WOLFSSL_TLS13) && \
2559725585
!defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS)
2559825586
/*
@@ -25970,31 +25958,28 @@ int SendData(WOLFSSL* ssl, const void* data, size_t sz)
2597025958
}
2597125959
#endif /* WOLFSSL_DTLS13 */
2597225960

25973-
buffSz = wolfSSL_GetMaxFragSize(ssl, (word32)sz - sent);
25974-
2597525961
if (sent == (word32)sz) break;
2597625962

25963+
buffSz = (word32)sz - sent;
25964+
outputSz = wolfSSL_GetRecordSize(ssl, (word32)sz - sent, 1);
2597725965
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_DTLS_SIZE_CHECK)
25978-
if (ssl->options.dtls && ((size_t)buffSz < (word32)sz - sent)) {
25979-
error = DTLS_SIZE_ERROR;
25980-
ssl->error = error;
25981-
WOLFSSL_ERROR(error);
25982-
return error;
25983-
}
25984-
#endif
25985-
outputSz = buffSz + COMP_EXTRA + DTLS_RECORD_HEADER_SZ;
25986-
if (IsEncryptionOn(ssl, 1) || ssl->options.tls1_3)
25987-
outputSz += cipherExtraData(ssl);
25988-
25989-
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
2599025966
if (ssl->options.dtls) {
25991-
byte cidSz = 0;
25992-
if ((cidSz = DtlsGetCidTxSize(ssl)) > 0)
25993-
outputSz += cidSz + 1; /* +1 for inner content type */
25994-
}
25967+
int mtu;
25968+
#if defined(WOLFSSL_DTLS_MTU)
25969+
mtu = ssl->dtlsMtuSz;
25970+
#else
25971+
mtu = MAX_MTU;
2599525972
#endif
25973+
if (outputSz > mtu) {
25974+
error = DTLS_SIZE_ERROR;
25975+
ssl->error = error;
25976+
WOLFSSL_ERROR(error);
25977+
return error;
25978+
}
25979+
}
25980+
#endif /* WOLFSSL_DTLS && !WOLFSSL_NO_DTLS_SIZE_CHECK */
2599625981

25997-
/* check for available size */
25982+
/* check for available size, it does also DTLS MTU checks */
2599825983
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
2599925984
return (ssl->error = ret);
2600025985

@@ -41811,53 +41796,102 @@ int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev)
4181141796

4181241797
#endif /* WOLFSSL_ASYNC_CRYPT */
4181341798

41799+
#if !defined(NO_TLS)
41800+
/** Return the record size for sending payloadSz of data
41801+
* @param ssl WOLFSSL object
41802+
* @param payloadSz Size of data to be sent in record
41803+
* @param isEncrypted 1 if encryption is on, 0 if not
41804+
* @return Record size for sending payloadSz of data
41805+
*/
41806+
int wolfSSL_GetRecordSize(WOLFSSL *ssl, int payloadSz, int isEncrypted)
41807+
{
41808+
int recordSz;
41809+
41810+
if (ssl == NULL)
41811+
return BAD_FUNC_ARG;
41812+
41813+
if (isEncrypted) {
41814+
recordSz = BuildMessage(ssl, NULL, 0, NULL, payloadSz, application_data,
41815+
0, 1, 0, CUR_ORDER);
41816+
/* use a safe upper bound in case of error */
41817+
if (recordSz < 0) {
41818+
recordSz = payloadSz + DTLS_RECORD_HEADER_SZ
41819+
+ cipherExtraData(ssl) + COMP_EXTRA;
41820+
}
41821+
}
41822+
else {
41823+
recordSz = payloadSz;
41824+
if (ssl->options.dtls) {
41825+
recordSz += DTLS_RECORD_HEADER_SZ;
41826+
}
41827+
else {
41828+
recordSz += RECORD_HEADER_SZ;
41829+
}
41830+
41831+
}
41832+
return recordSz;
41833+
}
41834+
#endif
41835+
41836+
/** Return the maximum plaintext size for the current MTU.
41837+
* @param ssl WOLFSSL object containing ciphersuite information.
41838+
* @return Max plaintext size for current MTU
41839+
*/
41840+
int wolfSSL_GetMaxPlaintextSize(WOLFSSL *ssl)
41841+
{
41842+
int maxFrag;
41843+
41844+
if (ssl == NULL)
41845+
return BAD_FUNC_ARG;
41846+
41847+
maxFrag = wolfSSL_GetMaxFragSize(ssl);
41848+
41849+
#if defined(WOLFSSL_DTLS)
41850+
if (IsDtlsNotSctpMode(ssl)) {
41851+
int recordSz;
41852+
int mtu;
41853+
41854+
recordSz = wolfSSL_GetRecordSize(ssl, maxFrag, IsEncryptionOn(ssl, 1));
41855+
41856+
#if defined(WOLFSSL_DTLS_MTU)
41857+
mtu = ssl->dtlsMtuSz;
41858+
#else
41859+
mtu = MAX_MTU;
41860+
#endif
41861+
if (recordSz > mtu) {
41862+
maxFrag -= (recordSz - mtu);
41863+
}
41864+
#ifndef WOLFSSL_AEAD_ONLY
41865+
/* account for padding if using block cipher*/
41866+
if (ssl->specs.cipher_type == block)
41867+
maxFrag -= ssl->specs.block_size;
41868+
#endif
41869+
}
41870+
#endif /* WOLFSSL_DTLS */
41871+
41872+
return maxFrag;
4181441873

41874+
}
4181541875
/**
4181641876
* Return the max fragment size. This is essentially the maximum
4181741877
* fragment_length available.
4181841878
* @param ssl WOLFSSL object containing ciphersuite information.
41819-
* @param maxFragment The amount of space we want to check is available. This
41820-
* is only the fragment length WITHOUT the (D)TLS headers.
4182141879
* @return Max fragment size
4182241880
*/
41823-
int wolfSSL_GetMaxFragSize(WOLFSSL* ssl, int maxFragment)
41881+
int wolfSSL_GetMaxFragSize(WOLFSSL* ssl)
4182441882
{
41825-
(void) ssl; /* Avoid compiler warnings */
41883+
int maxFragment;
4182641884

41827-
if (maxFragment > MAX_RECORD_SIZE) {
41828-
maxFragment = MAX_RECORD_SIZE;
41829-
}
41885+
if (ssl == NULL)
41886+
return BAD_FUNC_ARG;
41887+
41888+
maxFragment = MAX_RECORD_SIZE;
4183041889

4183141890
#ifdef HAVE_MAX_FRAGMENT
4183241891
if ((ssl->max_fragment != 0) && ((word16)maxFragment > ssl->max_fragment)) {
4183341892
maxFragment = ssl->max_fragment;
4183441893
}
4183541894
#endif /* HAVE_MAX_FRAGMENT */
41836-
#ifdef WOLFSSL_DTLS
41837-
if (IsDtlsNotSctpMode(ssl)) {
41838-
int outputSz, mtuSz;
41839-
41840-
/* Given a input buffer size of maxFragment, how big will the
41841-
* encrypted output be? */
41842-
if (IsEncryptionOn(ssl, 1)) {
41843-
outputSz = BuildMessage(ssl, NULL, 0, NULL,
41844-
maxFragment + DTLS_HANDSHAKE_HEADER_SZ,
41845-
application_data, 0, 1, 0, CUR_ORDER);
41846-
}
41847-
else {
41848-
outputSz = maxFragment + DTLS_RECORD_HEADER_SZ +
41849-
DTLS_HANDSHAKE_HEADER_SZ;
41850-
}
41851-
41852-
/* Readjust maxFragment for MTU size. */
41853-
#if defined(WOLFSSL_DTLS_MTU)
41854-
mtuSz = ssl->dtlsMtuSz;
41855-
#else
41856-
mtuSz = MAX_MTU;
41857-
#endif
41858-
maxFragment = ModifyForMTU(ssl, maxFragment, outputSz, mtuSz);
41859-
}
41860-
#endif
4186141895

4186241896
return maxFragment;
4186341897
}

src/ssl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2905,7 +2905,7 @@ int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
29052905
return BAD_FUNC_ARG;
29062906
}
29072907

2908-
return wolfSSL_GetMaxFragSize(ssl, OUTPUT_RECORD_SIZE);
2908+
return min(OUTPUT_RECORD_SIZE, wolfSSL_GetMaxPlaintextSize(ssl));
29092909
}
29102910

29112911

src/tls13.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4522,7 +4522,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
45224522

45234523
{
45244524
#ifdef WOLFSSL_DTLS_CH_FRAG
4525-
word16 maxFrag = wolfSSL_GetMaxFragSize(ssl, MAX_RECORD_SIZE);
4525+
word16 maxFrag = wolfSSL_GetMaxPlaintextSize(ssl);
45264526
word16 lenWithoutExts = args->length;
45274527
#endif
45284528

@@ -8872,7 +8872,7 @@ static int SendTls13Certificate(WOLFSSL* ssl)
88728872
if (ssl->fragOffset != 0)
88738873
length -= (ssl->fragOffset + headerSz);
88748874

8875-
maxFragment = (word32)wolfSSL_GetMaxFragSize(ssl, MAX_RECORD_SIZE);
8875+
maxFragment = (word32)wolfSSL_GetMaxPlaintextSize(ssl);
88768876

88778877
extIdx = 0;
88788878

tests/api/test_dtls.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,11 +1559,11 @@ int test_dtls_mtu_fragment_headroom(void)
15591559
test_memio_clear_buffer(&test_ctx, 0);
15601560

15611561
/* Measure application-data record overhead. */
1562-
ExpectIntEQ(wolfSSL_write(ssl_c, "A", 1), 1);
1562+
ExpectIntEQ(wolfSSL_write(ssl_c, payload, 32), 32);
15631563
ExpectIntEQ(test_ctx.s_msg_count, 1);
15641564
recordLen = test_ctx.s_len;
1565-
ExpectIntGT(recordLen, 1);
1566-
overhead = recordLen - 1;
1565+
ExpectIntGT(recordLen, 32);
1566+
overhead = recordLen - 32;
15671567

15681568
/* Reset buffers before MTU-limited send. */
15691569
test_memio_clear_buffer(&test_ctx, 0);

wolfssl/internal.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6595,7 +6595,10 @@ WOLFSSL_LOCAL int VerifyClientSuite(word16 havePSK, byte cipherSuite0,
65956595
byte cipherSuite);
65966596

65976597
WOLFSSL_LOCAL int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length);
6598-
WOLFSSL_LOCAL int wolfSSL_GetMaxFragSize(WOLFSSL* ssl, int maxFragment);
6598+
WOLFSSL_LOCAL int wolfSSL_GetRecordSize(WOLFSSL *ssl, int payloadSz,
6599+
int isEncrypted);
6600+
WOLFSSL_LOCAL int wolfSSL_GetMaxPlaintextSize(WOLFSSL *ssl);
6601+
WOLFSSL_LOCAL int wolfSSL_GetMaxFragSize(WOLFSSL* ssl);
65996602

66006603
#if defined(WOLFSSL_IOTSAFE) && defined(HAVE_PK_CALLBACKS)
66016604
WOLFSSL_LOCAL IOTSAFE *wolfSSL_get_iotsafe_ctx(WOLFSSL *ssl);

0 commit comments

Comments
 (0)