From: jsing Date: Wed, 5 Jan 2022 17:10:02 +0000 (+0000) Subject: Rename tls13_key_share to tls_key_share. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=b8e3503d5a72fa2dd94bf4dfb3676d7ef2762ce5;p=openbsd Rename tls13_key_share to tls_key_share. In preparation to use the key share code in both the TLSv1.3 and legacy stacks, rename tls13_key_share to tls_key_share, moving it into the shared handshake struct. Further changes will then allow the legacy stack to make use of the same code for ephemeral key exchange. ok inoguchi@ tb@ --- diff --git a/lib/libssl/Makefile b/lib/libssl/Makefile index 82e139911e7..565a3f15433 100644 --- a/lib/libssl/Makefile +++ b/lib/libssl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.72 2021/10/23 13:12:14 jsing Exp $ +# $OpenBSD: Makefile,v 1.73 2022/01/05 17:10:02 jsing Exp $ .include .ifndef NOMAN @@ -75,14 +75,14 @@ SRCS= \ tls13_handshake.c \ tls13_handshake_msg.c \ tls13_key_schedule.c \ - tls13_key_share.c \ tls13_legacy.c \ tls13_lib.c \ tls13_record.c \ tls13_record_layer.c \ tls13_server.c \ tls_buffer.c \ - tls_content.c + tls_content.c \ + tls_key_share.c HDRS= dtls1.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h tls1.h diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c index 497dea6f083..b83a3805479 100644 --- a/lib/libssl/s3_lib.c +++ b/lib/libssl/s3_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_lib.c,v 1.219 2021/11/02 13:59:29 tb Exp $ */ +/* $OpenBSD: s3_lib.c,v 1.220 2022/01/05 17:10:02 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1569,7 +1569,8 @@ ssl3_free(SSL *s) EC_KEY_free(S3I(s)->tmp.ecdh); freezero(S3I(s)->tmp.x25519, X25519_KEY_LENGTH); - tls13_key_share_free(S3I(s)->hs.tls13.key_share); + tls_key_share_free(S3I(s)->hs.key_share); + tls13_secrets_destroy(S3I(s)->hs.tls13.secrets); freezero(S3I(s)->hs.tls13.cookie, S3I(s)->hs.tls13.cookie_len); tls13_clienthello_hash_clear(&S3I(s)->hs.tls13); @@ -1612,8 +1613,8 @@ ssl3_clear(SSL *s) S3I(s)->hs.sigalgs = NULL; S3I(s)->hs.sigalgs_len = 0; - tls13_key_share_free(S3I(s)->hs.tls13.key_share); - S3I(s)->hs.tls13.key_share = NULL; + tls_key_share_free(S3I(s)->hs.key_share); + S3I(s)->hs.key_share = NULL; tls13_secrets_destroy(S3I(s)->hs.tls13.secrets); S3I(s)->hs.tls13.secrets = NULL; @@ -1686,8 +1687,8 @@ _SSL_get_peer_tmp_key(SSL *s, EVP_PKEY **key) } else if (sc->peer_x25519_tmp != NULL) { if (!ssl_kex_dummy_ecdhe_x25519(pkey)) goto err; - } else if (S3I(s)->hs.tls13.key_share != NULL) { - if (!tls13_key_share_peer_pkey(S3I(s)->hs.tls13.key_share, + } else if (S3I(s)->hs.key_share != NULL) { + if (!tls_key_share_peer_pkey(S3I(s)->hs.key_share, pkey)) goto err; } else { diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index d53c9ec273b..d6d20c2ceba 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.372 2021/12/04 14:03:22 jsing Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.373 2022/01/05 17:10:02 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -539,7 +539,6 @@ typedef struct ssl_handshake_tls13_st { uint16_t server_version; uint16_t server_group; - struct tls13_key_share *key_share; struct tls13_secrets *secrets; uint8_t *cookie; @@ -605,6 +604,9 @@ typedef struct ssl_handshake_st { uint8_t *sigalgs; size_t sigalgs_len; + /* Key share for ephemeral key exchange. */ + struct tls_key_share *key_share; + /* * Copies of the verify data sent in our finished message and the * verify data received in the finished message sent by our peer. diff --git a/lib/libssl/ssl_tlsext.c b/lib/libssl/ssl_tlsext.c index 74b54154e38..4cc406526dc 100644 --- a/lib/libssl/ssl_tlsext.c +++ b/lib/libssl/ssl_tlsext.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_tlsext.c,v 1.103 2022/01/04 11:01:58 jsing Exp $ */ +/* $OpenBSD: ssl_tlsext.c,v 1.104 2022/01/05 17:10:02 jsing Exp $ */ /* * Copyright (c) 2016, 2017, 2019 Joel Sing * Copyright (c) 2017 Doug Hogan @@ -1461,11 +1461,11 @@ tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb) return 0; if (!CBB_add_u16(&client_shares, - tls13_key_share_group(S3I(s)->hs.tls13.key_share))) + tls_key_share_group(S3I(s)->hs.key_share))) return 0; if (!CBB_add_u16_length_prefixed(&client_shares, &key_exchange)) return 0; - if (!tls13_key_share_public(S3I(s)->hs.tls13.key_share, &key_exchange)) + if (!tls_key_share_public(S3I(s)->hs.key_share, &key_exchange)) return 0; if (!CBB_flush(cbb)) @@ -1502,7 +1502,7 @@ tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) */ if (S3I(s)->hs.our_max_tls_version < TLS1_3_VERSION) continue; - if (S3I(s)->hs.tls13.key_share != NULL) + if (S3I(s)->hs.key_share != NULL) continue; /* XXX - consider implementing server preference. */ @@ -1510,10 +1510,10 @@ tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) continue; /* Decode and store the selected key share. */ - S3I(s)->hs.tls13.key_share = tls13_key_share_new(group); - if (S3I(s)->hs.tls13.key_share == NULL) + S3I(s)->hs.key_share = tls_key_share_new(group); + if (S3I(s)->hs.key_share == NULL) goto err; - if (!tls13_key_share_peer_public(S3I(s)->hs.tls13.key_share, + if (!tls_key_share_peer_public(S3I(s)->hs.key_share, group, &key_exchange)) goto err; } @@ -1544,14 +1544,14 @@ tlsext_keyshare_server_build(SSL *s, uint16_t msg_type, CBB *cbb) return CBB_add_u16(cbb, S3I(s)->hs.tls13.server_group); } - if (S3I(s)->hs.tls13.key_share == NULL) + if (S3I(s)->hs.key_share == NULL) return 0; - if (!CBB_add_u16(cbb, tls13_key_share_group(S3I(s)->hs.tls13.key_share))) + if (!CBB_add_u16(cbb, tls_key_share_group(S3I(s)->hs.key_share))) return 0; if (!CBB_add_u16_length_prefixed(cbb, &key_exchange)) return 0; - if (!tls13_key_share_public(S3I(s)->hs.tls13.key_share, &key_exchange)) + if (!tls_key_share_public(S3I(s)->hs.key_share, &key_exchange)) return 0; if (!CBB_flush(cbb)) @@ -1582,10 +1582,10 @@ tlsext_keyshare_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) if (!CBS_get_u16_length_prefixed(cbs, &key_exchange)) return 0; - if (S3I(s)->hs.tls13.key_share == NULL) + if (S3I(s)->hs.key_share == NULL) return 0; - if (!tls13_key_share_peer_public(S3I(s)->hs.tls13.key_share, + if (!tls_key_share_peer_public(S3I(s)->hs.key_share, group, &key_exchange)) goto err; diff --git a/lib/libssl/tls13_client.c b/lib/libssl/tls13_client.c index 4dfb02581a1..8ba78cd02b5 100644 --- a/lib/libssl/tls13_client.c +++ b/lib/libssl/tls13_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls13_client.c,v 1.88 2021/10/25 10:01:46 jsing Exp $ */ +/* $OpenBSD: tls13_client.c,v 1.89 2022/01/05 17:10:02 jsing Exp $ */ /* * Copyright (c) 2018, 2019 Joel Sing * @@ -51,9 +51,9 @@ tls13_client_init(struct tls13_ctx *ctx) tls1_get_group_list(s, 0, &groups, &groups_len); if (groups_len < 1) return 0; - if ((ctx->hs->tls13.key_share = tls13_key_share_new(groups[0])) == NULL) + if ((ctx->hs->key_share = tls_key_share_new(groups[0])) == NULL) return 0; - if (!tls13_key_share_generate(ctx->hs->tls13.key_share)) + if (!tls_key_share_generate(ctx->hs->key_share)) return 0; arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); @@ -343,7 +343,7 @@ tls13_client_engage_record_protection(struct tls13_ctx *ctx) /* Derive the shared key and engage record protection. */ - if (!tls13_key_share_derive(ctx->hs->tls13.key_share, &shared_key, + if (!tls_key_share_derive(ctx->hs->key_share, &shared_key, &shared_key_len)) goto err; @@ -442,15 +442,15 @@ tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb) */ if (!tls1_check_curve(ctx->ssl, ctx->hs->tls13.server_group)) return 0; /* XXX alert */ - if (ctx->hs->tls13.server_group == tls13_key_share_group(ctx->hs->tls13.key_share)) + if (ctx->hs->tls13.server_group == tls_key_share_group(ctx->hs->key_share)) return 0; /* XXX alert */ /* Switch to new key share. */ - tls13_key_share_free(ctx->hs->tls13.key_share); - if ((ctx->hs->tls13.key_share = - tls13_key_share_new(ctx->hs->tls13.server_group)) == NULL) + tls_key_share_free(ctx->hs->key_share); + if ((ctx->hs->key_share = + tls_key_share_new(ctx->hs->tls13.server_group)) == NULL) return 0; - if (!tls13_key_share_generate(ctx->hs->tls13.key_share)) + if (!tls_key_share_generate(ctx->hs->key_share)) return 0; if (!tls13_client_hello_build(ctx, cbb)) diff --git a/lib/libssl/tls13_internal.h b/lib/libssl/tls13_internal.h index 7e3b081966d..4c3a328023a 100644 --- a/lib/libssl/tls13_internal.h +++ b/lib/libssl/tls13_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls13_internal.h,v 1.95 2021/10/23 13:12:14 jsing Exp $ */ +/* $OpenBSD: tls13_internal.h,v 1.96 2022/01/05 17:10:02 jsing Exp $ */ /* * Copyright (c) 2018 Bob Beck * Copyright (c) 2018 Theo Buehler @@ -158,24 +158,6 @@ int tls13_derive_application_secrets(struct tls13_secrets *secrets, int tls13_update_client_traffic_secret(struct tls13_secrets *secrets); int tls13_update_server_traffic_secret(struct tls13_secrets *secrets); -/* - * Key shares. - */ -struct tls13_key_share; - -struct tls13_key_share *tls13_key_share_new(uint16_t group_id); -struct tls13_key_share *tls13_key_share_new_nid(int nid); -void tls13_key_share_free(struct tls13_key_share *ks); - -uint16_t tls13_key_share_group(struct tls13_key_share *ks); -int tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey); -int tls13_key_share_generate(struct tls13_key_share *ks); -int tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb); -int tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group, - CBS *cbs); -int tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key, - size_t *shared_key_len); - /* * Record Layer. */ diff --git a/lib/libssl/tls13_key_share.c b/lib/libssl/tls13_key_share.c deleted file mode 100644 index 70f1b673f6c..00000000000 --- a/lib/libssl/tls13_key_share.c +++ /dev/null @@ -1,306 +0,0 @@ -/* $OpenBSD: tls13_key_share.c,v 1.7 2022/01/04 11:01:58 jsing Exp $ */ -/* - * Copyright (c) 2020 Joel Sing - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include - -#include "bytestring.h" -#include "ssl_locl.h" -#include "tls13_internal.h" - -struct tls13_key_share { - int nid; - uint16_t group_id; - - EC_KEY *ecdhe; - EC_KEY *ecdhe_peer; - - uint8_t *x25519_public; - uint8_t *x25519_private; - uint8_t *x25519_peer_public; -}; - -struct tls13_key_share * -tls13_key_share_new(uint16_t group_id) -{ - struct tls13_key_share *ks; - int nid; - - if ((nid = tls1_ec_curve_id2nid(group_id)) == 0) - return NULL; - - if ((ks = calloc(1, sizeof(struct tls13_key_share))) == NULL) - return NULL; - - ks->group_id = group_id; - ks->nid = nid; - - return ks; -} - -struct tls13_key_share * -tls13_key_share_new_nid(int nid) -{ - uint16_t group_id; - - if ((group_id = tls1_ec_nid2curve_id(nid)) == 0) - return NULL; - - return tls13_key_share_new(group_id); -} - -void -tls13_key_share_free(struct tls13_key_share *ks) -{ - if (ks == NULL) - return; - - EC_KEY_free(ks->ecdhe); - EC_KEY_free(ks->ecdhe_peer); - - freezero(ks->x25519_public, X25519_KEY_LENGTH); - freezero(ks->x25519_private, X25519_KEY_LENGTH); - freezero(ks->x25519_peer_public, X25519_KEY_LENGTH); - - freezero(ks, sizeof(*ks)); -} - -uint16_t -tls13_key_share_group(struct tls13_key_share *ks) -{ - return ks->group_id; -} - -int -tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey) -{ - if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) { - if (!ssl_kex_dummy_ecdhe_x25519(pkey)) - return 0; - } else if (ks->ecdhe_peer != NULL) { - if (!EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer)) - return 0; - } else { - return 0; - } - - return 1; -} - -static int -tls13_key_share_generate_ecdhe_ecp(struct tls13_key_share *ks) -{ - EC_KEY *ecdhe = NULL; - int ret = 0; - - if (ks->ecdhe != NULL) - goto err; - - if ((ecdhe = EC_KEY_new()) == NULL) - goto err; - if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid)) - goto err; - - ks->ecdhe = ecdhe; - ecdhe = NULL; - - ret = 1; - - err: - EC_KEY_free(ecdhe); - - return ret; -} - -static int -tls13_key_share_generate_x25519(struct tls13_key_share *ks) -{ - uint8_t *public = NULL, *private = NULL; - int ret = 0; - - if (ks->x25519_public != NULL || ks->x25519_private != NULL) - goto err; - - if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL) - goto err; - if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL) - goto err; - - X25519_keypair(public, private); - - ks->x25519_public = public; - ks->x25519_private = private; - public = NULL; - private = NULL; - - ret = 1; - - err: - freezero(public, X25519_KEY_LENGTH); - freezero(private, X25519_KEY_LENGTH); - - return ret; -} - -int -tls13_key_share_generate(struct tls13_key_share *ks) -{ - if (ks->nid == NID_X25519) - return tls13_key_share_generate_x25519(ks); - - return tls13_key_share_generate_ecdhe_ecp(ks); -} - -static int -tls13_key_share_public_ecdhe_ecp(struct tls13_key_share *ks, CBB *cbb) -{ - if (ks->ecdhe == NULL) - return 0; - - return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb); -} - -static int -tls13_key_share_public_x25519(struct tls13_key_share *ks, CBB *cbb) -{ - if (ks->x25519_public == NULL) - return 0; - - return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH); -} - -int -tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb) -{ - if (ks->nid == NID_X25519) - return tls13_key_share_public_x25519(ks, cbb); - - return tls13_key_share_public_ecdhe_ecp(ks, cbb); -} - -static int -tls13_key_share_peer_public_ecdhe_ecp(struct tls13_key_share *ks, CBS *cbs) -{ - EC_KEY *ecdhe = NULL; - int ret = 0; - - if (ks->ecdhe_peer != NULL) - goto err; - - if ((ecdhe = EC_KEY_new()) == NULL) - goto err; - if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs)) - goto err; - - ks->ecdhe_peer = ecdhe; - ecdhe = NULL; - - ret = 1; - - err: - EC_KEY_free(ecdhe); - - return ret; -} - -static int -tls13_key_share_peer_public_x25519(struct tls13_key_share *ks, CBS *cbs) -{ - size_t out_len; - - if (ks->x25519_peer_public != NULL) - return 0; - - if (CBS_len(cbs) != X25519_KEY_LENGTH) - return 0; - - return CBS_stow(cbs, &ks->x25519_peer_public, &out_len); -} - -int -tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group, - CBS *cbs) -{ - if (ks->group_id != group) - return 0; - - if (ks->nid == NID_X25519) { - if (!tls13_key_share_peer_public_x25519(ks, cbs)) - return 0; - } else { - if (!tls13_key_share_peer_public_ecdhe_ecp(ks, cbs)) - return 0; - } - - return 1; -} - -static int -tls13_key_share_derive_ecdhe_ecp(struct tls13_key_share *ks, - uint8_t **shared_key, size_t *shared_key_len) -{ - if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL) - return 0; - - return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer, - shared_key, shared_key_len); -} - -static int -tls13_key_share_derive_x25519(struct tls13_key_share *ks, - uint8_t **shared_key, size_t *shared_key_len) -{ - uint8_t *sk = NULL; - int ret = 0; - - if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL) - goto err; - - if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL) - goto err; - if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public)) - goto err; - - *shared_key = sk; - *shared_key_len = X25519_KEY_LENGTH; - sk = NULL; - - ret = 1; - - err: - freezero(sk, X25519_KEY_LENGTH); - - return ret; -} - -int -tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key, - size_t *shared_key_len) -{ - if (*shared_key != NULL) - return 0; - - *shared_key_len = 0; - - if (ks->nid == NID_X25519) - return tls13_key_share_derive_x25519(ks, shared_key, - shared_key_len); - - return tls13_key_share_derive_ecdhe_ecp(ks, shared_key, - shared_key_len); -} diff --git a/lib/libssl/tls13_server.c b/lib/libssl/tls13_server.c index f5066f958a5..739ef066099 100644 --- a/lib/libssl/tls13_server.c +++ b/lib/libssl/tls13_server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls13_server.c,v 1.89 2021/12/26 14:59:52 jsing Exp $ */ +/* $OpenBSD: tls13_server.c,v 1.90 2022/01/05 17:10:02 jsing Exp $ */ /* * Copyright (c) 2019, 2020 Joel Sing * Copyright (c) 2020 Bob Beck @@ -295,7 +295,7 @@ tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs) * has been enabled. This would probably mean using either an * INITIAL | WITHOUT_HRR state, or another intermediate state. */ - if (ctx->hs->tls13.key_share != NULL) + if (ctx->hs->key_share != NULL) ctx->handshake_stage.hs_type |= NEGOTIATED | WITHOUT_HRR; /* XXX - check this is the correct point */ @@ -360,7 +360,7 @@ tls13_server_engage_record_protection(struct tls13_ctx *ctx) SSL *s = ctx->ssl; int ret = 0; - if (!tls13_key_share_derive(ctx->hs->tls13.key_share, + if (!tls_key_share_derive(ctx->hs->key_share, &shared_key, &shared_key_len)) goto err; @@ -425,7 +425,7 @@ tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb) if (!tls13_synthetic_handshake_message(ctx)) return 0; - if (ctx->hs->tls13.key_share != NULL) + if (ctx->hs->key_share != NULL) return 0; if ((nid = tls1_get_shared_curve(ctx->ssl)) == NID_undef) return 0; @@ -485,9 +485,9 @@ tls13_servername_process(struct tls13_ctx *ctx) int tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb) { - if (ctx->hs->tls13.key_share == NULL) + if (ctx->hs->key_share == NULL) return 0; - if (!tls13_key_share_generate(ctx->hs->tls13.key_share)) + if (!tls_key_share_generate(ctx->hs->key_share)) return 0; if (!tls13_servername_process(ctx)) return 0; diff --git a/lib/libssl/tls_internal.h b/lib/libssl/tls_internal.h index 10af32efdda..87c7f3b7dd5 100644 --- a/lib/libssl/tls_internal.h +++ b/lib/libssl/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.1 2021/10/23 13:12:14 jsing Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.2 2022/01/05 17:10:03 jsing Exp $ */ /* * Copyright (c) 2018, 2019, 2021 Joel Sing * @@ -18,6 +18,8 @@ #ifndef HEADER_TLS_INTERNAL_H #define HEADER_TLS_INTERNAL_H +#include + #include "bytestring.h" __BEGIN_HIDDEN_DECLS @@ -51,6 +53,24 @@ ssize_t tls_buffer_extend(struct tls_buffer *buf, size_t len, void tls_buffer_cbs(struct tls_buffer *buf, CBS *cbs); int tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len); +/* + * Key shares. + */ +struct tls_key_share; + +struct tls_key_share *tls_key_share_new(uint16_t group_id); +struct tls_key_share *tls_key_share_new_nid(int nid); +void tls_key_share_free(struct tls_key_share *ks); + +uint16_t tls_key_share_group(struct tls_key_share *ks); +int tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey); +int tls_key_share_generate(struct tls_key_share *ks); +int tls_key_share_public(struct tls_key_share *ks, CBB *cbb); +int tls_key_share_peer_public(struct tls_key_share *ks, uint16_t group, + CBS *cbs); +int tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key, + size_t *shared_key_len); + __END_HIDDEN_DECLS #endif diff --git a/lib/libssl/tls_key_share.c b/lib/libssl/tls_key_share.c new file mode 100644 index 00000000000..1bce651e10e --- /dev/null +++ b/lib/libssl/tls_key_share.c @@ -0,0 +1,307 @@ +/* $OpenBSD: tls_key_share.c,v 1.1 2022/01/05 17:10:03 jsing Exp $ */ +/* + * Copyright (c) 2020 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "bytestring.h" +#include "ssl_locl.h" +#include "tls_internal.h" + +struct tls_key_share { + int nid; + uint16_t group_id; + + EC_KEY *ecdhe; + EC_KEY *ecdhe_peer; + + uint8_t *x25519_public; + uint8_t *x25519_private; + uint8_t *x25519_peer_public; +}; + +struct tls_key_share * +tls_key_share_new(uint16_t group_id) +{ + struct tls_key_share *ks; + int nid; + + if ((nid = tls1_ec_curve_id2nid(group_id)) == 0) + return NULL; + + if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL) + return NULL; + + ks->group_id = group_id; + ks->nid = nid; + + return ks; +} + +struct tls_key_share * +tls_key_share_new_nid(int nid) +{ + uint16_t group_id; + + if ((group_id = tls1_ec_nid2curve_id(nid)) == 0) + return NULL; + + return tls_key_share_new(group_id); +} + +void +tls_key_share_free(struct tls_key_share *ks) +{ + if (ks == NULL) + return; + + EC_KEY_free(ks->ecdhe); + EC_KEY_free(ks->ecdhe_peer); + + freezero(ks->x25519_public, X25519_KEY_LENGTH); + freezero(ks->x25519_private, X25519_KEY_LENGTH); + freezero(ks->x25519_peer_public, X25519_KEY_LENGTH); + + freezero(ks, sizeof(*ks)); +} + +uint16_t +tls_key_share_group(struct tls_key_share *ks) +{ + return ks->group_id; +} + +int +tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey) +{ + if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) { + if (!ssl_kex_dummy_ecdhe_x25519(pkey)) + return 0; + } else if (ks->ecdhe_peer != NULL) { + if (!EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer)) + return 0; + } else { + return 0; + } + + return 1; +} + +static int +tls_key_share_generate_ecdhe_ecp(struct tls_key_share *ks) +{ + EC_KEY *ecdhe = NULL; + int ret = 0; + + if (ks->ecdhe != NULL) + goto err; + + if ((ecdhe = EC_KEY_new()) == NULL) + goto err; + if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid)) + goto err; + + ks->ecdhe = ecdhe; + ecdhe = NULL; + + ret = 1; + + err: + EC_KEY_free(ecdhe); + + return ret; +} + +static int +tls_key_share_generate_x25519(struct tls_key_share *ks) +{ + uint8_t *public = NULL, *private = NULL; + int ret = 0; + + if (ks->x25519_public != NULL || ks->x25519_private != NULL) + goto err; + + if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL) + goto err; + if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL) + goto err; + + X25519_keypair(public, private); + + ks->x25519_public = public; + ks->x25519_private = private; + public = NULL; + private = NULL; + + ret = 1; + + err: + freezero(public, X25519_KEY_LENGTH); + freezero(private, X25519_KEY_LENGTH); + + return ret; +} + +int +tls_key_share_generate(struct tls_key_share *ks) +{ + if (ks->nid == NID_X25519) + return tls_key_share_generate_x25519(ks); + + return tls_key_share_generate_ecdhe_ecp(ks); +} + +static int +tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->ecdhe == NULL) + return 0; + + return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb); +} + +static int +tls_key_share_public_x25519(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->x25519_public == NULL) + return 0; + + return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH); +} + +int +tls_key_share_public(struct tls_key_share *ks, CBB *cbb) +{ + if (ks->nid == NID_X25519) + return tls_key_share_public_x25519(ks, cbb); + + return tls_key_share_public_ecdhe_ecp(ks, cbb); +} + +static int +tls_key_share_peer_public_ecdhe_ecp(struct tls_key_share *ks, CBS *cbs) +{ + EC_KEY *ecdhe = NULL; + int ret = 0; + + if (ks->ecdhe_peer != NULL) + goto err; + + if ((ecdhe = EC_KEY_new()) == NULL) + goto err; + if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs)) + goto err; + + ks->ecdhe_peer = ecdhe; + ecdhe = NULL; + + ret = 1; + + err: + EC_KEY_free(ecdhe); + + return ret; +} + +static int +tls_key_share_peer_public_x25519(struct tls_key_share *ks, CBS *cbs) +{ + size_t out_len; + + if (ks->x25519_peer_public != NULL) + return 0; + + if (CBS_len(cbs) != X25519_KEY_LENGTH) + return 0; + + return CBS_stow(cbs, &ks->x25519_peer_public, &out_len); +} + +int +tls_key_share_peer_public(struct tls_key_share *ks, uint16_t group, + CBS *cbs) +{ + if (ks->group_id != group) + return 0; + + if (ks->nid == NID_X25519) { + if (!tls_key_share_peer_public_x25519(ks, cbs)) + return 0; + } else { + if (!tls_key_share_peer_public_ecdhe_ecp(ks, cbs)) + return 0; + } + + return 1; +} + +static int +tls_key_share_derive_ecdhe_ecp(struct tls_key_share *ks, + uint8_t **shared_key, size_t *shared_key_len) +{ + if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL) + return 0; + + return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer, + shared_key, shared_key_len); +} + +static int +tls_key_share_derive_x25519(struct tls_key_share *ks, + uint8_t **shared_key, size_t *shared_key_len) +{ + uint8_t *sk = NULL; + int ret = 0; + + if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL) + goto err; + + if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL) + goto err; + if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public)) + goto err; + + *shared_key = sk; + *shared_key_len = X25519_KEY_LENGTH; + sk = NULL; + + ret = 1; + + err: + freezero(sk, X25519_KEY_LENGTH); + + return ret; +} + +int +tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key, + size_t *shared_key_len) +{ + if (*shared_key != NULL) + return 0; + + *shared_key_len = 0; + + if (ks->nid == NID_X25519) + return tls_key_share_derive_x25519(ks, shared_key, + shared_key_len); + + return tls_key_share_derive_ecdhe_ecp(ks, shared_key, + shared_key_len); +}