summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2016-12-21 16:44:31 +0000
committerjsing <>2016-12-21 16:44:31 +0000
commit6e8ed6997ed910925a8bd07c763df51e7d9fad26 (patch)
treef6cf578a76dfa7785435b0a23d672ccd20cb86f2 /src/lib
parent8815d5c3f9c607a6753e58d4c790a789abf0d2e2 (diff)
downloadopenbsd-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.c260
-rw-r--r--src/lib/libssl/s3_lib.c12
-rw-r--r--src/lib/libssl/s3_srvr.c117
-rw-r--r--src/lib/libssl/ssl3.h4
-rw-r--r--src/lib/libssl/ssl_cert.c3
-rw-r--r--src/lib/libssl/ssl_locl.h3
-rw-r--r--src/lib/libssl/t1_lib.c8
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
1186static int 1187static int
1188ssl3_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
1245static int
1246ssl3_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
1272static int
1187ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) 1273ssl3_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
2012static int 2058static int
2013ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb) 2059ssl3_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
2149static int
2150ssl3_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
2117static int 2195static int
2196ssl3_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
2217static int
2118ssl3_send_client_kex_gost(SSL *s, SESS_CERT *sess_cert, CBB *cbb) 2218ssl3_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
1271int 1272static int
1272ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) 1273ssl3_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
1407static int
1408ssl3_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
1453static int
1454ssl3_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
1407int 1466int
1408ssl3_send_server_key_exchange(SSL *s) 1467ssl3_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
1824static int 1883static int
1825ssl3_get_client_kex_ecdhe(SSL *s, unsigned char *p, long n) 1884ssl3_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
1973static int 2032static int
2033ssl3_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
2071static int
2072ssl3_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
2080static int
1974ssl3_get_client_kex_gost(SSL *s, unsigned char *p, long n) 2081ssl3_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
247static const uint8_t ecformats_default[] = { 248static const uint8_t ecformats_default[] = {
@@ -251,6 +252,7 @@ static const uint8_t ecformats_default[] = {
251}; 252};
252 253
253static const uint16_t eccurves_default[] = { 254static 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 }