summaryrefslogtreecommitdiffstats
path: root/lib/libssl/t1_enc.c
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2017-03-07 13:37:03 +0000
committerjsing <jsing@openbsd.org>2017-03-07 13:37:03 +0000
commit9ce461170e6b6421ac4d1f32cfd03603bb681c33 (patch)
treeb762be680956fbe9a349ef22f38d36be0535eb9d /lib/libssl/t1_enc.c
parentfix spacing after empty .Fl (diff)
downloadwireguard-openbsd-9ce461170e6b6421ac4d1f32cfd03603bb681c33.tar.xz
wireguard-openbsd-9ce461170e6b6421ac4d1f32cfd03603bb681c33.zip
Correctly handle TLS PRF with MD5+SHA1 - the secret has to be partitioned
and each hash processed separately. Tested by tb@
Diffstat (limited to 'lib/libssl/t1_enc.c')
-rw-r--r--lib/libssl/t1_enc.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/lib/libssl/t1_enc.c b/lib/libssl/t1_enc.c
index 84f2e182d9e..ac037478d63 100644
--- a/lib/libssl/t1_enc.c
+++ b/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_enc.c,v 1.98 2017/03/06 15:08:57 jsing Exp $ */
+/* $OpenBSD: t1_enc.c,v 1.99 2017/03/07 13:37:03 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -378,6 +378,7 @@ tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2,
int slen, unsigned char *out1, unsigned char *out2, int olen)
{
const EVP_MD *md;
+ size_t hlen;
int i;
memset(out1, 0, olen);
@@ -385,13 +386,33 @@ tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2,
if (!ssl_get_handshake_evp_md(s, &md))
return (0);
+ if (md->type == NID_md5_sha1) {
+ /*
+ * Partition secret between MD5 and SHA1, then XOR result.
+ * If the secret length is odd, a one byte overlap is used.
+ */
+ hlen = slen - (slen / 2);
+ if (!tls1_P_hash(EVP_md5(), sec, hlen, seed1, seed1_len, seed2,
+ seed2_len, seed3, seed3_len, seed4, seed4_len, seed5,
+ seed5_len, out1, olen))
+ return (0);
+
+ sec += slen - hlen;
+ if (!tls1_P_hash(EVP_sha1(), sec, hlen, seed1, seed1_len, seed2,
+ seed2_len, seed3, seed3_len, seed4, seed4_len, seed5,
+ seed5_len, out2, olen))
+ return (0);
+
+ for (i = 0; i < olen; i++)
+ out1[i] ^= out2[i];
+
+ return (1);
+ }
+
if (!tls1_P_hash(md, sec, slen, seed1, seed1_len, seed2, seed2_len,
- seed3, seed3_len, seed4, seed4_len, seed5, seed5_len, out2, olen))
+ seed3, seed3_len, seed4, seed4_len, seed5, seed5_len, out1, olen))
return (0);
- for (i = 0; i < olen; i++)
- out1[i] ^= out2[i];
-
return (1);
}