@@ -41862,13 +41862,39 @@ int wolfSSL_GetMaxPlaintextSize(WOLFSSL *ssl)
4186241862#else
4186341863 mtu = MAX_MTU;
4186441864#endif
41865- if (recordSz > mtu) {
41866- maxFrag -= (recordSz - mtu);
41865+
41866+ recordSz = wolfssl_i_GetRecordSize(ssl, maxFrag, IsEncryptionOn(ssl, 1));
41867+ /* record size of maxFrag fits in MTU */
41868+ if (recordSz <= mtu) {
41869+ return maxFrag;
4186741870 }
41871+
41872+ /* adjust plaintext size to fit in MTU */
41873+ maxFrag -= (recordSz - mtu);
41874+ if (maxFrag <= 0) {
41875+ WOLFSSL_MSG("MTU too small for any plaintext");
41876+ return DTLS_SIZE_ERROR;
41877+ }
41878+
4186841879#ifndef WOLFSSL_AEAD_ONLY
41869- /* account for padding if using block cipher*/
41870- if (ssl->specs.cipher_type == block)
41871- maxFrag -= ssl->specs.block_size;
41880+ /* For block ciphers, reducing maxFrag may change padding alignment,
41881+ * causing the record to still exceed MTU. Iterate to find exact fit.
41882+ * Converges in at most 2 iterations due to bounded padding variance. */
41883+ if (ssl->specs.cipher_type == block) {
41884+ int iter;
41885+ for (iter = 0; iter < 2; iter++) {
41886+ recordSz = wolfssl_i_GetRecordSize(ssl, maxFrag,
41887+ IsEncryptionOn(ssl, 1));
41888+ if (recordSz <= mtu)
41889+ break;
41890+ maxFrag -= (recordSz - mtu);
41891+ }
41892+ if (recordSz > mtu) {
41893+ /* this should never happen */
41894+ WOLFSSL_MSG("Failed to fit record in MTU after padding adjust");
41895+ return DTLS_SIZE_ERROR;
41896+ }
41897+ }
4187241898#endif
4187341899 }
4187441900#endif /* WOLFSSL_DTLS */
0 commit comments