diff options
author | jsing <jsing@openbsd.org> | 2017-03-07 13:37:03 +0000 |
---|---|---|
committer | jsing <jsing@openbsd.org> | 2017-03-07 13:37:03 +0000 |
commit | 9ce461170e6b6421ac4d1f32cfd03603bb681c33 (patch) | |
tree | b762be680956fbe9a349ef22f38d36be0535eb9d /lib/libssl/t1_enc.c | |
parent | fix spacing after empty .Fl (diff) | |
download | wireguard-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.c | 31 |
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); } |