1 /* $OpenBSD: tls_key_share.c,v 1.7 2022/07/02 16:00:12 tb Exp $ */
3 * Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <openssl/curve25519.h>
21 #include <openssl/dh.h>
22 #include <openssl/ec.h>
23 #include <openssl/evp.h>
25 #include "bytestring.h"
27 #include "tls_internal.h"
29 struct tls_key_share
{
40 uint8_t *x25519_public
;
41 uint8_t *x25519_private
;
42 uint8_t *x25519_peer_public
;
45 static struct tls_key_share
*
46 tls_key_share_new_internal(int nid
, uint16_t group_id
)
48 struct tls_key_share
*ks
;
50 if ((ks
= calloc(1, sizeof(struct tls_key_share
))) == NULL
)
53 ks
->group_id
= group_id
;
59 struct tls_key_share
*
60 tls_key_share_new(uint16_t group_id
)
64 if (!tls1_ec_group_id2nid(group_id
, &nid
))
67 return tls_key_share_new_internal(nid
, group_id
);
70 struct tls_key_share
*
71 tls_key_share_new_nid(int nid
)
73 uint16_t group_id
= 0;
75 if (nid
!= NID_dhKeyAgreement
) {
76 if (!tls1_ec_nid2group_id(nid
, &group_id
))
80 return tls_key_share_new_internal(nid
, group_id
);
84 tls_key_share_free(struct tls_key_share
*ks
)
90 DH_free(ks
->dhe_peer
);
92 EC_KEY_free(ks
->ecdhe
);
93 EC_KEY_free(ks
->ecdhe_peer
);
95 freezero(ks
->x25519_public
, X25519_KEY_LENGTH
);
96 freezero(ks
->x25519_private
, X25519_KEY_LENGTH
);
97 freezero(ks
->x25519_peer_public
, X25519_KEY_LENGTH
);
99 freezero(ks
, sizeof(*ks
));
103 tls_key_share_group(struct tls_key_share
*ks
)
109 tls_key_share_nid(struct tls_key_share
*ks
)
115 tls_key_share_set_key_bits(struct tls_key_share
*ks
, size_t key_bits
)
117 ks
->key_bits
= key_bits
;
121 tls_key_share_set_dh_params(struct tls_key_share
*ks
, DH
*dh_params
)
123 if (ks
->nid
!= NID_dhKeyAgreement
)
125 if (ks
->dhe
!= NULL
|| ks
->dhe_peer
!= NULL
)
128 if ((ks
->dhe
= DHparams_dup(dh_params
)) == NULL
)
130 if ((ks
->dhe_peer
= DHparams_dup(dh_params
)) == NULL
)
137 tls_key_share_peer_pkey(struct tls_key_share
*ks
, EVP_PKEY
*pkey
)
139 if (ks
->nid
== NID_dhKeyAgreement
&& ks
->dhe_peer
!= NULL
)
140 return EVP_PKEY_set1_DH(pkey
, ks
->dhe_peer
);
142 if (ks
->nid
== NID_X25519
&& ks
->x25519_peer_public
!= NULL
)
143 return ssl_kex_dummy_ecdhe_x25519(pkey
);
145 if (ks
->ecdhe_peer
!= NULL
)
146 return EVP_PKEY_set1_EC_KEY(pkey
, ks
->ecdhe_peer
);
152 tls_key_share_generate_dhe(struct tls_key_share
*ks
)
155 * If auto params are not being used then we must already have DH
158 if (ks
->key_bits
== 0) {
162 return ssl_kex_generate_dhe(ks
->dhe
, ks
->dhe
);
165 if (ks
->dhe
!= NULL
|| ks
->dhe_peer
!= NULL
)
168 if ((ks
->dhe
= DH_new()) == NULL
)
170 if (!ssl_kex_generate_dhe_params_auto(ks
->dhe
, ks
->key_bits
))
172 if ((ks
->dhe_peer
= DHparams_dup(ks
->dhe
)) == NULL
)
179 tls_key_share_generate_ecdhe_ecp(struct tls_key_share
*ks
)
181 EC_KEY
*ecdhe
= NULL
;
184 if (ks
->ecdhe
!= NULL
)
187 if ((ecdhe
= EC_KEY_new()) == NULL
)
189 if (!ssl_kex_generate_ecdhe_ecp(ecdhe
, ks
->nid
))
204 tls_key_share_generate_x25519(struct tls_key_share
*ks
)
206 uint8_t *public = NULL
, *private = NULL
;
209 if (ks
->x25519_public
!= NULL
|| ks
->x25519_private
!= NULL
)
212 if ((public = calloc(1, X25519_KEY_LENGTH
)) == NULL
)
214 if ((private = calloc(1, X25519_KEY_LENGTH
)) == NULL
)
217 X25519_keypair(public, private);
219 ks
->x25519_public
= public;
220 ks
->x25519_private
= private;
227 freezero(public, X25519_KEY_LENGTH
);
228 freezero(private, X25519_KEY_LENGTH
);
234 tls_key_share_generate(struct tls_key_share
*ks
)
236 if (ks
->nid
== NID_dhKeyAgreement
)
237 return tls_key_share_generate_dhe(ks
);
239 if (ks
->nid
== NID_X25519
)
240 return tls_key_share_generate_x25519(ks
);
242 return tls_key_share_generate_ecdhe_ecp(ks
);
246 tls_key_share_params_dhe(struct tls_key_share
*ks
, CBB
*cbb
)
251 return ssl_kex_params_dhe(ks
->dhe
, cbb
);
255 tls_key_share_params(struct tls_key_share
*ks
, CBB
*cbb
)
257 if (ks
->nid
== NID_dhKeyAgreement
)
258 return tls_key_share_params_dhe(ks
, cbb
);
264 tls_key_share_public_dhe(struct tls_key_share
*ks
, CBB
*cbb
)
269 return ssl_kex_public_dhe(ks
->dhe
, cbb
);
273 tls_key_share_public_ecdhe_ecp(struct tls_key_share
*ks
, CBB
*cbb
)
275 if (ks
->ecdhe
== NULL
)
278 return ssl_kex_public_ecdhe_ecp(ks
->ecdhe
, cbb
);
282 tls_key_share_public_x25519(struct tls_key_share
*ks
, CBB
*cbb
)
284 if (ks
->x25519_public
== NULL
)
287 return CBB_add_bytes(cbb
, ks
->x25519_public
, X25519_KEY_LENGTH
);
291 tls_key_share_public(struct tls_key_share
*ks
, CBB
*cbb
)
293 if (ks
->nid
== NID_dhKeyAgreement
)
294 return tls_key_share_public_dhe(ks
, cbb
);
296 if (ks
->nid
== NID_X25519
)
297 return tls_key_share_public_x25519(ks
, cbb
);
299 return tls_key_share_public_ecdhe_ecp(ks
, cbb
);
303 tls_key_share_peer_params_dhe(struct tls_key_share
*ks
, CBS
*cbs
,
304 int *decode_error
, int *invalid_params
)
306 if (ks
->dhe
!= NULL
|| ks
->dhe_peer
!= NULL
)
309 if ((ks
->dhe_peer
= DH_new()) == NULL
)
311 if (!ssl_kex_peer_params_dhe(ks
->dhe_peer
, cbs
, decode_error
,
314 if ((ks
->dhe
= DHparams_dup(ks
->dhe_peer
)) == NULL
)
321 tls_key_share_peer_params(struct tls_key_share
*ks
, CBS
*cbs
,
322 int *decode_error
, int *invalid_params
)
324 if (ks
->nid
!= NID_dhKeyAgreement
)
327 return tls_key_share_peer_params_dhe(ks
, cbs
, decode_error
,
332 tls_key_share_peer_public_dhe(struct tls_key_share
*ks
, CBS
*cbs
,
333 int *decode_error
, int *invalid_key
)
335 if (ks
->dhe_peer
== NULL
)
338 return ssl_kex_peer_public_dhe(ks
->dhe_peer
, cbs
, decode_error
,
343 tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share
*ks
, CBS
*cbs
)
345 EC_KEY
*ecdhe
= NULL
;
348 if (ks
->ecdhe_peer
!= NULL
)
351 if ((ecdhe
= EC_KEY_new()) == NULL
)
353 if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe
, ks
->nid
, cbs
))
356 ks
->ecdhe_peer
= ecdhe
;
368 tls_key_share_peer_public_x25519(struct tls_key_share
*ks
, CBS
*cbs
,
375 if (ks
->x25519_peer_public
!= NULL
)
378 if (CBS_len(cbs
) != X25519_KEY_LENGTH
) {
383 return CBS_stow(cbs
, &ks
->x25519_peer_public
, &out_len
);
387 tls_key_share_peer_public(struct tls_key_share
*ks
, CBS
*cbs
, int *decode_error
,
392 if (invalid_key
!= NULL
)
395 if (ks
->nid
== NID_dhKeyAgreement
)
396 return tls_key_share_peer_public_dhe(ks
, cbs
, decode_error
,
399 if (ks
->nid
== NID_X25519
)
400 return tls_key_share_peer_public_x25519(ks
, cbs
, decode_error
);
402 return tls_key_share_peer_public_ecdhe_ecp(ks
, cbs
);
406 tls_key_share_derive_dhe(struct tls_key_share
*ks
,
407 uint8_t **shared_key
, size_t *shared_key_len
)
409 if (ks
->dhe
== NULL
|| ks
->dhe_peer
== NULL
)
412 return ssl_kex_derive_dhe(ks
->dhe
, ks
->dhe_peer
, shared_key
,
417 tls_key_share_derive_ecdhe_ecp(struct tls_key_share
*ks
,
418 uint8_t **shared_key
, size_t *shared_key_len
)
420 if (ks
->ecdhe
== NULL
|| ks
->ecdhe_peer
== NULL
)
423 return ssl_kex_derive_ecdhe_ecp(ks
->ecdhe
, ks
->ecdhe_peer
,
424 shared_key
, shared_key_len
);
428 tls_key_share_derive_x25519(struct tls_key_share
*ks
,
429 uint8_t **shared_key
, size_t *shared_key_len
)
434 if (ks
->x25519_private
== NULL
|| ks
->x25519_peer_public
== NULL
)
437 if ((sk
= calloc(1, X25519_KEY_LENGTH
)) == NULL
)
439 if (!X25519(sk
, ks
->x25519_private
, ks
->x25519_peer_public
))
443 *shared_key_len
= X25519_KEY_LENGTH
;
449 freezero(sk
, X25519_KEY_LENGTH
);
455 tls_key_share_derive(struct tls_key_share
*ks
, uint8_t **shared_key
,
456 size_t *shared_key_len
)
458 if (*shared_key
!= NULL
)
463 if (ks
->nid
== NID_dhKeyAgreement
)
464 return tls_key_share_derive_dhe(ks
, shared_key
,
467 if (ks
->nid
== NID_X25519
)
468 return tls_key_share_derive_x25519(ks
, shared_key
,
471 return tls_key_share_derive_ecdhe_ecp(ks
, shared_key
,
476 tls_key_share_peer_security(const SSL
*ssl
, struct tls_key_share
*ks
)
479 case NID_dhKeyAgreement
:
480 return ssl_security_dh(ssl
, ks
->dhe_peer
);