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/libssl/s3_srvr.c | |
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/libssl/s3_srvr.c')
-rw-r--r-- | src/lib/libssl/s3_srvr.c | 117 |
1 files changed, 112 insertions, 5 deletions
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 | ||