Here is an experimental patch I wrote that implements the 1/n-1
record splitting technique for OpenSSL. I am sending it here for
consideration by OpenSSL upstream developers.
By default the 0/n split is used but in case the
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS flag is set, we split the first
record with 1/n-1.
Tomas Mraz
diff -up openssl-1.0.0e/ssl/s3_both.c.beast openssl-1.0.0e/ssl/s3_both.c
--- openssl-1.0.0e/ssl/s3_both.c.beast 2010-03-25 00:16:49.000000000 +0100
+++ openssl-1.0.0e/ssl/s3_both.c 2011-10-13 14:05:50.000000000 +0200
@@ -758,15 +758,12 @@ int ssl3_setup_write_buffer(SSL *s)
if (s->s3->wbuf.buf == NULL)
{
len = s->max_send_fragment
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
- + headerlen + align;
+ + 2 * (SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ + headerlen + align);
#ifndef OPENSSL_NO_COMP
if (!(s->options & SSL_OP_NO_COMPRESSION))
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
- if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
- len += headerlen + align
- + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
goto err;
diff -up openssl-1.0.0e/ssl/s3_enc.c.beast openssl-1.0.0e/ssl/s3_enc.c
--- openssl-1.0.0e/ssl/s3_enc.c.beast 2011-09-07 14:00:41.000000000 +0200
+++ openssl-1.0.0e/ssl/s3_enc.c 2011-10-13 14:05:50.000000000 +0200
@@ -428,23 +428,20 @@ int ssl3_setup_key_block(SSL *s)
ret = ssl3_generate_key_block(s,p,num);
- if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ /* enable vulnerability countermeasure for CBC ciphers with
+ * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+ s->s3->need_empty_fragments = 1 + (s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ? 1 : 0);
+
+ if (s->session->cipher != NULL)
{
- /* enable vulnerability countermeasure for CBC ciphers with
- * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
- */
- s->s3->need_empty_fragments = 1;
+ if (s->session->cipher->algorithm_enc == SSL_eNULL)
+ s->s3->need_empty_fragments = 0;
- if (s->session->cipher != NULL)
- {
- if (s->session->cipher->algorithm_enc == SSL_eNULL)
- s->s3->need_empty_fragments = 0;
-
#ifndef OPENSSL_NO_RC4
- if (s->session->cipher->algorithm_enc == SSL_RC4)
- s->s3->need_empty_fragments = 0;
+ if (s->session->cipher->algorithm_enc == SSL_RC4)
+ s->s3->need_empty_fragments = 0;
#endif
- }
}
return ret;
diff -up openssl-1.0.0e/ssl/s3_pkt.c.beast openssl-1.0.0e/ssl/s3_pkt.c
--- openssl-1.0.0e/ssl/s3_pkt.c.beast 2011-05-25 17:21:12.000000000 +0200
+++ openssl-1.0.0e/ssl/s3_pkt.c 2011-10-13 14:05:50.000000000 +0200
@@ -685,7 +685,10 @@ static int do_ssl3_write(SSL *s, int typ
* this prepares and buffers the data for an empty fragment
* (these 'prefix_len' bytes are sent out later
* together with the actual payload) */
- prefix_len = do_ssl3_write(s, type, buf, 0, 1);
+ prefix_len = do_ssl3_write(s, type, buf,
+ s->s3->need_empty_fragments-1, 1);
+ buf += s->s3->need_empty_fragments-1;
+ len -= s->s3->need_empty_fragments-1;
if (prefix_len <= 0)
goto err;
diff -up openssl-1.0.0e/ssl/t1_enc.c.beast openssl-1.0.0e/ssl/t1_enc.c
--- openssl-1.0.0e/ssl/t1_enc.c.beast 2011-09-07 14:00:41.000000000 +0200
+++ openssl-1.0.0e/ssl/t1_enc.c 2011-10-13 14:07:55.000000000 +0200
@@ -608,23 +608,20 @@ printf("\nkey block\n");
{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
#endif
- if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ /* enable vulnerability countermeasure for CBC ciphers with
+ * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+ s->s3->need_empty_fragments = 1 + (s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ? 1 : 0);
+
+ if (s->session->cipher != NULL)
{
- /* enable vulnerability countermeasure for CBC ciphers with
- * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
- */
- s->s3->need_empty_fragments = 1;
+ if (s->session->cipher->algorithm_enc == SSL_eNULL)
+ s->s3->need_empty_fragments = 0;
- if (s->session->cipher != NULL)
- {
- if (s->session->cipher->algorithm_enc == SSL_eNULL)
- s->s3->need_empty_fragments = 0;
-
#ifndef OPENSSL_NO_RC4
- if (s->session->cipher->algorithm_enc == SSL_RC4)
- s->s3->need_empty_fragments = 0;
+ if (s->session->cipher->algorithm_enc == SSL_RC4)
+ s->s3->need_empty_fragments = 0;
#endif
- }
}
ret = 1;