From ebc190065928188a93dc1ae2904ac8b110780c50 Mon Sep 17 00:00:00 2001 From: Billy Brumley Date: Tue, 10 Dec 2019 16:16:41 +0200 Subject: [PATCH 1/8] [sntrup761] Add experimental OID for SNTRUP761 --- crypto/objects/objects.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index c49d4c568b..75099d7379 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1611,6 +1611,8 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response 1 3 101 112 : ED25519 1 3 101 113 : ED448 +# NIST PQC KEM hacks +1 3 6 1 4 1 50263 0 3 1 20 : SNTRUP761 # NIDs for cipher key exchange : KxRSA : kx-rsa -- 2.34.0 From 5a57446bcb948c2d8b8c2f880d90a76bcac61d37 Mon Sep 17 00:00:00 2001 From: raja-ashok Date: Fri, 25 Jan 2019 21:04:49 +0530 Subject: [PATCH 3/8] Backport of logic from TLS1.3 FFDHE Support This cherry picks the commit 9aaecbfc98eb89a03f72b35d343e08f377e7803a from the master (3.0) branch. The libcrypto and libssl support for FFDHE has beem stripped out of the original commit, what has been preserved is the logic in libssl to handle TLS 1.3 non-EC groups. The idea is to keep the logic as similar as possible to the master branch for easier backport or forward-port of features from this experimental 1.1.1 branch. Co-authored-by: Nicola Tuveri (cherry picked from commit 9aaecbfc98eb89a03f72b35d343e08f377e7803a) --- ssl/s3_lib.c | 47 ++++++++----- ssl/ssl_local.h | 13 ++-- ssl/statem/extensions_clnt.c | 27 +++++--- ssl/statem/extensions_srvr.c | 3 +- ssl/t1_lib.c | 129 +++++++++++++++++++++-------------- 5 files changed, 134 insertions(+), 85 deletions(-) diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index b256a4b935..2f1a659a93 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4688,13 +4688,13 @@ EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm) EVP_PKEY_CTX_free(pctx); return pkey; } -#ifndef OPENSSL_NO_EC + /* Generate a private key from a group ID */ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) { + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); uint16_t gtype; if (ginf == NULL) { @@ -4702,11 +4702,15 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) ERR_R_INTERNAL_ERROR); goto err; } - gtype = ginf->flags & TLS_CURVE_TYPE; - if (gtype == TLS_CURVE_CUSTOM) - pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); - else - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + gtype = ginf->flags & TLS_GROUP_TYPE; +# ifndef OPENSSL_NO_EC + { + if (gtype == TLS_GROUP_CURVE_CUSTOM) + pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); + else + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + } +# endif if (pctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, ERR_R_MALLOC_FAILURE); @@ -4717,12 +4721,16 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) ERR_R_EVP_LIB); goto err; } - if (gtype != TLS_CURVE_CUSTOM - && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_EVP_LIB); - goto err; +# ifndef OPENSSL_NO_EC + { + if (gtype != TLS_GROUP_CURVE_CUSTOM + && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, + ERR_R_EVP_LIB); + goto err; + } } +# endif if (EVP_PKEY_keygen(pctx, &pkey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, ERR_R_EVP_LIB); @@ -4743,11 +4751,12 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); + int pkey_ctx_id; if (ginf == NULL) goto err; - if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) { + if ((ginf->flags & TLS_GROUP_TYPE) == TLS_GROUP_CURVE_CUSTOM) { pkey = EVP_PKEY_new(); if (pkey != NULL && EVP_PKEY_set_type(pkey, ginf->nid)) return pkey; @@ -4755,13 +4764,18 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) return NULL; } - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + pkey_ctx_id = EVP_PKEY_EC; + pctx = EVP_PKEY_CTX_new_id(pkey_ctx_id, NULL); if (pctx == NULL) goto err; if (EVP_PKEY_paramgen_init(pctx) <= 0) goto err; - if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) - goto err; +# ifndef OPENSSL_NO_EC + { + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) + goto err; + } +# endif if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { EVP_PKEY_free(pkey); pkey = NULL; @@ -4771,7 +4785,6 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) EVP_PKEY_CTX_free(pctx); return pkey; } -#endif /* Derive secrets for ECDH/DH */ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 9f346e30e8..ee82a8d25d 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -1507,14 +1507,16 @@ typedef struct sigalg_lookup_st { typedef struct tls_group_info_st { int nid; /* Curve NID */ int secbits; /* Bits of security (from SP800-57) */ - uint16_t flags; /* Flags: currently just group type */ + uint32_t flags; /* For group type and applicable TLS versions */ + uint16_t group_id; /* Group ID */ } TLS_GROUP_INFO; /* flags values */ -# define TLS_CURVE_TYPE 0x3 /* Mask for group type */ -# define TLS_CURVE_PRIME 0x0 -# define TLS_CURVE_CHAR2 0x1 -# define TLS_CURVE_CUSTOM 0x2 +# define TLS_GROUP_TYPE 0x00000007U /* Mask for group type */ +# define TLS_GROUP_CURVE_PRIME 0x00000001U +# define TLS_GROUP_CURVE_CHAR2 0x00000002U +# define TLS_GROUP_CURVE_CUSTOM 0x00000004U +# define TLS_GROUP_ONLY_FOR_TLS1_3 0x00000010U typedef struct cert_pkey_st CERT_PKEY; @@ -2521,6 +2523,7 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, size_t *num_formats); __owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id); __owur EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id); +__owur int tls_valid_group(SSL *s, uint16_t group_id, int version); __owur EVP_PKEY *ssl_generate_param_group(uint16_t id); # endif /* OPENSSL_NO_EC */ diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 9d38ac23b5..71ab157908 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -174,36 +174,45 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, { const uint16_t *pgroups = NULL; size_t num_groups = 0, i; + int min_version, max_version, reason; if (!use_ecc(s)) return EXT_RETURN_NOT_SENT; + reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); + if (reason != 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, reason); + return EXT_RETURN_FAIL; + } + /* * Add TLS extension supported_groups to the ClientHello message */ - /* TODO(TLS1.3): Add support for DHE groups */ tls1_get_supported_groups(s, &pgroups, &num_groups); if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups) /* Sub-packet for supported_groups extension */ || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_start_sub_packet_u16(pkt)) { + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - /* Copy curve ID if supported */ + /* Copy group ID if supported */ for (i = 0; i < num_groups; i++) { uint16_t ctmp = pgroups[i]; - if (tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) { + if (tls_valid_group(s, ctmp, max_version) + && tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) { if (!WPACKET_put_bytes_u16(pkt, ctmp)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, + ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 04f64f8106..67d3d0bd51 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1432,7 +1432,8 @@ EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, for (i = 0; i < numgroups; i++) { uint16_t group = groups[i]; - if (tls_curve_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) { + if (tls_valid_group(s, group, SSL_version(s)) + && tls_curve_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) { if (first) { /* * Check if the client is already using our preferred group. If diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index b1d3add187..a2b9c367f0 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -131,44 +131,42 @@ int tls1_clear(SSL *s) return 1; } -#ifndef OPENSSL_NO_EC - /* * Table of curve information. - * Do not delete entries or reorder this array! It is used as a lookup - * table: the index of each entry is one less than the TLS curve id. */ static const TLS_GROUP_INFO nid_list[] = { - {NID_sect163k1, 80, TLS_CURVE_CHAR2}, /* sect163k1 (1) */ - {NID_sect163r1, 80, TLS_CURVE_CHAR2}, /* sect163r1 (2) */ - {NID_sect163r2, 80, TLS_CURVE_CHAR2}, /* sect163r2 (3) */ - {NID_sect193r1, 80, TLS_CURVE_CHAR2}, /* sect193r1 (4) */ - {NID_sect193r2, 80, TLS_CURVE_CHAR2}, /* sect193r2 (5) */ - {NID_sect233k1, 112, TLS_CURVE_CHAR2}, /* sect233k1 (6) */ - {NID_sect233r1, 112, TLS_CURVE_CHAR2}, /* sect233r1 (7) */ - {NID_sect239k1, 112, TLS_CURVE_CHAR2}, /* sect239k1 (8) */ - {NID_sect283k1, 128, TLS_CURVE_CHAR2}, /* sect283k1 (9) */ - {NID_sect283r1, 128, TLS_CURVE_CHAR2}, /* sect283r1 (10) */ - {NID_sect409k1, 192, TLS_CURVE_CHAR2}, /* sect409k1 (11) */ - {NID_sect409r1, 192, TLS_CURVE_CHAR2}, /* sect409r1 (12) */ - {NID_sect571k1, 256, TLS_CURVE_CHAR2}, /* sect571k1 (13) */ - {NID_sect571r1, 256, TLS_CURVE_CHAR2}, /* sect571r1 (14) */ - {NID_secp160k1, 80, TLS_CURVE_PRIME}, /* secp160k1 (15) */ - {NID_secp160r1, 80, TLS_CURVE_PRIME}, /* secp160r1 (16) */ - {NID_secp160r2, 80, TLS_CURVE_PRIME}, /* secp160r2 (17) */ - {NID_secp192k1, 80, TLS_CURVE_PRIME}, /* secp192k1 (18) */ - {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME}, /* secp192r1 (19) */ - {NID_secp224k1, 112, TLS_CURVE_PRIME}, /* secp224k1 (20) */ - {NID_secp224r1, 112, TLS_CURVE_PRIME}, /* secp224r1 (21) */ - {NID_secp256k1, 128, TLS_CURVE_PRIME}, /* secp256k1 (22) */ - {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME}, /* secp256r1 (23) */ - {NID_secp384r1, 192, TLS_CURVE_PRIME}, /* secp384r1 (24) */ - {NID_secp521r1, 256, TLS_CURVE_PRIME}, /* secp521r1 (25) */ - {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */ - {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ - {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ - {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ - {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ +# ifndef OPENSSL_NO_EC + {NID_sect163k1, 80, TLS_GROUP_CURVE_CHAR2, 0x0001}, /* sect163k1 (1) */ + {NID_sect163r1, 80, TLS_GROUP_CURVE_CHAR2, 0x0002}, /* sect163r1 (2) */ + {NID_sect163r2, 80, TLS_GROUP_CURVE_CHAR2, 0x0003}, /* sect163r2 (3) */ + {NID_sect193r1, 80, TLS_GROUP_CURVE_CHAR2, 0x0004}, /* sect193r1 (4) */ + {NID_sect193r2, 80, TLS_GROUP_CURVE_CHAR2, 0x0005}, /* sect193r2 (5) */ + {NID_sect233k1, 112, TLS_GROUP_CURVE_CHAR2, 0x0006}, /* sect233k1 (6) */ + {NID_sect233r1, 112, TLS_GROUP_CURVE_CHAR2, 0x0007}, /* sect233r1 (7) */ + {NID_sect239k1, 112, TLS_GROUP_CURVE_CHAR2, 0x0008}, /* sect239k1 (8) */ + {NID_sect283k1, 128, TLS_GROUP_CURVE_CHAR2, 0x0009}, /* sect283k1 (9) */ + {NID_sect283r1, 128, TLS_GROUP_CURVE_CHAR2, 0x000A}, /* sect283r1 (10) */ + {NID_sect409k1, 192, TLS_GROUP_CURVE_CHAR2, 0x000B}, /* sect409k1 (11) */ + {NID_sect409r1, 192, TLS_GROUP_CURVE_CHAR2, 0x000C}, /* sect409r1 (12) */ + {NID_sect571k1, 256, TLS_GROUP_CURVE_CHAR2, 0x000D}, /* sect571k1 (13) */ + {NID_sect571r1, 256, TLS_GROUP_CURVE_CHAR2, 0x000E}, /* sect571r1 (14) */ + {NID_secp160k1, 80, TLS_GROUP_CURVE_PRIME, 0x000F}, /* secp160k1 (15) */ + {NID_secp160r1, 80, TLS_GROUP_CURVE_PRIME, 0x0010}, /* secp160r1 (16) */ + {NID_secp160r2, 80, TLS_GROUP_CURVE_PRIME, 0x0011}, /* secp160r2 (17) */ + {NID_secp192k1, 80, TLS_GROUP_CURVE_PRIME, 0x0012}, /* secp192k1 (18) */ + {NID_X9_62_prime192v1, 80, TLS_GROUP_CURVE_PRIME, 0x0013}, /* secp192r1 (19) */ + {NID_secp224k1, 112, TLS_GROUP_CURVE_PRIME, 0x0014}, /* secp224k1 (20) */ + {NID_secp224r1, 112, TLS_GROUP_CURVE_PRIME, 0x0015}, /* secp224r1 (21) */ + {NID_secp256k1, 128, TLS_GROUP_CURVE_PRIME, 0x0016}, /* secp256k1 (22) */ + {NID_X9_62_prime256v1, 128, TLS_GROUP_CURVE_PRIME, 0x0017}, /* secp256r1 (23) */ + {NID_secp384r1, 192, TLS_GROUP_CURVE_PRIME, 0x0018}, /* secp384r1 (24) */ + {NID_secp521r1, 256, TLS_GROUP_CURVE_PRIME, 0x0019}, /* secp521r1 (25) */ + {NID_brainpoolP256r1, 128, TLS_GROUP_CURVE_PRIME, 0x001A}, /* brainpoolP256r1 (26) */ + {NID_brainpoolP384r1, 192, TLS_GROUP_CURVE_PRIME, 0x001B}, /* brainpoolP384r1 (27) */ + {NID_brainpoolP512r1, 256, TLS_GROUP_CURVE_PRIME, 0x001C}, /* brainpool512r1 (28) */ + {EVP_PKEY_X25519, 128, TLS_GROUP_CURVE_CUSTOM, 0x001D}, /* X25519 (29) */ + {EVP_PKEY_X448, 224, TLS_GROUP_CURVE_CUSTOM, 0x001E}, /* X448 (30) */ +# endif /* OPENSSL_NO_EC */ }; static const unsigned char ecformats_default[] = { @@ -178,14 +176,18 @@ static const unsigned char ecformats_default[] = { }; /* The default curves */ -static const uint16_t eccurves_default[] = { +static const uint16_t supported_groups_default[] = { +# ifndef OPENSSL_NO_EC 29, /* X25519 (29) */ 23, /* secp256r1 (23) */ 30, /* X448 (30) */ 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ +# endif /* OPENSSL_NO_EC */ }; +#ifndef OPENSSL_NO_EC + static const uint16_t suiteb_curves[] = { TLSEXT_curve_P_256, TLSEXT_curve_P_384 @@ -193,18 +195,23 @@ static const uint16_t suiteb_curves[] = { const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id) { - /* ECC curves from RFC 4492 and RFC 7027 */ - if (group_id < 1 || group_id > OSSL_NELEM(nid_list)) - return NULL; - return &nid_list[group_id - 1]; + size_t i; + + /* ECC curves from RFC 4492 and RFC 7027 FFDHE group from RFC 8446 */ + for (i = 0; i < OSSL_NELEM(nid_list); i++) { + if (nid_list[i].group_id == group_id) + return &nid_list[i]; + } + return NULL; } static uint16_t tls1_nid2group_id(int nid) { size_t i; + for (i = 0; i < OSSL_NELEM(nid_list); i++) { if (nid_list[i].nid == nid) - return (uint16_t)(i + 1); + return nid_list[i].group_id; } return 0; } @@ -236,8 +243,8 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, default: if (s->ext.supportedgroups == NULL) { - *pgroups = eccurves_default; - *pgroupslen = OSSL_NELEM(eccurves_default); + *pgroups = supported_groups_default; + *pgroupslen = OSSL_NELEM(supported_groups_default); } else { *pgroups = s->ext.supportedgroups; *pgroupslen = s->ext.supportedgroups_len; @@ -246,6 +253,17 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, } } +int tls_valid_group(SSL *s, uint16_t group_id, int version) +{ + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(group_id); + + if (version < TLS1_3_VERSION) { + if ((ginfo->flags & TLS_GROUP_ONLY_FOR_TLS1_3) != 0) + return 0; + } + return 1; +} + /* See if curve is allowed by security callback */ int tls_curve_allowed(SSL *s, uint16_t curve, int op) { @@ -255,7 +273,7 @@ int tls_curve_allowed(SSL *s, uint16_t curve, int op) if (cinfo == NULL) return 0; # ifdef OPENSSL_NO_EC2M - if (cinfo->flags & TLS_CURVE_CHAR2) + if (cinfo->flags & TLS_GROUP_CURVE_CHAR2) return 0; # endif ctmp[0] = curve >> 8; @@ -341,10 +359,12 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, uint16_t *glist; size_t i; /* - * Bitmap of groups included to detect duplicates: only works while group - * ids < 32 + * Bitmap of groups included to detect duplicates: two variables are added + * to detect duplicates as some values are more than 32. */ - unsigned long dup_list = 0; + unsigned long *dup_list = NULL; + unsigned long dup_list_egrp = 0; + unsigned long dup_list_dhgrp = 0; if (ngroups == 0) { SSLerr(SSL_F_TLS1_SET_GROUPS, SSL_R_BAD_LENGTH); @@ -357,20 +377,23 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, for (i = 0; i < ngroups; i++) { unsigned long idmask; uint16_t id; - /* TODO(TLS1.3): Convert for DH groups */ id = tls1_nid2group_id(groups[i]); - idmask = 1L << id; - if (!id || (dup_list & idmask)) { - OPENSSL_free(glist); - return 0; - } - dup_list |= idmask; + if ((id & 0x00FF) >= (sizeof(unsigned long) * 8)) + goto err; + idmask = 1L << (id & 0x00FF); + dup_list = (id < 0x100) ? &dup_list_egrp : &dup_list_dhgrp; + if (!id || ((*dup_list) & idmask)) + goto err; + *dup_list |= idmask; glist[i] = id; } OPENSSL_free(*pext); *pext = glist; *pextlen = ngroups; return 1; +err: + OPENSSL_free(glist); + return 0; } # define MAX_CURVELIST OSSL_NELEM(nid_list) -- 2.34.0 From 56b09f251d652fc9a3611f4c4d51f500e3115858 Mon Sep 17 00:00:00 2001 From: Billy Brumley Date: Tue, 10 Dec 2019 16:16:41 +0200 Subject: [PATCH 4/8] [sntrup761] Add libssl support for SNTRUP761 Co-authored-by: Nicola Tuveri --- ssl/s3_lib.c | 6 ++--- ssl/ssl_local.h | 5 +++- ssl/statem/extensions_clnt.c | 48 ++++++++++++++++++++++++--------- ssl/statem/extensions_srvr.c | 51 ++++++++++++++++++++++++++---------- ssl/t1_lib.c | 2 ++ 5 files changed, 81 insertions(+), 31 deletions(-) diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 2f1a659a93..94a5e3cf23 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4705,7 +4705,7 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) gtype = ginf->flags & TLS_GROUP_TYPE; # ifndef OPENSSL_NO_EC { - if (gtype == TLS_GROUP_CURVE_CUSTOM) + if (gtype & (TLS_GROUP_CURVE_CUSTOM | TLS_GROUP_KEM)) pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); else pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); @@ -4723,7 +4723,7 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) } # ifndef OPENSSL_NO_EC { - if (gtype != TLS_GROUP_CURVE_CUSTOM + if (!(gtype & (TLS_GROUP_CURVE_CUSTOM | TLS_GROUP_KEM)) && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, ERR_R_EVP_LIB); @@ -4756,7 +4756,7 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) if (ginf == NULL) goto err; - if ((ginf->flags & TLS_GROUP_TYPE) == TLS_GROUP_CURVE_CUSTOM) { + if ((ginf->flags & TLS_GROUP_TYPE) & (TLS_GROUP_CURVE_CUSTOM | TLS_GROUP_KEM)) { pkey = EVP_PKEY_new(); if (pkey != NULL && EVP_PKEY_set_type(pkey, ginf->nid)) return pkey; diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index ee82a8d25d..2baf0c6d76 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -1512,12 +1512,15 @@ typedef struct tls_group_info_st { } TLS_GROUP_INFO; /* flags values */ -# define TLS_GROUP_TYPE 0x00000007U /* Mask for group type */ +# define TLS_GROUP_TYPE 0x0000000FU /* Mask for group type */ # define TLS_GROUP_CURVE_PRIME 0x00000001U # define TLS_GROUP_CURVE_CHAR2 0x00000002U # define TLS_GROUP_CURVE_CUSTOM 0x00000004U +# define TLS_GROUP_KEM 0x00000008U # define TLS_GROUP_ONLY_FOR_TLS1_3 0x00000010U +# define TLS_GROUP_KEM_FOR_TLS1_3 (TLS_GROUP_KEM|TLS_GROUP_ONLY_FOR_TLS1_3) + typedef struct cert_pkey_st CERT_PKEY; /* diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 71ab157908..12abb6154c 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1809,6 +1809,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, unsigned int group_id; PACKET encoded_pt; EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL; + const TLS_GROUP_INFO *ginf = NULL; /* Sanity check */ if (ckey == NULL || s->s3->peer_tmp != NULL) { @@ -1879,19 +1880,40 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - skey = EVP_PKEY_new(); - if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - ERR_R_MALLOC_FAILURE); - EVP_PKEY_free(skey); - return 0; - } - if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_BAD_ECPOINT); - EVP_PKEY_free(skey); - return 0; + if ((ginf = tls1_group_id_lookup(group_id)) != NULL + && (ginf->flags & TLS_GROUP_TYPE) == TLS_GROUP_KEM) { + EVP_PKEY_CTX *pctx = NULL; + + pctx = EVP_PKEY_CTX_new(ckey, NULL); + if (pctx == NULL || EVP_PKEY_decrypt_init(pctx) <= 0 + || EVP_PKEY_decrypt(pctx, NULL, NULL, + PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, + ERR_R_INTERNAL_ERROR); + EVP_PKEY_CTX_free(pctx); + return 0; + } + + skey = ckey; + EVP_PKEY_up_ref(ckey); + + EVP_PKEY_CTX_free(pctx); + } else { + skey = EVP_PKEY_new(); + if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, + ERR_R_MALLOC_FAILURE); + EVP_PKEY_free(skey); + return 0; + } + if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt))) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, + SSL_R_BAD_ECPOINT); + EVP_PKEY_free(skey); + return 0; + } } if (ssl_derive(s, ckey, skey, 1) == 0) { diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 67d3d0bd51..dd565447db 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1684,9 +1684,10 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 - unsigned char *encodedPoint; + unsigned char *encodedPoint = NULL; size_t encoded_pt_len = 0; EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL; + const TLS_GROUP_INFO *ginf = NULL; if (s->hello_retry_request == SSL_HRR_PENDING) { if (ckey != NULL) { @@ -1731,20 +1732,42 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - skey = ssl_generate_pkey(ckey); - if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_MALLOC_FAILURE); - return EXT_RETURN_FAIL; - } + if ((ginf = tls1_group_id_lookup(s->s3->group_id)) != NULL + && (ginf->flags & TLS_GROUP_TYPE) == TLS_GROUP_KEM) { + EVP_PKEY_CTX *pctx = NULL; - /* Generate encoding of server key */ - encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); - if (encoded_pt_len == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_EC_LIB); - EVP_PKEY_free(skey); - return EXT_RETURN_FAIL; + pctx = EVP_PKEY_CTX_new(ckey, NULL); + if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0 + || EVP_PKEY_encrypt(pctx, NULL, &encoded_pt_len, NULL, 0) <= 0 + || (encodedPoint = OPENSSL_malloc(encoded_pt_len)) == NULL + || EVP_PKEY_encrypt(pctx, encodedPoint, &encoded_pt_len, + NULL, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_INTERNAL_ERROR); + OPENSSL_free(encodedPoint); + EVP_PKEY_CTX_free(pctx); + return EXT_RETURN_FAIL; + } + + skey = ckey; + EVP_PKEY_up_ref(ckey); + + EVP_PKEY_CTX_free(pctx); + } else { + skey = ssl_generate_pkey(ckey); + if (skey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_MALLOC_FAILURE); + return EXT_RETURN_FAIL; + } + /* Generate encoding of server key */ + encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); + if (encoded_pt_len == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_EC_LIB); + EVP_PKEY_free(skey); + return EXT_RETURN_FAIL; + } } if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index a2b9c367f0..2290eb3f5f 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -167,6 +167,7 @@ static const TLS_GROUP_INFO nid_list[] = { {EVP_PKEY_X25519, 128, TLS_GROUP_CURVE_CUSTOM, 0x001D}, /* X25519 (29) */ {EVP_PKEY_X448, 224, TLS_GROUP_CURVE_CUSTOM, 0x001E}, /* X448 (30) */ # endif /* OPENSSL_NO_EC */ + {NID_SNTRUP761, 128, TLS_GROUP_KEM_FOR_TLS1_3, 0xFE00}, }; static const unsigned char ecformats_default[] = { @@ -184,6 +185,7 @@ static const uint16_t supported_groups_default[] = { 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ # endif /* OPENSSL_NO_EC */ + 0xFE00, /* sntrup761 (0xFE00) */ }; #ifndef OPENSSL_NO_EC -- 2.34.0 From 499b9942d5f39a94cddb19bd8fcacdb1083a511b Mon Sep 17 00:00:00 2001 From: Nicola Tuveri Date: Sun, 2 May 2021 16:40:08 +0300 Subject: [PATCH 6/8] [sntrup857] Add experimental OID for SNTRUP857 --- crypto/objects/objects.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 75099d7379..0d288662a2 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1613,6 +1613,7 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response # NIST PQC KEM hacks 1 3 6 1 4 1 50263 0 3 1 20 : SNTRUP761 +1 3 6 1 4 1 50263 0 3 1 21 : SNTRUP857 # NIDs for cipher key exchange : KxRSA : kx-rsa -- 2.34.0 From 7fe50869e615a26503c33eddf1fc6e11d18b42cb Mon Sep 17 00:00:00 2001 From: Nicola Tuveri Date: Sun, 2 May 2021 16:58:37 +0300 Subject: [PATCH 8/8] [sntrup857] Add libssl support for SNTRUP857 --- ssl/t1_lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 2290eb3f5f..ce87b8f3de 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -168,6 +168,7 @@ static const TLS_GROUP_INFO nid_list[] = { {EVP_PKEY_X448, 224, TLS_GROUP_CURVE_CUSTOM, 0x001E}, /* X448 (30) */ # endif /* OPENSSL_NO_EC */ {NID_SNTRUP761, 128, TLS_GROUP_KEM_FOR_TLS1_3, 0xFE00}, + {NID_SNTRUP857, 192, TLS_GROUP_KEM_FOR_TLS1_3, 0xFE01}, }; static const unsigned char ecformats_default[] = { @@ -186,6 +187,7 @@ static const uint16_t supported_groups_default[] = { 24, /* secp384r1 (24) */ # endif /* OPENSSL_NO_EC */ 0xFE00, /* sntrup761 (0xFE00) */ + 0xFE01, /* sntrup857 (0xFE01) */ }; #ifndef OPENSSL_NO_EC -- 2.34.0