Fragmentation for ServerKeyExchange and CeriticateVerify

- The `ssl->dtlsMtuSz` value is the maximum possible size of the DTLS record layer. We read `ssl->dtlsMtuSz + 100` in case peer has slightly different MTU set.
- The `-u` option in the examples takes the value of the MTU size.
- MTU tests are added in `tests/test-dtls-mtu.conf`
This commit is contained in:
Juliusz Sosinowicz
2021-04-12 20:02:18 +02:00
parent c6077b6767
commit 70a3857ae8
7 changed files with 2431 additions and 217 deletions

View File

@@ -1529,6 +1529,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
size_t throughput = 0;
int doDTLS = 0;
int dtlsUDP = 0;
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
defined(WOLFSSL_DTLS)
int dtlsMTU = 0;
#endif
int dtlsSCTP = 0;
int doMcast = 0;
int matchName = 0;
@@ -1713,7 +1717,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifndef WOLFSSL_VXWORKS
/* Not used: All used */
while ((ch = mygetopt(argc, argv, "?:"
"ab:c:defgh:i;jk:l:mnop:q:rstuv:wxyz"
"ab:c:defgh:i;jk:l:mnop:q:rstu;v:wxyz"
"A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:"
"01:23:45689"
"@#")) != -1) {
@@ -1753,6 +1757,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
case 'u' :
doDTLS = 1;
dtlsUDP = 1;
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
defined(WOLFSSL_DTLS)
dtlsMTU = atoi(myoptarg);
#endif
break;
case 'G' :
@@ -2493,6 +2501,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (fewerPackets)
wolfSSL_CTX_set_group_messages(ctx);
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
defined(WOLFSSL_DTLS)
if (dtlsMTU)
wolfSSL_CTX_dtls_set_mtu(ctx, dtlsMTU);
#endif
#ifndef NO_DH
if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits)

View File

@@ -1027,6 +1027,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
int useAnon = 0;
int doDTLS = 0;
int dtlsUDP = 0;
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
defined(WOLFSSL_DTLS)
int dtlsMTU = 0;
#endif
int dtlsSCTP = 0;
int doMcast = 0;
#ifdef WOLFSSL_DTLS
@@ -1220,7 +1224,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
/* Not Used: h, z, W, X, 7, 9 */
while ((ch = mygetopt(argc, argv, "?:"
"abc:defgijk:l:mnop:q:rstuv:wxy"
"abc:defgijk:l:mnop:q:rstu;v:wxy"
"A:B:C:D:E:FGH:IJKL:MNO:PQR:S:T;UVYZ:"
"01:23:4:5689"
"@#")) != -1) {
@@ -1268,6 +1272,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
case 'u' :
doDTLS = 1;
dtlsUDP = 1;
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
defined(WOLFSSL_DTLS)
dtlsMTU = atoi(myoptarg);
#endif
break;
case 'G' :
@@ -1884,6 +1892,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
if (fewerPackets)
wolfSSL_CTX_set_group_messages(ctx);
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
defined(WOLFSSL_DTLS)
if (dtlsMTU)
wolfSSL_CTX_dtls_set_mtu(ctx, dtlsMTU);
#endif
#ifdef WOLFSSL_SCTP
if (dtlsSCTP)

View File

@@ -174,6 +174,8 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
#endif
#endif
static int cipherExtraData(WOLFSSL* ssl);
#ifdef WOLFSSL_DTLS
static WC_INLINE int DtlsCheckWindow(WOLFSSL* ssl);
static WC_INLINE int DtlsUpdateWindow(WOLFSSL* ssl);
@@ -5849,7 +5851,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#endif
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
ssl->dtlsMtuSz = ctx->dtlsMtuSz;
ssl->dtls_expected_rx = ssl->dtlsMtuSz;
/* Add 100 bytes so that we can operate with slight difference
* in set MTU size on each peer */
ssl->dtls_expected_rx = ssl->dtlsMtuSz + 100;
#else
ssl->dtls_expected_rx = MAX_MTU;
#endif
@@ -7554,7 +7558,7 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket)
input = pool->buf;
inputSz = pool->sz;
sendSz = inputSz + MAX_MSG_EXTRA;
sendSz = inputSz + cipherExtraData(ssl);
#ifdef HAVE_SECURE_RENEGOTIATION
/*
@@ -8144,6 +8148,162 @@ static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
AddHandShakeHeader(output + outputAdj, length, fragOffset, fragSz, type, ssl);
}
#endif /* NO_CERTS */
/**
* Send the handshake message. This funcion handles fragmenting the message
* so that it will fit into the desired MTU or the max fragment size.
* @param ssl Connection object
* @param input Input starting at the record layer header. This function
* assumes that the appropriate record and handshake headers
* are present. These headers must assume no fragmentation.
* That is handled here.
* @param inputSz Length of message excluding headers (this is the total
* length of all fragments)
* @param type Type of message being sent
* @return 0 on success and negative otherwise
*/
static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
enum HandShakeType type, const char* packetName)
{
int maxFrag;
int ret = 0;
int headerSz;
WOLFSSL_ENTER("SendHandshakeMsg");
(void)type;
(void)packetName;
if (ssl == NULL || input == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls)
headerSz = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
else
#endif
{
/* In TLS we send one handshake header in total, not one
* per fragment like in DTLS. The handshake header should
* already be in the input buffer. */
inputSz += HANDSHAKE_HEADER_SZ;
headerSz = RECORD_HEADER_SZ;
}
maxFrag = wolfSSL_GetMaxRecordSize(ssl, (int)inputSz);
/* Make sure input is not the ssl output buffer as this
* function doesn't handle that */
if (input >= ssl->buffers.outputBuffer.buffer &&
input <= ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.bufferSize) {
WOLFSSL_MSG("Can't use output buffer for input in SendHandshakeMsg");
return BAD_FUNC_ARG;
}
if (ssl->fragOffset == 0) {
/* Hash it before the loop as we modify the input with
* encryption on */
ret = HashOutput(ssl, input, headerSz + (int)inputSz, 0);
if (ret != 0)
return ret;
#ifdef WOLFSSL_DTLS
/* Decrement msg number so that we continue to use the
* same msg number for this msg */
if (ssl->options.dtls)
ssl->keys.dtls_handshake_number--;
#endif
}
while (ssl->fragOffset < inputSz) {
byte* output;
int outputSz;
byte* data = input + ssl->fragOffset + headerSz;
word32 fragSz = (word32)maxFrag;
if (inputSz - ssl->fragOffset < fragSz)
fragSz = inputSz - ssl->fragOffset;
/* check for available size */
outputSz = headerSz + fragSz;
if (IsEncryptionOn(ssl, 1))
outputSz += cipherExtraData(ssl);
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
return ret;
output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* scan-build complains that this may be null */
if (output == NULL)
return MEMORY_E;
if (IsEncryptionOn(ssl, 1)) {
/* First we need to add the fragment header ourselves.
* We do this in the input to minimize allocations */
int dataSz = (int)fragSz;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
data -= DTLS_HANDSHAKE_HEADER_SZ;
dataSz += DTLS_HANDSHAKE_HEADER_SZ;
AddHandShakeHeader(data,
inputSz, ssl->fragOffset, fragSz, type, ssl);
}
if (ssl->options.dtls)
ssl->keys.dtls_handshake_number--;
if (IsDtlsNotSctpMode(ssl) &&
(ret = DtlsMsgPoolSave(ssl, data,
fragSz + DTLS_HANDSHAKE_HEADER_SZ, type))
!= 0)
return ret;
#endif
ret = BuildMessage(ssl, output, outputSz,
data, dataSz, handshake, 0, 0, 0, CUR_ORDER);
if (ret >= 0)
outputSz = ret;
else
return ret;
ret = 0;
}
else {
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls)
AddFragHeaders(output, fragSz, ssl->fragOffset,
inputSz, type, ssl);
else
#endif
AddRecordHeader(output, fragSz, handshake, ssl, CUR_ORDER);
XMEMCPY(output + headerSz, data, fragSz);
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
ssl->keys.dtls_handshake_number--;
DtlsSEQIncrement(ssl, CUR_ORDER);
}
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl, output, headerSz + fragSz,
type)) != 0) {
return ret;
}
}
#endif
}
ssl->buffers.outputBuffer.length += outputSz;
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
if (ssl->hsInfoOn) {
AddPacketName(ssl, packetName);
}
if (ssl->toInfoOn) {
AddPacketInfo(ssl, packetName, handshake,
output, outputSz, WRITE_PROTO, ssl->heap);
}
#endif
ssl->fragOffset += fragSz;
if (!ssl->options.groupMessages)
ret = SendBuffered(ssl);
if (ret != 0)
return ret;
}
#ifdef WOLFSSL_DTLS
/* Increment msg number once we sent all fragments */
if (ssl->options.dtls)
ssl->keys.dtls_handshake_number++;
#endif
ssl->fragOffset = 0;
return ret;
}
#endif /* !WOLFSSL_NO_TLS12 */
@@ -8509,14 +8669,31 @@ int CheckAvailableSize(WOLFSSL *ssl, int size)
}
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls &&
size + ssl->buffers.outputBuffer.length -
ssl->buffers.outputBuffer.idx > ssl->dtls_expected_rx) {
int ret;
WOLFSSL_MSG("CheckAvailableSize() flushing buffer "
"to make room for new message");
if ((ret = SendBuffered(ssl)) != 0) {
return ret;
if (ssl->options.dtls) {
if (size + ssl->buffers.outputBuffer.length -
ssl->buffers.outputBuffer.idx >
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
ssl->dtlsMtuSz
#else
ssl->dtls_expected_rx
#endif
) {
int ret;
WOLFSSL_MSG("CheckAvailableSize() flushing buffer "
"to make room for new message");
if ((ret = SendBuffered(ssl)) != 0) {
return ret;
}
}
if (size > (int)
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
ssl->dtlsMtuSz
#else
ssl->dtls_expected_rx
#endif
) {
WOLFSSL_MSG("CheckAvailableSize() called with size greater than MTU.");
return DTLS_SIZE_ERROR;
}
}
#endif
@@ -25031,14 +25208,12 @@ int SendCertificateVerify(WOLFSSL* ssl)
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_scv;
}
/* get output buffer */
args->output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* Use tmp buffer */
args->input = (byte*)XMALLOC(args->sendSz,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL)
ERROR_OUT(MEMORY_E, exit_scv);
args->output = args->input;
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_BUILD;
@@ -25328,32 +25503,6 @@ int SendCertificateVerify(WOLFSSL* ssl)
AddHeaders(args->output, (word32)args->length + args->extraSz +
VERIFY_HEADER, certificate_verify, ssl);
args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
(word32)args->length + args->extraSz + VERIFY_HEADER;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
args->sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
}
#endif
if (IsEncryptionOn(ssl, 1)) {
int recordHeaderSz = RECORD_HEADER_SZ;
if (ssl->options.dtls)
recordHeaderSz += DTLS_RECORD_EXTRA;
args->inputSz = args->sendSz - recordHeaderSz;
/* build msg adds rec hdr */
args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL) {
ERROR_OUT(MEMORY_E, exit_scv);
}
XMEMCPY(args->input, args->output + recordHeaderSz,
args->inputSz);
}
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_END;
} /* case TLS_ASYNC_FINALIZE */
@@ -25361,59 +25510,11 @@ int SendCertificateVerify(WOLFSSL* ssl)
case TLS_ASYNC_END:
{
if (IsEncryptionOn(ssl, 1)) {
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl) &&
(ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, certificate_verify)) != 0) {
goto exit_scv;
}
#endif
ret = BuildMessage(ssl, args->output,
MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
args->input, args->inputSz, handshake,
1, 0, 1, CUR_ORDER);
#ifdef WOLFSSL_ASYNC_CRYPT
if (ret == WC_PENDING_E)
goto exit_scv;
#endif
XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
args->input = NULL; /* make sure its not double free'd on cleanup */
if (ret >= 0) {
args->sendSz = ret;
ret = 0;
}
}
else {
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
ret = DtlsMsgPoolSave(ssl, args->output, args->sendSz, certificate_verify);
}
if (ret == 0 && ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
if (ret == 0)
ret = HashOutput(ssl, args->output, args->sendSz, 0);
}
if (ret != 0) {
ret = SendHandshakeMsg(ssl, args->output, (word32)args->length + args->extraSz +
VERIFY_HEADER, certificate_verify, "CertificateVerify");
if (ret != 0)
goto exit_scv;
}
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
if (ssl->hsInfoOn)
AddPacketName(ssl, "CertificateVerify");
if (ssl->toInfoOn)
AddPacketInfo(ssl, "CertificateVerify", handshake,
args->output, args->sendSz, WRITE_PROTO, ssl->heap);
#endif
ssl->buffers.outputBuffer.length += args->sendSz;
if (!ssl->options.groupMessages) {
ret = SendBuffered(ssl);
}
break;
}
default:
@@ -26306,14 +26407,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
}
/* get output buffer */
args->output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* Use tmp buffer */
args->input = (byte*)XMALLOC(args->sendSz,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL)
ERROR_OUT(MEMORY_E, exit_sske);
args->output = args->input;
AddHeaders(args->output, args->length,
server_key_exchange, ssl);
@@ -26369,14 +26468,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
}
/* get output buffer */
args->output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* Use tmp buffer */
args->input = (byte*)XMALLOC(args->sendSz,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL)
ERROR_OUT(MEMORY_E, exit_sske);
args->output = args->input;
AddHeaders(args->output, args->length,
server_key_exchange, ssl);
@@ -26487,14 +26584,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
}
/* get output buffer */
args->output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* Use tmp buffer */
args->input = (byte*)XMALLOC(args->sendSz,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL)
ERROR_OUT(MEMORY_E, exit_sske);
args->output = args->input;
/* key data */
c16toa((word16)hintLen, args->output + args->idx);
@@ -26689,14 +26784,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
}
/* get output buffer */
args->output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* Use tmp buffer */
args->input = (byte*)XMALLOC(args->sendSz,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL)
ERROR_OUT(MEMORY_E, exit_sske);
args->output = args->input;
/* record and message headers will be added below, when we're sure
of the sig length */
@@ -26933,14 +27026,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
args->sendSz += MAX_MSG_EXTRA;
}
/* check for available size */
if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
goto exit_sske;
}
/* get output buffer */
args->output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
/* Use tmp buffer */
args->input = (byte*)XMALLOC(args->sendSz,
ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL)
ERROR_OUT(MEMORY_E, exit_sske);
args->output = args->input;
AddHeaders(args->output, args->length,
server_key_exchange, ssl);
@@ -27449,73 +27540,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
if (IsEncryptionOn(ssl, 1)) {
args->inputSz = args->length + HANDSHAKE_HEADER_SZ;
if (ssl->options.dtls)
args->inputSz += DTLS_HANDSHAKE_EXTRA;
args->input = (byte*)XMALLOC(args->inputSz, ssl->heap,
DYNAMIC_TYPE_IN_BUFFER);
if (args->input == NULL) {
ERROR_OUT(MEMORY_E, exit_sske);
}
if (args->output == NULL) {
ERROR_OUT(BUFFER_ERROR, exit_sske);
}
if (!ssl->options.dtls)
XMEMCPY(args->input, args->output + RECORD_HEADER_SZ,
args->inputSz);
else
XMEMCPY(args->input, args->output + DTLS_RECORD_HEADER_SZ,
args->inputSz);
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl) &&
(ret = DtlsMsgPoolSave(ssl, args->input, args->inputSz, server_key_exchange))
!= 0) {
goto exit_sske;
}
#endif
ret = BuildMessage(ssl, args->output, args->sendSz,
args->input, args->inputSz, handshake, 1, 0, 0, CUR_ORDER);
XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
args->input = NULL;
/* make sure its not double free'd on cleanup */
if (ret >= 0) {
args->sendSz = ret;
ret = 0;
}
}
else {
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
if ((ret = DtlsMsgPoolSave(ssl,
args->output, args->sendSz, server_key_exchange)) != 0) {
goto exit_sske;
}
}
if (ssl->options.dtls)
DtlsSEQIncrement(ssl, CUR_ORDER);
#endif
ret = HashOutput(ssl, args->output, args->sendSz, 0);
if (ret != 0) {
goto exit_sske;
}
}
#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
if (ssl->hsInfoOn) {
AddPacketName(ssl, "ServerKeyExchange");
}
if (ssl->toInfoOn) {
AddPacketInfo(ssl, "ServerKeyExchange", handshake,
args->output, args->sendSz, WRITE_PROTO, ssl->heap);
}
#endif
ret = SendHandshakeMsg(ssl, args->output, args->length,
server_key_exchange, "ServerKeyExchange");
if (ret != 0)
goto exit_sske;
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_END;
@@ -27524,11 +27552,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case TLS_ASYNC_END:
{
ssl->buffers.outputBuffer.length += args->sendSz;
if (!ssl->options.groupMessages) {
ret = SendBuffered(ssl);
}
ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
break;
}
@@ -31621,22 +31644,20 @@ int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment)
#endif /* HAVE_MAX_FRAGMENT */
#ifdef WOLFSSL_DTLS
if (IsDtlsNotSctpMode(ssl)) {
int cipherExtra = IsEncryptionOn(ssl, 1) ? cipherExtraData(ssl) : 0;
if (maxFragment > MAX_UDP_SIZE) {
maxFragment = MAX_UDP_SIZE;
}
if (maxFragment > MAX_MTU - COMP_EXTRA - DTLS_RECORD_HEADER_SZ -
DTLS_HANDSHAKE_HEADER_SZ) {
DTLS_HANDSHAKE_HEADER_SZ - cipherExtra) {
maxFragment = MAX_MTU - COMP_EXTRA - DTLS_RECORD_HEADER_SZ -
DTLS_HANDSHAKE_HEADER_SZ;
DTLS_HANDSHAKE_HEADER_SZ - cipherExtra;
}
#if defined(WOLFSSL_DTLS_MTU)
{
int overheadSz = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ +
COMP_EXTRA;
if (IsEncryptionOn(ssl, 1))
overheadSz += cipherExtraData(ssl);
if (maxFragment >
ssl->dtlsMtuSz - overheadSz) {
COMP_EXTRA + cipherExtra;
if (maxFragment > ssl->dtlsMtuSz - overheadSz) {
maxFragment = ssl->dtlsMtuSz - overheadSz;
}
}

View File

@@ -2043,7 +2043,9 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
if (ssl->options.dtlsSctp)
#endif
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz);
/* Add 100 bytes so that we can operate with slight difference
* in set MTU size on each peer */
ssl->dtls_expected_rx = max(ssl->dtls_expected_rx, ssl->dtlsMtuSz + 100);
#endif
}
#endif

View File

@@ -33,6 +33,7 @@ EXTRA_DIST += tests/test.conf \
tests/test-dtls-fails.conf \
tests/test-dtls-fails-cipher.conf \
tests/test-dtls-group.conf \
tests/test-dtls-mtu.conf \
tests/test-dtls-reneg-client.conf \
tests/test-dtls-reneg-server.conf \
tests/test-dtls-resume.conf \

View File

@@ -978,6 +978,19 @@ int SuiteTest(int argc, char** argv)
goto exit;
}
#endif
#ifdef WOLFSSL_DTLS_MTU
/* Add dtls different MTU size tests.
* These also use grouping to force wolfSSL to
* bounce off the MTU limit more */
strcpy(argv0[1], "tests/test-dtls-mtu.conf");
printf("starting dtls MTU tests\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
args.return_code = EXIT_FAILURE;
goto exit;
}
#endif
#ifdef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES
/* add dtls extra suites */
strcpy(argv0[1], "tests/test-dtls-sha2.conf");

2151
tests/test-dtls-mtu.conf Normal file

File diff suppressed because it is too large Load Diff