summaryrefslogtreecommitdiffstats
path: root/lib/libssl/tls13_key_share.c
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2020-02-04 18:06:26 +0000
committerjsing <jsing@openbsd.org>2020-02-04 18:06:26 +0000
commit9b242555e30c6c9ae35c1ac38e3d30d179f87d2b (patch)
tree755ac68cfa3f91b47da7059a30bdf7e6fd496c58 /lib/libssl/tls13_key_share.c
parentWe are not using aes. (diff)
downloadwireguard-openbsd-9b242555e30c6c9ae35c1ac38e3d30d179f87d2b.tar.xz
wireguard-openbsd-9b242555e30c6c9ae35c1ac38e3d30d179f87d2b.zip
Add support for TLSv1.3 key shares with secp256r1 and secp384r1 groups.
ok inoguchi@ tb@
Diffstat (limited to 'lib/libssl/tls13_key_share.c')
-rw-r--r--lib/libssl/tls13_key_share.c103
1 files changed, 98 insertions, 5 deletions
diff --git a/lib/libssl/tls13_key_share.c b/lib/libssl/tls13_key_share.c
index 3fe38ecc377..c38a3e3cb8e 100644
--- a/lib/libssl/tls13_key_share.c
+++ b/lib/libssl/tls13_key_share.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls13_key_share.c,v 1.2 2020/02/01 12:41:58 jsing Exp $ */
+/* $OpenBSD: tls13_key_share.c,v 1.3 2020/02/04 18:06:26 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
@@ -27,6 +27,9 @@ 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;
@@ -59,6 +62,9 @@ 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);
@@ -73,6 +79,31 @@ tls13_key_share_group(struct tls13_key_share *ks)
}
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;
@@ -105,13 +136,24 @@ tls13_key_share_generate_x25519(struct tls13_key_share *ks)
int
tls13_key_share_generate(struct tls13_key_share *ks)
{
- if (ks->nid == NID_X25519)
+ if (ks->nid == NID_X9_62_prime256v1 || ks->nid == NID_secp384r1)
+ return tls13_key_share_generate_ecdhe_ecp(ks);
+ else if (ks->nid == NID_X25519)
return tls13_key_share_generate_x25519(ks);
return 0;
}
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)
@@ -130,7 +172,10 @@ tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb)
if (!CBB_add_u16_length_prefixed(cbb, &key_exchange))
goto err;
- if (ks->nid == NID_X25519) {
+ if (ks->nid == NID_X9_62_prime256v1 || ks->nid == NID_secp384r1) {
+ if (!tls13_key_share_public_ecdhe_ecp(ks, &key_exchange))
+ goto err;
+ } else if (ks->nid == NID_X25519) {
if (!tls13_key_share_public_x25519(ks, &key_exchange))
goto err;
} else {
@@ -147,10 +192,38 @@ tls13_key_share_public(struct tls13_key_share *ks, CBB *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;
@@ -164,15 +237,31 @@ tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
if (ks->group_id != group)
return 0;
- if (ks->nid == NID_X25519) {
+ if (ks->nid == NID_X9_62_prime256v1 || ks->nid == NID_secp384r1) {
+ if (!tls13_key_share_peer_public_ecdhe_ecp(ks, cbs))
+ return 0;
+ } else if (ks->nid == NID_X25519) {
if (!tls13_key_share_peer_public_x25519(ks, cbs))
return 0;
+ } else {
+ 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)
{
@@ -208,9 +297,13 @@ tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
*shared_key_len = 0;
- if (ks->nid == NID_X25519)
+ if (ks->nid == NID_X9_62_prime256v1 || ks->nid == NID_secp384r1) {
+ return tls13_key_share_derive_ecdhe_ecp(ks, shared_key,
+ shared_key_len);
+ } else if (ks->nid == NID_X25519) {
return tls13_key_share_derive_x25519(ks, shared_key,
shared_key_len);
+ }
return 0;
}