DTLS fragmentation doesn't consider the additional data required with  
using encryption, so the packet size then exceeds the MTU when  
fragmentation is performed. This patch subtracts the size of the mac  
and the additional encryption bytes of the maximum possible length for  
a fragment, if necessary.

Thanks to Daniel Mentz for finding this bug.

Regards,
Robin


--- ssl/d1_both.c       1 Oct 2009 00:03:50 -0000       1.14.2.15
+++ ssl/d1_both.c       30 Oct 2009 15:16:40 -0000
@@ -177,7 +177,7 @@
        {
        int ret;
        int curr_mtu;
-       unsigned int len, frag_off;
+       unsigned int len, frag_off, mac_size, blocksize;

        /* AHA!  Figure out the MTU, and stick to the right size */
        if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
@@ -225,11 +225,22 @@
                OPENSSL_assert(s->init_num ==
                        (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);

+       if (s->write_hash)
+               mac_size = EVP_MD_CTX_size(s->write_hash);
+       else
+               mac_size = 0;
+
+       if (s->enc_write_ctx &&
+               (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & 
EVP_CIPH_CBC_MODE))
+               blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
+       else
+               blocksize = 0;
+
        frag_off = 0;
        while( s->init_num)
                {
                curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
-                       DTLS1_RT_HEADER_LENGTH;
+                       DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;

                if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
                        {
@@ -237,7 +248,8 @@
                        ret = BIO_flush(SSL_get_wbio(s));
                        if ( ret <= 0)
                                return ret;
-                       curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH;
+                       curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
+                               mac_size - blocksize;
                        }

                if ( s->init_num > curr_mtu)



Attachment: dtls-mtu-fragment-bug.patch
Description: Binary data

Reply via email to