Rename tls13_key_share to tls_key_share.
authorjsing <jsing@openbsd.org>
Wed, 5 Jan 2022 17:10:02 +0000 (17:10 +0000)
committerjsing <jsing@openbsd.org>
Wed, 5 Jan 2022 17:10:02 +0000 (17:10 +0000)
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@

lib/libssl/Makefile
lib/libssl/s3_lib.c
lib/libssl/ssl_locl.h
lib/libssl/ssl_tlsext.c
lib/libssl/tls13_client.c
lib/libssl/tls13_internal.h
lib/libssl/tls13_key_share.c [deleted file]
lib/libssl/tls13_server.c
lib/libssl/tls_internal.h
lib/libssl/tls_key_share.c [new file with mode: 0644]

index 82e1399..565a3f1 100644 (file)
@@ -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 <bsd.own.mk>
 .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
 
index 497dea6..b83a380 100644 (file)
@@ -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 {
index d53c9ec..d6d20c2 100644 (file)
@@ -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.
index 74b5415..4cc4065 100644 (file)
@@ -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 <jsing@openbsd.org>
  * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -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;
 
index 4dfb025..8ba78cd 100644 (file)
@@ -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 <jsing@openbsd.org>
  *
@@ -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))
index 7e3b081..4c3a328 100644 (file)
@@ -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 <beck@openbsd.org>
  * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -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 (file)
index 70f1b67..0000000
+++ /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 <jsing@openbsd.org>
- *
- * 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 <stdlib.h>
-
-#include <openssl/curve25519.h>
-
-#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);
-}
index f5066f9..739ef06 100644 (file)
@@ -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 <jsing@openbsd.org>
  * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
@@ -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;
index 10af32e..87c7f3b 100644 (file)
@@ -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 <jsing@openbsd.org>
  *
@@ -18,6 +18,8 @@
 #ifndef HEADER_TLS_INTERNAL_H
 #define HEADER_TLS_INTERNAL_H
 
+#include <openssl/evp.h>
+
 #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 (file)
index 0000000..1bce651
--- /dev/null
@@ -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 <jsing@openbsd.org>
+ *
+ * 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 <stdlib.h>
+
+#include <openssl/curve25519.h>
+#include <openssl/ec.h>
+
+#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);
+}