xref: /dflybsd-src/crypto/libressl/ssl/tls_key_share.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls_key_share.c,v 1.7 2022/07/02 16:00:12 tb Exp $ */
2*de0e0e4dSAntonio Huete Jimenez /*
3*de0e0e4dSAntonio Huete Jimenez  * Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org>
4*de0e0e4dSAntonio Huete Jimenez  *
5*de0e0e4dSAntonio Huete Jimenez  * Permission to use, copy, modify, and distribute this software for any
6*de0e0e4dSAntonio Huete Jimenez  * purpose with or without fee is hereby granted, provided that the above
7*de0e0e4dSAntonio Huete Jimenez  * copyright notice and this permission notice appear in all copies.
8*de0e0e4dSAntonio Huete Jimenez  *
9*de0e0e4dSAntonio Huete Jimenez  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*de0e0e4dSAntonio Huete Jimenez  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*de0e0e4dSAntonio Huete Jimenez  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*de0e0e4dSAntonio Huete Jimenez  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*de0e0e4dSAntonio Huete Jimenez  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*de0e0e4dSAntonio Huete Jimenez  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*de0e0e4dSAntonio Huete Jimenez  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*de0e0e4dSAntonio Huete Jimenez  */
17*de0e0e4dSAntonio Huete Jimenez 
18*de0e0e4dSAntonio Huete Jimenez #include <stdlib.h>
19*de0e0e4dSAntonio Huete Jimenez 
20*de0e0e4dSAntonio Huete Jimenez #include <openssl/curve25519.h>
21*de0e0e4dSAntonio Huete Jimenez #include <openssl/dh.h>
22*de0e0e4dSAntonio Huete Jimenez #include <openssl/ec.h>
23*de0e0e4dSAntonio Huete Jimenez #include <openssl/evp.h>
24*de0e0e4dSAntonio Huete Jimenez 
25*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h"
26*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
27*de0e0e4dSAntonio Huete Jimenez #include "tls_internal.h"
28*de0e0e4dSAntonio Huete Jimenez 
29*de0e0e4dSAntonio Huete Jimenez struct tls_key_share {
30*de0e0e4dSAntonio Huete Jimenez 	int nid;
31*de0e0e4dSAntonio Huete Jimenez 	uint16_t group_id;
32*de0e0e4dSAntonio Huete Jimenez 	size_t key_bits;
33*de0e0e4dSAntonio Huete Jimenez 
34*de0e0e4dSAntonio Huete Jimenez 	DH *dhe;
35*de0e0e4dSAntonio Huete Jimenez 	DH *dhe_peer;
36*de0e0e4dSAntonio Huete Jimenez 
37*de0e0e4dSAntonio Huete Jimenez 	EC_KEY *ecdhe;
38*de0e0e4dSAntonio Huete Jimenez 	EC_KEY *ecdhe_peer;
39*de0e0e4dSAntonio Huete Jimenez 
40*de0e0e4dSAntonio Huete Jimenez 	uint8_t *x25519_public;
41*de0e0e4dSAntonio Huete Jimenez 	uint8_t *x25519_private;
42*de0e0e4dSAntonio Huete Jimenez 	uint8_t *x25519_peer_public;
43*de0e0e4dSAntonio Huete Jimenez };
44*de0e0e4dSAntonio Huete Jimenez 
45*de0e0e4dSAntonio Huete Jimenez static struct tls_key_share *
tls_key_share_new_internal(int nid,uint16_t group_id)46*de0e0e4dSAntonio Huete Jimenez tls_key_share_new_internal(int nid, uint16_t group_id)
47*de0e0e4dSAntonio Huete Jimenez {
48*de0e0e4dSAntonio Huete Jimenez 	struct tls_key_share *ks;
49*de0e0e4dSAntonio Huete Jimenez 
50*de0e0e4dSAntonio Huete Jimenez 	if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL)
51*de0e0e4dSAntonio Huete Jimenez 		return NULL;
52*de0e0e4dSAntonio Huete Jimenez 
53*de0e0e4dSAntonio Huete Jimenez 	ks->group_id = group_id;
54*de0e0e4dSAntonio Huete Jimenez 	ks->nid = nid;
55*de0e0e4dSAntonio Huete Jimenez 
56*de0e0e4dSAntonio Huete Jimenez 	return ks;
57*de0e0e4dSAntonio Huete Jimenez }
58*de0e0e4dSAntonio Huete Jimenez 
59*de0e0e4dSAntonio Huete Jimenez struct tls_key_share *
tls_key_share_new(uint16_t group_id)60*de0e0e4dSAntonio Huete Jimenez tls_key_share_new(uint16_t group_id)
61*de0e0e4dSAntonio Huete Jimenez {
62*de0e0e4dSAntonio Huete Jimenez 	int nid;
63*de0e0e4dSAntonio Huete Jimenez 
64*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_ec_group_id2nid(group_id, &nid))
65*de0e0e4dSAntonio Huete Jimenez 		return NULL;
66*de0e0e4dSAntonio Huete Jimenez 
67*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_new_internal(nid, group_id);
68*de0e0e4dSAntonio Huete Jimenez }
69*de0e0e4dSAntonio Huete Jimenez 
70*de0e0e4dSAntonio Huete Jimenez struct tls_key_share *
tls_key_share_new_nid(int nid)71*de0e0e4dSAntonio Huete Jimenez tls_key_share_new_nid(int nid)
72*de0e0e4dSAntonio Huete Jimenez {
73*de0e0e4dSAntonio Huete Jimenez 	uint16_t group_id = 0;
74*de0e0e4dSAntonio Huete Jimenez 
75*de0e0e4dSAntonio Huete Jimenez 	if (nid != NID_dhKeyAgreement) {
76*de0e0e4dSAntonio Huete Jimenez 		if (!tls1_ec_nid2group_id(nid, &group_id))
77*de0e0e4dSAntonio Huete Jimenez 			return NULL;
78*de0e0e4dSAntonio Huete Jimenez 	}
79*de0e0e4dSAntonio Huete Jimenez 
80*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_new_internal(nid, group_id);
81*de0e0e4dSAntonio Huete Jimenez }
82*de0e0e4dSAntonio Huete Jimenez 
83*de0e0e4dSAntonio Huete Jimenez void
tls_key_share_free(struct tls_key_share * ks)84*de0e0e4dSAntonio Huete Jimenez tls_key_share_free(struct tls_key_share *ks)
85*de0e0e4dSAntonio Huete Jimenez {
86*de0e0e4dSAntonio Huete Jimenez 	if (ks == NULL)
87*de0e0e4dSAntonio Huete Jimenez 		return;
88*de0e0e4dSAntonio Huete Jimenez 
89*de0e0e4dSAntonio Huete Jimenez 	DH_free(ks->dhe);
90*de0e0e4dSAntonio Huete Jimenez 	DH_free(ks->dhe_peer);
91*de0e0e4dSAntonio Huete Jimenez 
92*de0e0e4dSAntonio Huete Jimenez 	EC_KEY_free(ks->ecdhe);
93*de0e0e4dSAntonio Huete Jimenez 	EC_KEY_free(ks->ecdhe_peer);
94*de0e0e4dSAntonio Huete Jimenez 
95*de0e0e4dSAntonio Huete Jimenez 	freezero(ks->x25519_public, X25519_KEY_LENGTH);
96*de0e0e4dSAntonio Huete Jimenez 	freezero(ks->x25519_private, X25519_KEY_LENGTH);
97*de0e0e4dSAntonio Huete Jimenez 	freezero(ks->x25519_peer_public, X25519_KEY_LENGTH);
98*de0e0e4dSAntonio Huete Jimenez 
99*de0e0e4dSAntonio Huete Jimenez 	freezero(ks, sizeof(*ks));
100*de0e0e4dSAntonio Huete Jimenez }
101*de0e0e4dSAntonio Huete Jimenez 
102*de0e0e4dSAntonio Huete Jimenez uint16_t
tls_key_share_group(struct tls_key_share * ks)103*de0e0e4dSAntonio Huete Jimenez tls_key_share_group(struct tls_key_share *ks)
104*de0e0e4dSAntonio Huete Jimenez {
105*de0e0e4dSAntonio Huete Jimenez 	return ks->group_id;
106*de0e0e4dSAntonio Huete Jimenez }
107*de0e0e4dSAntonio Huete Jimenez 
108*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_nid(struct tls_key_share * ks)109*de0e0e4dSAntonio Huete Jimenez tls_key_share_nid(struct tls_key_share *ks)
110*de0e0e4dSAntonio Huete Jimenez {
111*de0e0e4dSAntonio Huete Jimenez 	return ks->nid;
112*de0e0e4dSAntonio Huete Jimenez }
113*de0e0e4dSAntonio Huete Jimenez 
114*de0e0e4dSAntonio Huete Jimenez void
tls_key_share_set_key_bits(struct tls_key_share * ks,size_t key_bits)115*de0e0e4dSAntonio Huete Jimenez tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits)
116*de0e0e4dSAntonio Huete Jimenez {
117*de0e0e4dSAntonio Huete Jimenez 	ks->key_bits = key_bits;
118*de0e0e4dSAntonio Huete Jimenez }
119*de0e0e4dSAntonio Huete Jimenez 
120*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_set_dh_params(struct tls_key_share * ks,DH * dh_params)121*de0e0e4dSAntonio Huete Jimenez tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params)
122*de0e0e4dSAntonio Huete Jimenez {
123*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid != NID_dhKeyAgreement)
124*de0e0e4dSAntonio Huete Jimenez 		return 0;
125*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe != NULL || ks->dhe_peer != NULL)
126*de0e0e4dSAntonio Huete Jimenez 		return 0;
127*de0e0e4dSAntonio Huete Jimenez 
128*de0e0e4dSAntonio Huete Jimenez 	if ((ks->dhe = DHparams_dup(dh_params)) == NULL)
129*de0e0e4dSAntonio Huete Jimenez 		return 0;
130*de0e0e4dSAntonio Huete Jimenez 	if ((ks->dhe_peer = DHparams_dup(dh_params)) == NULL)
131*de0e0e4dSAntonio Huete Jimenez 		return 0;
132*de0e0e4dSAntonio Huete Jimenez 
133*de0e0e4dSAntonio Huete Jimenez 	return 1;
134*de0e0e4dSAntonio Huete Jimenez }
135*de0e0e4dSAntonio Huete Jimenez 
136*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_peer_pkey(struct tls_key_share * ks,EVP_PKEY * pkey)137*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey)
138*de0e0e4dSAntonio Huete Jimenez {
139*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_dhKeyAgreement && ks->dhe_peer != NULL)
140*de0e0e4dSAntonio Huete Jimenez 		return EVP_PKEY_set1_DH(pkey, ks->dhe_peer);
141*de0e0e4dSAntonio Huete Jimenez 
142*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL)
143*de0e0e4dSAntonio Huete Jimenez 		return ssl_kex_dummy_ecdhe_x25519(pkey);
144*de0e0e4dSAntonio Huete Jimenez 
145*de0e0e4dSAntonio Huete Jimenez 	if (ks->ecdhe_peer != NULL)
146*de0e0e4dSAntonio Huete Jimenez 		return EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer);
147*de0e0e4dSAntonio Huete Jimenez 
148*de0e0e4dSAntonio Huete Jimenez 	return 0;
149*de0e0e4dSAntonio Huete Jimenez }
150*de0e0e4dSAntonio Huete Jimenez 
151*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_generate_dhe(struct tls_key_share * ks)152*de0e0e4dSAntonio Huete Jimenez tls_key_share_generate_dhe(struct tls_key_share *ks)
153*de0e0e4dSAntonio Huete Jimenez {
154*de0e0e4dSAntonio Huete Jimenez 	/*
155*de0e0e4dSAntonio Huete Jimenez 	 * If auto params are not being used then we must already have DH
156*de0e0e4dSAntonio Huete Jimenez 	 * parameters set.
157*de0e0e4dSAntonio Huete Jimenez 	 */
158*de0e0e4dSAntonio Huete Jimenez 	if (ks->key_bits == 0) {
159*de0e0e4dSAntonio Huete Jimenez 		if (ks->dhe == NULL)
160*de0e0e4dSAntonio Huete Jimenez 			return 0;
161*de0e0e4dSAntonio Huete Jimenez 
162*de0e0e4dSAntonio Huete Jimenez 		return ssl_kex_generate_dhe(ks->dhe, ks->dhe);
163*de0e0e4dSAntonio Huete Jimenez 	}
164*de0e0e4dSAntonio Huete Jimenez 
165*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe != NULL || ks->dhe_peer != NULL)
166*de0e0e4dSAntonio Huete Jimenez 		return 0;
167*de0e0e4dSAntonio Huete Jimenez 
168*de0e0e4dSAntonio Huete Jimenez 	if ((ks->dhe = DH_new()) == NULL)
169*de0e0e4dSAntonio Huete Jimenez 		return 0;
170*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_kex_generate_dhe_params_auto(ks->dhe, ks->key_bits))
171*de0e0e4dSAntonio Huete Jimenez 		return 0;
172*de0e0e4dSAntonio Huete Jimenez 	if ((ks->dhe_peer = DHparams_dup(ks->dhe)) == NULL)
173*de0e0e4dSAntonio Huete Jimenez 		return 0;
174*de0e0e4dSAntonio Huete Jimenez 
175*de0e0e4dSAntonio Huete Jimenez 	return 1;
176*de0e0e4dSAntonio Huete Jimenez }
177*de0e0e4dSAntonio Huete Jimenez 
178*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_generate_ecdhe_ecp(struct tls_key_share * ks)179*de0e0e4dSAntonio Huete Jimenez tls_key_share_generate_ecdhe_ecp(struct tls_key_share *ks)
180*de0e0e4dSAntonio Huete Jimenez {
181*de0e0e4dSAntonio Huete Jimenez 	EC_KEY *ecdhe = NULL;
182*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
183*de0e0e4dSAntonio Huete Jimenez 
184*de0e0e4dSAntonio Huete Jimenez 	if (ks->ecdhe != NULL)
185*de0e0e4dSAntonio Huete Jimenez 		goto err;
186*de0e0e4dSAntonio Huete Jimenez 
187*de0e0e4dSAntonio Huete Jimenez 	if ((ecdhe = EC_KEY_new()) == NULL)
188*de0e0e4dSAntonio Huete Jimenez 		goto err;
189*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid))
190*de0e0e4dSAntonio Huete Jimenez 		goto err;
191*de0e0e4dSAntonio Huete Jimenez 
192*de0e0e4dSAntonio Huete Jimenez 	ks->ecdhe = ecdhe;
193*de0e0e4dSAntonio Huete Jimenez 	ecdhe = NULL;
194*de0e0e4dSAntonio Huete Jimenez 
195*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
196*de0e0e4dSAntonio Huete Jimenez 
197*de0e0e4dSAntonio Huete Jimenez  err:
198*de0e0e4dSAntonio Huete Jimenez 	EC_KEY_free(ecdhe);
199*de0e0e4dSAntonio Huete Jimenez 
200*de0e0e4dSAntonio Huete Jimenez 	return ret;
201*de0e0e4dSAntonio Huete Jimenez }
202*de0e0e4dSAntonio Huete Jimenez 
203*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_generate_x25519(struct tls_key_share * ks)204*de0e0e4dSAntonio Huete Jimenez tls_key_share_generate_x25519(struct tls_key_share *ks)
205*de0e0e4dSAntonio Huete Jimenez {
206*de0e0e4dSAntonio Huete Jimenez 	uint8_t *public = NULL, *private = NULL;
207*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
208*de0e0e4dSAntonio Huete Jimenez 
209*de0e0e4dSAntonio Huete Jimenez 	if (ks->x25519_public != NULL || ks->x25519_private != NULL)
210*de0e0e4dSAntonio Huete Jimenez 		goto err;
211*de0e0e4dSAntonio Huete Jimenez 
212*de0e0e4dSAntonio Huete Jimenez 	if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL)
213*de0e0e4dSAntonio Huete Jimenez 		goto err;
214*de0e0e4dSAntonio Huete Jimenez 	if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL)
215*de0e0e4dSAntonio Huete Jimenez 		goto err;
216*de0e0e4dSAntonio Huete Jimenez 
217*de0e0e4dSAntonio Huete Jimenez 	X25519_keypair(public, private);
218*de0e0e4dSAntonio Huete Jimenez 
219*de0e0e4dSAntonio Huete Jimenez 	ks->x25519_public = public;
220*de0e0e4dSAntonio Huete Jimenez 	ks->x25519_private = private;
221*de0e0e4dSAntonio Huete Jimenez 	public = NULL;
222*de0e0e4dSAntonio Huete Jimenez 	private = NULL;
223*de0e0e4dSAntonio Huete Jimenez 
224*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
225*de0e0e4dSAntonio Huete Jimenez 
226*de0e0e4dSAntonio Huete Jimenez  err:
227*de0e0e4dSAntonio Huete Jimenez 	freezero(public, X25519_KEY_LENGTH);
228*de0e0e4dSAntonio Huete Jimenez 	freezero(private, X25519_KEY_LENGTH);
229*de0e0e4dSAntonio Huete Jimenez 
230*de0e0e4dSAntonio Huete Jimenez 	return ret;
231*de0e0e4dSAntonio Huete Jimenez }
232*de0e0e4dSAntonio Huete Jimenez 
233*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_generate(struct tls_key_share * ks)234*de0e0e4dSAntonio Huete Jimenez tls_key_share_generate(struct tls_key_share *ks)
235*de0e0e4dSAntonio Huete Jimenez {
236*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_dhKeyAgreement)
237*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_generate_dhe(ks);
238*de0e0e4dSAntonio Huete Jimenez 
239*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_X25519)
240*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_generate_x25519(ks);
241*de0e0e4dSAntonio Huete Jimenez 
242*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_generate_ecdhe_ecp(ks);
243*de0e0e4dSAntonio Huete Jimenez }
244*de0e0e4dSAntonio Huete Jimenez 
245*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_params_dhe(struct tls_key_share * ks,CBB * cbb)246*de0e0e4dSAntonio Huete Jimenez tls_key_share_params_dhe(struct tls_key_share *ks, CBB *cbb)
247*de0e0e4dSAntonio Huete Jimenez {
248*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe == NULL)
249*de0e0e4dSAntonio Huete Jimenez 		return 0;
250*de0e0e4dSAntonio Huete Jimenez 
251*de0e0e4dSAntonio Huete Jimenez 	return ssl_kex_params_dhe(ks->dhe, cbb);
252*de0e0e4dSAntonio Huete Jimenez }
253*de0e0e4dSAntonio Huete Jimenez 
254*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_params(struct tls_key_share * ks,CBB * cbb)255*de0e0e4dSAntonio Huete Jimenez tls_key_share_params(struct tls_key_share *ks, CBB *cbb)
256*de0e0e4dSAntonio Huete Jimenez {
257*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_dhKeyAgreement)
258*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_params_dhe(ks, cbb);
259*de0e0e4dSAntonio Huete Jimenez 
260*de0e0e4dSAntonio Huete Jimenez 	return 0;
261*de0e0e4dSAntonio Huete Jimenez }
262*de0e0e4dSAntonio Huete Jimenez 
263*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_public_dhe(struct tls_key_share * ks,CBB * cbb)264*de0e0e4dSAntonio Huete Jimenez tls_key_share_public_dhe(struct tls_key_share *ks, CBB *cbb)
265*de0e0e4dSAntonio Huete Jimenez {
266*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe == NULL)
267*de0e0e4dSAntonio Huete Jimenez 		return 0;
268*de0e0e4dSAntonio Huete Jimenez 
269*de0e0e4dSAntonio Huete Jimenez 	return ssl_kex_public_dhe(ks->dhe, cbb);
270*de0e0e4dSAntonio Huete Jimenez }
271*de0e0e4dSAntonio Huete Jimenez 
272*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_public_ecdhe_ecp(struct tls_key_share * ks,CBB * cbb)273*de0e0e4dSAntonio Huete Jimenez tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb)
274*de0e0e4dSAntonio Huete Jimenez {
275*de0e0e4dSAntonio Huete Jimenez 	if (ks->ecdhe == NULL)
276*de0e0e4dSAntonio Huete Jimenez 		return 0;
277*de0e0e4dSAntonio Huete Jimenez 
278*de0e0e4dSAntonio Huete Jimenez 	return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb);
279*de0e0e4dSAntonio Huete Jimenez }
280*de0e0e4dSAntonio Huete Jimenez 
281*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_public_x25519(struct tls_key_share * ks,CBB * cbb)282*de0e0e4dSAntonio Huete Jimenez tls_key_share_public_x25519(struct tls_key_share *ks, CBB *cbb)
283*de0e0e4dSAntonio Huete Jimenez {
284*de0e0e4dSAntonio Huete Jimenez 	if (ks->x25519_public == NULL)
285*de0e0e4dSAntonio Huete Jimenez 		return 0;
286*de0e0e4dSAntonio Huete Jimenez 
287*de0e0e4dSAntonio Huete Jimenez 	return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH);
288*de0e0e4dSAntonio Huete Jimenez }
289*de0e0e4dSAntonio Huete Jimenez 
290*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_public(struct tls_key_share * ks,CBB * cbb)291*de0e0e4dSAntonio Huete Jimenez tls_key_share_public(struct tls_key_share *ks, CBB *cbb)
292*de0e0e4dSAntonio Huete Jimenez {
293*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_dhKeyAgreement)
294*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_public_dhe(ks, cbb);
295*de0e0e4dSAntonio Huete Jimenez 
296*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_X25519)
297*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_public_x25519(ks, cbb);
298*de0e0e4dSAntonio Huete Jimenez 
299*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_public_ecdhe_ecp(ks, cbb);
300*de0e0e4dSAntonio Huete Jimenez }
301*de0e0e4dSAntonio Huete Jimenez 
302*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_peer_params_dhe(struct tls_key_share * ks,CBS * cbs,int * decode_error,int * invalid_params)303*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_params_dhe(struct tls_key_share *ks, CBS *cbs,
304*de0e0e4dSAntonio Huete Jimenez     int *decode_error, int *invalid_params)
305*de0e0e4dSAntonio Huete Jimenez {
306*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe != NULL || ks->dhe_peer != NULL)
307*de0e0e4dSAntonio Huete Jimenez 		return 0;
308*de0e0e4dSAntonio Huete Jimenez 
309*de0e0e4dSAntonio Huete Jimenez 	if ((ks->dhe_peer = DH_new()) == NULL)
310*de0e0e4dSAntonio Huete Jimenez 		return 0;
311*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_kex_peer_params_dhe(ks->dhe_peer, cbs, decode_error,
312*de0e0e4dSAntonio Huete Jimenez 	    invalid_params))
313*de0e0e4dSAntonio Huete Jimenez 		return 0;
314*de0e0e4dSAntonio Huete Jimenez 	if ((ks->dhe = DHparams_dup(ks->dhe_peer)) == NULL)
315*de0e0e4dSAntonio Huete Jimenez 		return 0;
316*de0e0e4dSAntonio Huete Jimenez 
317*de0e0e4dSAntonio Huete Jimenez 	return 1;
318*de0e0e4dSAntonio Huete Jimenez }
319*de0e0e4dSAntonio Huete Jimenez 
320*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_peer_params(struct tls_key_share * ks,CBS * cbs,int * decode_error,int * invalid_params)321*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs,
322*de0e0e4dSAntonio Huete Jimenez     int *decode_error, int *invalid_params)
323*de0e0e4dSAntonio Huete Jimenez {
324*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid != NID_dhKeyAgreement)
325*de0e0e4dSAntonio Huete Jimenez 		return 0;
326*de0e0e4dSAntonio Huete Jimenez 
327*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_peer_params_dhe(ks, cbs, decode_error,
328*de0e0e4dSAntonio Huete Jimenez 	     invalid_params);
329*de0e0e4dSAntonio Huete Jimenez }
330*de0e0e4dSAntonio Huete Jimenez 
331*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_peer_public_dhe(struct tls_key_share * ks,CBS * cbs,int * decode_error,int * invalid_key)332*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_public_dhe(struct tls_key_share *ks, CBS *cbs,
333*de0e0e4dSAntonio Huete Jimenez     int *decode_error, int *invalid_key)
334*de0e0e4dSAntonio Huete Jimenez {
335*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe_peer == NULL)
336*de0e0e4dSAntonio Huete Jimenez 		return 0;
337*de0e0e4dSAntonio Huete Jimenez 
338*de0e0e4dSAntonio Huete Jimenez 	return ssl_kex_peer_public_dhe(ks->dhe_peer, cbs, decode_error,
339*de0e0e4dSAntonio Huete Jimenez 	    invalid_key);
340*de0e0e4dSAntonio Huete Jimenez }
341*de0e0e4dSAntonio Huete Jimenez 
342*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share * ks,CBS * cbs)343*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share *ks, CBS *cbs)
344*de0e0e4dSAntonio Huete Jimenez {
345*de0e0e4dSAntonio Huete Jimenez 	EC_KEY *ecdhe = NULL;
346*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
347*de0e0e4dSAntonio Huete Jimenez 
348*de0e0e4dSAntonio Huete Jimenez 	if (ks->ecdhe_peer != NULL)
349*de0e0e4dSAntonio Huete Jimenez 		goto err;
350*de0e0e4dSAntonio Huete Jimenez 
351*de0e0e4dSAntonio Huete Jimenez 	if ((ecdhe = EC_KEY_new()) == NULL)
352*de0e0e4dSAntonio Huete Jimenez 		goto err;
353*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs))
354*de0e0e4dSAntonio Huete Jimenez 		goto err;
355*de0e0e4dSAntonio Huete Jimenez 
356*de0e0e4dSAntonio Huete Jimenez 	ks->ecdhe_peer = ecdhe;
357*de0e0e4dSAntonio Huete Jimenez 	ecdhe = NULL;
358*de0e0e4dSAntonio Huete Jimenez 
359*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
360*de0e0e4dSAntonio Huete Jimenez 
361*de0e0e4dSAntonio Huete Jimenez  err:
362*de0e0e4dSAntonio Huete Jimenez 	EC_KEY_free(ecdhe);
363*de0e0e4dSAntonio Huete Jimenez 
364*de0e0e4dSAntonio Huete Jimenez 	return ret;
365*de0e0e4dSAntonio Huete Jimenez }
366*de0e0e4dSAntonio Huete Jimenez 
367*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_peer_public_x25519(struct tls_key_share * ks,CBS * cbs,int * decode_error)368*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_public_x25519(struct tls_key_share *ks, CBS *cbs,
369*de0e0e4dSAntonio Huete Jimenez     int *decode_error)
370*de0e0e4dSAntonio Huete Jimenez {
371*de0e0e4dSAntonio Huete Jimenez 	size_t out_len;
372*de0e0e4dSAntonio Huete Jimenez 
373*de0e0e4dSAntonio Huete Jimenez 	*decode_error = 0;
374*de0e0e4dSAntonio Huete Jimenez 
375*de0e0e4dSAntonio Huete Jimenez 	if (ks->x25519_peer_public != NULL)
376*de0e0e4dSAntonio Huete Jimenez 		return 0;
377*de0e0e4dSAntonio Huete Jimenez 
378*de0e0e4dSAntonio Huete Jimenez 	if (CBS_len(cbs) != X25519_KEY_LENGTH) {
379*de0e0e4dSAntonio Huete Jimenez 		*decode_error = 1;
380*de0e0e4dSAntonio Huete Jimenez 		return 0;
381*de0e0e4dSAntonio Huete Jimenez 	}
382*de0e0e4dSAntonio Huete Jimenez 
383*de0e0e4dSAntonio Huete Jimenez 	return CBS_stow(cbs, &ks->x25519_peer_public, &out_len);
384*de0e0e4dSAntonio Huete Jimenez }
385*de0e0e4dSAntonio Huete Jimenez 
386*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_peer_public(struct tls_key_share * ks,CBS * cbs,int * decode_error,int * invalid_key)387*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs, int *decode_error,
388*de0e0e4dSAntonio Huete Jimenez     int *invalid_key)
389*de0e0e4dSAntonio Huete Jimenez {
390*de0e0e4dSAntonio Huete Jimenez 	*decode_error = 0;
391*de0e0e4dSAntonio Huete Jimenez 
392*de0e0e4dSAntonio Huete Jimenez 	if (invalid_key != NULL)
393*de0e0e4dSAntonio Huete Jimenez 		*invalid_key = 0;
394*de0e0e4dSAntonio Huete Jimenez 
395*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_dhKeyAgreement)
396*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_peer_public_dhe(ks, cbs, decode_error,
397*de0e0e4dSAntonio Huete Jimenez 		    invalid_key);
398*de0e0e4dSAntonio Huete Jimenez 
399*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_X25519)
400*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_peer_public_x25519(ks, cbs, decode_error);
401*de0e0e4dSAntonio Huete Jimenez 
402*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_peer_public_ecdhe_ecp(ks, cbs);
403*de0e0e4dSAntonio Huete Jimenez }
404*de0e0e4dSAntonio Huete Jimenez 
405*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_derive_dhe(struct tls_key_share * ks,uint8_t ** shared_key,size_t * shared_key_len)406*de0e0e4dSAntonio Huete Jimenez tls_key_share_derive_dhe(struct tls_key_share *ks,
407*de0e0e4dSAntonio Huete Jimenez     uint8_t **shared_key, size_t *shared_key_len)
408*de0e0e4dSAntonio Huete Jimenez {
409*de0e0e4dSAntonio Huete Jimenez 	if (ks->dhe == NULL || ks->dhe_peer == NULL)
410*de0e0e4dSAntonio Huete Jimenez 		return 0;
411*de0e0e4dSAntonio Huete Jimenez 
412*de0e0e4dSAntonio Huete Jimenez 	return ssl_kex_derive_dhe(ks->dhe, ks->dhe_peer, shared_key,
413*de0e0e4dSAntonio Huete Jimenez 	    shared_key_len);
414*de0e0e4dSAntonio Huete Jimenez }
415*de0e0e4dSAntonio Huete Jimenez 
416*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_derive_ecdhe_ecp(struct tls_key_share * ks,uint8_t ** shared_key,size_t * shared_key_len)417*de0e0e4dSAntonio Huete Jimenez tls_key_share_derive_ecdhe_ecp(struct tls_key_share *ks,
418*de0e0e4dSAntonio Huete Jimenez     uint8_t **shared_key, size_t *shared_key_len)
419*de0e0e4dSAntonio Huete Jimenez {
420*de0e0e4dSAntonio Huete Jimenez 	if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL)
421*de0e0e4dSAntonio Huete Jimenez 		return 0;
422*de0e0e4dSAntonio Huete Jimenez 
423*de0e0e4dSAntonio Huete Jimenez 	return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer,
424*de0e0e4dSAntonio Huete Jimenez 	    shared_key, shared_key_len);
425*de0e0e4dSAntonio Huete Jimenez }
426*de0e0e4dSAntonio Huete Jimenez 
427*de0e0e4dSAntonio Huete Jimenez static int
tls_key_share_derive_x25519(struct tls_key_share * ks,uint8_t ** shared_key,size_t * shared_key_len)428*de0e0e4dSAntonio Huete Jimenez tls_key_share_derive_x25519(struct tls_key_share *ks,
429*de0e0e4dSAntonio Huete Jimenez     uint8_t **shared_key, size_t *shared_key_len)
430*de0e0e4dSAntonio Huete Jimenez {
431*de0e0e4dSAntonio Huete Jimenez 	uint8_t *sk = NULL;
432*de0e0e4dSAntonio Huete Jimenez 	int ret = 0;
433*de0e0e4dSAntonio Huete Jimenez 
434*de0e0e4dSAntonio Huete Jimenez 	if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL)
435*de0e0e4dSAntonio Huete Jimenez 		goto err;
436*de0e0e4dSAntonio Huete Jimenez 
437*de0e0e4dSAntonio Huete Jimenez 	if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL)
438*de0e0e4dSAntonio Huete Jimenez 		goto err;
439*de0e0e4dSAntonio Huete Jimenez 	if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public))
440*de0e0e4dSAntonio Huete Jimenez 		goto err;
441*de0e0e4dSAntonio Huete Jimenez 
442*de0e0e4dSAntonio Huete Jimenez 	*shared_key = sk;
443*de0e0e4dSAntonio Huete Jimenez 	*shared_key_len = X25519_KEY_LENGTH;
444*de0e0e4dSAntonio Huete Jimenez 	sk = NULL;
445*de0e0e4dSAntonio Huete Jimenez 
446*de0e0e4dSAntonio Huete Jimenez 	ret = 1;
447*de0e0e4dSAntonio Huete Jimenez 
448*de0e0e4dSAntonio Huete Jimenez  err:
449*de0e0e4dSAntonio Huete Jimenez 	freezero(sk, X25519_KEY_LENGTH);
450*de0e0e4dSAntonio Huete Jimenez 
451*de0e0e4dSAntonio Huete Jimenez 	return ret;
452*de0e0e4dSAntonio Huete Jimenez }
453*de0e0e4dSAntonio Huete Jimenez 
454*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_derive(struct tls_key_share * ks,uint8_t ** shared_key,size_t * shared_key_len)455*de0e0e4dSAntonio Huete Jimenez tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key,
456*de0e0e4dSAntonio Huete Jimenez     size_t *shared_key_len)
457*de0e0e4dSAntonio Huete Jimenez {
458*de0e0e4dSAntonio Huete Jimenez 	if (*shared_key != NULL)
459*de0e0e4dSAntonio Huete Jimenez 		return 0;
460*de0e0e4dSAntonio Huete Jimenez 
461*de0e0e4dSAntonio Huete Jimenez 	*shared_key_len = 0;
462*de0e0e4dSAntonio Huete Jimenez 
463*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_dhKeyAgreement)
464*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_derive_dhe(ks, shared_key,
465*de0e0e4dSAntonio Huete Jimenez 		    shared_key_len);
466*de0e0e4dSAntonio Huete Jimenez 
467*de0e0e4dSAntonio Huete Jimenez 	if (ks->nid == NID_X25519)
468*de0e0e4dSAntonio Huete Jimenez 		return tls_key_share_derive_x25519(ks, shared_key,
469*de0e0e4dSAntonio Huete Jimenez 		    shared_key_len);
470*de0e0e4dSAntonio Huete Jimenez 
471*de0e0e4dSAntonio Huete Jimenez 	return tls_key_share_derive_ecdhe_ecp(ks, shared_key,
472*de0e0e4dSAntonio Huete Jimenez 	    shared_key_len);
473*de0e0e4dSAntonio Huete Jimenez }
474*de0e0e4dSAntonio Huete Jimenez 
475*de0e0e4dSAntonio Huete Jimenez int
tls_key_share_peer_security(const SSL * ssl,struct tls_key_share * ks)476*de0e0e4dSAntonio Huete Jimenez tls_key_share_peer_security(const SSL *ssl, struct tls_key_share *ks)
477*de0e0e4dSAntonio Huete Jimenez {
478*de0e0e4dSAntonio Huete Jimenez 	switch (ks->nid) {
479*de0e0e4dSAntonio Huete Jimenez 	case NID_dhKeyAgreement:
480*de0e0e4dSAntonio Huete Jimenez 		return ssl_security_dh(ssl, ks->dhe_peer);
481*de0e0e4dSAntonio Huete Jimenez 	default:
482*de0e0e4dSAntonio Huete Jimenez 		return 0;
483*de0e0e4dSAntonio Huete Jimenez 	}
484*de0e0e4dSAntonio Huete Jimenez }
485