On Wed, 2011-10-05 at 14:31 -0700, no_spam...@yahoo.com wrote:
> Are there plans for OpenSSL to adopt the 1/n-1 record splitting
> technique (credit Xuelei Fan) that the browsers appear to be using to
> mitigate the BEAST attack?
>  
> I realize that OpenSSL currently contains a different mitigation
> technique (sending empty fragments).  Evidently there are broken SSL
> implementations still in use that don't get along with this technique.

Here is an experimental patch written by me that implements the 1/n-1
record splitting technique for OpenSSL. Please test it if you're
interested.
-- 
Tomas Mraz
No matter how far down the wrong road you've gone, turn back.
                                              Turkish proverb
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