diff options
author | jsing <> | 2016-12-21 16:44:31 +0000 |
---|---|---|
committer | jsing <> | 2016-12-21 16:44:31 +0000 |
commit | 6e8ed6997ed910925a8bd07c763df51e7d9fad26 (patch) | |
tree | f6cf578a76dfa7785435b0a23d672ccd20cb86f2 /src/lib | |
parent | 8815d5c3f9c607a6753e58d4c790a789abf0d2e2 (diff) | |
download | openbsd-6e8ed6997ed910925a8bd07c763df51e7d9fad26.tar.gz openbsd-6e8ed6997ed910925a8bd07c763df51e7d9fad26.tar.bz2 openbsd-6e8ed6997ed910925a8bd07c763df51e7d9fad26.zip |
Add support for ECDHE with X25519.
Testing of an earlier revision by naddy@.
ok beck@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/s3_clnt.c | 260 | ||||
-rw-r--r-- | src/lib/libssl/s3_lib.c | 12 | ||||
-rw-r--r-- | src/lib/libssl/s3_srvr.c | 117 | ||||
-rw-r--r-- | src/lib/libssl/ssl3.h | 4 | ||||
-rw-r--r-- | src/lib/libssl/ssl_cert.c | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 8 |
7 files changed, 316 insertions, 91 deletions
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c index be6e461a1e..07457e95a7 100644 --- a/src/lib/libssl/s3_clnt.c +++ b/src/lib/libssl/s3_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_clnt.c,v 1.156 2016/12/18 13:52:53 jsing Exp $ */ | 1 | /* $OpenBSD: s3_clnt.c,v 1.157 2016/12/21 16:44:31 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 | * |
@@ -156,6 +156,7 @@ | |||
156 | 156 | ||
157 | #include <openssl/bn.h> | 157 | #include <openssl/bn.h> |
158 | #include <openssl/buffer.h> | 158 | #include <openssl/buffer.h> |
159 | #include <openssl/curve25519.h> | ||
159 | #include <openssl/dh.h> | 160 | #include <openssl/dh.h> |
160 | #include <openssl/evp.h> | 161 | #include <openssl/evp.h> |
161 | #include <openssl/md5.h> | 162 | #include <openssl/md5.h> |
@@ -1184,19 +1185,99 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) | |||
1184 | } | 1185 | } |
1185 | 1186 | ||
1186 | static int | 1187 | static int |
1188 | ssl3_get_server_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, int nid, CBS *public) | ||
1189 | { | ||
1190 | const EC_GROUP *group; | ||
1191 | EC_GROUP *ngroup = NULL; | ||
1192 | EC_POINT *point = NULL; | ||
1193 | BN_CTX *bn_ctx = NULL; | ||
1194 | EC_KEY *ecdh = NULL; | ||
1195 | int ret = -1; | ||
1196 | |||
1197 | /* | ||
1198 | * Extract the server's ephemeral ECDH public key. | ||
1199 | */ | ||
1200 | |||
1201 | if ((ecdh = EC_KEY_new()) == NULL) { | ||
1202 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); | ||
1203 | goto err; | ||
1204 | } | ||
1205 | |||
1206 | if ((ngroup = EC_GROUP_new_by_curve_name(nid)) == NULL) { | ||
1207 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); | ||
1208 | goto err; | ||
1209 | } | ||
1210 | if (EC_KEY_set_group(ecdh, ngroup) == 0) { | ||
1211 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); | ||
1212 | goto err; | ||
1213 | } | ||
1214 | |||
1215 | group = EC_KEY_get0_group(ecdh); | ||
1216 | |||
1217 | if ((point = EC_POINT_new(group)) == NULL || | ||
1218 | (bn_ctx = BN_CTX_new()) == NULL) { | ||
1219 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); | ||
1220 | goto err; | ||
1221 | } | ||
1222 | |||
1223 | if (EC_POINT_oct2point(group, point, CBS_data(public), | ||
1224 | CBS_len(public), bn_ctx) == 0) { | ||
1225 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); | ||
1226 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | ||
1227 | goto err; | ||
1228 | } | ||
1229 | |||
1230 | EC_KEY_set_public_key(ecdh, point); | ||
1231 | sc->peer_ecdh_tmp = ecdh; | ||
1232 | ecdh = NULL; | ||
1233 | |||
1234 | ret = 1; | ||
1235 | |||
1236 | err: | ||
1237 | BN_CTX_free(bn_ctx); | ||
1238 | EC_GROUP_free(ngroup); | ||
1239 | EC_POINT_free(point); | ||
1240 | EC_KEY_free(ecdh); | ||
1241 | |||
1242 | return (ret); | ||
1243 | } | ||
1244 | |||
1245 | static int | ||
1246 | ssl3_get_server_kex_ecdhe_ecx(SSL *s, SESS_CERT *sc, int nid, CBS *public) | ||
1247 | { | ||
1248 | size_t outlen; | ||
1249 | |||
1250 | if (nid != NID_X25519) { | ||
1251 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); | ||
1252 | goto err; | ||
1253 | } | ||
1254 | |||
1255 | if (CBS_len(public) != X25519_KEY_LENGTH) { | ||
1256 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); | ||
1257 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | ||
1258 | goto err; | ||
1259 | } | ||
1260 | |||
1261 | if (!CBS_stow(public, &sc->peer_x25519_tmp, &outlen)) { | ||
1262 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); | ||
1263 | goto err; | ||
1264 | } | ||
1265 | |||
1266 | return (1); | ||
1267 | |||
1268 | err: | ||
1269 | return (-1); | ||
1270 | } | ||
1271 | |||
1272 | static int | ||
1187 | ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) | 1273 | ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) |
1188 | { | 1274 | { |
1189 | CBS cbs, ecpoint; | 1275 | CBS cbs, public; |
1190 | uint8_t curve_type; | 1276 | uint8_t curve_type; |
1191 | uint16_t curve_id; | 1277 | uint16_t curve_id; |
1192 | EC_POINT *srvr_ecpoint = NULL; | ||
1193 | EC_KEY *ecdh = NULL; | ||
1194 | BN_CTX *bn_ctx = NULL; | ||
1195 | const EC_GROUP *group; | ||
1196 | EC_GROUP *ngroup = NULL; | ||
1197 | SESS_CERT *sc; | 1278 | SESS_CERT *sc; |
1198 | int curve_nid; | ||
1199 | long alg_a; | 1279 | long alg_a; |
1280 | int nid; | ||
1200 | int al; | 1281 | int al; |
1201 | 1282 | ||
1202 | alg_a = s->s3->tmp.new_cipher->algorithm_auth; | 1283 | alg_a = s->s3->tmp.new_cipher->algorithm_auth; |
@@ -1207,15 +1288,6 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) | |||
1207 | 1288 | ||
1208 | CBS_init(&cbs, *pp, *nn); | 1289 | CBS_init(&cbs, *pp, *nn); |
1209 | 1290 | ||
1210 | /* | ||
1211 | * Extract EC parameters and the server's ephemeral ECDH public key. | ||
1212 | */ | ||
1213 | |||
1214 | if ((ecdh = EC_KEY_new()) == NULL) { | ||
1215 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); | ||
1216 | goto err; | ||
1217 | } | ||
1218 | |||
1219 | /* Only named curves are supported. */ | 1291 | /* Only named curves are supported. */ |
1220 | if (!CBS_get_u8(&cbs, &curve_type) || | 1292 | if (!CBS_get_u8(&cbs, &curve_type) || |
1221 | curve_type != NAMED_CURVE_TYPE || | 1293 | curve_type != NAMED_CURVE_TYPE || |
@@ -1235,39 +1307,22 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) | |||
1235 | goto f_err; | 1307 | goto f_err; |
1236 | } | 1308 | } |
1237 | 1309 | ||
1238 | if ((curve_nid = tls1_ec_curve_id2nid(curve_id)) == 0) { | 1310 | if ((nid = tls1_ec_curve_id2nid(curve_id)) == 0) { |
1239 | al = SSL_AD_INTERNAL_ERROR; | 1311 | al = SSL_AD_INTERNAL_ERROR; |
1240 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, | 1312 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, |
1241 | SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); | 1313 | SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); |
1242 | goto f_err; | 1314 | goto f_err; |
1243 | } | 1315 | } |
1244 | 1316 | ||
1245 | if ((ngroup = EC_GROUP_new_by_curve_name(curve_nid)) == NULL) { | 1317 | if (!CBS_get_u8_length_prefixed(&cbs, &public)) |
1246 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); | ||
1247 | goto err; | ||
1248 | } | ||
1249 | if (EC_KEY_set_group(ecdh, ngroup) == 0) { | ||
1250 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); | ||
1251 | goto err; | ||
1252 | } | ||
1253 | |||
1254 | group = EC_KEY_get0_group(ecdh); | ||
1255 | |||
1256 | /* Next, get the encoded ECPoint */ | ||
1257 | if ((srvr_ecpoint = EC_POINT_new(group)) == NULL || | ||
1258 | (bn_ctx = BN_CTX_new()) == NULL) { | ||
1259 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); | ||
1260 | goto err; | ||
1261 | } | ||
1262 | |||
1263 | if (!CBS_get_u8_length_prefixed(&cbs, &ecpoint)) | ||
1264 | goto truncated; | 1318 | goto truncated; |
1265 | 1319 | ||
1266 | if (EC_POINT_oct2point(group, srvr_ecpoint, CBS_data(&ecpoint), | 1320 | if (nid == NID_X25519) { |
1267 | CBS_len(&ecpoint), bn_ctx) == 0) { | 1321 | if (ssl3_get_server_kex_ecdhe_ecx(s, sc, nid, &public) != 1) |
1268 | al = SSL_AD_DECODE_ERROR; | 1322 | goto err; |
1269 | SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); | 1323 | } else { |
1270 | goto f_err; | 1324 | if (ssl3_get_server_kex_ecdhe_ecp(s, sc, nid, &public) != 1) |
1325 | goto err; | ||
1271 | } | 1326 | } |
1272 | 1327 | ||
1273 | /* | 1328 | /* |
@@ -1283,13 +1338,6 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) | |||
1283 | /* XXX - Anonymous ECDH, so no certificate or pkey. */ | 1338 | /* XXX - Anonymous ECDH, so no certificate or pkey. */ |
1284 | *pkey = NULL; | 1339 | *pkey = NULL; |
1285 | 1340 | ||
1286 | EC_KEY_set_public_key(ecdh, srvr_ecpoint); | ||
1287 | sc->peer_ecdh_tmp = ecdh; | ||
1288 | |||
1289 | BN_CTX_free(bn_ctx); | ||
1290 | EC_GROUP_free(ngroup); | ||
1291 | EC_POINT_free(srvr_ecpoint); | ||
1292 | |||
1293 | *nn = CBS_len(&cbs); | 1341 | *nn = CBS_len(&cbs); |
1294 | *pp = (unsigned char *)CBS_data(&cbs); | 1342 | *pp = (unsigned char *)CBS_data(&cbs); |
1295 | 1343 | ||
@@ -1303,11 +1351,6 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) | |||
1303 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 1351 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
1304 | 1352 | ||
1305 | err: | 1353 | err: |
1306 | BN_CTX_free(bn_ctx); | ||
1307 | EC_GROUP_free(ngroup); | ||
1308 | EC_POINT_free(srvr_ecpoint); | ||
1309 | EC_KEY_free(ecdh); | ||
1310 | |||
1311 | return (-1); | 1354 | return (-1); |
1312 | } | 1355 | } |
1313 | 1356 | ||
@@ -1360,6 +1403,9 @@ ssl3_get_server_key_exchange(SSL *s) | |||
1360 | 1403 | ||
1361 | EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); | 1404 | EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); |
1362 | s->session->sess_cert->peer_ecdh_tmp = NULL; | 1405 | s->session->sess_cert->peer_ecdh_tmp = NULL; |
1406 | |||
1407 | free(s->session->sess_cert->peer_x25519_tmp); | ||
1408 | s->session->sess_cert->peer_x25519_tmp = NULL; | ||
1363 | } else { | 1409 | } else { |
1364 | s->session->sess_cert = ssl_sess_cert_new(); | 1410 | s->session->sess_cert = ssl_sess_cert_new(); |
1365 | if (s->session->sess_cert == NULL) | 1411 | if (s->session->sess_cert == NULL) |
@@ -2010,11 +2056,11 @@ err: | |||
2010 | } | 2056 | } |
2011 | 2057 | ||
2012 | static int | 2058 | static int |
2013 | ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | 2059 | ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb) |
2014 | { | 2060 | { |
2015 | EC_KEY *clnt_ecdh = NULL; | 2061 | const EC_GROUP *group = NULL; |
2016 | const EC_GROUP *srvr_group = NULL; | 2062 | const EC_POINT *point = NULL; |
2017 | const EC_POINT *srvr_ecpoint = NULL; | 2063 | EC_KEY *ecdh = NULL; |
2018 | BN_CTX *bn_ctx = NULL; | 2064 | BN_CTX *bn_ctx = NULL; |
2019 | unsigned char *key = NULL; | 2065 | unsigned char *key = NULL; |
2020 | unsigned char *data; | 2066 | unsigned char *data; |
@@ -2023,40 +2069,30 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2023 | int ret = -1; | 2069 | int ret = -1; |
2024 | CBB ecpoint; | 2070 | CBB ecpoint; |
2025 | 2071 | ||
2026 | if (sess_cert->peer_ecdh_tmp == NULL) { | 2072 | if ((group = EC_KEY_get0_group(sc->peer_ecdh_tmp)) == NULL || |
2027 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); | 2073 | (point = EC_KEY_get0_public_key(sc->peer_ecdh_tmp)) == NULL) { |
2028 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2074 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2029 | ERR_R_INTERNAL_ERROR); | 2075 | ERR_R_INTERNAL_ERROR); |
2030 | goto err; | 2076 | goto err; |
2031 | } | 2077 | } |
2032 | 2078 | ||
2033 | srvr_group = EC_KEY_get0_group(sess_cert->peer_ecdh_tmp); | 2079 | if ((ecdh = EC_KEY_new()) == NULL) { |
2034 | srvr_ecpoint = EC_KEY_get0_public_key(sess_cert->peer_ecdh_tmp); | ||
2035 | |||
2036 | if (srvr_group == NULL || srvr_ecpoint == NULL) { | ||
2037 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2038 | ERR_R_INTERNAL_ERROR); | ||
2039 | goto err; | ||
2040 | } | ||
2041 | |||
2042 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { | ||
2043 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2080 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2044 | ERR_R_MALLOC_FAILURE); | 2081 | ERR_R_MALLOC_FAILURE); |
2045 | goto err; | 2082 | goto err; |
2046 | } | 2083 | } |
2047 | 2084 | ||
2048 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { | 2085 | if (!EC_KEY_set_group(ecdh, group)) { |
2049 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); | 2086 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); |
2050 | goto err; | 2087 | goto err; |
2051 | } | 2088 | } |
2052 | 2089 | ||
2053 | /* Generate a new ECDH key pair. */ | 2090 | /* Generate a new ECDH key pair. */ |
2054 | if (!(EC_KEY_generate_key(clnt_ecdh))) { | 2091 | if (!(EC_KEY_generate_key(ecdh))) { |
2055 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | 2092 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); |
2056 | goto err; | 2093 | goto err; |
2057 | } | 2094 | } |
2058 | key_size = ECDH_size(clnt_ecdh); | 2095 | if ((key_size = ECDH_size(ecdh)) <= 0) { |
2059 | if (key_size <= 0) { | ||
2060 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | 2096 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); |
2061 | goto err; | 2097 | goto err; |
2062 | } | 2098 | } |
@@ -2064,7 +2100,7 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2064 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2100 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2065 | ERR_R_MALLOC_FAILURE); | 2101 | ERR_R_MALLOC_FAILURE); |
2066 | } | 2102 | } |
2067 | key_len = ECDH_compute_key(key, key_size, srvr_ecpoint, clnt_ecdh, NULL); | 2103 | key_len = ECDH_compute_key(key, key_size, point, ecdh, NULL); |
2068 | if (key_len <= 0) { | 2104 | if (key_len <= 0) { |
2069 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | 2105 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); |
2070 | goto err; | 2106 | goto err; |
@@ -2075,8 +2111,7 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2075 | s->method->ssl3_enc->generate_master_secret(s, | 2111 | s->method->ssl3_enc->generate_master_secret(s, |
2076 | s->session->master_key, key, key_len); | 2112 | s->session->master_key, key, key_len); |
2077 | 2113 | ||
2078 | encoded_len = EC_POINT_point2oct(srvr_group, | 2114 | encoded_len = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), |
2079 | EC_KEY_get0_public_key(clnt_ecdh), | ||
2080 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | 2115 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); |
2081 | if (encoded_len == 0) { | 2116 | if (encoded_len == 0) { |
2082 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | 2117 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); |
@@ -2094,7 +2129,7 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2094 | goto err; | 2129 | goto err; |
2095 | if (!CBB_add_space(&ecpoint, &data, encoded_len)) | 2130 | if (!CBB_add_space(&ecpoint, &data, encoded_len)) |
2096 | goto err; | 2131 | goto err; |
2097 | if (EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh), | 2132 | if (EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), |
2098 | POINT_CONVERSION_UNCOMPRESSED, data, encoded_len, | 2133 | POINT_CONVERSION_UNCOMPRESSED, data, encoded_len, |
2099 | bn_ctx) == 0) | 2134 | bn_ctx) == 0) |
2100 | goto err; | 2135 | goto err; |
@@ -2108,13 +2143,78 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | |||
2108 | explicit_bzero(key, key_size); | 2143 | explicit_bzero(key, key_size); |
2109 | free(key); | 2144 | free(key); |
2110 | 2145 | ||
2111 | BN_CTX_free(bn_ctx); | 2146 | return (ret); |
2112 | EC_KEY_free(clnt_ecdh); | 2147 | } |
2148 | |||
2149 | static int | ||
2150 | ssl3_send_client_kex_ecdhe_ecx(SSL *s, SESS_CERT *sc, CBB *cbb) | ||
2151 | { | ||
2152 | uint8_t *public_key = NULL, *private_key = NULL, *shared_key = NULL; | ||
2153 | int ret = -1; | ||
2154 | CBB ecpoint; | ||
2155 | |||
2156 | /* Generate X25519 key pair and derive shared key. */ | ||
2157 | if ((public_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
2158 | goto err; | ||
2159 | if ((private_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
2160 | goto err; | ||
2161 | if ((shared_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
2162 | goto err; | ||
2163 | X25519_keypair(public_key, private_key); | ||
2164 | if (!X25519(shared_key, private_key, sc->peer_x25519_tmp)) | ||
2165 | goto err; | ||
2166 | |||
2167 | /* Serialize the public key. */ | ||
2168 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) | ||
2169 | goto err; | ||
2170 | if (!CBB_add_bytes(&ecpoint, public_key, X25519_KEY_LENGTH)) | ||
2171 | goto err; | ||
2172 | if (!CBB_flush(cbb)) | ||
2173 | goto err; | ||
2174 | |||
2175 | /* Generate master key from the result. */ | ||
2176 | s->session->master_key_length = | ||
2177 | s->method->ssl3_enc->generate_master_secret(s, | ||
2178 | s->session->master_key, shared_key, X25519_KEY_LENGTH); | ||
2179 | |||
2180 | ret = 1; | ||
2181 | |||
2182 | err: | ||
2183 | if (private_key != NULL) | ||
2184 | explicit_bzero(private_key, X25519_KEY_LENGTH); | ||
2185 | if (shared_key != NULL) | ||
2186 | explicit_bzero(shared_key, X25519_KEY_LENGTH); | ||
2187 | |||
2188 | free(public_key); | ||
2189 | free(private_key); | ||
2190 | free(shared_key); | ||
2113 | 2191 | ||
2114 | return (ret); | 2192 | return (ret); |
2115 | } | 2193 | } |
2116 | 2194 | ||
2117 | static int | 2195 | static int |
2196 | ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sc, CBB *cbb) | ||
2197 | { | ||
2198 | if (sc->peer_x25519_tmp != NULL) { | ||
2199 | if (ssl3_send_client_kex_ecdhe_ecx(s, sc, cbb) != 1) | ||
2200 | goto err; | ||
2201 | } else if (sc->peer_ecdh_tmp != NULL) { | ||
2202 | if (ssl3_send_client_kex_ecdhe_ecp(s, sc, cbb) != 1) | ||
2203 | goto err; | ||
2204 | } else { | ||
2205 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); | ||
2206 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2207 | ERR_R_INTERNAL_ERROR); | ||
2208 | goto err; | ||
2209 | } | ||
2210 | |||
2211 | return (1); | ||
2212 | |||
2213 | err: | ||
2214 | return (-1); | ||
2215 | } | ||
2216 | |||
2217 | static int | ||
2118 | ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb) | 2218 | ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb) |
2119 | { | 2219 | { |
2120 | unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; | 2220 | unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; |
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index db9292172d..212de5f7a4 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_lib.c,v 1.113 2016/12/06 13:17:52 jsing Exp $ */ | 1 | /* $OpenBSD: s3_lib.c,v 1.114 2016/12/21 16:44:31 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 | * |
@@ -151,6 +151,7 @@ | |||
151 | #include <limits.h> | 151 | #include <limits.h> |
152 | #include <stdio.h> | 152 | #include <stdio.h> |
153 | 153 | ||
154 | #include <openssl/curve25519.h> | ||
154 | #include <openssl/dh.h> | 155 | #include <openssl/dh.h> |
155 | #include <openssl/md5.h> | 156 | #include <openssl/md5.h> |
156 | #include <openssl/objects.h> | 157 | #include <openssl/objects.h> |
@@ -1835,6 +1836,10 @@ ssl3_free(SSL *s) | |||
1835 | DH_free(s->s3->tmp.dh); | 1836 | DH_free(s->s3->tmp.dh); |
1836 | EC_KEY_free(s->s3->tmp.ecdh); | 1837 | EC_KEY_free(s->s3->tmp.ecdh); |
1837 | 1838 | ||
1839 | if (s->s3->tmp.x25519 != NULL) | ||
1840 | explicit_bzero(s->s3->tmp.x25519, X25519_KEY_LENGTH); | ||
1841 | free(s->s3->tmp.x25519); | ||
1842 | |||
1838 | if (s->s3->tmp.ca_names != NULL) | 1843 | if (s->s3->tmp.ca_names != NULL) |
1839 | sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); | 1844 | sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); |
1840 | BIO_free(s->s3->handshake_buffer); | 1845 | BIO_free(s->s3->handshake_buffer); |
@@ -1861,6 +1866,11 @@ ssl3_clear(SSL *s) | |||
1861 | EC_KEY_free(s->s3->tmp.ecdh); | 1866 | EC_KEY_free(s->s3->tmp.ecdh); |
1862 | s->s3->tmp.ecdh = NULL; | 1867 | s->s3->tmp.ecdh = NULL; |
1863 | 1868 | ||
1869 | if (s->s3->tmp.x25519 != NULL) | ||
1870 | explicit_bzero(s->s3->tmp.x25519, X25519_KEY_LENGTH); | ||
1871 | free(s->s3->tmp.x25519); | ||
1872 | s->s3->tmp.x25519 = NULL; | ||
1873 | |||
1864 | rp = s->s3->rbuf.buf; | 1874 | rp = s->s3->rbuf.buf; |
1865 | wp = s->s3->wbuf.buf; | 1875 | wp = s->s3->wbuf.buf; |
1866 | rlen = s->s3->rbuf.len; | 1876 | rlen = s->s3->rbuf.len; |
diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c index 3dd085115d..8e3dc11fc1 100644 --- a/src/lib/libssl/s3_srvr.c +++ b/src/lib/libssl/s3_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_srvr.c,v 1.137 2016/12/07 13:18:38 jsing Exp $ */ | 1 | /* $OpenBSD: s3_srvr.c,v 1.138 2016/12/21 16:44:31 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 | * |
@@ -154,6 +154,7 @@ | |||
154 | 154 | ||
155 | #include <openssl/bn.h> | 155 | #include <openssl/bn.h> |
156 | #include <openssl/buffer.h> | 156 | #include <openssl/buffer.h> |
157 | #include <openssl/curve25519.h> | ||
157 | #include <openssl/evp.h> | 158 | #include <openssl/evp.h> |
158 | #include <openssl/dh.h> | 159 | #include <openssl/dh.h> |
159 | #ifndef OPENSSL_NO_GOST | 160 | #ifndef OPENSSL_NO_GOST |
@@ -1268,8 +1269,8 @@ ssl3_send_server_kex_dhe(SSL *s, CBB *cbb) | |||
1268 | return (-1); | 1269 | return (-1); |
1269 | } | 1270 | } |
1270 | 1271 | ||
1271 | int | 1272 | static int |
1272 | ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) | 1273 | ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb) |
1273 | { | 1274 | { |
1274 | CBB ecpoint; | 1275 | CBB ecpoint; |
1275 | unsigned char *data; | 1276 | unsigned char *data; |
@@ -1283,7 +1284,6 @@ ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) | |||
1283 | 1284 | ||
1284 | ecdhp = s->cert->ecdh_tmp; | 1285 | ecdhp = s->cert->ecdh_tmp; |
1285 | if (s->cert->ecdh_tmp_auto != 0) { | 1286 | if (s->cert->ecdh_tmp_auto != 0) { |
1286 | int nid = tls1_get_shared_curve(s); | ||
1287 | if (nid != NID_undef) | 1287 | if (nid != NID_undef) |
1288 | ecdhp = EC_KEY_new_by_curve_name(nid); | 1288 | ecdhp = EC_KEY_new_by_curve_name(nid); |
1289 | } else if (ecdhp == NULL && s->cert->ecdh_tmp_cb != NULL) { | 1289 | } else if (ecdhp == NULL && s->cert->ecdh_tmp_cb != NULL) { |
@@ -1404,6 +1404,65 @@ ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) | |||
1404 | return (-1); | 1404 | return (-1); |
1405 | } | 1405 | } |
1406 | 1406 | ||
1407 | static int | ||
1408 | ssl3_send_server_kex_ecdhe_ecx(SSL *s, int nid, CBB *cbb) | ||
1409 | { | ||
1410 | uint8_t *public_key = NULL; | ||
1411 | int curve_id; | ||
1412 | CBB ecpoint; | ||
1413 | int ret = -1; | ||
1414 | |||
1415 | /* Generate an X25519 key pair. */ | ||
1416 | if (s->s3->tmp.x25519 != NULL) { | ||
1417 | SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, | ||
1418 | ERR_R_INTERNAL_ERROR); | ||
1419 | goto err; | ||
1420 | } | ||
1421 | if ((s->s3->tmp.x25519 = malloc(X25519_KEY_LENGTH)) == NULL) | ||
1422 | goto err; | ||
1423 | if ((public_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
1424 | goto err; | ||
1425 | X25519_keypair(public_key, s->s3->tmp.x25519); | ||
1426 | |||
1427 | /* Serialize public key. */ | ||
1428 | if ((curve_id = tls1_ec_nid2curve_id(nid)) == 0) { | ||
1429 | SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, | ||
1430 | SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); | ||
1431 | goto err; | ||
1432 | } | ||
1433 | |||
1434 | if (!CBB_add_u8(cbb, NAMED_CURVE_TYPE)) | ||
1435 | goto err; | ||
1436 | if (!CBB_add_u16(cbb, curve_id)) | ||
1437 | goto err; | ||
1438 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) | ||
1439 | goto err; | ||
1440 | if (!CBB_add_bytes(&ecpoint, public_key, X25519_KEY_LENGTH)) | ||
1441 | goto err; | ||
1442 | if (!CBB_flush(cbb)) | ||
1443 | goto err; | ||
1444 | |||
1445 | ret = 1; | ||
1446 | |||
1447 | err: | ||
1448 | free(public_key); | ||
1449 | |||
1450 | return (ret); | ||
1451 | } | ||
1452 | |||
1453 | static int | ||
1454 | ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) | ||
1455 | { | ||
1456 | int nid; | ||
1457 | |||
1458 | nid = tls1_get_shared_curve(s); | ||
1459 | |||
1460 | if (s->cert->ecdh_tmp_auto != 0 && nid == NID_X25519) | ||
1461 | return ssl3_send_server_kex_ecdhe_ecx(s, nid, cbb); | ||
1462 | |||
1463 | return ssl3_send_server_kex_ecdhe_ecp(s, nid, cbb); | ||
1464 | } | ||
1465 | |||
1407 | int | 1466 | int |
1408 | ssl3_send_server_key_exchange(SSL *s) | 1467 | ssl3_send_server_key_exchange(SSL *s) |
1409 | { | 1468 | { |
@@ -1822,7 +1881,7 @@ ssl3_get_client_kex_dhe(SSL *s, unsigned char *p, long n) | |||
1822 | } | 1881 | } |
1823 | 1882 | ||
1824 | static int | 1883 | static int |
1825 | ssl3_get_client_kex_ecdhe(SSL *s, unsigned char *p, long n) | 1884 | ssl3_get_client_kex_ecdhe_ecp(SSL *s, unsigned char *p, long n) |
1826 | { | 1885 | { |
1827 | EC_KEY *srvr_ecdh = NULL; | 1886 | EC_KEY *srvr_ecdh = NULL; |
1828 | EVP_PKEY *clnt_pub_pkey = NULL; | 1887 | EVP_PKEY *clnt_pub_pkey = NULL; |
@@ -1971,6 +2030,54 @@ ssl3_get_client_kex_ecdhe(SSL *s, unsigned char *p, long n) | |||
1971 | } | 2030 | } |
1972 | 2031 | ||
1973 | static int | 2032 | static int |
2033 | ssl3_get_client_kex_ecdhe_ecx(SSL *s, unsigned char *p, long n) | ||
2034 | { | ||
2035 | uint8_t *shared_key = NULL; | ||
2036 | CBS cbs, ecpoint; | ||
2037 | int ret = -1; | ||
2038 | |||
2039 | if (n < 0) | ||
2040 | goto err; | ||
2041 | |||
2042 | CBS_init(&cbs, p, n); | ||
2043 | if (!CBS_get_u8_length_prefixed(&cbs, &ecpoint)) | ||
2044 | goto err; | ||
2045 | if (CBS_len(&ecpoint) != X25519_KEY_LENGTH) | ||
2046 | goto err; | ||
2047 | |||
2048 | if ((shared_key = malloc(X25519_KEY_LENGTH)) == NULL) | ||
2049 | goto err; | ||
2050 | if (!X25519(shared_key, s->s3->tmp.x25519, CBS_data(&ecpoint))) | ||
2051 | goto err; | ||
2052 | |||
2053 | explicit_bzero(s->s3->tmp.x25519, X25519_KEY_LENGTH); | ||
2054 | free(s->s3->tmp.x25519); | ||
2055 | s->s3->tmp.x25519 = NULL; | ||
2056 | |||
2057 | s->session->master_key_length = | ||
2058 | s->method->ssl3_enc->generate_master_secret( | ||
2059 | s, s->session->master_key, shared_key, X25519_KEY_LENGTH); | ||
2060 | |||
2061 | ret = 1; | ||
2062 | |||
2063 | err: | ||
2064 | if (shared_key != NULL) | ||
2065 | explicit_bzero(shared_key, X25519_KEY_LENGTH); | ||
2066 | free(shared_key); | ||
2067 | |||
2068 | return (ret); | ||
2069 | } | ||
2070 | |||
2071 | static int | ||
2072 | ssl3_get_client_kex_ecdhe(SSL *s, unsigned char *p, long n) | ||
2073 | { | ||
2074 | if (s->s3->tmp.x25519 != NULL) | ||
2075 | return ssl3_get_client_kex_ecdhe_ecx(s, p, n); | ||
2076 | |||
2077 | return ssl3_get_client_kex_ecdhe_ecp(s, p, n); | ||
2078 | } | ||
2079 | |||
2080 | static int | ||
1974 | ssl3_get_client_kex_gost(SSL *s, unsigned char *p, long n) | 2081 | ssl3_get_client_kex_gost(SSL *s, unsigned char *p, long n) |
1975 | { | 2082 | { |
1976 | 2083 | ||
diff --git a/src/lib/libssl/ssl3.h b/src/lib/libssl/ssl3.h index 5ec2fe6f88..90fcae7914 100644 --- a/src/lib/libssl/ssl3.h +++ b/src/lib/libssl/ssl3.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl3.h,v 1.41 2015/07/19 06:23:51 doug Exp $ */ | 1 | /* $OpenBSD: ssl3.h,v 1.42 2016/12/21 16:44:31 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 | * |
@@ -440,6 +440,8 @@ typedef struct ssl3_state_st { | |||
440 | 440 | ||
441 | EC_KEY *ecdh; /* holds short lived ECDH key */ | 441 | EC_KEY *ecdh; /* holds short lived ECDH key */ |
442 | 442 | ||
443 | uint8_t *x25519; | ||
444 | |||
443 | /* used when SSL_ST_FLUSH_DATA is entered */ | 445 | /* used when SSL_ST_FLUSH_DATA is entered */ |
444 | int next_state; | 446 | int next_state; |
445 | 447 | ||
diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c index 7e92812e56..294745c9f9 100644 --- a/src/lib/libssl/ssl_cert.c +++ b/src/lib/libssl/ssl_cert.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_cert.c,v 1.52 2016/03/11 07:08:45 mmcc Exp $ */ | 1 | /* $OpenBSD: ssl_cert.c,v 1.53 2016/12/21 16:44:31 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 | * |
@@ -403,6 +403,7 @@ ssl_sess_cert_free(SESS_CERT *sc) | |||
403 | 403 | ||
404 | DH_free(sc->peer_dh_tmp); | 404 | DH_free(sc->peer_dh_tmp); |
405 | EC_KEY_free(sc->peer_ecdh_tmp); | 405 | EC_KEY_free(sc->peer_ecdh_tmp); |
406 | free(sc->peer_x25519_tmp); | ||
406 | 407 | ||
407 | free(sc); | 408 | free(sc); |
408 | } | 409 | } |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index d7484dd7a0..858be71627 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.140 2016/12/18 13:52:53 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.141 2016/12/21 16:44:31 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 | * |
@@ -468,6 +468,7 @@ typedef struct sess_cert_st { | |||
468 | 468 | ||
469 | DH *peer_dh_tmp; | 469 | DH *peer_dh_tmp; |
470 | EC_KEY *peer_ecdh_tmp; | 470 | EC_KEY *peer_ecdh_tmp; |
471 | uint8_t *peer_x25519_tmp; | ||
471 | 472 | ||
472 | int references; /* actually always 1 at the moment */ | 473 | int references; /* actually always 1 at the moment */ |
473 | } SESS_CERT; | 474 | } SESS_CERT; |
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 0a5958341b..4e4fa21687 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_lib.c,v 1.95 2016/12/18 13:52:53 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.96 2016/12/21 16:44:31 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 | * |
@@ -241,7 +241,8 @@ static int nid_list[] = { | |||
241 | NID_secp521r1, /* secp521r1 (25) */ | 241 | NID_secp521r1, /* secp521r1 (25) */ |
242 | NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ | 242 | NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ |
243 | NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ | 243 | NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ |
244 | NID_brainpoolP512r1 /* brainpoolP512r1 (28) */ | 244 | NID_brainpoolP512r1, /* brainpoolP512r1 (28) */ |
245 | NID_X25519, /* X25519 (29) */ | ||
245 | }; | 246 | }; |
246 | 247 | ||
247 | static const uint8_t ecformats_default[] = { | 248 | static const uint8_t ecformats_default[] = { |
@@ -251,6 +252,7 @@ static const uint8_t ecformats_default[] = { | |||
251 | }; | 252 | }; |
252 | 253 | ||
253 | static const uint16_t eccurves_default[] = { | 254 | static const uint16_t eccurves_default[] = { |
255 | 29, /* X25519 (29) */ | ||
254 | 14, /* sect571r1 (14) */ | 256 | 14, /* sect571r1 (14) */ |
255 | 13, /* sect571k1 (13) */ | 257 | 13, /* sect571k1 (13) */ |
256 | 25, /* secp521r1 (25) */ | 258 | 25, /* secp521r1 (25) */ |
@@ -352,6 +354,8 @@ tls1_ec_nid2curve_id(int nid) | |||
352 | return 27; | 354 | return 27; |
353 | case NID_brainpoolP512r1: /* brainpoolP512r1 (28) */ | 355 | case NID_brainpoolP512r1: /* brainpoolP512r1 (28) */ |
354 | return 28; | 356 | return 28; |
357 | case NID_X25519: /* X25519 (29) */ | ||
358 | return 29; | ||
355 | default: | 359 | default: |
356 | return 0; | 360 | return 0; |
357 | } | 361 | } |