On Wed, 2011-10-05 at 14:31 -0700, [email protected] 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;