diff options
Diffstat (limited to '')
| -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 | } |
