summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2021-11-29 16:00:32 +0000
committerjsing <>2021-11-29 16:00:32 +0000
commita0d7805041037ed2978f81fb42281572ecf06ba5 (patch)
treea67c634e81e938a386fd858c39b174adb55c4703
parentfa78f5478a96728245b0da9e87927ad51540d124 (diff)
downloadopenbsd-a0d7805041037ed2978f81fb42281572ecf06ba5.tar.gz
openbsd-a0d7805041037ed2978f81fb42281572ecf06ba5.tar.bz2
openbsd-a0d7805041037ed2978f81fb42281572ecf06ba5.zip
Factor out/rewrite DHE key exchange.
This follows what was done previously for ECDHE EC point key exchange and will allow for deduplication and further code improvement. Convert the TLSv1.2 client to use the new DHE key exchange functions. ok inoguchi@ tb@
-rw-r--r--src/lib/libssl/ssl_clnt.c84
-rw-r--r--src/lib/libssl/ssl_kex.c145
-rw-r--r--src/lib/libssl/ssl_locl.h10
3 files changed, 173 insertions, 66 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c
index 6fe15dcf1d..b349f24cb0 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.119 2021/11/26 16:41:42 tb Exp $ */ 1/* $OpenBSD: ssl_clnt.c,v 1.120 2021/11/29 16:00:32 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 *
@@ -1223,46 +1223,24 @@ ssl3_get_server_certificate(SSL *s)
1223static int 1223static int
1224ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, CBS *cbs) 1224ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, CBS *cbs)
1225{ 1225{
1226 CBS dhp, dhg, dhpk;
1227 BN_CTX *bn_ctx = NULL;
1228 SESS_CERT *sc = NULL; 1226 SESS_CERT *sc = NULL;
1229 DH *dh = NULL; 1227 DH *dh = NULL;
1230 long alg_a; 1228 long alg_a;
1231 int al;
1232 1229
1233 alg_a = S3I(s)->hs.cipher->algorithm_auth; 1230 alg_a = S3I(s)->hs.cipher->algorithm_auth;
1234 sc = s->session->sess_cert; 1231 sc = s->session->sess_cert;
1235 1232
1236 if ((dh = DH_new()) == NULL) { 1233 if ((dh = DH_new()) == NULL)
1237 SSLerror(s, ERR_R_DH_LIB);
1238 goto err;
1239 }
1240
1241 if (!CBS_get_u16_length_prefixed(cbs, &dhp))
1242 goto decode_err;
1243 if ((dh->p = BN_bin2bn(CBS_data(&dhp), CBS_len(&dhp), NULL)) == NULL) {
1244 SSLerror(s, ERR_R_BN_LIB);
1245 goto err; 1234 goto err;
1246 }
1247 1235
1248 if (!CBS_get_u16_length_prefixed(cbs, &dhg)) 1236 if (!ssl_kex_peer_params_dhe(dh, cbs))
1249 goto decode_err; 1237 goto decode_err;
1250 if ((dh->g = BN_bin2bn(CBS_data(&dhg), CBS_len(&dhg), NULL)) == NULL) { 1238 if (!ssl_kex_peer_public_dhe(dh, cbs))
1251 SSLerror(s, ERR_R_BN_LIB);
1252 goto err;
1253 }
1254
1255 if (!CBS_get_u16_length_prefixed(cbs, &dhpk))
1256 goto decode_err; 1239 goto decode_err;
1257 if ((dh->pub_key = BN_bin2bn(CBS_data(&dhpk), CBS_len(&dhpk),
1258 NULL)) == NULL) {
1259 SSLerror(s, ERR_R_BN_LIB);
1260 goto err;
1261 }
1262 1240
1263 /* 1241 /*
1264 * Check the strength of the DH key just constructed. 1242 * Check the strength of the DH key just constructed.
1265 * Discard keys weaker than 1024 bits. 1243 * Reject keys weaker than 1024 bits.
1266 */ 1244 */
1267 if (DH_size(dh) < 1024 / 8) { 1245 if (DH_size(dh) < 1024 / 8) {
1268 SSLerror(s, SSL_R_BAD_DH_P_LENGTH); 1246 SSLerror(s, SSL_R_BAD_DH_P_LENGTH);
@@ -1280,13 +1258,11 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, CBS *cbs)
1280 return (1); 1258 return (1);
1281 1259
1282 decode_err: 1260 decode_err:
1283 al = SSL_AD_DECODE_ERROR;
1284 SSLerror(s, SSL_R_BAD_PACKET_LENGTH); 1261 SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
1285 ssl3_send_alert(s, SSL3_AL_FATAL, al); 1262 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
1286 1263
1287 err: 1264 err:
1288 DH_free(dh); 1265 DH_free(dh);
1289 BN_CTX_free(bn_ctx);
1290 1266
1291 return (-1); 1267 return (-1);
1292} 1268}
@@ -1988,59 +1964,38 @@ ssl3_send_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
1988static int 1964static int
1989ssl3_send_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) 1965ssl3_send_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
1990{ 1966{
1991 DH *dh_srvr = NULL, *dh_clnt = NULL; 1967 DH *dh_clnt = NULL;
1992 unsigned char *key = NULL; 1968 DH *dh_srvr;
1993 int key_size = 0, key_len; 1969 uint8_t *key = NULL;
1994 unsigned char *data; 1970 size_t key_len = 0;
1995 int ret = -1; 1971 int ret = -1;
1996 CBB dh_Yc;
1997 1972
1998 /* Ensure that we have an ephemeral key for DHE. */ 1973 /* Ensure that we have an ephemeral key from the server for DHE. */
1999 if (sess_cert->peer_dh_tmp == NULL) { 1974 if ((dh_srvr = sess_cert->peer_dh_tmp) == NULL) {
2000 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); 1975 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
2001 SSLerror(s, SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); 1976 SSLerror(s, SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
2002 goto err; 1977 goto err;
2003 } 1978 }
2004 dh_srvr = sess_cert->peer_dh_tmp;
2005 1979
2006 /* Generate a new random key. */ 1980 if ((dh_clnt = DH_new()) == NULL)
2007 if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) {
2008 SSLerror(s, ERR_R_DH_LIB);
2009 goto err; 1981 goto err;
2010 } 1982
2011 if (!DH_generate_key(dh_clnt)) { 1983 if (!ssl_kex_generate_dhe(dh_clnt, dh_srvr))
2012 SSLerror(s, ERR_R_DH_LIB);
2013 goto err;
2014 }
2015 if ((key_size = DH_size(dh_clnt)) <= 0) {
2016 SSLerror(s, ERR_R_DH_LIB);
2017 goto err;
2018 }
2019 if ((key = malloc(key_size)) == NULL) {
2020 SSLerror(s, ERR_R_MALLOC_FAILURE);
2021 goto err; 1984 goto err;
2022 } 1985 if (!ssl_kex_public_dhe(dh_clnt, cbb))
2023 if ((key_len = DH_compute_key(key, dh_srvr->pub_key, dh_clnt)) <= 0) {
2024 SSLerror(s, ERR_R_DH_LIB);
2025 goto err; 1986 goto err;
2026 }
2027 1987
2028 if (!tls12_derive_master_secret(s, key, key_len)) 1988 if (!ssl_kex_derive_dhe(dh_clnt, dh_srvr, &key, &key_len))
2029 goto err; 1989 goto err;
2030 1990
2031 if (!CBB_add_u16_length_prefixed(cbb, &dh_Yc)) 1991 if (!tls12_derive_master_secret(s, key, key_len))
2032 goto err;
2033 if (!CBB_add_space(&dh_Yc, &data, BN_num_bytes(dh_clnt->pub_key)))
2034 goto err;
2035 BN_bn2bin(dh_clnt->pub_key, data);
2036 if (!CBB_flush(cbb))
2037 goto err; 1992 goto err;
2038 1993
2039 ret = 1; 1994 ret = 1;
2040 1995
2041 err: 1996 err:
2042 DH_free(dh_clnt); 1997 DH_free(dh_clnt);
2043 freezero(key, key_size); 1998 freezero(key, key_len);
2044 1999
2045 return (ret); 2000 return (ret);
2046} 2001}
@@ -2072,6 +2027,7 @@ ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb)
2072 2027
2073 if (!ssl_kex_derive_ecdhe_ecp(ecdh, sc->peer_ecdh_tmp, &key, &key_len)) 2028 if (!ssl_kex_derive_ecdhe_ecp(ecdh, sc->peer_ecdh_tmp, &key, &key_len))
2074 goto err; 2029 goto err;
2030
2075 if (!tls12_derive_master_secret(s, key, key_len)) 2031 if (!tls12_derive_master_secret(s, key, key_len))
2076 goto err; 2032 goto err;
2077 2033
diff --git a/src/lib/libssl/ssl_kex.c b/src/lib/libssl/ssl_kex.c
index 9f05fd60c9..26f991f190 100644
--- a/src/lib/libssl/ssl_kex.c
+++ b/src/lib/libssl/ssl_kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_kex.c,v 1.2 2020/04/18 14:07:56 jsing Exp $ */ 1/* $OpenBSD: ssl_kex.c,v 1.3 2021/11/29 16:00:32 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -17,6 +17,7 @@
17 17
18#include <stdlib.h> 18#include <stdlib.h>
19 19
20#include <openssl/dh.h>
20#include <openssl/ec.h> 21#include <openssl/ec.h>
21#include <openssl/ecdh.h> 22#include <openssl/ecdh.h>
22#include <openssl/evp.h> 23#include <openssl/evp.h>
@@ -25,6 +26,148 @@
25#include "bytestring.h" 26#include "bytestring.h"
26 27
27int 28int
29ssl_kex_generate_dhe(DH *dh, DH *dh_params)
30{
31 BN_free(dh->p);
32 BN_free(dh->g);
33 dh->p = NULL;
34 dh->g = NULL;
35
36 if ((dh->p = BN_dup(dh_params->p)) == NULL)
37 return 0;
38 if ((dh->g = BN_dup(dh_params->g)) == NULL)
39 return 0;
40
41 if (!DH_generate_key(dh))
42 return 0;
43
44 return 1;
45}
46
47int
48ssl_kex_params_dhe(DH *dh, CBB *cbb)
49{
50 int dh_p_len, dh_g_len;
51 CBB dh_p, dh_g;
52 uint8_t *data;
53
54 if ((dh_p_len = BN_num_bytes(dh->p)) <= 0)
55 return 0;
56 if ((dh_g_len = BN_num_bytes(dh->g)) <= 0)
57 return 0;
58
59 if (!CBB_add_u16_length_prefixed(cbb, &dh_p))
60 return 0;
61 if (!CBB_add_space(&dh_p, &data, dh_p_len))
62 return 0;
63 if (BN_bn2bin(dh->p, data) != dh_p_len)
64 return 0;
65
66 if (!CBB_add_u16_length_prefixed(cbb, &dh_g))
67 return 0;
68 if (!CBB_add_space(&dh_g, &data, dh_g_len))
69 return 0;
70 if (BN_bn2bin(dh->g, data) != dh_g_len)
71 return 0;
72
73 if (!CBB_flush(cbb))
74 return 0;
75
76 return 1;
77}
78
79int
80ssl_kex_public_dhe(DH *dh, CBB *cbb)
81{
82 uint8_t *data;
83 int dh_y_len;
84 CBB dh_y;
85
86 if ((dh_y_len = BN_num_bytes(dh->pub_key)) <= 0)
87 return 0;
88
89 if (!CBB_add_u16_length_prefixed(cbb, &dh_y))
90 return 0;
91 if (!CBB_add_space(&dh_y, &data, dh_y_len))
92 return 0;
93 if (BN_bn2bin(dh->pub_key, data) != dh_y_len)
94 return 0;
95
96 if (!CBB_flush(cbb))
97 return 0;
98
99 return 1;
100}
101
102int
103ssl_kex_peer_params_dhe(DH *dh, CBS *cbs)
104{
105 CBS dh_p, dh_g;
106
107 BN_free(dh->p);
108 BN_free(dh->g);
109 dh->p = NULL;
110 dh->g = NULL;
111
112 if (!CBS_get_u16_length_prefixed(cbs, &dh_p))
113 return 0;
114 if (!CBS_get_u16_length_prefixed(cbs, &dh_g))
115 return 0;
116
117 if ((dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL)
118 return 0;
119 if ((dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL)
120 return 0;
121
122 return 1;
123}
124
125int
126ssl_kex_peer_public_dhe(DH *dh, CBS *cbs)
127{
128 CBS dh_y;
129
130 BN_free(dh->pub_key);
131 dh->pub_key = NULL;
132
133 if (!CBS_get_u16_length_prefixed(cbs, &dh_y))
134 return 0;
135 if ((dh->pub_key = BN_bin2bn(CBS_data(&dh_y), CBS_len(&dh_y),
136 NULL)) == NULL)
137 return 0;
138
139 return 1;
140}
141
142int
143ssl_kex_derive_dhe(DH *dh, DH *dh_peer,
144 uint8_t **shared_key, size_t *shared_key_len)
145{
146 uint8_t *key = NULL;
147 int key_len = 0;
148 int ret = 0;
149
150 if ((key_len = DH_size(dh)) <= 0)
151 goto err;
152 if ((key = calloc(1, key_len)) == NULL)
153 goto err;
154
155 if ((key_len = DH_compute_key(key, dh_peer->pub_key, dh)) <= 0)
156 goto err;
157
158 *shared_key = key;
159 *shared_key_len = key_len;
160 key = NULL;
161
162 ret = 1;
163
164 err:
165 freezero(key, key_len);
166
167 return ret;
168}
169
170int
28ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey) 171ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey)
29{ 172{
30 EC_GROUP *group = NULL; 173 EC_GROUP *group = NULL;
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 27bf5ec41f..7810bcd05e 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.368 2021/10/25 10:09:28 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.369 2021/11/29 16:00:32 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 *
@@ -1447,6 +1447,14 @@ int ssl3_get_client_certificate(SSL *s);
1447int ssl3_get_client_key_exchange(SSL *s); 1447int ssl3_get_client_key_exchange(SSL *s);
1448int ssl3_get_cert_verify(SSL *s); 1448int ssl3_get_cert_verify(SSL *s);
1449 1449
1450int ssl_kex_generate_dhe(DH *dh, DH *dh_params);
1451int ssl_kex_params_dhe(DH *dh, CBB *cbb);
1452int ssl_kex_public_dhe(DH *dh, CBB *cbb);
1453int ssl_kex_peer_params_dhe(DH *dh, CBS *cbs);
1454int ssl_kex_peer_public_dhe(DH *dh, CBS *cbs);
1455int ssl_kex_derive_dhe(DH *dh, DH *dh_peer,
1456 uint8_t **shared_key, size_t *shared_key_len);
1457
1450int ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey); 1458int ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey);
1451int ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid); 1459int ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid);
1452int ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb); 1460int ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb);