@@ -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}
0 commit comments