@@ -10700,6 +10700,7 @@ static void AddFragHeaders(byte* output, word32 fragSz, word32 fragOffset,
1070010700}
1070110701#endif /* NO_CERTS */
1070210702
10703+
1070310704#if !defined(NO_WOLFSSL_SERVER) || \
1070410705 (!defined(NO_WOLFSSL_CLIENT) && !defined(NO_CERTS) && \
1070510706 !defined(WOLFSSL_NO_CLIENT_AUTH))
@@ -10745,7 +10746,13 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz,
1074510746 inputSz += HANDSHAKE_HEADER_SZ;
1074610747 rHdrSz = RECORD_HEADER_SZ;
1074710748 }
10748- maxFrag = wolfSSL_GetMaxFragSize(ssl, (int)inputSz);
10749+ maxFrag = wolfSSL_GetMaxPlaintextSize(ssl);
10750+ #ifdef WOLFSSL_DTLS
10751+ if (ssl->options.dtls) {
10752+ /* In DTLS the handshake header is per fragment */
10753+ maxFrag -= DTLS_HANDSHAKE_HEADER_SZ;
10754+ }
10755+ #endif
1074910756
1075010757 /* Make sure input is not the ssl output buffer as this
1075110758 * function doesn't handle that */
@@ -24793,9 +24800,12 @@ int SendCertificate(WOLFSSL* ssl)
2479324800 if (ssl->fragOffset != 0)
2479424801 length -= (ssl->fragOffset + headerSz);
2479524802
24796- maxFragment = MAX_RECORD_SIZE;
2479724803
24798- maxFragment = (word32)wolfSSL_GetMaxFragSize(ssl, (int)maxFragment);
24804+ maxFragment = (word32)wolfSSL_GetMaxPlaintextSize(ssl);
24805+ if (ssl->options.dtls)
24806+ maxFragment -= DTLS_HANDSHAKE_HEADER_SZ;
24807+ else
24808+ maxFragment -= HANDSHAKE_HEADER_SZ;
2479924809
2480024810 while (length > 0 && ret == 0) {
2480124811 byte* output = NULL;
@@ -25572,27 +25582,6 @@ int IsSCR(WOLFSSL* ssl)
2557225582}
2557325583
2557425584
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-
2559625585#if !defined(NO_TLS) && defined(WOLFSSL_TLS13) && \
2559725586 !defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS)
2559825587/*
@@ -25970,31 +25959,26 @@ int SendData(WOLFSSL* ssl, const void* data, size_t sz)
2597025959 }
2597125960#endif /* WOLFSSL_DTLS13 */
2597225961
25973- buffSz = wolfSSL_GetMaxFragSize(ssl, (word32)sz - sent);
25974-
2597525962 if (sent == (word32)sz) break;
2597625963
25977- #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)
25964+ buffSz = (word32)sz - sent;
25965+ outputSz = wolfSSL_GetRecordSize(ssl, (word32)sz - sent);
25966+ #if defined(WOLFSSL_DTLS)
2599025967 if (ssl->options.dtls) {
25991- byte cidSz = 0;
25992- if ((cidSz = DtlsGetCidTxSize(ssl)) > 0)
25993- outputSz += cidSz + 1; /* +1 for inner content type */
25968+ int mtu;
25969+ #if defined(WOLFSSL_DTLS_MTU)
25970+ mtu = ssl->dtlsMtuSz;
25971+ #else
25972+ mtu = MAX_MTU;
25973+ #endif
25974+ if (outputSz > mtu) {
25975+ ssl->error = DTLS_SIZE_ERROR;
25976+ return WOLFSSL_FATAL_ERROR;
25977+ }
2599425978 }
2599525979#endif
2599625980
25997- /* check for available size */
25981+ /* check for available size, it does also DTLS MTU checks */
2599825982 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
2599925983 return (ssl->error = ret);
2600025984
@@ -41811,53 +41795,100 @@ int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev)
4181141795
4181241796#endif /* WOLFSSL_ASYNC_CRYPT */
4181341797
41798+ /** Return the record size for sending payloadSz of data
41799+ * @param ssl WOLFSSL object containing ciphersuite information.
41800+ * @param payloadSz Size of data to be sent in record
41801+ * @return Record size for sending payloadSz of data
41802+ */
41803+ int wolfSSL_GetRecordSize(WOLFSSL *ssl, int payloadSz)
41804+ {
41805+ int recordSize;
41806+
41807+ if (IsEncryptionOn(ssl, 1)) {
41808+ recordSize = BuildMessage(ssl, NULL, 0, NULL, payloadSz, application_data,
41809+ 0, 1, 0, CUR_ORDER);
41810+ /* use a safe upper bound in case of error */
41811+ if (recordSize < 0) {
41812+ recordSize = payloadSz + DTLS_RECORD_HEADER_SZ
41813+ + cipherExtraData(ssl) + COMP_EXTRA;
41814+ }
41815+ }
41816+ else {
41817+ recordSize = payloadSz;
41818+ if (ssl->options.dtls) {
41819+ recordSize += DTLS_RECORD_HEADER_SZ;
41820+ }
41821+ else {
41822+ recordSize += RECORD_HEADER_SZ;
41823+ }
41824+
41825+ }
41826+ return recordSize;
41827+ }
41828+
41829+ /** Return the maximum plaintext size for the current MTU.
41830+ * @param ssl WOLFSSL object containing ciphersuite information.
41831+ * @return Max plaintext size for current MTU
41832+ */
41833+ int wolfSSL_GetMaxPlaintextSize(WOLFSSL *ssl)
41834+ {
41835+ int maxFrag;
41836+
41837+ maxFrag = wolfSSL_GetMaxFragSize(ssl);
4181441838
41839+ #if defined(WOLFSSL_DTLS)
41840+ if (ssl->options.dtls) {
41841+ int recordSize;
41842+ int mtu;
41843+
41844+ if (IsEncryptionOn(ssl, 1)) {
41845+ recordSize = BuildMessage(ssl, NULL, 0, NULL, maxFrag, handshake, 0, 1,
41846+ 0, CUR_ORDER);
41847+ /* use a safe upper bound in case of error */
41848+ if (recordSize < 0) {
41849+ recordSize = maxFrag + DTLS_RECORD_HEADER_SZ + cipherExtraData(ssl);
41850+ }
41851+ }
41852+ else {
41853+ recordSize = maxFrag + DTLS_RECORD_HEADER_SZ;
41854+ }
41855+ #if defined(WOLFSSL_DTLS_MTU)
41856+ mtu = ssl->dtlsMtuSz;
41857+ #else
41858+ mtu = DEFAULT_DTLS_MTU;
41859+ #endif
41860+ if (recordSize > mtu) {
41861+ maxFrag -= (recordSize - mtu);
41862+ }
41863+ #ifndef WOLFSSL_AEAD_ONLY
41864+ /* account for padding if using block cipher*/
41865+ if (ssl->specs.cipher_type == block)
41866+ maxFrag -= ssl->specs.block_size;
41867+ #endif
41868+ }
41869+ #endif /* WOLFSSL_DTLS */
41870+
41871+ return maxFrag;
41872+
41873+ }
4181541874/**
4181641875 * Return the max fragment size. This is essentially the maximum
4181741876 * fragment_length available.
4181841877 * @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.
4182141878 * @return Max fragment size
4182241879 */
41823- int wolfSSL_GetMaxFragSize(WOLFSSL* ssl, int maxFragment )
41880+ int wolfSSL_GetMaxFragSize(WOLFSSL* ssl)
4182441881{
4182541882 (void) ssl; /* Avoid compiler warnings */
41883+ int maxFragment;
4182641884
41827- if (maxFragment > MAX_RECORD_SIZE) {
41828- maxFragment = MAX_RECORD_SIZE;
41829- }
41885+ maxFragment = MAX_RECORD_SIZE;
4183041886
4183141887#ifdef HAVE_MAX_FRAGMENT
4183241888 if ((ssl->max_fragment != 0) && ((word16)maxFragment > ssl->max_fragment)) {
4183341889 maxFragment = ssl->max_fragment;
4183441890 }
4183541891#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
4186141892
4186241893 return maxFragment;
4186341894}
0 commit comments