diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2017-03-07 13:37:04 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2017-03-07 13:37:04 +0000 |
commit | 4b72a4c94a67b765fd9af7640675b304211da494 (patch) | |
tree | af40d130d86972050e923b158d0f1bc3b9ed214a /lib | |
parent | 0052e915c4a343b09c34e9dbaa36af859a4feb43 (diff) |
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')
-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); } |