diff options
author | jsing <> | 2021-04-30 19:26:45 +0000 |
---|---|---|
committer | jsing <> | 2021-04-30 19:26:45 +0000 |
commit | 43140dd2d9a01de0fff0ae59aec0e1d7cda76474 (patch) | |
tree | 3facea5851b6c8afd6d09865048a1f9e6e0c0c8b /src/lib | |
parent | 83b76ed417b8b5f76bcd75ebddd3441a55c890ce (diff) | |
download | openbsd-43140dd2d9a01de0fff0ae59aec0e1d7cda76474.tar.gz openbsd-43140dd2d9a01de0fff0ae59aec0e1d7cda76474.tar.bz2 openbsd-43140dd2d9a01de0fff0ae59aec0e1d7cda76474.zip |
Clean up and harden TLSv1.2 master key derivation.
The master key and its length are only stored in one location, so it makes
no sense to handle these outside of the derivation function (the current
'out' argument is unused). This simplifies the various call sites.
If derivation fails for some reason, fail hard rather than continuing on
and hoping that something deals with this correctly later.
ok inoguchi@ tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 29 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 6 | ||||
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 26 | ||||
-rw-r--r-- | src/lib/libssl/t1_enc.c | 19 | ||||
-rw-r--r-- | src/lib/libssl/tls12_lib.c | 25 |
5 files changed, 51 insertions, 54 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index c129bb6d66..a38d1f1ed4 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_clnt.c,v 1.93 2021/04/25 13:15:22 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.94 2021/04/30 19:26:44 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -2001,9 +2001,8 @@ ssl3_send_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2001 | if (!CBB_flush(cbb)) | 2001 | if (!CBB_flush(cbb)) |
2002 | goto err; | 2002 | goto err; |
2003 | 2003 | ||
2004 | s->session->master_key_length = | 2004 | if (!tls12_derive_master_secret(s, pms, sizeof(pms))) |
2005 | tls1_generate_master_secret(s, | 2005 | goto err; |
2006 | s->session->master_key, pms, sizeof(pms)); | ||
2007 | 2006 | ||
2008 | ret = 1; | 2007 | ret = 1; |
2009 | 2008 | ||
@@ -2055,10 +2054,8 @@ ssl3_send_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2055 | goto err; | 2054 | goto err; |
2056 | } | 2055 | } |
2057 | 2056 | ||
2058 | /* Generate master key from the result. */ | 2057 | if (!tls12_derive_master_secret(s, key, key_len)) |
2059 | s->session->master_key_length = | 2058 | goto err; |
2060 | tls1_generate_master_secret(s, | ||
2061 | s->session->master_key, key, key_len); | ||
2062 | 2059 | ||
2063 | if (!CBB_add_u16_length_prefixed(cbb, &dh_Yc)) | 2060 | if (!CBB_add_u16_length_prefixed(cbb, &dh_Yc)) |
2064 | goto err; | 2061 | goto err; |
@@ -2104,8 +2101,8 @@ ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb) | |||
2104 | 2101 | ||
2105 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, sc->peer_ecdh_tmp, &key, &key_len)) | 2102 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, sc->peer_ecdh_tmp, &key, &key_len)) |
2106 | goto err; | 2103 | goto err; |
2107 | s->session->master_key_length = tls1_generate_master_secret(s, | 2104 | if (!tls12_derive_master_secret(s, key, key_len)) |
2108 | s->session->master_key, key, key_len); | 2105 | goto err; |
2109 | 2106 | ||
2110 | ret = 1; | 2107 | ret = 1; |
2111 | 2108 | ||
@@ -2142,10 +2139,8 @@ ssl3_send_client_kex_ecdhe_ecx(SSL *s, SESS_CERT *sc, CBB *cbb) | |||
2142 | if (!CBB_flush(cbb)) | 2139 | if (!CBB_flush(cbb)) |
2143 | goto err; | 2140 | goto err; |
2144 | 2141 | ||
2145 | /* Generate master key from the result. */ | 2142 | if (!tls12_derive_master_secret(s, shared_key, X25519_KEY_LENGTH)) |
2146 | s->session->master_key_length = | 2143 | goto err; |
2147 | tls1_generate_master_secret(s, | ||
2148 | s->session->master_key, shared_key, X25519_KEY_LENGTH); | ||
2149 | 2144 | ||
2150 | ret = 1; | 2145 | ret = 1; |
2151 | 2146 | ||
@@ -2276,9 +2271,9 @@ ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2276 | s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; | 2271 | s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; |
2277 | } | 2272 | } |
2278 | EVP_PKEY_CTX_free(pkey_ctx); | 2273 | EVP_PKEY_CTX_free(pkey_ctx); |
2279 | s->session->master_key_length = | 2274 | |
2280 | tls1_generate_master_secret(s, | 2275 | if (!tls12_derive_master_secret(s, premaster_secret, 32)) |
2281 | s->session->master_key, premaster_secret, 32); | 2276 | goto err; |
2282 | 2277 | ||
2283 | ret = 1; | 2278 | ret = 1; |
2284 | 2279 | ||
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index a9cab69ee0..c55dada70f 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.338 2021/04/25 13:15:22 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.339 2021/04/30 19:26:44 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1379,8 +1379,6 @@ int tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len, | |||
1379 | void tls1_cleanup_key_block(SSL *s); | 1379 | void tls1_cleanup_key_block(SSL *s); |
1380 | int tls1_change_cipher_state(SSL *s, int which); | 1380 | int tls1_change_cipher_state(SSL *s, int which); |
1381 | int tls1_setup_key_block(SSL *s); | 1381 | int tls1_setup_key_block(SSL *s); |
1382 | int tls1_generate_master_secret(SSL *s, unsigned char *out, | ||
1383 | unsigned char *p, int len); | ||
1384 | int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, | 1382 | int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, |
1385 | const char *label, size_t llen, const unsigned char *p, size_t plen, | 1383 | const char *label, size_t llen, const unsigned char *p, size_t plen, |
1386 | int use_context); | 1384 | int use_context); |
@@ -1389,6 +1387,8 @@ int ssl_ok(SSL *s); | |||
1389 | 1387 | ||
1390 | int tls12_derive_finished(SSL *s); | 1388 | int tls12_derive_finished(SSL *s); |
1391 | int tls12_derive_peer_finished(SSL *s); | 1389 | int tls12_derive_peer_finished(SSL *s); |
1390 | int tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret, | ||
1391 | size_t premaster_secret_len); | ||
1392 | 1392 | ||
1393 | int ssl_using_ecc_cipher(SSL *s); | 1393 | int ssl_using_ecc_cipher(SSL *s); |
1394 | int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); | 1394 | int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); |
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 2c15081f45..32ffa88f15 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.104 2021/04/25 13:15:22 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.105 2021/04/30 19:26:45 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1797,9 +1797,8 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs) | |||
1797 | p = fakekey; | 1797 | p = fakekey; |
1798 | } | 1798 | } |
1799 | 1799 | ||
1800 | s->session->master_key_length = | 1800 | if (!tls12_derive_master_secret(s, p, SSL_MAX_MASTER_KEY_LENGTH)) |
1801 | tls1_generate_master_secret(s, | 1801 | goto err; |
1802 | s->session->master_key, p, SSL_MAX_MASTER_KEY_LENGTH); | ||
1803 | 1802 | ||
1804 | freezero(pms, pms_len); | 1803 | freezero(pms, pms_len); |
1805 | 1804 | ||
@@ -1867,8 +1866,8 @@ ssl3_get_client_kex_dhe(SSL *s, CBS *cbs) | |||
1867 | goto fatal_err; | 1866 | goto fatal_err; |
1868 | } | 1867 | } |
1869 | 1868 | ||
1870 | s->session->master_key_length = tls1_generate_master_secret(s, | 1869 | if (!tls12_derive_master_secret(s, key, key_len)) |
1871 | s->session->master_key, key, key_len); | 1870 | goto err; |
1872 | 1871 | ||
1873 | DH_free(S3I(s)->tmp.dh); | 1872 | DH_free(S3I(s)->tmp.dh); |
1874 | S3I(s)->tmp.dh = NULL; | 1873 | S3I(s)->tmp.dh = NULL; |
@@ -1928,8 +1927,8 @@ ssl3_get_client_kex_ecdhe_ecp(SSL *s, CBS *cbs) | |||
1928 | /* Derive the shared secret and compute master secret. */ | 1927 | /* Derive the shared secret and compute master secret. */ |
1929 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, ecdh_peer, &key, &key_len)) | 1928 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, ecdh_peer, &key, &key_len)) |
1930 | goto err; | 1929 | goto err; |
1931 | s->session->master_key_length = tls1_generate_master_secret(s, | 1930 | if (!tls12_derive_master_secret(s, key, key_len)) |
1932 | s->session->master_key, key, key_len); | 1931 | goto err; |
1933 | 1932 | ||
1934 | EC_KEY_free(S3I(s)->tmp.ecdh); | 1933 | EC_KEY_free(S3I(s)->tmp.ecdh); |
1935 | S3I(s)->tmp.ecdh = NULL; | 1934 | S3I(s)->tmp.ecdh = NULL; |
@@ -1966,9 +1965,8 @@ ssl3_get_client_kex_ecdhe_ecx(SSL *s, CBS *cbs) | |||
1966 | freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH); | 1965 | freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH); |
1967 | S3I(s)->tmp.x25519 = NULL; | 1966 | S3I(s)->tmp.x25519 = NULL; |
1968 | 1967 | ||
1969 | s->session->master_key_length = | 1968 | if (!tls12_derive_master_secret(s, shared_key, X25519_KEY_LENGTH)) |
1970 | tls1_generate_master_secret( | 1969 | goto err; |
1971 | s, s->session->master_key, shared_key, X25519_KEY_LENGTH); | ||
1972 | 1970 | ||
1973 | ret = 1; | 1971 | ret = 1; |
1974 | 1972 | ||
@@ -2033,10 +2031,8 @@ ssl3_get_client_kex_gost(SSL *s, CBS *cbs) | |||
2033 | goto gerr; | 2031 | goto gerr; |
2034 | } | 2032 | } |
2035 | 2033 | ||
2036 | /* Generate master secret */ | 2034 | if (!tls12_derive_master_secret(s, premaster_secret, 32)) |
2037 | s->session->master_key_length = | 2035 | goto err; |
2038 | tls1_generate_master_secret( | ||
2039 | s, s->session->master_key, premaster_secret, 32); | ||
2040 | 2036 | ||
2041 | /* Check if pubkey from client certificate was used */ | 2037 | /* Check if pubkey from client certificate was used */ |
2042 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, | 2038 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 3f93bcecf5..642c210900 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_enc.c,v 1.139 2021/04/25 13:15:22 jsing Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.140 2021/04/30 19:26:45 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -466,23 +466,6 @@ tls1_setup_key_block(SSL *s) | |||
466 | } | 466 | } |
467 | 467 | ||
468 | int | 468 | int |
469 | tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, | ||
470 | int len) | ||
471 | { | ||
472 | if (len < 0) | ||
473 | return 0; | ||
474 | |||
475 | if (!tls1_PRF(s, p, len, | ||
476 | TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, | ||
477 | s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, | ||
478 | s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, | ||
479 | s->session->master_key, SSL_MAX_MASTER_KEY_LENGTH)) | ||
480 | return 0; | ||
481 | |||
482 | return (SSL_MAX_MASTER_KEY_LENGTH); | ||
483 | } | ||
484 | |||
485 | int | ||
486 | tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, | 469 | tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, |
487 | const char *label, size_t llen, const unsigned char *context, | 470 | const char *label, size_t llen, const unsigned char *context, |
488 | size_t contextlen, int use_context) | 471 | size_t contextlen, int use_context) |
diff --git a/src/lib/libssl/tls12_lib.c b/src/lib/libssl/tls12_lib.c index 520f41678d..e7171ba833 100644 --- a/src/lib/libssl/tls12_lib.c +++ b/src/lib/libssl/tls12_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls12_lib.c,v 1.1 2021/04/25 13:15:23 jsing Exp $ */ | 1 | /* $OpenBSD: tls12_lib.c,v 1.2 2021/04/30 19:26:45 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -90,3 +90,26 @@ tls12_derive_peer_finished(SSL *s) | |||
90 | &S3I(s)->hs.peer_finished_len); | 90 | &S3I(s)->hs.peer_finished_len); |
91 | } | 91 | } |
92 | } | 92 | } |
93 | |||
94 | int | ||
95 | tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret, | ||
96 | size_t premaster_secret_len) | ||
97 | { | ||
98 | s->session->master_key_length = 0; | ||
99 | |||
100 | if (premaster_secret_len == 0) | ||
101 | return 0; | ||
102 | |||
103 | CTASSERT(sizeof(s->session->master_key) == SSL_MAX_MASTER_KEY_LENGTH); | ||
104 | |||
105 | if (!tls1_PRF(s, premaster_secret, premaster_secret_len, | ||
106 | TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, | ||
107 | s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, | ||
108 | s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0, | ||
109 | s->session->master_key, sizeof(s->session->master_key))) | ||
110 | return 0; | ||
111 | |||
112 | s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; | ||
113 | |||
114 | return 1; | ||
115 | } | ||