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 $ */
22/* Copyright (C) 1995-1998 Eric Young ([email protected] ) 33 * All rights reserved.
44 *
156156
157157#include <openssl/bn.h>
158158#include <openssl/buffer.h>
159+ #include <openssl/curve25519.h>
159160#include <openssl/dh.h>
160161#include <openssl/evp.h>
161162#include <openssl/md5.h>
@@ -1183,20 +1184,100 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
11831184 return (-1 );
11841185}
11851186
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+
11861272static int
11871273ssl3_get_server_kex_ecdhe (SSL * s , EVP_PKEY * * pkey , unsigned char * * pp , long * nn )
11881274{
1189- CBS cbs , ecpoint ;
1275+ CBS cbs , public ;
11901276 uint8_t curve_type ;
11911277 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 ;
11971278 SESS_CERT * sc ;
1198- int curve_nid ;
11991279 long alg_a ;
1280+ int nid ;
12001281 int al ;
12011282
12021283 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)
12071288
12081289 CBS_init (& cbs , * pp , * nn );
12091290
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-
12191291 /* Only named curves are supported. */
12201292 if (!CBS_get_u8 (& cbs , & curve_type ) ||
12211293 curve_type != NAMED_CURVE_TYPE ||
@@ -1235,39 +1307,22 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
12351307 goto f_err ;
12361308 }
12371309
1238- if ((curve_nid = tls1_ec_curve_id2nid (curve_id )) == 0 ) {
1310+ if ((nid = tls1_ec_curve_id2nid (curve_id )) == 0 ) {
12391311 al = SSL_AD_INTERNAL_ERROR ;
12401312 SSLerr (SSL_F_SSL3_GET_KEY_EXCHANGE ,
12411313 SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS );
12421314 goto f_err ;
12431315 }
12441316
1245- if ((ngroup = EC_GROUP_new_by_curve_name (curve_nid )) == NULL ) {
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 ))
1317+ if (!CBS_get_u8_length_prefixed (& cbs , & public ))
12641318 goto truncated ;
12651319
1266- if (EC_POINT_oct2point (group , srvr_ecpoint , CBS_data (& ecpoint ),
1267- CBS_len (& ecpoint ), bn_ctx ) == 0 ) {
1268- al = SSL_AD_DECODE_ERROR ;
1269- SSLerr (SSL_F_SSL3_GET_KEY_EXCHANGE , SSL_R_BAD_ECPOINT );
1270- goto f_err ;
1320+ if (nid == NID_X25519 ) {
1321+ if (ssl3_get_server_kex_ecdhe_ecx (s , sc , nid , & public ) != 1 )
1322+ goto err ;
1323+ } else {
1324+ if (ssl3_get_server_kex_ecdhe_ecp (s , sc , nid , & public ) != 1 )
1325+ goto err ;
12711326 }
12721327
12731328 /*
@@ -1283,13 +1338,6 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
12831338 /* XXX - Anonymous ECDH, so no certificate or pkey. */
12841339 * pkey = NULL ;
12851340
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-
12931341 * nn = CBS_len (& cbs );
12941342 * pp = (unsigned char * )CBS_data (& cbs );
12951343
@@ -1303,11 +1351,6 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
13031351 ssl3_send_alert (s , SSL3_AL_FATAL , al );
13041352
13051353 err :
1306- BN_CTX_free (bn_ctx );
1307- EC_GROUP_free (ngroup );
1308- EC_POINT_free (srvr_ecpoint );
1309- EC_KEY_free (ecdh );
1310-
13111354 return (-1 );
13121355}
13131356
@@ -1360,6 +1403,9 @@ ssl3_get_server_key_exchange(SSL *s)
13601403
13611404 EC_KEY_free (s -> session -> sess_cert -> peer_ecdh_tmp );
13621405 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 ;
13631409 } else {
13641410 s -> session -> sess_cert = ssl_sess_cert_new ();
13651411 if (s -> session -> sess_cert == NULL )
@@ -2010,11 +2056,11 @@ ssl3_send_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
20102056}
20112057
20122058static 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 )
20142060{
2015- EC_KEY * clnt_ecdh = NULL ;
2016- const EC_GROUP * srvr_group = NULL ;
2017- const EC_POINT * srvr_ecpoint = NULL ;
2061+ const EC_GROUP * group = NULL ;
2062+ const EC_POINT * point = NULL ;
2063+ EC_KEY * ecdh = NULL ;
20182064 BN_CTX * bn_ctx = NULL ;
20192065 unsigned char * key = NULL ;
20202066 unsigned char * data ;
@@ -2023,48 +2069,38 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
20232069 int ret = -1 ;
20242070 CBB ecpoint ;
20252071
2026- if (sess_cert -> peer_ecdh_tmp == NULL ) {
2027- ssl3_send_alert ( s , SSL3_AL_FATAL , SSL_AD_HANDSHAKE_FAILURE );
2072+ if (( group = EC_KEY_get0_group ( sc -> peer_ecdh_tmp )) == NULL ||
2073+ ( point = EC_KEY_get0_public_key ( sc -> peer_ecdh_tmp )) == NULL ) {
20282074 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE ,
20292075 ERR_R_INTERNAL_ERROR );
20302076 goto err ;
20312077 }
20322078
2033- srvr_group = EC_KEY_get0_group (sess_cert -> peer_ecdh_tmp );
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 ) {
2079+ if ((ecdh = EC_KEY_new ()) == NULL ) {
20432080 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE ,
20442081 ERR_R_MALLOC_FAILURE );
20452082 goto err ;
20462083 }
20472084
2048- if (!EC_KEY_set_group (clnt_ecdh , srvr_group )) {
2085+ if (!EC_KEY_set_group (ecdh , group )) {
20492086 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE , ERR_R_EC_LIB );
20502087 goto err ;
20512088 }
20522089
20532090 /* Generate a new ECDH key pair. */
2054- if (!(EC_KEY_generate_key (clnt_ecdh ))) {
2091+ if (!(EC_KEY_generate_key (ecdh ))) {
20552092 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE , ERR_R_ECDH_LIB );
20562093 goto err ;
20572094 }
2058- key_size = ECDH_size (clnt_ecdh );
2059- if (key_size <= 0 ) {
2095+ if ((key_size = ECDH_size (ecdh )) <= 0 ) {
20602096 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE , ERR_R_ECDH_LIB );
20612097 goto err ;
20622098 }
20632099 if ((key = malloc (key_size )) == NULL ) {
20642100 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE ,
20652101 ERR_R_MALLOC_FAILURE );
20662102 }
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 );
20682104 if (key_len <= 0 ) {
20692105 SSLerr (SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE , ERR_R_ECDH_LIB );
20702106 goto err ;
@@ -2075,8 +2111,7 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
20752111 s -> method -> ssl3_enc -> generate_master_secret (s ,
20762112 s -> session -> master_key , key , key_len );
20772113
2078- encoded_len = EC_POINT_point2oct (srvr_group ,
2079- EC_KEY_get0_public_key (clnt_ecdh ),
2114+ encoded_len = EC_POINT_point2oct (group , EC_KEY_get0_public_key (ecdh ),
20802115 POINT_CONVERSION_UNCOMPRESSED , NULL , 0 , NULL );
20812116 if (encoded_len == 0 ) {
20822117 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)
20942129 goto err ;
20952130 if (!CBB_add_space (& ecpoint , & data , encoded_len ))
20962131 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 ),
20982133 POINT_CONVERSION_UNCOMPRESSED , data , encoded_len ,
20992134 bn_ctx ) == 0 )
21002135 goto err ;
@@ -2108,12 +2143,77 @@ ssl3_send_client_kex_ecdhe(SSL *s, SESS_CERT *sess_cert, CBB *cbb)
21082143 explicit_bzero (key , key_size );
21092144 free (key );
21102145
2111- BN_CTX_free (bn_ctx );
2112- EC_KEY_free (clnt_ecdh );
2146+ return (ret );
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 );
21132191
21142192 return (ret );
21152193}
21162194
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+
21172217static int
21182218ssl3_send_client_kex_gost (SSL * s , SESS_CERT * sess_cert , CBB * cbb )
21192219{
0 commit comments