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;

Reply via email to