diff options
author | jsing <> | 2020-01-30 16:25:09 +0000 |
---|---|---|
committer | jsing <> | 2020-01-30 16:25:09 +0000 |
commit | 1f07a6fc3b3b9d44b731e6cf17fd00b540758db8 (patch) | |
tree | c2c8df4a9c431efa5cc0db8ff09bf1be05c80c4e /src/lib | |
parent | 668fa98385559e6ca53555e32da8e7eb618f0d80 (diff) | |
download | openbsd-1f07a6fc3b3b9d44b731e6cf17fd00b540758db8.tar.gz openbsd-1f07a6fc3b3b9d44b731e6cf17fd00b540758db8.tar.bz2 openbsd-1f07a6fc3b3b9d44b731e6cf17fd00b540758db8.zip |
Factor out/rewrite the ECDHE EC point key exchange code.
This reduces replication between the existing TLS client/server and allows
the code to soon be reused for TLSv1.3.
With feedback from inoguchi@ and tb@
ok inoguchi@ tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/Makefile | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 109 | ||||
-rw-r--r-- | src/lib/libssl/ssl_kex.c | 141 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 10 | ||||
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 98 |
5 files changed, 188 insertions, 173 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index b38bb5f682..489c4fd217 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.60 2020/01/22 07:58:27 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.61 2020/01/30 16:25:09 jsing Exp $ |
2 | 2 | ||
3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
4 | .ifndef NOMAN | 4 | .ifndef NOMAN |
@@ -51,6 +51,7 @@ SRCS= \ | |||
51 | ssl_clnt.c \ | 51 | ssl_clnt.c \ |
52 | ssl_err.c \ | 52 | ssl_err.c \ |
53 | ssl_init.c \ | 53 | ssl_init.c \ |
54 | ssl_kex.c \ | ||
54 | ssl_lib.c \ | 55 | ssl_lib.c \ |
55 | ssl_methods.c \ | 56 | ssl_methods.c \ |
56 | ssl_packet.c \ | 57 | ssl_packet.c \ |
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index 22e02735c8..dfb1d7ddb6 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.62 2020/01/23 10:48:37 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.63 2020/01/30 16:25:09 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 | * |
@@ -1263,56 +1263,27 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, CBS *cbs) | |||
1263 | static int | 1263 | static int |
1264 | ssl3_get_server_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, int nid, CBS *public) | 1264 | ssl3_get_server_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, int nid, CBS *public) |
1265 | { | 1265 | { |
1266 | const EC_GROUP *group; | ||
1267 | EC_GROUP *ngroup = NULL; | ||
1268 | EC_POINT *point = NULL; | ||
1269 | BN_CTX *bn_ctx = NULL; | ||
1270 | EC_KEY *ecdh = NULL; | 1266 | EC_KEY *ecdh = NULL; |
1271 | int ret = -1; | 1267 | int ret = -1; |
1272 | 1268 | ||
1273 | /* | 1269 | /* Extract the server's ephemeral ECDH public key. */ |
1274 | * Extract the server's ephemeral ECDH public key. | ||
1275 | */ | ||
1276 | |||
1277 | if ((ecdh = EC_KEY_new()) == NULL) { | 1270 | if ((ecdh = EC_KEY_new()) == NULL) { |
1278 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 1271 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
1279 | goto err; | 1272 | goto err; |
1280 | } | 1273 | } |
1281 | 1274 | if (!ssl_kex_peer_public_ecdhe_ecp(ecdh, nid, public)) { | |
1282 | if ((ngroup = EC_GROUP_new_by_curve_name(nid)) == NULL) { | ||
1283 | SSLerror(s, ERR_R_EC_LIB); | ||
1284 | goto err; | ||
1285 | } | ||
1286 | if (EC_KEY_set_group(ecdh, ngroup) == 0) { | ||
1287 | SSLerror(s, ERR_R_EC_LIB); | ||
1288 | goto err; | ||
1289 | } | ||
1290 | |||
1291 | group = EC_KEY_get0_group(ecdh); | ||
1292 | |||
1293 | if ((point = EC_POINT_new(group)) == NULL || | ||
1294 | (bn_ctx = BN_CTX_new()) == NULL) { | ||
1295 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1296 | goto err; | ||
1297 | } | ||
1298 | |||
1299 | if (EC_POINT_oct2point(group, point, CBS_data(public), | ||
1300 | CBS_len(public), bn_ctx) == 0) { | ||
1301 | SSLerror(s, SSL_R_BAD_ECPOINT); | 1275 | SSLerror(s, SSL_R_BAD_ECPOINT); |
1302 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | 1276 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); |
1303 | goto err; | 1277 | goto err; |
1304 | } | 1278 | } |
1305 | 1279 | ||
1306 | EC_KEY_set_public_key(ecdh, point); | 1280 | sc->peer_nid = nid; |
1307 | sc->peer_ecdh_tmp = ecdh; | 1281 | sc->peer_ecdh_tmp = ecdh; |
1308 | ecdh = NULL; | 1282 | ecdh = NULL; |
1309 | 1283 | ||
1310 | ret = 1; | 1284 | ret = 1; |
1311 | 1285 | ||
1312 | err: | 1286 | err: |
1313 | BN_CTX_free(bn_ctx); | ||
1314 | EC_GROUP_free(ngroup); | ||
1315 | EC_POINT_free(point); | ||
1316 | EC_KEY_free(ecdh); | 1287 | EC_KEY_free(ecdh); |
1317 | 1288 | ||
1318 | return (ret); | 1289 | return (ret); |
@@ -2049,87 +2020,37 @@ err: | |||
2049 | static int | 2020 | static int |
2050 | ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb) | 2021 | ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb) |
2051 | { | 2022 | { |
2052 | const EC_GROUP *group = NULL; | ||
2053 | const EC_POINT *point = NULL; | ||
2054 | EC_KEY *ecdh = NULL; | 2023 | EC_KEY *ecdh = NULL; |
2055 | BN_CTX *bn_ctx = NULL; | 2024 | uint8_t *key = NULL; |
2056 | unsigned char *key = NULL; | 2025 | size_t key_len = 0; |
2057 | unsigned char *data; | ||
2058 | size_t encoded_len; | ||
2059 | int key_size = 0, key_len; | ||
2060 | int ret = -1; | 2026 | int ret = -1; |
2061 | CBB ecpoint; | 2027 | CBB ecpoint; |
2062 | 2028 | ||
2063 | if ((group = EC_KEY_get0_group(sc->peer_ecdh_tmp)) == NULL || | ||
2064 | (point = EC_KEY_get0_public_key(sc->peer_ecdh_tmp)) == NULL) { | ||
2065 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
2066 | goto err; | ||
2067 | } | ||
2068 | |||
2069 | if ((ecdh = EC_KEY_new()) == NULL) { | 2029 | if ((ecdh = EC_KEY_new()) == NULL) { |
2070 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 2030 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
2071 | goto err; | 2031 | goto err; |
2072 | } | 2032 | } |
2073 | 2033 | ||
2074 | if (!EC_KEY_set_group(ecdh, group)) { | 2034 | if (!ssl_kex_generate_ecdhe_ecp(ecdh, sc->peer_nid)) |
2075 | SSLerror(s, ERR_R_EC_LIB); | ||
2076 | goto err; | 2035 | goto err; |
2077 | } | ||
2078 | 2036 | ||
2079 | /* Generate a new ECDH key pair. */ | 2037 | /* Encode our public key. */ |
2080 | if (!EC_KEY_generate_key(ecdh)) { | ||
2081 | SSLerror(s, ERR_R_ECDH_LIB); | ||
2082 | goto err; | ||
2083 | } | ||
2084 | if ((key_size = ECDH_size(ecdh)) <= 0) { | ||
2085 | SSLerror(s, ERR_R_ECDH_LIB); | ||
2086 | goto err; | ||
2087 | } | ||
2088 | if ((key = malloc(key_size)) == NULL) { | ||
2089 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
2090 | goto err; | ||
2091 | } | ||
2092 | key_len = ECDH_compute_key(key, key_size, point, ecdh, NULL); | ||
2093 | if (key_len <= 0) { | ||
2094 | SSLerror(s, ERR_R_ECDH_LIB); | ||
2095 | goto err; | ||
2096 | } | ||
2097 | |||
2098 | /* Generate master key from the result. */ | ||
2099 | s->session->master_key_length = | ||
2100 | tls1_generate_master_secret(s, | ||
2101 | s->session->master_key, key, key_len); | ||
2102 | |||
2103 | encoded_len = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), | ||
2104 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | ||
2105 | if (encoded_len == 0) { | ||
2106 | SSLerror(s, ERR_R_ECDH_LIB); | ||
2107 | goto err; | ||
2108 | } | ||
2109 | |||
2110 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
2111 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
2112 | goto err; | ||
2113 | } | ||
2114 | |||
2115 | /* Encode the public key. */ | ||
2116 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) | 2038 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) |
2117 | goto err; | 2039 | goto err; |
2118 | if (!CBB_add_space(&ecpoint, &data, encoded_len)) | 2040 | if (!ssl_kex_public_ecdhe_ecp(ecdh, &ecpoint)) |
2119 | goto err; | ||
2120 | if (EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), | ||
2121 | POINT_CONVERSION_UNCOMPRESSED, data, encoded_len, | ||
2122 | bn_ctx) == 0) | ||
2123 | goto err; | 2041 | goto err; |
2124 | if (!CBB_flush(cbb)) | 2042 | if (!CBB_flush(cbb)) |
2125 | goto err; | 2043 | goto err; |
2126 | 2044 | ||
2045 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, sc->peer_ecdh_tmp, &key, &key_len)) | ||
2046 | goto err; | ||
2047 | s->session->master_key_length = tls1_generate_master_secret(s, | ||
2048 | s->session->master_key, key, key_len); | ||
2049 | |||
2127 | ret = 1; | 2050 | ret = 1; |
2128 | 2051 | ||
2129 | err: | 2052 | err: |
2130 | freezero(key, key_size); | 2053 | freezero(key, key_len); |
2131 | |||
2132 | BN_CTX_free(bn_ctx); | ||
2133 | EC_KEY_free(ecdh); | 2054 | EC_KEY_free(ecdh); |
2134 | 2055 | ||
2135 | return (ret); | 2056 | return (ret); |
diff --git a/src/lib/libssl/ssl_kex.c b/src/lib/libssl/ssl_kex.c new file mode 100644 index 0000000000..439c1702b3 --- /dev/null +++ b/src/lib/libssl/ssl_kex.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* $OpenBSD: ssl_kex.c,v 1.1 2020/01/30 16:25:09 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <stdlib.h> | ||
19 | |||
20 | #include <openssl/ec.h> | ||
21 | #include <openssl/ecdh.h> | ||
22 | |||
23 | #include "bytestring.h" | ||
24 | |||
25 | int | ||
26 | ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid) | ||
27 | { | ||
28 | EC_GROUP *group; | ||
29 | int ret = 0; | ||
30 | |||
31 | if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) | ||
32 | goto err; | ||
33 | |||
34 | if (!EC_KEY_set_group(ecdh, group)) | ||
35 | goto err; | ||
36 | if (!EC_KEY_generate_key(ecdh)) | ||
37 | goto err; | ||
38 | |||
39 | ret = 1; | ||
40 | |||
41 | err: | ||
42 | EC_GROUP_free(group); | ||
43 | |||
44 | return ret; | ||
45 | } | ||
46 | |||
47 | int | ||
48 | ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb) | ||
49 | { | ||
50 | const EC_GROUP *group; | ||
51 | const EC_POINT *point; | ||
52 | uint8_t *ecp; | ||
53 | size_t ecp_len; | ||
54 | int ret = 0; | ||
55 | |||
56 | if ((group = EC_KEY_get0_group(ecdh)) == NULL) | ||
57 | goto err; | ||
58 | if ((point = EC_KEY_get0_public_key(ecdh)) == NULL) | ||
59 | goto err; | ||
60 | |||
61 | if ((ecp_len = EC_POINT_point2oct(group, point, | ||
62 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)) == 0) | ||
63 | goto err; | ||
64 | if (!CBB_add_space(cbb, &ecp, ecp_len)) | ||
65 | goto err; | ||
66 | if ((EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, | ||
67 | ecp, ecp_len, NULL)) == 0) | ||
68 | goto err; | ||
69 | |||
70 | ret = 1; | ||
71 | |||
72 | err: | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | int | ||
77 | ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs) | ||
78 | { | ||
79 | EC_GROUP *group = NULL; | ||
80 | EC_POINT *point = NULL; | ||
81 | int ret = 0; | ||
82 | |||
83 | if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) | ||
84 | goto err; | ||
85 | |||
86 | if (!EC_KEY_set_group(ecdh, group)) | ||
87 | goto err; | ||
88 | |||
89 | if ((point = EC_POINT_new(group)) == NULL) | ||
90 | goto err; | ||
91 | if (EC_POINT_oct2point(group, point, CBS_data(cbs), CBS_len(cbs), | ||
92 | NULL) == 0) | ||
93 | goto err; | ||
94 | if (!EC_KEY_set_public_key(ecdh, point)) | ||
95 | goto err; | ||
96 | |||
97 | ret = 1; | ||
98 | |||
99 | err: | ||
100 | EC_GROUP_free(group); | ||
101 | EC_POINT_free(point); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | int | ||
107 | ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer, | ||
108 | uint8_t **shared_key, size_t *shared_key_len) | ||
109 | { | ||
110 | const EC_POINT *point; | ||
111 | uint8_t *sk = NULL; | ||
112 | int sk_len = 0; | ||
113 | int ret = 0; | ||
114 | |||
115 | if (!EC_GROUP_check(EC_KEY_get0_group(ecdh), NULL)) | ||
116 | goto err; | ||
117 | if (!EC_GROUP_check(EC_KEY_get0_group(ecdh_peer), NULL)) | ||
118 | goto err; | ||
119 | |||
120 | if ((point = EC_KEY_get0_public_key(ecdh_peer)) == NULL) | ||
121 | goto err; | ||
122 | |||
123 | if ((sk_len = ECDH_size(ecdh)) <= 0) | ||
124 | goto err; | ||
125 | if ((sk = calloc(1, sk_len)) == NULL) | ||
126 | goto err; | ||
127 | |||
128 | if (ECDH_compute_key(sk, sk_len, point, ecdh, NULL) <= 0) | ||
129 | goto err; | ||
130 | |||
131 | *shared_key = sk; | ||
132 | *shared_key_len = sk_len; | ||
133 | sk = NULL; | ||
134 | |||
135 | ret = 1; | ||
136 | |||
137 | err: | ||
138 | freezero(sk, sk_len); | ||
139 | |||
140 | return ret; | ||
141 | } | ||
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 6c33ec9743..5ff6f39b45 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.257 2020/01/29 17:08:49 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.258 2020/01/30 16:25:09 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 | * |
@@ -872,6 +872,7 @@ typedef struct ssl3_state_internal_st { | |||
872 | DH *dh; | 872 | DH *dh; |
873 | 873 | ||
874 | EC_KEY *ecdh; /* holds short lived ECDH key */ | 874 | EC_KEY *ecdh; /* holds short lived ECDH key */ |
875 | int ecdh_nid; | ||
875 | 876 | ||
876 | uint8_t *x25519; | 877 | uint8_t *x25519; |
877 | 878 | ||
@@ -1017,6 +1018,7 @@ typedef struct sess_cert_st { | |||
1017 | /* Obviously we don't have the private keys of these, | 1018 | /* Obviously we don't have the private keys of these, |
1018 | * so maybe we shouldn't even use the CERT_PKEY type here. */ | 1019 | * so maybe we shouldn't even use the CERT_PKEY type here. */ |
1019 | 1020 | ||
1021 | int peer_nid; | ||
1020 | DH *peer_dh_tmp; | 1022 | DH *peer_dh_tmp; |
1021 | EC_KEY *peer_ecdh_tmp; | 1023 | EC_KEY *peer_ecdh_tmp; |
1022 | uint8_t *peer_x25519_tmp; | 1024 | uint8_t *peer_x25519_tmp; |
@@ -1278,6 +1280,12 @@ int ssl3_get_client_certificate(SSL *s); | |||
1278 | int ssl3_get_client_key_exchange(SSL *s); | 1280 | int ssl3_get_client_key_exchange(SSL *s); |
1279 | int ssl3_get_cert_verify(SSL *s); | 1281 | int ssl3_get_cert_verify(SSL *s); |
1280 | 1282 | ||
1283 | int ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid); | ||
1284 | int ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb); | ||
1285 | int ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs); | ||
1286 | int ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer, | ||
1287 | uint8_t **shared_key, size_t *shared_key_len); | ||
1288 | |||
1281 | int tls1_new(SSL *s); | 1289 | int tls1_new(SSL *s); |
1282 | void tls1_free(SSL *s); | 1290 | void tls1_free(SSL *s); |
1283 | void tls1_clear(SSL *s); | 1291 | void tls1_clear(SSL *s); |
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 6b49afe6a8..843d2ee249 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.70 2020/01/23 10:48:37 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.71 2020/01/30 16:25:09 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 | * |
@@ -1347,12 +1347,7 @@ ssl3_send_server_kex_dhe(SSL *s, CBB *cbb) | |||
1347 | static int | 1347 | static int |
1348 | ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb) | 1348 | ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb) |
1349 | { | 1349 | { |
1350 | const EC_GROUP *group; | ||
1351 | const EC_POINT *pubkey; | ||
1352 | unsigned char *data; | ||
1353 | int encoded_len = 0; | ||
1354 | int curve_id = 0; | 1350 | int curve_id = 0; |
1355 | BN_CTX *bn_ctx = NULL; | ||
1356 | EC_KEY *ecdh; | 1351 | EC_KEY *ecdh; |
1357 | CBB ecpoint; | 1352 | CBB ecpoint; |
1358 | int al; | 1353 | int al; |
@@ -1371,39 +1366,20 @@ ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb) | |||
1371 | goto err; | 1366 | goto err; |
1372 | } | 1367 | } |
1373 | 1368 | ||
1374 | if ((S3I(s)->tmp.ecdh = EC_KEY_new_by_curve_name(nid)) == NULL) { | 1369 | if ((S3I(s)->tmp.ecdh = EC_KEY_new()) == NULL) { |
1375 | al = SSL_AD_HANDSHAKE_FAILURE; | 1370 | al = SSL_AD_HANDSHAKE_FAILURE; |
1376 | SSLerror(s, SSL_R_MISSING_TMP_ECDH_KEY); | 1371 | SSLerror(s, SSL_R_MISSING_TMP_ECDH_KEY); |
1377 | goto f_err; | 1372 | goto f_err; |
1378 | } | 1373 | } |
1374 | S3I(s)->tmp.ecdh_nid = nid; | ||
1379 | ecdh = S3I(s)->tmp.ecdh; | 1375 | ecdh = S3I(s)->tmp.ecdh; |
1380 | 1376 | ||
1381 | if (!EC_KEY_generate_key(ecdh)) { | 1377 | if (!ssl_kex_generate_ecdhe_ecp(ecdh, nid)) |
1382 | SSLerror(s, ERR_R_ECDH_LIB); | ||
1383 | goto err; | ||
1384 | } | ||
1385 | if ((group = EC_KEY_get0_group(ecdh)) == NULL || | ||
1386 | (pubkey = EC_KEY_get0_public_key(ecdh)) == NULL || | ||
1387 | EC_KEY_get0_private_key(ecdh) == NULL) { | ||
1388 | SSLerror(s, ERR_R_ECDH_LIB); | ||
1389 | goto err; | 1378 | goto err; |
1390 | } | ||
1391 | 1379 | ||
1392 | /* | 1380 | /* |
1393 | * Encode the public key. | 1381 | * Encode the public key. |
1394 | */ | 1382 | * |
1395 | encoded_len = EC_POINT_point2oct(group, pubkey, | ||
1396 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | ||
1397 | if (encoded_len == 0) { | ||
1398 | SSLerror(s, ERR_R_ECDH_LIB); | ||
1399 | goto err; | ||
1400 | } | ||
1401 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
1402 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1403 | goto err; | ||
1404 | } | ||
1405 | |||
1406 | /* | ||
1407 | * Only named curves are supported in ECDH ephemeral key exchanges. | 1383 | * Only named curves are supported in ECDH ephemeral key exchanges. |
1408 | * In this case the ServerKeyExchange message has: | 1384 | * In this case the ServerKeyExchange message has: |
1409 | * [1 byte CurveType], [2 byte CurveName] | 1385 | * [1 byte CurveType], [2 byte CurveName] |
@@ -1416,25 +1392,16 @@ ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb) | |||
1416 | goto err; | 1392 | goto err; |
1417 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) | 1393 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) |
1418 | goto err; | 1394 | goto err; |
1419 | if (!CBB_add_space(&ecpoint, &data, encoded_len)) | 1395 | if (!ssl_kex_public_ecdhe_ecp(ecdh, &ecpoint)) |
1420 | goto err; | 1396 | goto err; |
1421 | if (EC_POINT_point2oct(group, pubkey, POINT_CONVERSION_UNCOMPRESSED, | ||
1422 | data, encoded_len, bn_ctx) == 0) { | ||
1423 | SSLerror(s, ERR_R_ECDH_LIB); | ||
1424 | goto err; | ||
1425 | } | ||
1426 | if (!CBB_flush(cbb)) | 1397 | if (!CBB_flush(cbb)) |
1427 | goto err; | 1398 | goto err; |
1428 | 1399 | ||
1429 | BN_CTX_free(bn_ctx); | ||
1430 | |||
1431 | return (1); | 1400 | return (1); |
1432 | 1401 | ||
1433 | f_err: | 1402 | f_err: |
1434 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 1403 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
1435 | err: | 1404 | err: |
1436 | BN_CTX_free(bn_ctx); | ||
1437 | |||
1438 | return (-1); | 1405 | return (-1); |
1439 | } | 1406 | } |
1440 | 1407 | ||
@@ -1861,20 +1828,13 @@ ssl3_get_client_kex_dhe(SSL *s, CBS *cbs) | |||
1861 | static int | 1828 | static int |
1862 | ssl3_get_client_kex_ecdhe_ecp(SSL *s, CBS *cbs) | 1829 | ssl3_get_client_kex_ecdhe_ecp(SSL *s, CBS *cbs) |
1863 | { | 1830 | { |
1864 | unsigned char *key = NULL; | 1831 | uint8_t *key = NULL; |
1865 | int key_size = 0, key_len; | 1832 | size_t key_len = 0; |
1866 | EC_POINT *point = NULL; | 1833 | EC_KEY *ecdh_peer = NULL; |
1867 | BN_CTX *bn_ctx = NULL; | ||
1868 | const EC_GROUP *group; | ||
1869 | EC_KEY *ecdh; | 1834 | EC_KEY *ecdh; |
1870 | CBS public; | 1835 | CBS public; |
1871 | int ret = -1; | 1836 | int ret = -1; |
1872 | 1837 | ||
1873 | if (!CBS_get_u8_length_prefixed(cbs, &public)) | ||
1874 | goto err; | ||
1875 | if (CBS_len(cbs) != 0) | ||
1876 | goto err; | ||
1877 | |||
1878 | /* | 1838 | /* |
1879 | * Use the ephemeral values we saved when generating the | 1839 | * Use the ephemeral values we saved when generating the |
1880 | * ServerKeyExchange message. | 1840 | * ServerKeyExchange message. |
@@ -1883,54 +1843,38 @@ ssl3_get_client_kex_ecdhe_ecp(SSL *s, CBS *cbs) | |||
1883 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 1843 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
1884 | goto err; | 1844 | goto err; |
1885 | } | 1845 | } |
1886 | group = EC_KEY_get0_group(ecdh); | ||
1887 | 1846 | ||
1888 | /* | 1847 | /* |
1889 | * Get client's public key from encoded point in the ClientKeyExchange | 1848 | * Get client's public key from encoded point in the ClientKeyExchange |
1890 | * message. | 1849 | * message. |
1891 | */ | 1850 | */ |
1892 | if ((bn_ctx = BN_CTX_new()) == NULL) { | 1851 | if (!CBS_get_u8_length_prefixed(cbs, &public)) |
1893 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1894 | goto err; | ||
1895 | } | ||
1896 | if ((point = EC_POINT_new(group)) == NULL) { | ||
1897 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1898 | goto err; | 1852 | goto err; |
1899 | } | 1853 | if (CBS_len(cbs) != 0) |
1900 | if (EC_POINT_oct2point(group, point, CBS_data(&public), | ||
1901 | CBS_len(&public), bn_ctx) == 0) { | ||
1902 | SSLerror(s, ERR_R_EC_LIB); | ||
1903 | goto err; | 1854 | goto err; |
1904 | } | ||
1905 | 1855 | ||
1906 | /* Compute the shared pre-master secret */ | 1856 | if ((ecdh_peer = EC_KEY_new()) == NULL) |
1907 | if ((key_size = ECDH_size(ecdh)) <= 0) { | ||
1908 | SSLerror(s, ERR_R_ECDH_LIB); | ||
1909 | goto err; | ||
1910 | } | ||
1911 | if ((key = malloc(key_size)) == NULL) { | ||
1912 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1913 | goto err; | 1857 | goto err; |
1914 | } | 1858 | |
1915 | if ((key_len = ECDH_compute_key(key, key_size, point, ecdh, | 1859 | if (!ssl_kex_peer_public_ecdhe_ecp(ecdh_peer, S3I(s)->tmp.ecdh_nid, |
1916 | NULL)) <= 0) { | 1860 | &public)) |
1917 | SSLerror(s, ERR_R_ECDH_LIB); | ||
1918 | goto err; | 1861 | goto err; |
1919 | } | ||
1920 | 1862 | ||
1921 | /* Compute the master secret */ | 1863 | /* Derive the shared secret and compute master secret. */ |
1864 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, ecdh_peer, &key, &key_len)) | ||
1865 | goto err; | ||
1922 | s->session->master_key_length = tls1_generate_master_secret(s, | 1866 | s->session->master_key_length = tls1_generate_master_secret(s, |
1923 | s->session->master_key, key, key_len); | 1867 | s->session->master_key, key, key_len); |
1924 | 1868 | ||
1925 | EC_KEY_free(S3I(s)->tmp.ecdh); | 1869 | EC_KEY_free(S3I(s)->tmp.ecdh); |
1926 | S3I(s)->tmp.ecdh = NULL; | 1870 | S3I(s)->tmp.ecdh = NULL; |
1871 | S3I(s)->tmp.ecdh_nid = NID_undef; | ||
1927 | 1872 | ||
1928 | ret = 1; | 1873 | ret = 1; |
1929 | 1874 | ||
1930 | err: | 1875 | err: |
1931 | freezero(key, key_size); | 1876 | freezero(key, key_len); |
1932 | EC_POINT_free(point); | 1877 | EC_KEY_free(ecdh_peer); |
1933 | BN_CTX_free(bn_ctx); | ||
1934 | 1878 | ||
1935 | return (ret); | 1879 | return (ret); |
1936 | } | 1880 | } |