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