From f785987ce739e20256eb67b362a15f289d5120b3 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Tue, 4 Feb 2020 18:06:26 +0000 Subject: Add support for TLSv1.3 key shares with secp256r1 and secp384r1 groups. ok inoguchi@ tb@ --- src/lib/libssl/tls13_key_share.c | 103 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/libssl/tls13_key_share.c b/src/lib/libssl/tls13_key_share.c index 3fe38ecc37..c38a3e3cb8 100644 --- a/src/lib/libssl/tls13_key_share.c +++ b/src/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 * @@ -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); @@ -72,6 +78,31 @@ tls13_key_share_group(struct tls13_key_share *ks) return ks->group_id; } +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) { @@ -105,12 +136,23 @@ 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) { @@ -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 { @@ -146,11 +191,39 @@ tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb) return 0; } +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,14 +237,30 @@ 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; } -- cgit v1.2.3-55-g6feb