From abb9401c342629560c95a0f4be5bdffc8b571dfb Mon Sep 17 00:00:00 2001 From: Hakase Date: Mon, 6 Apr 2020 21:52:36 +0900 Subject: [PATCH] Update 3.0.0-dev equal patch, Add revert patch. --- openssl-3.0.0-dev-chacha_draft_revert.patch | 512 +++++++ openssl-equal-3.0.0-dev.patch | 205 +-- openssl-equal-3.0.0-dev_ciphers.patch | 215 +-- openssl-equal-3.0.0-dev_ciphers_revert.patch | 1258 ++++++++++++++++++ openssl-equal-3.0.0-dev_revert.patch | 1182 ++++++++++++++++ 5 files changed, 3197 insertions(+), 175 deletions(-) create mode 100644 openssl-3.0.0-dev-chacha_draft_revert.patch create mode 100644 openssl-equal-3.0.0-dev_ciphers_revert.patch create mode 100644 openssl-equal-3.0.0-dev_revert.patch diff --git a/openssl-3.0.0-dev-chacha_draft_revert.patch b/openssl-3.0.0-dev-chacha_draft_revert.patch new file mode 100644 index 0000000..9dc586e --- /dev/null +++ b/openssl-3.0.0-dev-chacha_draft_revert.patch @@ -0,0 +1,512 @@ +diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c +index df8e5a5bcb..81bab72bcf 100644 +--- a/crypto/evp/c_allc.c ++++ b/crypto/evp/c_allc.c +@@ -265,6 +265,7 @@ void openssl_add_all_ciphers_int(void) + EVP_add_cipher(EVP_chacha20()); + # ifndef OPENSSL_NO_POLY1305 + EVP_add_cipher(EVP_chacha20_poly1305()); ++ EVP_add_cipher(EVP_chacha20_poly1305_draft()); + # endif + #endif + } +diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c +index b7340b147d..4080db7554 100644 +--- a/crypto/evp/e_chacha20_poly1305.c ++++ b/crypto/evp/e_chacha20_poly1305.c +@@ -156,6 +156,7 @@ typedef struct { + struct { uint64_t aad, text; } len; + int aad, mac_inited, tag_len, nonce_len; + size_t tls_payload_length; ++ unsigned char draft:1; + } EVP_CHACHA_AEAD_CTX; + + # define NO_TLS_PAYLOAD_LENGTH ((size_t)-1) +@@ -176,6 +177,7 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx, + actx->aad = 0; + actx->mac_inited = 0; + actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; ++ actx->draft = 0; + + if (iv != NULL) { + unsigned char temp[CHACHA_CTR_SIZE] = { 0 }; +@@ -197,6 +199,27 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx, + return 1; + } + ++static int chacha20_poly1305_draft_init_key(EVP_CIPHER_CTX *ctx, ++ const unsigned char *inkey, ++ const unsigned char *iv, int enc) ++{ ++ EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); ++ ++ if (!inkey) ++ return 1; ++ ++ actx->len.aad = 0; ++ actx->len.text = 0; ++ actx->aad = 0; ++ actx->mac_inited = 0; ++ actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; ++ actx->draft = 1; ++ ++ chacha_init_key(ctx, inkey, NULL, enc); ++ ++ return 1; ++} ++ + # if !defined(OPENSSL_SMALL_FOOTPRINT) + + # if defined(POLY1305_ASM) && (defined(__x86_64) || defined(__x86_64__) || \ +@@ -367,10 +390,11 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + { + EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); + size_t rem, plen = actx->tls_payload_length; ++ uint64_t thirteen = EVP_AEAD_TLS1_AAD_LEN; + + if (!actx->mac_inited) { + # if !defined(OPENSSL_SMALL_FOOTPRINT) +- if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL) ++ if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL && !actx->draft) + return chacha20_poly1305_tls_cipher(ctx, out, in, len); + # endif + actx->key.counter[0] = 0; +@@ -397,9 +421,14 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + return len; + } else { /* plain- or ciphertext */ + if (actx->aad) { /* wrap up aad */ +- if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE)) +- Poly1305_Update(POLY1305_ctx(actx), zero, +- POLY1305_BLOCK_SIZE - rem); ++ if (actx->draft) { ++ thirteen = actx->len.aad; ++ Poly1305_Update(POLY1305_ctx(actx), (const unsigned char *)&thirteen, sizeof(thirteen)); ++ } else { ++ if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE)) ++ Poly1305_Update(POLY1305_ctx(actx), zero, ++ POLY1305_BLOCK_SIZE - rem); ++ } + actx->aad = 0; + } + +@@ -432,40 +461,52 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + } is_endian = { 1 }; + unsigned char temp[POLY1305_BLOCK_SIZE]; + ++ if (actx->draft) { ++ thirteen = actx->len.text; ++ Poly1305_Update(POLY1305_ctx(actx), (const unsigned char *)&thirteen, sizeof(thirteen)); ++ } ++ + if (actx->aad) { /* wrap up aad */ +- if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE)) +- Poly1305_Update(POLY1305_ctx(actx), zero, +- POLY1305_BLOCK_SIZE - rem); ++ if (actx->draft) { ++ thirteen = actx->len.aad; ++ Poly1305_Update(POLY1305_ctx(actx), (const unsigned char *)&thirteen, sizeof(thirteen)); ++ } else { ++ if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE)) ++ Poly1305_Update(POLY1305_ctx(actx), zero, ++ POLY1305_BLOCK_SIZE - rem); ++ } + actx->aad = 0; + } + +- if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE)) +- Poly1305_Update(POLY1305_ctx(actx), zero, +- POLY1305_BLOCK_SIZE - rem); ++ if (!actx->draft) { ++ if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE)) ++ Poly1305_Update(POLY1305_ctx(actx), zero, ++ POLY1305_BLOCK_SIZE - rem); + +- if (is_endian.little) { +- Poly1305_Update(POLY1305_ctx(actx), +- (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE); +- } else { +- temp[0] = (unsigned char)(actx->len.aad); +- temp[1] = (unsigned char)(actx->len.aad>>8); +- temp[2] = (unsigned char)(actx->len.aad>>16); +- temp[3] = (unsigned char)(actx->len.aad>>24); +- temp[4] = (unsigned char)(actx->len.aad>>32); +- temp[5] = (unsigned char)(actx->len.aad>>40); +- temp[6] = (unsigned char)(actx->len.aad>>48); +- temp[7] = (unsigned char)(actx->len.aad>>56); +- +- temp[8] = (unsigned char)(actx->len.text); +- temp[9] = (unsigned char)(actx->len.text>>8); +- temp[10] = (unsigned char)(actx->len.text>>16); +- temp[11] = (unsigned char)(actx->len.text>>24); +- temp[12] = (unsigned char)(actx->len.text>>32); +- temp[13] = (unsigned char)(actx->len.text>>40); +- temp[14] = (unsigned char)(actx->len.text>>48); +- temp[15] = (unsigned char)(actx->len.text>>56); +- +- Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE); ++ if (is_endian.little) { ++ Poly1305_Update(POLY1305_ctx(actx), ++ (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE); ++ } else { ++ temp[0] = (unsigned char)(actx->len.aad); ++ temp[1] = (unsigned char)(actx->len.aad>>8); ++ temp[2] = (unsigned char)(actx->len.aad>>16); ++ temp[3] = (unsigned char)(actx->len.aad>>24); ++ temp[4] = (unsigned char)(actx->len.aad>>32); ++ temp[5] = (unsigned char)(actx->len.aad>>40); ++ temp[6] = (unsigned char)(actx->len.aad>>48); ++ temp[7] = (unsigned char)(actx->len.aad>>56); ++ ++ temp[8] = (unsigned char)(actx->len.text); ++ temp[9] = (unsigned char)(actx->len.text>>8); ++ temp[10] = (unsigned char)(actx->len.text>>16); ++ temp[11] = (unsigned char)(actx->len.text>>24); ++ temp[12] = (unsigned char)(actx->len.text>>32); ++ temp[13] = (unsigned char)(actx->len.text>>40); ++ temp[14] = (unsigned char)(actx->len.text>>48); ++ temp[15] = (unsigned char)(actx->len.text>>56); ++ ++ Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE); ++ } + } + Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag + : temp); +@@ -539,12 +580,14 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: ++ if (actx->draft) return -1; + if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN) + return 0; + actx->nonce_len = arg; + return 1; + + case EVP_CTRL_AEAD_SET_IV_FIXED: ++ if (actx->draft) return -1; + if (arg != 12) + return 0; + actx->nonce[0] = actx->key.counter[1] +@@ -629,9 +672,32 @@ static EVP_CIPHER chacha20_poly1305 = { + NULL /* app_data */ + }; + ++static EVP_CIPHER chacha20_poly1305_draft = { ++ NID_chacha20_poly1305_draft, ++ 1, /* block_size */ ++ CHACHA_KEY_SIZE, /* key_len */ ++ 0, /* iv_len, none */ ++ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV | ++ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | ++ EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER, ++ chacha20_poly1305_draft_init_key, ++ chacha20_poly1305_cipher, ++ chacha20_poly1305_cleanup, ++ 0, /* 0 moves context-specific structure allocation to ctrl */ ++ NULL, /* set_asn1_parameters */ ++ NULL, /* get_asn1_parameters */ ++ chacha20_poly1305_ctrl, ++ NULL /* app_data */ ++}; ++ + const EVP_CIPHER *EVP_chacha20_poly1305(void) + { + return(&chacha20_poly1305); + } ++ ++const EVP_CIPHER *EVP_chacha20_poly1305_draft(void) ++{ ++ return(&chacha20_poly1305_draft); ++} + # endif + #endif +diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h +index 77b4418cd4..6b3d7f9085 100644 +--- a/crypto/objects/obj_dat.h ++++ b/crypto/objects/obj_dat.h +@@ -1088,7 +1088,7 @@ static const unsigned char so[7845] = { + 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x08, /* [ 7836] OBJ_NAIRealm */ + }; + +-#define NUM_NID 1218 ++#define NUM_NID 1219 + static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"UNDEF", "undefined", NID_undef}, + {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, +@@ -2308,9 +2308,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"modp_4096", "modp_4096", NID_modp_4096}, + {"modp_6144", "modp_6144", NID_modp_6144}, + {"modp_8192", "modp_8192", NID_modp_8192}, ++ {"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft}, + }; + +-#define NUM_SN 1209 ++#define NUM_SN 1210 + static const unsigned int sn_objs[NUM_SN] = { + 364, /* "AD_DVCS" */ + 419, /* "AES-128-CBC" */ +@@ -2433,6 +2434,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 417, /* "CSPName" */ + 1019, /* "ChaCha20" */ + 1018, /* "ChaCha20-Poly1305" */ ++ 1218, /* "ChaCha20-Poly1305-D" */ + 367, /* "CrlID" */ + 391, /* "DC" */ + 31, /* "DES-CBC" */ +@@ -3523,7 +3525,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1093, /* "x509ExtAdmission" */ + }; + +-#define NUM_LN 1209 ++#define NUM_LN 1210 + static const unsigned int ln_objs[NUM_LN] = { + 363, /* "AD Time Stamping" */ + 405, /* "ANSI X9.62" */ +@@ -3912,6 +3914,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 883, /* "certificateRevocationList" */ + 1019, /* "chacha20" */ + 1018, /* "chacha20-poly1305" */ ++ 1218, /* "chacha20-poly1305-draft" */ + 54, /* "challengePassword" */ + 407, /* "characteristic-two-field" */ + 395, /* "clearance" */ +diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num +index 15aa1e9772..6fb028c1e8 100644 +--- a/crypto/objects/obj_mac.num ++++ b/crypto/objects/obj_mac.num +@@ -1215,3 +1215,4 @@ modp_3072 1214 + modp_4096 1215 + modp_6144 1216 + modp_8192 1217 ++chacha20_poly1305_draft 1218 +diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt +index 9819c539b7..bb4a9958d0 100644 +--- a/crypto/objects/objects.txt ++++ b/crypto/objects/objects.txt +@@ -1549,6 +1549,7 @@ sm-scheme 104 7 : SM4-CTR : sm4-ctr + : AES-192-CBC-HMAC-SHA256 : aes-192-cbc-hmac-sha256 + : AES-256-CBC-HMAC-SHA256 : aes-256-cbc-hmac-sha256 + : ChaCha20-Poly1305 : chacha20-poly1305 ++ : ChaCha20-Poly1305-D : chacha20-poly1305-draft + : ChaCha20 : chacha20 + + ISO-US 10046 2 1 : dhpublicnumber : X9.42 DH +diff --git a/include/openssl/evp.h b/include/openssl/evp.h +index 4903fc5f42..97a6e9bfee 100644 +--- a/include/openssl/evp.h ++++ b/include/openssl/evp.h +@@ -993,6 +993,7 @@ const EVP_CIPHER *EVP_camellia_256_ctr(void); + const EVP_CIPHER *EVP_chacha20(void); + # ifndef OPENSSL_NO_POLY1305 + const EVP_CIPHER *EVP_chacha20_poly1305(void); ++const EVP_CIPHER *EVP_chacha20_poly1305_draft(void); + # endif + # endif + +diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h +index 0e564ac6d2..3a074d62cb 100644 +--- a/include/openssl/obj_mac.h ++++ b/include/openssl/obj_mac.h +@@ -4857,6 +4857,10 @@ + #define LN_chacha20_poly1305 "chacha20-poly1305" + #define NID_chacha20_poly1305 1018 + ++#define SN_chacha20_poly1305_draft "ChaCha20-Poly1305-D" ++#define LN_chacha20_poly1305_draft "chacha20-poly1305-draft" ++#define NID_chacha20_poly1305_draft 1218 ++ + #define SN_chacha20 "ChaCha20" + #define LN_chacha20 "chacha20" + #define NID_chacha20 1019 +diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h +index e75394676f..cedfbe26c6 100644 +--- a/include/openssl/ssl.h ++++ b/include/openssl/ssl.h +@@ -131,6 +131,7 @@ extern "C" { + # define SSL_TXT_CAMELLIA256 "CAMELLIA256" + # define SSL_TXT_CAMELLIA "CAMELLIA" + # define SSL_TXT_CHACHA20 "CHACHA20" ++# define SSL_TXT_CHACHA20_D "CHACHA20-D" + # define SSL_TXT_GOST "GOST89" + # define SSL_TXT_ARIA "ARIA" + # define SSL_TXT_ARIA_GCM "ARIAGCM" +diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h +index 9181e0d2c1..0244b1ab99 100644 +--- a/include/openssl/tls1.h ++++ b/include/openssl/tls1.h +@@ -578,7 +578,12 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb + # define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C09A + # define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C09B + +-/* draft-ietf-tls-chacha20-poly1305-03 */ ++/* Chacha20-Poly1305-Draft ciphersuites from draft-agl-tls-chacha20poly1305-04 */ ++# define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_D 0x0300CC13 ++# define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D 0x0300CC14 ++# define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305_D 0x0300CC15 ++ ++/* Chacha20-Poly1305 ciphersuites from RFC7905 */ + # define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCA8 + # define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 0x0300CCA9 + # define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCAA +@@ -743,6 +748,9 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb + # define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305 "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" + # define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" + # define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" ++# define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305_D "OLD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" ++# define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305_D "OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" ++# define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D "OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" + # define TLS1_RFC_PSK_WITH_CHACHA20_POLY1305 "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256" + # define TLS1_RFC_ECDHE_PSK_WITH_CHACHA20_POLY1305 "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256" + # define TLS1_RFC_DHE_PSK_WITH_CHACHA20_POLY1305 "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +@@ -1071,7 +1079,12 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb + # define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-RSA-CAMELLIA128-SHA256" + # define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-RSA-CAMELLIA256-SHA384" + +-/* draft-ietf-tls-chacha20-poly1305-03 */ ++/* Chacha20-Poly1305-Draft ciphersuites from draft-agl-tls-chacha20poly1305-04 */ ++# define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_D "ECDHE-RSA-CHACHA20-POLY1305-OLD" ++# define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D "ECDHE-ECDSA-CHACHA20-POLY1305-OLD" ++# define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_D "DHE-RSA-CHACHA20-POLY1305-OLD" ++ ++/* Chacha20-Poly1305 ciphersuites from RFC7905 */ + # define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305" + # define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" + # define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" +diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c +index 26f19108ee..25ad398f7e 100644 +--- a/ssl/s3_lib.c ++++ b/ssl/s3_lib.c +@@ -2084,6 +2084,54 @@ static SSL_CIPHER ssl3_ciphers[] = { + 256, + 256, + }, ++ { ++ 1, ++ TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_D, ++ TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305_D, ++ TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305_D, ++ SSL_kDHE, ++ SSL_aRSA, ++ SSL_CHACHA20POLY1305_D, ++ SSL_AEAD, ++ TLS1_2_VERSION, TLS1_2_VERSION, ++ DTLS1_2_VERSION, DTLS1_2_VERSION, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_D, ++ TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305_D, ++ TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_D, ++ SSL_kECDHE, ++ SSL_aRSA, ++ SSL_CHACHA20POLY1305_D, ++ SSL_AEAD, ++ TLS1_2_VERSION, TLS1_2_VERSION, ++ DTLS1_2_VERSION, DTLS1_2_VERSION, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D, ++ TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D, ++ TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D, ++ SSL_kECDHE, ++ SSL_aECDSA, ++ SSL_CHACHA20POLY1305_D, ++ SSL_AEAD, ++ TLS1_2_VERSION, TLS1_2_VERSION, ++ DTLS1_2_VERSION, DTLS1_2_VERSION, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, ++ 256, ++ 256, ++ }, + { + 1, + TLS1_TXT_PSK_WITH_CHACHA20_POLY1305, +diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c +index 04ffae325c..b04abb0df7 100644 +--- a/ssl/ssl_ciph.c ++++ b/ssl/ssl_ciph.c +@@ -44,7 +44,8 @@ + #define SSL_ENC_CHACHA_IDX 19 + #define SSL_ENC_ARIA128GCM_IDX 20 + #define SSL_ENC_ARIA256GCM_IDX 21 +-#define SSL_ENC_NUM_IDX 22 ++#define SSL_ENC_CHACHA20_D_IDX 22 ++#define SSL_ENC_NUM_IDX 23 + + /* NB: make sure indices in these tables match values above */ + +@@ -77,6 +78,7 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { + {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */ + {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */ + {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */ ++ {SSL_CHACHA20POLY1305_D, NID_chacha20_poly1305_draft}, /* SSL_ENC_CHACHA20POLY1305_IDX 22 */ + }; + + static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; +@@ -276,6 +278,7 @@ static const SSL_CIPHER cipher_aliases[] = { + {0, SSL_TXT_CAMELLIA256, NULL, 0, 0, 0, SSL_CAMELLIA256}, + {0, SSL_TXT_CAMELLIA, NULL, 0, 0, 0, SSL_CAMELLIA}, + {0, SSL_TXT_CHACHA20, NULL, 0, 0, 0, SSL_CHACHA20}, ++ {0, SSL_TXT_CHACHA20_D, NULL, 0, 0, 0, SSL_CHACHA20POLY1305_D}, + {0, SSL_TXT_GOST2012_GOST8912_GOST8912, NULL, 0, 0, 0, SSL_eGOST2814789CNT12}, + + {0, SSL_TXT_ARIA, NULL, 0, 0, 0, SSL_ARIA}, +@@ -1798,6 +1801,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) + case SSL_CHACHA20POLY1305: + enc = "CHACHA20/POLY1305(256)"; + break; ++ case SSL_CHACHA20POLY1305_D: ++ enc = "CHACHA20/POLY1305-Draft(256)"; ++ break; + default: + enc = "unknown"; + break; +@@ -2117,7 +2123,7 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, + out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 16; + } else if (c->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) { + out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 8; +- } else if (c->algorithm_enc & SSL_CHACHA20POLY1305) { ++ } else if (c->algorithm_enc & (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_D)) { + out = 16; + } else if (c->algorithm_mac & SSL_AEAD) { + /* We're supposed to have handled all the AEAD modes above */ +diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h +index f0f0a53ecf..e3935b4edb 100644 +--- a/ssl/ssl_local.h ++++ b/ssl/ssl_local.h +@@ -234,12 +234,13 @@ + # define SSL_CHACHA20POLY1305 0x00080000U + # define SSL_ARIA128GCM 0x00100000U + # define SSL_ARIA256GCM 0x00200000U ++# define SSL_CHACHA20POLY1305_D 0x00400000U + + # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) + # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) + # define SSL_AES (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM) + # define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) +-# define SSL_CHACHA20 (SSL_CHACHA20POLY1305) ++# define SSL_CHACHA20 (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_D) + # define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM) + # define SSL_ARIA (SSL_ARIAGCM) + +diff --git a/util/libcrypto.num b/util/libcrypto.num +index f81fefb9b2..e7ab97676c 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -4622,6 +4622,7 @@ i2d_KeyParams ? 3_0_0 EXIST::FUNCTION: + d2i_KeyParams ? 3_0_0 EXIST::FUNCTION: + i2d_KeyParams_bio ? 3_0_0 EXIST::FUNCTION: + d2i_KeyParams_bio ? 3_0_0 EXIST::FUNCTION: ++EVP_chacha20_poly1305_draft ? 3_0_0 EXIST::FUNCTION:CHACHA,POLY1305 + OSSL_CMP_PKISTATUS_it ? 3_0_0 EXIST::FUNCTION:CMP + d2i_OSSL_CMP_PKIHEADER ? 3_0_0 EXIST::FUNCTION:CMP + i2d_OSSL_CMP_PKIHEADER ? 3_0_0 EXIST::FUNCTION:CMP diff --git a/openssl-equal-3.0.0-dev.patch b/openssl-equal-3.0.0-dev.patch index 4e4cfd2..81ba905 100644 --- a/openssl-equal-3.0.0-dev.patch +++ b/openssl-equal-3.0.0-dev.patch @@ -1,46 +1,47 @@ diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt -index b59c8ba1c6..78f6009efd 100644 +index f467ea909f..76cc311ba8 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt -@@ -1824,13 +1824,13 @@ X509V3_F_X509_PURPOSE_SET:141:X509_PURPOSE_set - X509_F_ADD_CERT_DIR:100:add_cert_dir - X509_F_BUILD_CHAIN:106:build_chain - X509_F_BY_FILE_CTRL:101:by_file_ctrl -+X509_F_CACHE_OBJECTS:163:cache_objects - X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints - X509_F_CHECK_POLICY:145:check_policy - X509_F_COMMON_VERIFY_SM2:165:common_verify_sm2 - X509_F_DANE_I2D:107:dane_i2d - X509_F_DIR_CTRL:102:dir_ctrl - X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject --X509_F_CACHE_OBJECTS:163:cache_objects - X509_F_I2D_X509_AUX:151:i2d_X509_AUX - X509_F_LOOKUP_CERTS_SK:152:lookup_certs_sk - X509_F_NETSCAPE_SPKI_B64_DECODE:129:NETSCAPE_SPKI_b64_decode -@@ -3068,6 +3068,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key +@@ -3009,6 +3009,7 @@ SM2_R_INVALID_ENCODING:104:invalid encoding + SM2_R_INVALID_FIELD:105:invalid field + SM2_R_NO_PARAMETERS_SET:109:no parameters set + SM2_R_USER_ID_TOO_LARGE:106:user id too large ++SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\ + application data after close notify + SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake +@@ -3115,7 +3116,6 @@ SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received + SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message + SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch + SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async +-SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello + SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs + SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request +@@ -3166,6 +3166,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\ mixed handshake and non handshake data -+SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:295:mixed special operator with groups -+SSL_R_NESTED_GROUP:296:nested group ++SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups ++SSL_R_NESTED_GROUP:297:nested group SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate SSL_R_NOT_SERVER:284:not server -@@ -3175,7 +3177,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines +@@ -3273,7 +3275,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading -+SSL_R_UNEXPECTED_GROUP_CLOSE:297:unexpected group close ++SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close SSL_R_UNEXPECTED_MESSAGE:244:unexpected message -+SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:299:unexpected operator in group ++SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group SSL_R_UNEXPECTED_RECORD:245:unexpected record SSL_R_UNINITIALIZED:276:uninitialized SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type -diff --git a/doc/man1/openssl-ciphers.pod b/doc/man1/openssl-ciphers.pod -index 8ba80ba15d..fcda3998bf 100644 ---- a/doc/man1/openssl-ciphers.pod -+++ b/doc/man1/openssl-ciphers.pod -@@ -401,6 +401,21 @@ permissible. +diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in +index 9e5224579a..020bdcbcb9 100644 +--- a/doc/man1/openssl-ciphers.pod.in ++++ b/doc/man1/openssl-ciphers.pod.in +@@ -405,6 +405,21 @@ permissible. =back @@ -63,7 +64,7 @@ index 8ba80ba15d..fcda3998bf 100644 The following lists give the SSL or TLS cipher suites names from the diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h -index 25e304ed10..2d3418f595 100644 +index e1617aae45..a04a3e1552 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -10,12 +10,6 @@ @@ -79,30 +80,46 @@ index 25e304ed10..2d3418f595 100644 # include # include -@@ -609,6 +603,8 @@ int ERR_load_SSL_strings(void); +@@ -462,6 +456,7 @@ int ERR_load_SSL_strings(void); + /* + * SSL reason codes. + */ ++# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 + # define SSL_R_APP_DATA_IN_HANDSHAKE 100 + # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +@@ -561,7 +556,6 @@ int ERR_load_SSL_strings(void); + # define SSL_R_EXTRA_DATA_IN_MESSAGE 153 + # define SSL_R_EXT_LENGTH_MISMATCH 163 + # define SSL_R_FAILED_TO_INIT_ASYNC 405 +-# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_FRAGMENTED_CLIENT_HELLO 401 + # define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 + # define SSL_R_HTTPS_PROXY_REQUEST 155 +@@ -611,6 +605,8 @@ int ERR_load_SSL_strings(void); # define SSL_R_MISSING_TMP_DH_KEY 171 # define SSL_R_MISSING_TMP_ECDH_KEY 311 # define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 -+# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 295 -+# define SSL_R_NESTED_GROUP 296 ++# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 296 ++# define SSL_R_NESTED_GROUP 297 # define SSL_R_NOT_ON_RECORD_BOUNDARY 182 # define SSL_R_NOT_REPLACING_CERTIFICATE 289 # define SSL_R_NOT_SERVER 284 -@@ -740,7 +736,9 @@ int ERR_load_SSL_strings(void); +@@ -742,7 +738,9 @@ int ERR_load_SSL_strings(void); # define SSL_R_UNEXPECTED_CCS_MESSAGE 262 # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 # define SSL_R_UNEXPECTED_EOF_WHILE_READING 294 -+# define SSL_R_UNEXPECTED_GROUP_CLOSE 297 ++# define SSL_R_UNEXPECTED_GROUP_CLOSE 299 # define SSL_R_UNEXPECTED_MESSAGE 244 -+# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 299 ++# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 305 # define SSL_R_UNEXPECTED_RECORD 245 # define SSL_R_UNINITIALIZED 276 # define SSL_R_UNKNOWN_ALERT_TYPE 246 diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c -index 706290be9b..fbc13c5a05 100644 +index 9902fa3811..3033ba3b3a 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c -@@ -168,7 +168,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -169,7 +169,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_3DES, SSL_SHA1, @@ -111,7 +128,7 @@ index 706290be9b..fbc13c5a05 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -233,7 +233,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -234,7 +234,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_AES128, SSL_SHA1, @@ -120,7 +137,7 @@ index 706290be9b..fbc13c5a05 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -297,7 +297,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -298,7 +298,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_AES256, SSL_SHA1, @@ -129,7 +146,7 @@ index 706290be9b..fbc13c5a05 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -4124,6 +4124,17 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) +@@ -4145,6 +4145,17 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) return 1; } @@ -147,7 +164,7 @@ index 706290be9b..fbc13c5a05 100644 /* * ssl3_choose_cipher - choose a cipher from those offered by the client * @s: SSL connection -@@ -4133,15 +4144,23 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) +@@ -4154,15 +4165,23 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) * Returns the selected cipher or NULL when no common ciphers. */ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, @@ -177,7 +194,7 @@ index 706290be9b..fbc13c5a05 100644 /* Let's see which ciphers we can support */ -@@ -4168,54 +4187,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4189,54 +4208,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, } OSSL_TRACE_END(TLS_CIPHER); /* SUITE-B takes precedence over server preference and ChaCha priortiy */ @@ -235,7 +252,7 @@ index 706290be9b..fbc13c5a05 100644 allow = srvr; } -@@ -4246,14 +4224,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4267,14 +4245,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { c = sk_SSL_CIPHER_value(prio, i); @@ -254,7 +271,7 @@ index 706290be9b..fbc13c5a05 100644 /* * Since TLS 1.3 ciphersuites can be used with any auth or -@@ -4275,10 +4255,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4296,10 +4276,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #ifndef OPENSSL_NO_PSK /* with PSK there must be server callback set */ if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL) @@ -267,7 +284,7 @@ index 706290be9b..fbc13c5a05 100644 OSSL_TRACE7(TLS_CIPHER, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, alg_a, mask_k, mask_a, (void *)c, c->name); -@@ -4294,6 +4274,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4315,6 +4295,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, if (!ok) continue; @@ -282,7 +299,7 @@ index 706290be9b..fbc13c5a05 100644 } ii = sk_SSL_CIPHER_find(allow, c); if (ii >= 0) { -@@ -4301,14 +4289,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4322,14 +4310,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED, c->strength_bits, 0, (void *)c)) continue; @@ -298,7 +315,7 @@ index 706290be9b..fbc13c5a05 100644 if (prefer_sha256) { const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); -@@ -4325,13 +4306,38 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4346,13 +4327,38 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, ret = tmp; continue; } @@ -342,7 +359,7 @@ index 706290be9b..fbc13c5a05 100644 } diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c -index 64c791636a..2317b9e495 100644 +index 066c38a7cc..f1e3d1cbe2 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -154,6 +154,7 @@ typedef struct cipher_order_st { @@ -353,7 +370,7 @@ index 64c791636a..2317b9e495 100644 struct cipher_order_st *next, *prev; } CIPHER_ORDER; -@@ -258,6 +259,7 @@ static const SSL_CIPHER cipher_aliases[] = { +@@ -259,6 +260,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_TLSV1, NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, {0, "TLSv1.0", NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, {0, SSL_TXT_TLSV1_2, NULL, 0, 0, 0, 0, 0, TLS1_2_VERSION}, @@ -361,7 +378,7 @@ index 64c791636a..2317b9e495 100644 /* strength classes */ {0, SSL_TXT_LOW, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW}, -@@ -659,6 +661,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, +@@ -673,6 +675,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, co_list[co_list_num].next = NULL; co_list[co_list_num].prev = NULL; co_list[co_list_num].active = 0; @@ -369,7 +386,7 @@ index 64c791636a..2317b9e495 100644 co_list_num++; } -@@ -752,8 +755,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -766,8 +769,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, uint32_t alg_enc, uint32_t alg_mac, int min_tls, uint32_t algo_strength, int rule, @@ -380,7 +397,7 @@ index 64c791636a..2317b9e495 100644 { CIPHER_ORDER *head, *tail, *curr, *next, *last; const SSL_CIPHER *cp; -@@ -761,9 +764,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -775,9 +778,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, OSSL_TRACE_BEGIN(TLS_CIPHER){ BIO_printf(trc_out, @@ -392,7 +409,7 @@ index 64c791636a..2317b9e495 100644 } if (rule == CIPHER_DEL || rule == CIPHER_BUMP) -@@ -840,6 +843,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -854,6 +857,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, if (!curr->active) { ll_append_tail(&head, curr, &tail); curr->active = 1; @@ -400,7 +417,7 @@ index 64c791636a..2317b9e495 100644 } } /* Move the added cipher to this location */ -@@ -847,6 +851,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -861,6 +865,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, /* reverse == 0 */ if (curr->active) { ll_append_tail(&head, curr, &tail); @@ -408,7 +425,7 @@ index 64c791636a..2317b9e495 100644 } } else if (rule == CIPHER_DEL) { /* reverse == 1 */ -@@ -858,6 +863,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -872,6 +877,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, */ ll_append_head(&head, curr, &tail); curr->active = 0; @@ -416,7 +433,7 @@ index 64c791636a..2317b9e495 100644 } } else if (rule == CIPHER_BUMP) { if (curr->active) -@@ -927,8 +933,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, +@@ -941,8 +947,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, */ for (i = max_strength_bits; i >= 0; i--) if (number_uses[i] > 0) @@ -427,7 +444,7 @@ index 64c791636a..2317b9e495 100644 OPENSSL_free(number_uses); return 1; -@@ -942,7 +948,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -956,7 +962,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength; int min_tls; const char *l, *buf; @@ -436,7 +453,7 @@ index 64c791636a..2317b9e495 100644 uint32_t cipher_id = 0; char ch; -@@ -953,18 +959,66 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -967,18 +973,66 @@ static int ssl_cipher_process_rulestr(const char *rule_str, if (ch == '\0') break; /* done */ @@ -504,7 +521,7 @@ index 64c791636a..2317b9e495 100644 } else { rule = CIPHER_ADD; } -@@ -989,7 +1043,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1003,7 +1057,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, while (((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || @@ -513,7 +530,7 @@ index 64c791636a..2317b9e495 100644 #else while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.') || (ch == '=')) -@@ -1006,7 +1060,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1020,7 +1074,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, * alphanumeric, so we call this an error. */ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); @@ -522,7 +539,7 @@ index 64c791636a..2317b9e495 100644 l++; break; } -@@ -1185,8 +1239,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1199,8 +1253,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str, } else if (found) { ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, @@ -533,7 +550,7 @@ index 64c791636a..2317b9e495 100644 } else { while ((*l != '\0') && !ITEM_SEP(*l)) l++; -@@ -1195,6 +1249,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1209,6 +1263,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, break; /* done */ } @@ -545,7 +562,7 @@ index 64c791636a..2317b9e495 100644 return retval; } -@@ -1358,7 +1417,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) +@@ -1372,7 +1431,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str); if (ret && ctx->cipher_list != NULL) @@ -554,7 +571,7 @@ index 64c791636a..2317b9e495 100644 ctx->tls13_ciphersuites); return ret; -@@ -1371,10 +1430,10 @@ int SSL_set_ciphersuites(SSL *s, const char *str) +@@ -1385,10 +1444,10 @@ int SSL_set_ciphersuites(SSL *s, const char *str) if (s->cipher_list == NULL) { if ((cipher_list = SSL_get_ciphers(s)) != NULL) @@ -567,7 +584,7 @@ index 64c791636a..2317b9e495 100644 s->tls13_ciphersuites); return ret; -@@ -1382,17 +1441,20 @@ int SSL_set_ciphersuites(SSL *s, const char *str) +@@ -1396,17 +1455,20 @@ int SSL_set_ciphersuites(SSL *s, const char *str) STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) *tls13_ciphersuites, @@ -591,7 +608,7 @@ index 64c791636a..2317b9e495 100644 /* * Return with error if nothing to do. -@@ -1441,16 +1503,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1455,16 +1517,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * preference). */ ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD, @@ -615,7 +632,7 @@ index 64c791636a..2317b9e495 100644 &head, &tail); /* -@@ -1459,13 +1521,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1473,13 +1535,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * strength. */ ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD, @@ -632,7 +649,7 @@ index 64c791636a..2317b9e495 100644 &tail); /* -@@ -1473,16 +1535,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1487,16 +1549,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * disabled. (For applications that allow them, they aren't too bad, but * we prefer authenticated ciphers.) */ @@ -653,7 +670,7 @@ index 64c791636a..2317b9e495 100644 &tail); /* -@@ -1498,7 +1560,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1512,7 +1574,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs. * TODO(openssl-team): is there an easier way to accomplish all this? */ @@ -662,7 +679,7 @@ index 64c791636a..2317b9e495 100644 &head, &tail); /* -@@ -1514,15 +1576,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1528,15 +1590,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * Because we now bump ciphers to the top of the list, we proceed in * reverse order of preference. */ @@ -685,7 +702,7 @@ index 64c791636a..2317b9e495 100644 /* * We also need cipher aliases for selecting based on the rule_str. -@@ -1536,9 +1601,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1550,9 +1615,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max); if (ca_list == NULL) { @@ -696,7 +713,7 @@ index 64c791636a..2317b9e495 100644 } ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mkey, disabled_auth, disabled_enc, -@@ -1563,28 +1627,19 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1577,28 +1641,19 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, OPENSSL_free(ca_list); /* Not needed anymore */ @@ -732,7 +749,7 @@ index 64c791636a..2317b9e495 100644 OSSL_TRACE_BEGIN(TLS_CIPHER) { BIO_printf(trc_out, "cipher selection:\n"); -@@ -1596,26 +1651,51 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1610,26 +1665,51 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, for (curr = head; curr != NULL; curr = curr->next) { if (curr->active) { if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { @@ -794,10 +811,28 @@ index 64c791636a..2317b9e495 100644 char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c -index 517e90c141..7f578a25ff 100644 +index 85d9dd8448..64f7577a90 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c -@@ -255,6 +255,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { +@@ -14,6 +14,8 @@ + #ifndef OPENSSL_NO_ERR + + static const ERR_STRING_DATA SSL_str_reasons[] = { ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), ++ "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY), + "application data after close notify"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APP_DATA_IN_HANDSHAKE), +@@ -171,8 +173,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "ext length mismatch"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), + "failed to init async"}, +- {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), +- "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), + "fragmented client hello"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_GOT_A_FIN_BEFORE_A_CCS), +@@ -257,6 +257,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "missing tmp ecdh key"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA), "mixed handshake and non handshake data"}, @@ -807,7 +842,7 @@ index 517e90c141..7f578a25ff 100644 {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY), "not on record boundary"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE), -@@ -491,7 +494,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { +@@ -493,7 +496,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unexpected end of early data"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING), "unexpected eof while reading"}, @@ -820,7 +855,7 @@ index 517e90c141..7f578a25ff 100644 {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c -index 977b599055..474a32e085 100644 +index a08ddb138b..fc6d1ac2a3 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1127,6 +1127,71 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) @@ -967,7 +1002,7 @@ index 977b599055..474a32e085 100644 /* Dup the client_CA list */ if (!dup_ca_names(&ret->ca_names, s->ca_names) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h -index 31c01328ce..587c40df36 100644 +index c48bcb9a9a..dfb3e13464 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -789,11 +789,48 @@ int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, @@ -1049,10 +1084,10 @@ index 31c01328ce..587c40df36 100644 +struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_from_ciphers( + STACK_OF(SSL_CIPHER) *ciphers); +struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s); + __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc); __owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s, - const EVP_CIPHER **enc, const EVP_MD **md, - int *mac_pkey_type, size_t *mac_secret_size, -@@ -2448,7 +2492,7 @@ __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, +@@ -2450,7 +2494,7 @@ __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk); __owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, @@ -1062,10 +1097,10 @@ index 31c01328ce..587c40df36 100644 __owur int ssl3_new(SSL *s); void ssl3_free(SSL *s); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c -index ab032ae956..433f2fa2bf 100644 +index 43f9811163..769f0c7eb6 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c -@@ -1764,7 +1764,7 @@ static int tls_early_post_process_client_hello(SSL *s) +@@ -1774,7 +1774,7 @@ static int tls_early_post_process_client_hello(SSL *s) /* For TLSv1.3 we must select the ciphersuite *before* session resumption */ if (SSL_IS_TLS13(s)) { const SSL_CIPHER *cipher = @@ -1074,7 +1109,7 @@ index ab032ae956..433f2fa2bf 100644 if (cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, -@@ -1947,7 +1947,7 @@ static int tls_early_post_process_client_hello(SSL *s) +@@ -1957,7 +1957,7 @@ static int tls_early_post_process_client_hello(SSL *s) /* check if some cipher was preferred by call back */ if (pref_cipher == NULL) pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers, @@ -1083,7 +1118,7 @@ index ab032ae956..433f2fa2bf 100644 if (pref_cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, -@@ -1956,8 +1956,9 @@ static int tls_early_post_process_client_hello(SSL *s) +@@ -1966,8 +1966,9 @@ static int tls_early_post_process_client_hello(SSL *s) } s->session->cipher = pref_cipher; @@ -1095,7 +1130,7 @@ index ab032ae956..433f2fa2bf 100644 sk_SSL_CIPHER_free(s->cipher_list_by_id); s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->peer_ciphers); } -@@ -2269,7 +2270,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) +@@ -2279,7 +2280,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) /* In TLSv1.3 we selected the ciphersuite before resumption */ if (!SSL_IS_TLS13(s)) { cipher = diff --git a/openssl-equal-3.0.0-dev_ciphers.patch b/openssl-equal-3.0.0-dev_ciphers.patch index eb054e8..f52f7de 100644 --- a/openssl-equal-3.0.0-dev_ciphers.patch +++ b/openssl-equal-3.0.0-dev_ciphers.patch @@ -1,46 +1,47 @@ diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt -index b59c8ba1c6..78f6009efd 100644 +index f467ea909f..76cc311ba8 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt -@@ -1824,13 +1824,13 @@ X509V3_F_X509_PURPOSE_SET:141:X509_PURPOSE_set - X509_F_ADD_CERT_DIR:100:add_cert_dir - X509_F_BUILD_CHAIN:106:build_chain - X509_F_BY_FILE_CTRL:101:by_file_ctrl -+X509_F_CACHE_OBJECTS:163:cache_objects - X509_F_CHECK_NAME_CONSTRAINTS:149:check_name_constraints - X509_F_CHECK_POLICY:145:check_policy - X509_F_COMMON_VERIFY_SM2:165:common_verify_sm2 - X509_F_DANE_I2D:107:dane_i2d - X509_F_DIR_CTRL:102:dir_ctrl - X509_F_GET_CERT_BY_SUBJECT:103:get_cert_by_subject --X509_F_CACHE_OBJECTS:163:cache_objects - X509_F_I2D_X509_AUX:151:i2d_X509_AUX - X509_F_LOOKUP_CERTS_SK:152:lookup_certs_sk - X509_F_NETSCAPE_SPKI_B64_DECODE:129:NETSCAPE_SPKI_b64_decode -@@ -3068,6 +3068,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key +@@ -3009,6 +3009,7 @@ SM2_R_INVALID_ENCODING:104:invalid encoding + SM2_R_INVALID_FIELD:105:invalid field + SM2_R_NO_PARAMETERS_SET:109:no parameters set + SM2_R_USER_ID_TOO_LARGE:106:user id too large ++SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\ + application data after close notify + SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake +@@ -3115,7 +3116,6 @@ SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received + SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message + SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch + SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async +-SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello + SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs + SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request +@@ -3166,6 +3166,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\ mixed handshake and non handshake data -+SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:295:mixed special operator with groups -+SSL_R_NESTED_GROUP:296:nested group ++SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups ++SSL_R_NESTED_GROUP:297:nested group SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate SSL_R_NOT_SERVER:284:not server -@@ -3175,7 +3177,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines +@@ -3273,7 +3275,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading -+SSL_R_UNEXPECTED_GROUP_CLOSE:297:unexpected group close ++SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close SSL_R_UNEXPECTED_MESSAGE:244:unexpected message -+SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:299:unexpected operator in group ++SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group SSL_R_UNEXPECTED_RECORD:245:unexpected record SSL_R_UNINITIALIZED:276:uninitialized SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type -diff --git a/doc/man1/openssl-ciphers.pod b/doc/man1/openssl-ciphers.pod -index 8ba80ba15d..fcda3998bf 100644 ---- a/doc/man1/openssl-ciphers.pod -+++ b/doc/man1/openssl-ciphers.pod -@@ -401,6 +401,21 @@ permissible. +diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in +index 9e5224579a..020bdcbcb9 100644 +--- a/doc/man1/openssl-ciphers.pod.in ++++ b/doc/man1/openssl-ciphers.pod.in +@@ -405,6 +405,21 @@ permissible. =back @@ -63,7 +64,7 @@ index 8ba80ba15d..fcda3998bf 100644 The following lists give the SSL or TLS cipher suites names from the diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h -index 25e304ed10..2d3418f595 100644 +index e1617aae45..a04a3e1552 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -10,12 +10,6 @@ @@ -79,30 +80,46 @@ index 25e304ed10..2d3418f595 100644 # include # include -@@ -609,6 +603,8 @@ int ERR_load_SSL_strings(void); +@@ -462,6 +456,7 @@ int ERR_load_SSL_strings(void); + /* + * SSL reason codes. + */ ++# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 + # define SSL_R_APP_DATA_IN_HANDSHAKE 100 + # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +@@ -561,7 +556,6 @@ int ERR_load_SSL_strings(void); + # define SSL_R_EXTRA_DATA_IN_MESSAGE 153 + # define SSL_R_EXT_LENGTH_MISMATCH 163 + # define SSL_R_FAILED_TO_INIT_ASYNC 405 +-# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_FRAGMENTED_CLIENT_HELLO 401 + # define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 + # define SSL_R_HTTPS_PROXY_REQUEST 155 +@@ -611,6 +605,8 @@ int ERR_load_SSL_strings(void); # define SSL_R_MISSING_TMP_DH_KEY 171 # define SSL_R_MISSING_TMP_ECDH_KEY 311 # define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 -+# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 295 -+# define SSL_R_NESTED_GROUP 296 ++# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 296 ++# define SSL_R_NESTED_GROUP 297 # define SSL_R_NOT_ON_RECORD_BOUNDARY 182 # define SSL_R_NOT_REPLACING_CERTIFICATE 289 # define SSL_R_NOT_SERVER 284 -@@ -740,7 +736,9 @@ int ERR_load_SSL_strings(void); +@@ -742,7 +738,9 @@ int ERR_load_SSL_strings(void); # define SSL_R_UNEXPECTED_CCS_MESSAGE 262 # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 # define SSL_R_UNEXPECTED_EOF_WHILE_READING 294 -+# define SSL_R_UNEXPECTED_GROUP_CLOSE 297 ++# define SSL_R_UNEXPECTED_GROUP_CLOSE 299 # define SSL_R_UNEXPECTED_MESSAGE 244 -+# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 299 ++# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 305 # define SSL_R_UNEXPECTED_RECORD 245 # define SSL_R_UNINITIALIZED 276 # define SSL_R_UNKNOWN_ALERT_TYPE 246 diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c -index 706290be9b..6f8361037b 100644 +index 9902fa3811..0fc41e29f0 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c -@@ -32,7 +32,25 @@ const unsigned char tls12downgrade[] = { +@@ -33,7 +33,25 @@ const unsigned char tls12downgrade[] = { }; /* The list of available TLSv1.3 ciphers */ @@ -128,7 +145,7 @@ index 706290be9b..6f8361037b 100644 { 1, TLS1_3_RFC_AES_128_GCM_SHA256, -@@ -112,20 +130,8 @@ static SSL_CIPHER tls13_ciphers[] = { +@@ -113,20 +131,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_HANDSHAKE_MAC_SHA256, 128, 128, @@ -151,7 +168,7 @@ index 706290be9b..6f8361037b 100644 { 1, SSL3_TXT_RSA_NULL_MD5, -@@ -168,7 +174,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -169,7 +175,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_3DES, SSL_SHA1, @@ -160,7 +177,7 @@ index 706290be9b..6f8361037b 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -200,7 +206,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -201,7 +207,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_3DES, SSL_SHA1, @@ -169,7 +186,7 @@ index 706290be9b..6f8361037b 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -233,7 +239,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -234,7 +240,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_AES128, SSL_SHA1, @@ -178,7 +195,7 @@ index 706290be9b..6f8361037b 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -265,7 +271,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -266,7 +272,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_AES128, SSL_SHA1, @@ -187,7 +204,7 @@ index 706290be9b..6f8361037b 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -297,7 +303,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -298,7 +304,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_AES256, SSL_SHA1, @@ -196,7 +213,7 @@ index 706290be9b..6f8361037b 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -329,7 +335,7 @@ static SSL_CIPHER ssl3_ciphers[] = { +@@ -330,7 +336,7 @@ static SSL_CIPHER ssl3_ciphers[] = { SSL_aRSA, SSL_AES256, SSL_SHA1, @@ -205,7 +222,7 @@ index 706290be9b..6f8361037b 100644 DTLS1_BAD_VER, DTLS1_2_VERSION, SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, -@@ -4124,6 +4130,17 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) +@@ -4145,6 +4151,17 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) return 1; } @@ -223,7 +240,7 @@ index 706290be9b..6f8361037b 100644 /* * ssl3_choose_cipher - choose a cipher from those offered by the client * @s: SSL connection -@@ -4133,15 +4150,23 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) +@@ -4154,15 +4171,23 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) * Returns the selected cipher or NULL when no common ciphers. */ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, @@ -253,7 +270,7 @@ index 706290be9b..6f8361037b 100644 /* Let's see which ciphers we can support */ -@@ -4168,54 +4193,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4189,54 +4214,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, } OSSL_TRACE_END(TLS_CIPHER); /* SUITE-B takes precedence over server preference and ChaCha priortiy */ @@ -311,7 +328,7 @@ index 706290be9b..6f8361037b 100644 allow = srvr; } -@@ -4246,14 +4230,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4267,14 +4251,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { c = sk_SSL_CIPHER_value(prio, i); @@ -330,7 +347,7 @@ index 706290be9b..6f8361037b 100644 /* * Since TLS 1.3 ciphersuites can be used with any auth or -@@ -4275,10 +4261,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4296,10 +4282,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #ifndef OPENSSL_NO_PSK /* with PSK there must be server callback set */ if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL) @@ -343,7 +360,7 @@ index 706290be9b..6f8361037b 100644 OSSL_TRACE7(TLS_CIPHER, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, alg_a, mask_k, mask_a, (void *)c, c->name); -@@ -4294,6 +4280,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4315,6 +4301,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, if (!ok) continue; @@ -358,7 +375,7 @@ index 706290be9b..6f8361037b 100644 } ii = sk_SSL_CIPHER_find(allow, c); if (ii >= 0) { -@@ -4301,14 +4295,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4322,14 +4316,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED, c->strength_bits, 0, (void *)c)) continue; @@ -374,7 +391,7 @@ index 706290be9b..6f8361037b 100644 if (prefer_sha256) { const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); -@@ -4325,13 +4312,38 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +@@ -4346,13 +4333,38 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, ret = tmp; continue; } @@ -418,7 +435,7 @@ index 706290be9b..6f8361037b 100644 } diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c -index 64c791636a..2317b9e495 100644 +index 066c38a7cc..f1e3d1cbe2 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -154,6 +154,7 @@ typedef struct cipher_order_st { @@ -429,7 +446,7 @@ index 64c791636a..2317b9e495 100644 struct cipher_order_st *next, *prev; } CIPHER_ORDER; -@@ -258,6 +259,7 @@ static const SSL_CIPHER cipher_aliases[] = { +@@ -259,6 +260,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_TLSV1, NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, {0, "TLSv1.0", NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, {0, SSL_TXT_TLSV1_2, NULL, 0, 0, 0, 0, 0, TLS1_2_VERSION}, @@ -437,7 +454,7 @@ index 64c791636a..2317b9e495 100644 /* strength classes */ {0, SSL_TXT_LOW, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW}, -@@ -659,6 +661,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, +@@ -673,6 +675,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, co_list[co_list_num].next = NULL; co_list[co_list_num].prev = NULL; co_list[co_list_num].active = 0; @@ -445,7 +462,7 @@ index 64c791636a..2317b9e495 100644 co_list_num++; } -@@ -752,8 +755,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -766,8 +769,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, uint32_t alg_enc, uint32_t alg_mac, int min_tls, uint32_t algo_strength, int rule, @@ -456,7 +473,7 @@ index 64c791636a..2317b9e495 100644 { CIPHER_ORDER *head, *tail, *curr, *next, *last; const SSL_CIPHER *cp; -@@ -761,9 +764,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -775,9 +778,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, OSSL_TRACE_BEGIN(TLS_CIPHER){ BIO_printf(trc_out, @@ -468,7 +485,7 @@ index 64c791636a..2317b9e495 100644 } if (rule == CIPHER_DEL || rule == CIPHER_BUMP) -@@ -840,6 +843,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -854,6 +857,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, if (!curr->active) { ll_append_tail(&head, curr, &tail); curr->active = 1; @@ -476,7 +493,7 @@ index 64c791636a..2317b9e495 100644 } } /* Move the added cipher to this location */ -@@ -847,6 +851,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -861,6 +865,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, /* reverse == 0 */ if (curr->active) { ll_append_tail(&head, curr, &tail); @@ -484,7 +501,7 @@ index 64c791636a..2317b9e495 100644 } } else if (rule == CIPHER_DEL) { /* reverse == 1 */ -@@ -858,6 +863,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, +@@ -872,6 +877,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, */ ll_append_head(&head, curr, &tail); curr->active = 0; @@ -492,7 +509,7 @@ index 64c791636a..2317b9e495 100644 } } else if (rule == CIPHER_BUMP) { if (curr->active) -@@ -927,8 +933,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, +@@ -941,8 +947,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, */ for (i = max_strength_bits; i >= 0; i--) if (number_uses[i] > 0) @@ -503,7 +520,7 @@ index 64c791636a..2317b9e495 100644 OPENSSL_free(number_uses); return 1; -@@ -942,7 +948,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -956,7 +962,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength; int min_tls; const char *l, *buf; @@ -512,7 +529,7 @@ index 64c791636a..2317b9e495 100644 uint32_t cipher_id = 0; char ch; -@@ -953,18 +959,66 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -967,18 +973,66 @@ static int ssl_cipher_process_rulestr(const char *rule_str, if (ch == '\0') break; /* done */ @@ -580,7 +597,7 @@ index 64c791636a..2317b9e495 100644 } else { rule = CIPHER_ADD; } -@@ -989,7 +1043,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1003,7 +1057,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, while (((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || @@ -589,7 +606,7 @@ index 64c791636a..2317b9e495 100644 #else while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.') || (ch == '=')) -@@ -1006,7 +1060,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1020,7 +1074,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, * alphanumeric, so we call this an error. */ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); @@ -598,7 +615,7 @@ index 64c791636a..2317b9e495 100644 l++; break; } -@@ -1185,8 +1239,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1199,8 +1253,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str, } else if (found) { ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, @@ -609,7 +626,7 @@ index 64c791636a..2317b9e495 100644 } else { while ((*l != '\0') && !ITEM_SEP(*l)) l++; -@@ -1195,6 +1249,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, +@@ -1209,6 +1263,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, break; /* done */ } @@ -621,7 +638,7 @@ index 64c791636a..2317b9e495 100644 return retval; } -@@ -1358,7 +1417,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) +@@ -1372,7 +1431,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str); if (ret && ctx->cipher_list != NULL) @@ -630,7 +647,7 @@ index 64c791636a..2317b9e495 100644 ctx->tls13_ciphersuites); return ret; -@@ -1371,10 +1430,10 @@ int SSL_set_ciphersuites(SSL *s, const char *str) +@@ -1385,10 +1444,10 @@ int SSL_set_ciphersuites(SSL *s, const char *str) if (s->cipher_list == NULL) { if ((cipher_list = SSL_get_ciphers(s)) != NULL) @@ -643,7 +660,7 @@ index 64c791636a..2317b9e495 100644 s->tls13_ciphersuites); return ret; -@@ -1382,17 +1441,20 @@ int SSL_set_ciphersuites(SSL *s, const char *str) +@@ -1396,17 +1455,20 @@ int SSL_set_ciphersuites(SSL *s, const char *str) STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) *tls13_ciphersuites, @@ -667,7 +684,7 @@ index 64c791636a..2317b9e495 100644 /* * Return with error if nothing to do. -@@ -1441,16 +1503,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1455,16 +1517,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * preference). */ ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD, @@ -691,7 +708,7 @@ index 64c791636a..2317b9e495 100644 &head, &tail); /* -@@ -1459,13 +1521,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1473,13 +1535,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * strength. */ ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD, @@ -708,7 +725,7 @@ index 64c791636a..2317b9e495 100644 &tail); /* -@@ -1473,16 +1535,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1487,16 +1549,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * disabled. (For applications that allow them, they aren't too bad, but * we prefer authenticated ciphers.) */ @@ -729,7 +746,7 @@ index 64c791636a..2317b9e495 100644 &tail); /* -@@ -1498,7 +1560,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1512,7 +1574,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs. * TODO(openssl-team): is there an easier way to accomplish all this? */ @@ -738,7 +755,7 @@ index 64c791636a..2317b9e495 100644 &head, &tail); /* -@@ -1514,15 +1576,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1528,15 +1590,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, * Because we now bump ciphers to the top of the list, we proceed in * reverse order of preference. */ @@ -761,7 +778,7 @@ index 64c791636a..2317b9e495 100644 /* * We also need cipher aliases for selecting based on the rule_str. -@@ -1536,9 +1601,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1550,9 +1615,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max); if (ca_list == NULL) { @@ -772,7 +789,7 @@ index 64c791636a..2317b9e495 100644 } ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mkey, disabled_auth, disabled_enc, -@@ -1563,28 +1627,19 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1577,28 +1641,19 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, OPENSSL_free(ca_list); /* Not needed anymore */ @@ -808,7 +825,7 @@ index 64c791636a..2317b9e495 100644 OSSL_TRACE_BEGIN(TLS_CIPHER) { BIO_printf(trc_out, "cipher selection:\n"); -@@ -1596,26 +1651,51 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +@@ -1610,26 +1665,51 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, for (curr = head; curr != NULL; curr = curr->next) { if (curr->active) { if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { @@ -870,10 +887,28 @@ index 64c791636a..2317b9e495 100644 char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c -index 517e90c141..7f578a25ff 100644 +index 85d9dd8448..64f7577a90 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c -@@ -255,6 +255,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { +@@ -14,6 +14,8 @@ + #ifndef OPENSSL_NO_ERR + + static const ERR_STRING_DATA SSL_str_reasons[] = { ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), ++ "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY), + "application data after close notify"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APP_DATA_IN_HANDSHAKE), +@@ -171,8 +173,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "ext length mismatch"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), + "failed to init async"}, +- {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), +- "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), + "fragmented client hello"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_GOT_A_FIN_BEFORE_A_CCS), +@@ -257,6 +257,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "missing tmp ecdh key"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA), "mixed handshake and non handshake data"}, @@ -883,7 +918,7 @@ index 517e90c141..7f578a25ff 100644 {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY), "not on record boundary"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE), -@@ -491,7 +494,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { +@@ -493,7 +496,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unexpected end of early data"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING), "unexpected eof while reading"}, @@ -896,7 +931,7 @@ index 517e90c141..7f578a25ff 100644 {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c -index 977b599055..474a32e085 100644 +index a08ddb138b..fc6d1ac2a3 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1127,6 +1127,71 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) @@ -1043,7 +1078,7 @@ index 977b599055..474a32e085 100644 /* Dup the client_CA list */ if (!dup_ca_names(&ret->ca_names, s->ca_names) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h -index 31c01328ce..587c40df36 100644 +index c48bcb9a9a..dfb3e13464 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -789,11 +789,48 @@ int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, @@ -1125,10 +1160,10 @@ index 31c01328ce..587c40df36 100644 +struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_from_ciphers( + STACK_OF(SSL_CIPHER) *ciphers); +struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s); + __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc); __owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s, - const EVP_CIPHER **enc, const EVP_MD **md, - int *mac_pkey_type, size_t *mac_secret_size, -@@ -2448,7 +2492,7 @@ __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, +@@ -2450,7 +2494,7 @@ __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk); __owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, @@ -1138,10 +1173,10 @@ index 31c01328ce..587c40df36 100644 __owur int ssl3_new(SSL *s); void ssl3_free(SSL *s); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c -index ab032ae956..433f2fa2bf 100644 +index 43f9811163..769f0c7eb6 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c -@@ -1764,7 +1764,7 @@ static int tls_early_post_process_client_hello(SSL *s) +@@ -1774,7 +1774,7 @@ static int tls_early_post_process_client_hello(SSL *s) /* For TLSv1.3 we must select the ciphersuite *before* session resumption */ if (SSL_IS_TLS13(s)) { const SSL_CIPHER *cipher = @@ -1150,7 +1185,7 @@ index ab032ae956..433f2fa2bf 100644 if (cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, -@@ -1947,7 +1947,7 @@ static int tls_early_post_process_client_hello(SSL *s) +@@ -1957,7 +1957,7 @@ static int tls_early_post_process_client_hello(SSL *s) /* check if some cipher was preferred by call back */ if (pref_cipher == NULL) pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers, @@ -1159,7 +1194,7 @@ index ab032ae956..433f2fa2bf 100644 if (pref_cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, -@@ -1956,8 +1956,9 @@ static int tls_early_post_process_client_hello(SSL *s) +@@ -1966,8 +1966,9 @@ static int tls_early_post_process_client_hello(SSL *s) } s->session->cipher = pref_cipher; @@ -1171,7 +1206,7 @@ index ab032ae956..433f2fa2bf 100644 sk_SSL_CIPHER_free(s->cipher_list_by_id); s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->peer_ciphers); } -@@ -2269,7 +2270,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) +@@ -2279,7 +2280,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) /* In TLSv1.3 we selected the ciphersuite before resumption */ if (!SSL_IS_TLS13(s)) { cipher = diff --git a/openssl-equal-3.0.0-dev_ciphers_revert.patch b/openssl-equal-3.0.0-dev_ciphers_revert.patch new file mode 100644 index 0000000..7d35a4b --- /dev/null +++ b/openssl-equal-3.0.0-dev_ciphers_revert.patch @@ -0,0 +1,1258 @@ +diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt +index f467ea909f..76cc311ba8 100644 +--- a/crypto/err/openssl.txt ++++ b/crypto/err/openssl.txt +@@ -3009,6 +3009,7 @@ SM2_R_INVALID_ENCODING:104:invalid encoding + SM2_R_INVALID_FIELD:105:invalid field + SM2_R_NO_PARAMETERS_SET:109:no parameters set + SM2_R_USER_ID_TOO_LARGE:106:user id too large ++SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\ + application data after close notify + SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake +@@ -3115,7 +3116,6 @@ SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received + SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message + SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch + SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async +-SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello + SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs + SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request +@@ -3166,6 +3166,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key + SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key + SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\ + mixed handshake and non handshake data ++SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups ++SSL_R_NESTED_GROUP:297:nested group + SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary + SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate + SSL_R_NOT_SERVER:284:not server +@@ -3273,7 +3275,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines + SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message + SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data + SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading ++SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close + SSL_R_UNEXPECTED_MESSAGE:244:unexpected message ++SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group + SSL_R_UNEXPECTED_RECORD:245:unexpected record + SSL_R_UNINITIALIZED:276:uninitialized + SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type +diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in +index 9e5224579a..020bdcbcb9 100644 +--- a/doc/man1/openssl-ciphers.pod.in ++++ b/doc/man1/openssl-ciphers.pod.in +@@ -405,6 +405,21 @@ permissible. + + =back + ++=head1 EQUAL PREFERENCE GROUPS ++ ++If configuring a server, one may also configure equal-preference groups to ++partially respect the client's preferences when ++B is enabled. Ciphers in an equal-preference ++group have equal priority and use the client order. This may be used to ++enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305 ++based on client preferences. An equal-preference is specified with square ++brackets, combining multiple selectors separated by |. For example: ++ ++ [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256] ++ ++ Once an equal-preference group is used, future directives must be ++ opcode-less. ++ + =head1 CIPHER SUITE NAMES + + The following lists give the SSL or TLS cipher suites names from the +diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h +index e1617aae45..a04a3e1552 100644 +--- a/include/openssl/sslerr.h ++++ b/include/openssl/sslerr.h +@@ -10,12 +10,6 @@ + + #ifndef OPENSSL_SSLERR_H + # define OPENSSL_SSLERR_H +-# pragma once +- +-# include +-# ifndef OPENSSL_NO_DEPRECATED_3_0 +-# define HEADER_SSLERR_H +-# endif + + # include + # include +@@ -462,6 +456,7 @@ int ERR_load_SSL_strings(void); + /* + * SSL reason codes. + */ ++# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 + # define SSL_R_APP_DATA_IN_HANDSHAKE 100 + # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +@@ -561,7 +556,6 @@ int ERR_load_SSL_strings(void); + # define SSL_R_EXTRA_DATA_IN_MESSAGE 153 + # define SSL_R_EXT_LENGTH_MISMATCH 163 + # define SSL_R_FAILED_TO_INIT_ASYNC 405 +-# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_FRAGMENTED_CLIENT_HELLO 401 + # define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 + # define SSL_R_HTTPS_PROXY_REQUEST 155 +@@ -611,6 +605,8 @@ int ERR_load_SSL_strings(void); + # define SSL_R_MISSING_TMP_DH_KEY 171 + # define SSL_R_MISSING_TMP_ECDH_KEY 311 + # define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 ++# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 296 ++# define SSL_R_NESTED_GROUP 297 + # define SSL_R_NOT_ON_RECORD_BOUNDARY 182 + # define SSL_R_NOT_REPLACING_CERTIFICATE 289 + # define SSL_R_NOT_SERVER 284 +@@ -742,7 +738,9 @@ int ERR_load_SSL_strings(void); + # define SSL_R_UNEXPECTED_CCS_MESSAGE 262 + # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 + # define SSL_R_UNEXPECTED_EOF_WHILE_READING 294 ++# define SSL_R_UNEXPECTED_GROUP_CLOSE 299 + # define SSL_R_UNEXPECTED_MESSAGE 244 ++# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 305 + # define SSL_R_UNEXPECTED_RECORD 245 + # define SSL_R_UNINITIALIZED 276 + # define SSL_R_UNKNOWN_ALERT_TYPE 246 +diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c +index 26f19108ee..41bf523363 100644 +--- a/ssl/s3_lib.c ++++ b/ssl/s3_lib.c +@@ -33,7 +33,25 @@ const unsigned char tls12downgrade[] = { + }; + + /* The list of available TLSv1.3 ciphers */ ++/* Since nginx can not set the TLS 1.3 cipher, remove it temporarily. */ + static SSL_CIPHER tls13_ciphers[] = { ++ { ++ 0, ++ } ++}; ++ ++/* ++ * The list of available ciphers, mostly organized into the following ++ * groups: ++ * Always there ++ * EC ++ * PSK ++ * SRP (within that: RSA EC PSK) ++ * Cipher families: Chacha/poly, Camellia, Gost, IDEA, SEED ++ * Weak ciphers ++ */ ++static SSL_CIPHER ssl3_ciphers[] = { ++ /* TLSv1.3 ciphers */ + { + 1, + TLS1_3_RFC_AES_128_GCM_SHA256, +@@ -113,20 +131,8 @@ static SSL_CIPHER tls13_ciphers[] = { + SSL_HANDSHAKE_MAC_SHA256, + 128, + 128, +- } +-}; +- +-/* +- * The list of available ciphers, mostly organized into the following +- * groups: +- * Always there +- * EC +- * PSK +- * SRP (within that: RSA EC PSK) +- * Cipher families: Chacha/poly, Camellia, Gost, IDEA, SEED +- * Weak ciphers +- */ +-static SSL_CIPHER ssl3_ciphers[] = { ++ }, ++ /* List of cipher below TLSv1.3 */ + { + 1, + SSL3_TXT_RSA_NULL_MD5, +@@ -169,7 +175,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_3DES, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -201,7 +207,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_3DES, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -234,7 +240,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_AES128, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -266,7 +272,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_AES128, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -298,7 +304,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_AES256, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -330,7 +336,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_AES256, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -4142,6 +4148,17 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) + return 1; + } + ++struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s) ++{ ++ if (s->cipher_list != NULL) ++ return (s->cipher_list); ++ ++ if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) ++ return (s->ctx->cipher_list); ++ ++ return NULL; ++} ++ + /* + * ssl3_choose_cipher - choose a cipher from those offered by the client + * @s: SSL connection +@@ -4151,16 +4168,24 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) + * Returns the selected cipher or NULL when no common ciphers. + */ + const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +- STACK_OF(SSL_CIPHER) *srvr) ++ struct ssl_cipher_preference_list_st ++ *server_pref) + { + const SSL_CIPHER *c, *ret = NULL; +- STACK_OF(SSL_CIPHER) *prio, *allow; +- int i, ii, ok, prefer_sha256 = 0; ++ STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow; ++ int i, ii, ok, prefer_sha256 = 0, safari_ec = 0; + unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0; + const EVP_MD *mdsha256 = EVP_sha256(); +-#ifndef OPENSSL_NO_CHACHA +- STACK_OF(SSL_CIPHER) *prio_chacha = NULL; +-#endif ++ ++ /* in_group_flags will either be NULL, or will point to an array of ++ * bytes which indicate equal-preference groups in the |prio| stack. ++ * See the comment about |in_group_flags| in the ++ * |ssl_cipher_preference_list_st| struct. */ ++ const uint8_t *in_group_flags; ++ ++ /* group_min contains the minimal index so far found in a group, or -1 ++ * if no such value exists yet. */ ++ int group_min = -1; + + /* Let's see which ciphers we can support */ + +@@ -4187,54 +4212,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + } OSSL_TRACE_END(TLS_CIPHER); + + /* SUITE-B takes precedence over server preference and ChaCha priortiy */ +- if (tls1_suiteb(s)) { ++ if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) { + prio = srvr; ++ in_group_flags = server_pref->in_group_flags; + allow = clnt; +- } else if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { +- prio = srvr; +- allow = clnt; +-#ifndef OPENSSL_NO_CHACHA +- /* If ChaCha20 is at the top of the client preference list, +- and there are ChaCha20 ciphers in the server list, then +- temporarily prioritize all ChaCha20 ciphers in the servers list. */ +- if (s->options & SSL_OP_PRIORITIZE_CHACHA && sk_SSL_CIPHER_num(clnt) > 0) { +- c = sk_SSL_CIPHER_value(clnt, 0); +- if (c->algorithm_enc == SSL_CHACHA20POLY1305) { +- /* ChaCha20 is client preferred, check server... */ +- int num = sk_SSL_CIPHER_num(srvr); +- int found = 0; +- for (i = 0; i < num; i++) { +- c = sk_SSL_CIPHER_value(srvr, i); +- if (c->algorithm_enc == SSL_CHACHA20POLY1305) { +- found = 1; +- break; +- } +- } +- if (found) { +- prio_chacha = sk_SSL_CIPHER_new_reserve(NULL, num); +- /* if reserve fails, then there's likely a memory issue */ +- if (prio_chacha != NULL) { +- /* Put all ChaCha20 at the top, starting with the one we just found */ +- sk_SSL_CIPHER_push(prio_chacha, c); +- for (i++; i < num; i++) { +- c = sk_SSL_CIPHER_value(srvr, i); +- if (c->algorithm_enc == SSL_CHACHA20POLY1305) +- sk_SSL_CIPHER_push(prio_chacha, c); +- } +- /* Pull in the rest */ +- for (i = 0; i < num; i++) { +- c = sk_SSL_CIPHER_value(srvr, i); +- if (c->algorithm_enc != SSL_CHACHA20POLY1305) +- sk_SSL_CIPHER_push(prio_chacha, c); +- } +- prio = prio_chacha; +- } +- } +- } +- } +-# endif + } else { + prio = clnt; ++ in_group_flags = NULL; + allow = srvr; + } + +@@ -4265,14 +4249,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + c = sk_SSL_CIPHER_value(prio, i); + ++ ok = 1; ++ + /* Skip ciphers not supported by the protocol version */ + if (!SSL_IS_DTLS(s) && + ((s->version < c->min_tls) || (s->version > c->max_tls))) +- continue; ++ ok = 0; + if (SSL_IS_DTLS(s) && + (DTLS_VERSION_LT(s->version, c->min_dtls) || + DTLS_VERSION_GT(s->version, c->max_dtls))) +- continue; ++ ok = 0; + + /* + * Since TLS 1.3 ciphersuites can be used with any auth or +@@ -4294,10 +4280,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + #ifndef OPENSSL_NO_PSK + /* with PSK there must be server callback set */ + if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL) +- continue; ++ ok = 0; + #endif /* OPENSSL_NO_PSK */ + +- ok = (alg_k & mask_k) && (alg_a & mask_a); ++ ok = ok && (alg_k & mask_k) && (alg_a & mask_a); + OSSL_TRACE7(TLS_CIPHER, + "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", + ok, alg_k, alg_a, mask_k, mask_a, (void *)c, c->name); +@@ -4313,6 +4299,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + + if (!ok) + continue; ++ ++ safari_ec = 0; ++#if !defined(OPENSSL_NO_EC) ++ if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA)) { ++ if (s->s3.is_probably_safari) ++ safari_ec = 1; ++ } ++#endif + } + ii = sk_SSL_CIPHER_find(allow, c); + if (ii >= 0) { +@@ -4320,14 +4314,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED, + c->strength_bits, 0, (void *)c)) + continue; +-#if !defined(OPENSSL_NO_EC) +- if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA) +- && s->s3.is_probably_safari) { +- if (!ret) +- ret = sk_SSL_CIPHER_value(allow, ii); +- continue; +- } +-#endif ++ + if (prefer_sha256) { + const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); + +@@ -4339,13 +4326,38 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + ret = tmp; + continue; + } +- ret = sk_SSL_CIPHER_value(allow, ii); ++ ++ if (in_group_flags != NULL && in_group_flags[i] == 1) { ++ /* This element of |prio| is in a group. Update ++ * the minimum index found so far and continue ++ * looking. */ ++ if (group_min == -1 || group_min > ii) ++ group_min = ii; ++ } else { ++ if (group_min != -1 && group_min < ii) ++ ii = group_min; ++ if (safari_ec) { ++ if (!ret) ++ ret = sk_SSL_CIPHER_value(allow, ii); ++ continue; ++ } ++ ret = sk_SSL_CIPHER_value(allow, ii); ++ break; ++ } ++ } ++ ++ if (in_group_flags != NULL && !in_group_flags[i] && group_min != -1) { ++ /* We are about to leave a group, but we found a match ++ * in it, so that's our answer. */ ++ if (safari_ec) { ++ if (!ret) ++ ret = sk_SSL_CIPHER_value(allow, group_min); ++ continue; ++ } ++ ret = sk_SSL_CIPHER_value(allow, group_min); + break; + } + } +-#ifndef OPENSSL_NO_CHACHA +- sk_SSL_CIPHER_free(prio_chacha); +-#endif + return ret; + } + +diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c +index 04ffae325c..b67369f639 100644 +--- a/ssl/ssl_ciph.c ++++ b/ssl/ssl_ciph.c +@@ -193,6 +193,7 @@ typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + int active; + int dead; ++ int in_group; + struct cipher_order_st *next, *prev; + } CIPHER_ORDER; + +@@ -298,6 +299,7 @@ static const SSL_CIPHER cipher_aliases[] = { + {0, SSL_TXT_TLSV1, NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, + {0, "TLSv1.0", NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, + {0, SSL_TXT_TLSV1_2, NULL, 0, 0, 0, 0, 0, TLS1_2_VERSION}, ++ {0, "TLS13", NULL, 0, 0, 0, 0, 0, TLS1_3_VERSION}, + + /* strength classes */ + {0, SSL_TXT_LOW, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW}, +@@ -681,6 +683,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = 0; ++ co_list[co_list_num].in_group = 0; + co_list_num++; + } + +@@ -774,8 +777,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + uint32_t alg_auth, uint32_t alg_enc, + uint32_t alg_mac, int min_tls, + uint32_t algo_strength, int rule, +- int32_t strength_bits, CIPHER_ORDER **head_p, +- CIPHER_ORDER **tail_p) ++ int32_t strength_bits, int in_group, ++ CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) + { + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; +@@ -783,9 +786,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + + OSSL_TRACE_BEGIN(TLS_CIPHER){ + BIO_printf(trc_out, +- "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n", ++ "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d) g:%d\n", + rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls, +- algo_strength, strength_bits); ++ algo_strength, strength_bits, in_group); + } + + if (rule == CIPHER_DEL || rule == CIPHER_BUMP) +@@ -862,6 +865,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = 1; ++ curr->in_group = in_group; + } + } + /* Move the added cipher to this location */ +@@ -869,6 +873,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + /* reverse == 0 */ + if (curr->active) { + ll_append_tail(&head, curr, &tail); ++ curr->in_group = 0; + } + } else if (rule == CIPHER_DEL) { + /* reverse == 1 */ +@@ -880,6 +885,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + */ + ll_append_head(&head, curr, &tail); + curr->active = 0; ++ curr->in_group = 0; + } + } else if (rule == CIPHER_BUMP) { + if (curr->active) +@@ -949,8 +955,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + */ + for (i = max_strength_bits; i >= 0; i--) + if (number_uses[i] > 0) +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, +- tail_p); ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, ++ head_p, tail_p); + + OPENSSL_free(number_uses); + return 1; +@@ -964,7 +970,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength; + int min_tls; + const char *l, *buf; +- int j, multi, found, rule, retval, ok, buflen; ++ int j, multi, found, rule, retval, ok, buflen, in_group = 0, has_group = 0; + uint32_t cipher_id = 0; + char ch; + +@@ -975,18 +981,66 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + + if (ch == '\0') + break; /* done */ +- if (ch == '-') { ++ if (in_group) { ++ if (ch == ']') { ++ if (!in_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_UNEXPECTED_GROUP_CLOSE); ++ retval = found = in_group = 0; ++ break; ++ } ++ if (*tail_p) ++ (*tail_p)->in_group = 0; ++ in_group = 0; ++ l++; ++ continue; ++ } ++ if (ch == '|') { ++ rule = CIPHER_ADD; ++ l++; ++ continue; ++ } else if (!(ch >= 'a' && ch <= 'z') ++ && !(ch >= 'A' && ch <= 'Z') ++ && !(ch >= '0' && ch <= '9')) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); ++ retval = found = in_group = 0; ++ break; ++ } else { ++ rule = CIPHER_ADD; ++ } ++ } else if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; ++ } else if (ch == '!' && has_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); ++ retval = found = in_group = 0; ++ break; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; ++ } else if (ch == '@' && has_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); ++ retval = found = in_group = 0; ++ break; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; ++ } else if (ch == '[') { ++ if (in_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_NESTED_GROUP); ++ retval = found = in_group = 0; ++ break; ++ } ++ in_group = 1; ++ has_group = 1; ++ l++; ++ continue; + } else { + rule = CIPHER_ADD; + } +@@ -1011,7 +1065,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + while (((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || +- (ch == '-') || (ch == '.') || (ch == '=')) ++ (ch == '-') || (ch == '.') || (ch == '=') || (ch == '_')) + #else + while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.') + || (ch == '=')) +@@ -1028,7 +1082,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + * alphanumeric, so we call this an error. + */ + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); +- retval = found = 0; ++ retval = found = in_group = 0; + l++; + break; + } +@@ -1207,8 +1261,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + } else if (found) { + ssl_cipher_apply_rule(cipher_id, + alg_mkey, alg_auth, alg_enc, alg_mac, +- min_tls, algo_strength, rule, -1, head_p, +- tail_p); ++ min_tls, algo_strength, rule, -1, in_group, ++ head_p, tail_p); + } else { + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; +@@ -1217,6 +1271,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + break; /* done */ + } + ++ if (in_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); ++ retval = 0; ++ } ++ + return retval; + } + +@@ -1380,7 +1439,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) + int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str); + + if (ret && ctx->cipher_list != NULL) +- return update_cipher_list(&ctx->cipher_list, &ctx->cipher_list_by_id, ++ return update_cipher_list(&ctx->cipher_list->ciphers, &ctx->cipher_list_by_id, + ctx->tls13_ciphersuites); + + return ret; +@@ -1393,10 +1452,10 @@ int SSL_set_ciphersuites(SSL *s, const char *str) + + if (s->cipher_list == NULL) { + if ((cipher_list = SSL_get_ciphers(s)) != NULL) +- s->cipher_list = sk_SSL_CIPHER_dup(cipher_list); ++ s->cipher_list->ciphers = sk_SSL_CIPHER_dup(cipher_list); + } + if (ret && s->cipher_list != NULL) +- return update_cipher_list(&s->cipher_list, &s->cipher_list_by_id, ++ return update_cipher_list(&s->cipher_list->ciphers, &s->cipher_list_by_id, + s->tls13_ciphersuites); + + return ret; +@@ -1404,17 +1463,20 @@ int SSL_set_ciphersuites(SSL *s, const char *str) + + STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + STACK_OF(SSL_CIPHER) *tls13_ciphersuites, +- STACK_OF(SSL_CIPHER) **cipher_list, ++ struct ssl_cipher_preference_list_st **cipher_list, + STACK_OF(SSL_CIPHER) **cipher_list_by_id, + const char *rule_str, + CERT *c) + { +- int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases, i; ++ int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; + uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac; +- STACK_OF(SSL_CIPHER) *cipherstack; ++ STACK_OF(SSL_CIPHER) *cipherstack = NULL; + const char *rule_p; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + const SSL_CIPHER **ca_list = NULL; ++ uint8_t *in_group_flags = NULL; ++ unsigned int num_in_group_flags = 0; ++ struct ssl_cipher_preference_list_st *pref_list = NULL; + + /* + * Return with error if nothing to do. +@@ -1463,16 +1525,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * preference). + */ + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD, +- -1, &head, &tail); +- ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, +- &tail); +- ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, +- &tail); ++ -1, 0, &head, &tail); ++ ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, ++ &head, &tail); ++ ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, ++ &head, &tail); + + /* Within each strength group, we prefer GCM over CHACHA... */ +- ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1, ++ ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1, 0, + &head, &tail); +- ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1, ++ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1, 0, + &head, &tail); + + /* +@@ -1481,13 +1543,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * strength. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD, +- -1, &head, &tail); ++ -1, 0, &head, &tail); + + /* Temporarily enable everything else for sorting */ +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail); + + /* Low priority for MD5 */ +- ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + + /* +@@ -1495,16 +1557,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * disabled. (For applications that allow them, they aren't too bad, but + * we prefer authenticated ciphers.) + */ +- ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + +- ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); +- ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + + /* RC4 is sort-of broken -- move to the end */ +- ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + + /* +@@ -1520,7 +1582,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs. + * TODO(openssl-team): is there an easier way to accomplish all this? + */ +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1, ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1, 0, + &head, &tail); + + /* +@@ -1536,15 +1598,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * Because we now bump ciphers to the top of the list, we proceed in + * reverse order of preference. + */ +- ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1, ++ ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0, +- CIPHER_BUMP, -1, &head, &tail); ++ CIPHER_BUMP, -1, 0, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0, +- CIPHER_BUMP, -1, &head, &tail); ++ CIPHER_BUMP, -1, 0, &head, &tail); ++ ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_3_VERSION, 0, CIPHER_BUMP, -1, 0, ++ &head, &tail); + + /* Now disable everything (maintaining the ordering!) */ +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, &head, &tail); + + /* + * We also need cipher aliases for selecting based on the rule_str. +@@ -1558,9 +1623,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; + ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max); + if (ca_list == NULL) { +- OPENSSL_free(co_list); + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); +- return NULL; /* Failure */ ++ goto err; /* Failure */ + } + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, + disabled_mkey, disabled_auth, disabled_enc, +@@ -1585,28 +1649,19 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + + OPENSSL_free(ca_list); /* Not needed anymore */ + +- if (!ok) { /* Rule processing failure */ +- OPENSSL_free(co_list); +- return NULL; +- } ++ if (!ok) ++ goto err; /* Rule processing failure */ + + /* + * Allocate new "cipherstack" for the result, return with error + * if we cannot get one. + */ +- if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { +- OPENSSL_free(co_list); +- return NULL; +- } ++ if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) ++ goto err; + +- /* Add TLSv1.3 ciphers first - we always prefer those if possible */ +- for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) { +- if (!sk_SSL_CIPHER_push(cipherstack, +- sk_SSL_CIPHER_value(tls13_ciphersuites, i))) { +- sk_SSL_CIPHER_free(cipherstack); +- return NULL; +- } +- } ++ in_group_flags = OPENSSL_malloc(num_of_ciphers); ++ if (!in_group_flags) ++ goto err; + + OSSL_TRACE_BEGIN(TLS_CIPHER) { + BIO_printf(trc_out, "cipher selection:\n"); +@@ -1618,26 +1673,51 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + for (curr = head; curr != NULL; curr = curr->next) { + if (curr->active) { + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { +- OPENSSL_free(co_list); +- sk_SSL_CIPHER_free(cipherstack); + OSSL_TRACE_CANCEL(TLS_CIPHER); +- return NULL; ++ goto err; + } ++ in_group_flags[num_in_group_flags++] = curr->in_group; + if (trc_out != NULL) + BIO_printf(trc_out, "<%s>\n", curr->cipher->name); + } + } + OPENSSL_free(co_list); /* Not needed any longer */ ++ co_list = NULL; + OSSL_TRACE_END(TLS_CIPHER); + +- if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) { +- sk_SSL_CIPHER_free(cipherstack); +- return NULL; +- } +- sk_SSL_CIPHER_free(*cipher_list); +- *cipher_list = cipherstack; ++ if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) ++ goto err; ++ ++ pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); ++ if (!pref_list) ++ goto err; ++ pref_list->ciphers = cipherstack; ++ pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags); ++ if (!pref_list->in_group_flags) ++ goto err; ++ memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags); ++ OPENSSL_free(in_group_flags); ++ in_group_flags = NULL; ++ if (*cipher_list != NULL) ++ ssl_cipher_preference_list_free(*cipher_list); ++ *cipher_list = pref_list; ++ pref_list = NULL; + + return cipherstack; ++ ++err: ++ if (co_list) ++ OPENSSL_free(co_list); ++ if (in_group_flags) ++ OPENSSL_free(in_group_flags); ++ if (cipherstack) ++ sk_SSL_CIPHER_free(cipherstack); ++ if (pref_list && pref_list->in_group_flags) ++ OPENSSL_free(pref_list->in_group_flags); ++ if (pref_list) ++ OPENSSL_free(pref_list); ++ return NULL; ++ + } + + char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c +index 85d9dd8448..64f7577a90 100644 +--- a/ssl/ssl_err.c ++++ b/ssl/ssl_err.c +@@ -14,6 +14,8 @@ + #ifndef OPENSSL_NO_ERR + + static const ERR_STRING_DATA SSL_str_reasons[] = { ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), ++ "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY), + "application data after close notify"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APP_DATA_IN_HANDSHAKE), +@@ -171,8 +173,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "ext length mismatch"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), + "failed to init async"}, +- {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), +- "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), + "fragmented client hello"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_GOT_A_FIN_BEFORE_A_CCS), +@@ -257,6 +257,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "missing tmp ecdh key"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA), + "mixed handshake and non handshake data"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS), ++ "mixed special operator with groups"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NESTED_GROUP), "nested group"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY), + "not on record boundary"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE), +@@ -493,7 +496,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "unexpected end of early data"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING), + "unexpected eof while reading"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_GROUP_CLOSE), ++ "unexpected group close"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP), ++ "unexpected operator in group"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_RECORD), "unexpected record"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index b5239d6eb2..fcd5547f48 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -1127,6 +1127,71 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) + return X509_VERIFY_PARAM_set1(ssl->param, vpm); + } + ++void ssl_cipher_preference_list_free(struct ssl_cipher_preference_list_st ++ *cipher_list) ++{ ++ sk_SSL_CIPHER_free(cipher_list->ciphers); ++ OPENSSL_free(cipher_list->in_group_flags); ++ OPENSSL_free(cipher_list); ++} ++ ++struct ssl_cipher_preference_list_st* ++ssl_cipher_preference_list_dup(struct ssl_cipher_preference_list_st ++ *cipher_list) ++{ ++ struct ssl_cipher_preference_list_st* ret = NULL; ++ size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers); ++ ++ ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); ++ if (!ret) ++ goto err; ++ ret->ciphers = NULL; ++ ret->in_group_flags = NULL; ++ ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers); ++ if (!ret->ciphers) ++ goto err; ++ ret->in_group_flags = OPENSSL_malloc(n); ++ if (!ret->in_group_flags) ++ goto err; ++ memcpy(ret->in_group_flags, cipher_list->in_group_flags, n); ++ return ret; ++ ++err: ++ if (ret->ciphers) ++ sk_SSL_CIPHER_free(ret->ciphers); ++ if (ret) ++ OPENSSL_free(ret); ++ return NULL; ++} ++ ++struct ssl_cipher_preference_list_st* ++ssl_cipher_preference_list_from_ciphers(STACK_OF(SSL_CIPHER) *ciphers) ++{ ++ struct ssl_cipher_preference_list_st* ret = NULL; ++ size_t n = sk_SSL_CIPHER_num(ciphers); ++ ++ ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); ++ if (!ret) ++ goto err; ++ ret->ciphers = NULL; ++ ret->in_group_flags = NULL; ++ ret->ciphers = sk_SSL_CIPHER_dup(ciphers); ++ if (!ret->ciphers) ++ goto err; ++ ret->in_group_flags = OPENSSL_malloc(n); ++ if (!ret->in_group_flags) ++ goto err; ++ memset(ret->in_group_flags, 0, n); ++ return ret; ++ ++err: ++ if (ret->ciphers) ++ sk_SSL_CIPHER_free(ret->ciphers); ++ if (ret) ++ OPENSSL_free(ret); ++ return NULL; ++} ++ + X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) + { + return ctx->param; +@@ -1171,7 +1236,8 @@ void SSL_free(SSL *s) + BUF_MEM_free(s->init_buf); + + /* add extra stuff */ +- sk_SSL_CIPHER_free(s->cipher_list); ++ if (s->cipher_list != NULL) ++ ssl_cipher_preference_list_free(s->cipher_list); + sk_SSL_CIPHER_free(s->cipher_list_by_id); + sk_SSL_CIPHER_free(s->tls13_ciphersuites); + sk_SSL_CIPHER_free(s->peer_ciphers); +@@ -2566,9 +2632,9 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) + { + if (s != NULL) { + if (s->cipher_list != NULL) { +- return s->cipher_list; ++ return (s->cipher_list->ciphers); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { +- return s->ctx->cipher_list; ++ return (s->ctx->cipher_list->ciphers); + } + } + return NULL; +@@ -2642,8 +2708,8 @@ const char *SSL_get_cipher_list(const SSL *s, int n) + * preference */ + STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) + { +- if (ctx != NULL) +- return ctx->cipher_list; ++ if (ctx != NULL && ctx->cipher_list != NULL) ++ return ctx->cipher_list->ciphers; + return NULL; + } + +@@ -3153,7 +3219,7 @@ SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, + ret->tls13_ciphersuites, + &ret->cipher_list, &ret->cipher_list_by_id, + OSSL_default_cipher_list(), ret->cert) +- || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { ++ || sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) { + SSLerr(0, SSL_R_LIBRARY_HAS_NO_CIPHERS); + goto err2; + } +@@ -3334,7 +3400,7 @@ void SSL_CTX_free(SSL_CTX *a) + #ifndef OPENSSL_NO_CT + CTLOG_STORE_free(a->ctlog_store); + #endif +- sk_SSL_CIPHER_free(a->cipher_list); ++ ssl_cipher_preference_list_free(a->cipher_list); + sk_SSL_CIPHER_free(a->cipher_list_by_id); + sk_SSL_CIPHER_free(a->tls13_ciphersuites); + ssl_cert_free(a->cert); +@@ -4012,13 +4078,15 @@ SSL *SSL_dup(SSL *s) + + /* dup the cipher_list and cipher_list_by_id stacks */ + if (s->cipher_list != NULL) { +- if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) ++ ret->cipher_list = ssl_cipher_preference_list_dup(s->cipher_list); ++ if (ret->cipher_list == NULL) + goto err; + } +- if (s->cipher_list_by_id != NULL) +- if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) +- == NULL) ++ if (s->cipher_list_by_id != NULL) { ++ ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id); ++ if (ret->cipher_list_by_id == NULL) + goto err; ++ } + + /* Dup the client_CA list */ + if (!dup_ca_names(&ret->ca_names, s->ca_names) +diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h +index f0f0a53ecf..56eed2c1c1 100644 +--- a/ssl/ssl_local.h ++++ b/ssl/ssl_local.h +@@ -763,11 +763,48 @@ int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, + size_t max_size); + size_t ssl_hmac_size(const SSL_HMAC *ctx); + ++/* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with ++ * equal-preference groups. For TLS clients, the groups are moot because the ++ * server picks the cipher and groups cannot be expressed on the wire. However, ++ * for servers, the equal-preference groups allow the client's preferences to ++ * be partially respected. (This only has an effect with ++ * SSL_OP_CIPHER_SERVER_PREFERENCE). ++ * ++ * The equal-preference groups are expressed by grouping SSL_CIPHERs together. ++ * All elements of a group have the same priority: no ordering is expressed ++ * within a group. ++ * ++ * The values in |ciphers| are in one-to-one correspondence with ++ * |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of ++ * bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to ++ * indicate that the corresponding SSL_CIPHER is not the last element of a ++ * group, or 0 to indicate that it is. ++ * ++ * For example, if |in_group_flags| contains all zeros then that indicates a ++ * traditional, fully-ordered preference. Every SSL_CIPHER is the last element ++ * of the group (i.e. they are all in a one-element group). ++ * ++ * For a more complex example, consider: ++ * ciphers: A B C D E F ++ * in_group_flags: 1 1 0 0 1 0 ++ * ++ * That would express the following, order: ++ * ++ * A E ++ * B -> D -> F ++ * C ++ */ ++struct ssl_cipher_preference_list_st { ++ STACK_OF(SSL_CIPHER) *ciphers; ++ uint8_t *in_group_flags; ++}; ++ ++ + struct ssl_ctx_st { + OPENSSL_CTX *libctx; + + const SSL_METHOD *method; +- STACK_OF(SSL_CIPHER) *cipher_list; ++ struct ssl_cipher_preference_list_st *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* TLSv1.3 specific ciphersuites */ +@@ -1350,7 +1387,7 @@ struct ssl_st { + SSL_DANE dane; + /* crypto */ + STACK_OF(SSL_CIPHER) *peer_ciphers; +- STACK_OF(SSL_CIPHER) *cipher_list; ++ struct ssl_cipher_preference_list_st *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* TLSv1.3 specific ciphersuites */ + STACK_OF(SSL_CIPHER) *tls13_ciphersuites; +@@ -2323,7 +2360,7 @@ __owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, + const SSL_CIPHER *const *bp); + __owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + STACK_OF(SSL_CIPHER) *tls13_ciphersuites, +- STACK_OF(SSL_CIPHER) **cipher_list, ++ struct ssl_cipher_preference_list_st **cipher_list, + STACK_OF(SSL_CIPHER) **cipher_list_by_id, + const char *rule_str, + CERT *c); +@@ -2333,6 +2370,13 @@ __owur int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **scsvs, int sslv2format, + int fatal); + void ssl_update_cache(SSL *s, int mode); ++struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_dup( ++ struct ssl_cipher_preference_list_st *cipher_list); ++void ssl_cipher_preference_list_free( ++ struct ssl_cipher_preference_list_st *cipher_list); ++struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_from_ciphers( ++ STACK_OF(SSL_CIPHER) *ciphers); ++struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s); + __owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, + size_t *mac_secret_size, SSL_COMP **comp, +@@ -2418,7 +2462,7 @@ __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, + CERT_PKEY *cpk); + __owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, + STACK_OF(SSL_CIPHER) *clnt, +- STACK_OF(SSL_CIPHER) *srvr); ++ struct ssl_cipher_preference_list_st *srvr); + __owur int ssl3_digest_cached_records(SSL *s, int keep); + __owur int ssl3_new(SSL *s); + void ssl3_free(SSL *s); +diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c +index a23187290e..6348f1f9b6 100644 +--- a/ssl/statem/statem_srvr.c ++++ b/ssl/statem/statem_srvr.c +@@ -1774,7 +1774,7 @@ static int tls_early_post_process_client_hello(SSL *s) + /* For TLSv1.3 we must select the ciphersuite *before* session resumption */ + if (SSL_IS_TLS13(s)) { + const SSL_CIPHER *cipher = +- ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s)); ++ ssl3_choose_cipher(s, ciphers, ssl_get_cipher_preferences(s)); + + if (cipher == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, +@@ -1957,7 +1957,7 @@ static int tls_early_post_process_client_hello(SSL *s) + /* check if some cipher was preferred by call back */ + if (pref_cipher == NULL) + pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers, +- SSL_get_ciphers(s)); ++ ssl_get_cipher_preferences(s)); + if (pref_cipher == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, +@@ -1966,8 +1966,9 @@ static int tls_early_post_process_client_hello(SSL *s) + } + + s->session->cipher = pref_cipher; +- sk_SSL_CIPHER_free(s->cipher_list); +- s->cipher_list = sk_SSL_CIPHER_dup(s->peer_ciphers); ++ ssl_cipher_preference_list_free(s->cipher_list); ++ s->cipher_list = ssl_cipher_preference_list_from_ciphers( ++ s->peer_ciphers); + sk_SSL_CIPHER_free(s->cipher_list_by_id); + s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->peer_ciphers); + } +@@ -2279,7 +2280,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) + /* In TLSv1.3 we selected the ciphersuite before resumption */ + if (!SSL_IS_TLS13(s)) { + cipher = +- ssl3_choose_cipher(s, s->peer_ciphers, SSL_get_ciphers(s)); ++ ssl3_choose_cipher(s, s->peer_ciphers, ssl_get_cipher_preferences(s)); + + if (cipher == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, +diff --git a/util/libcrypto.num b/util/libcrypto.num +index f81fefb9b2..7d36cf81fe 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -3340,14 +3340,14 @@ CRYPTO_new_ex_data 3409 3_0_0 EXIST::FUNCTION: + PEM_read_PKCS8_PRIV_KEY_INFO 3410 3_0_0 EXIST::FUNCTION:STDIO + TS_VERIFY_CTX_new 3411 3_0_0 EXIST::FUNCTION:TS + BUF_MEM_new_ex 3412 3_0_0 EXIST::FUNCTION: +-RSA_padding_add_X931 3413 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_padding_add_X931 3413 3_0_0 EXIST::FUNCTION:RSA + BN_get0_nist_prime_256 3414 3_0_0 EXIST::FUNCTION: + CRYPTO_memcmp 3415 3_0_0 EXIST::FUNCTION: + DH_check_pub_key 3416 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH + ASN1_mbstring_copy 3417 3_0_0 EXIST::FUNCTION: + PKCS7_set_type 3418 3_0_0 EXIST::FUNCTION: + BIO_gets 3419 3_0_0 EXIST::FUNCTION: +-RSA_padding_check_PKCS1_type_1 3420 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_padding_check_PKCS1_type_1 3420 3_0_0 EXIST::FUNCTION:RSA + UI_ctrl 3421 3_0_0 EXIST::FUNCTION: + i2d_X509_REQ_fp 3422 3_0_0 EXIST::FUNCTION:STDIO + BN_BLINDING_convert_ex 3423 3_0_0 EXIST::FUNCTION: +@@ -4273,14 +4273,14 @@ EVP_PKEY_asn1_set_param_check 4368 3_0_0 EXIST::FUNCTION: + DH_check_ex 4369 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH + DH_check_pub_key_ex 4370 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH + DH_check_params_ex 4371 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH +-RSA_generate_multi_prime_key 4372 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_generate_multi_prime_key 4372 3_0_0 EXIST::FUNCTION:RSA + RSA_get_multi_prime_extra_count 4373 3_0_0 EXIST::FUNCTION:RSA + OCSP_resp_get0_signer 4374 3_0_0 EXIST::FUNCTION:OCSP + RSA_get0_multi_prime_crt_params 4375 3_0_0 EXIST::FUNCTION:RSA + RSA_set0_multi_prime_params 4376 3_0_0 EXIST::FUNCTION:RSA +-RSA_get_version 4377 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA +-RSA_meth_get_multi_prime_keygen 4378 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA +-RSA_meth_set_multi_prime_keygen 4379 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_get_version 4377 3_0_0 EXIST::FUNCTION:RSA ++RSA_meth_get_multi_prime_keygen 4378 3_0_0 EXIST::FUNCTION:RSA ++RSA_meth_set_multi_prime_keygen 4379 3_0_0 EXIST::FUNCTION:RSA + RAND_DRBG_get0_master 4380 3_0_0 EXIST::FUNCTION: + RAND_DRBG_set_reseed_time_interval 4381 3_0_0 EXIST::FUNCTION: + PROFESSION_INFO_get0_addProfessionInfo 4382 3_0_0 EXIST::FUNCTION: diff --git a/openssl-equal-3.0.0-dev_revert.patch b/openssl-equal-3.0.0-dev_revert.patch new file mode 100644 index 0000000..a4e3701 --- /dev/null +++ b/openssl-equal-3.0.0-dev_revert.patch @@ -0,0 +1,1182 @@ +diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt +index f467ea909f..76cc311ba8 100644 +--- a/crypto/err/openssl.txt ++++ b/crypto/err/openssl.txt +@@ -3009,6 +3009,7 @@ SM2_R_INVALID_ENCODING:104:invalid encoding + SM2_R_INVALID_FIELD:105:invalid field + SM2_R_NO_PARAMETERS_SET:109:no parameters set + SM2_R_USER_ID_TOO_LARGE:106:user id too large ++SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\ + application data after close notify + SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake +@@ -3115,7 +3116,6 @@ SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received + SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message + SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch + SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async +-SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed + SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello + SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs + SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request +@@ -3166,6 +3166,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key + SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key + SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\ + mixed handshake and non handshake data ++SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups ++SSL_R_NESTED_GROUP:297:nested group + SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary + SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate + SSL_R_NOT_SERVER:284:not server +@@ -3273,7 +3275,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines + SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message + SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data + SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading ++SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close + SSL_R_UNEXPECTED_MESSAGE:244:unexpected message ++SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group + SSL_R_UNEXPECTED_RECORD:245:unexpected record + SSL_R_UNINITIALIZED:276:uninitialized + SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type +diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in +index 9e5224579a..020bdcbcb9 100644 +--- a/doc/man1/openssl-ciphers.pod.in ++++ b/doc/man1/openssl-ciphers.pod.in +@@ -405,6 +405,21 @@ permissible. + + =back + ++=head1 EQUAL PREFERENCE GROUPS ++ ++If configuring a server, one may also configure equal-preference groups to ++partially respect the client's preferences when ++B is enabled. Ciphers in an equal-preference ++group have equal priority and use the client order. This may be used to ++enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305 ++based on client preferences. An equal-preference is specified with square ++brackets, combining multiple selectors separated by |. For example: ++ ++ [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256] ++ ++ Once an equal-preference group is used, future directives must be ++ opcode-less. ++ + =head1 CIPHER SUITE NAMES + + The following lists give the SSL or TLS cipher suites names from the +diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h +index e1617aae45..a04a3e1552 100644 +--- a/include/openssl/sslerr.h ++++ b/include/openssl/sslerr.h +@@ -10,12 +10,6 @@ + + #ifndef OPENSSL_SSLERR_H + # define OPENSSL_SSLERR_H +-# pragma once +- +-# include +-# ifndef OPENSSL_NO_DEPRECATED_3_0 +-# define HEADER_SSLERR_H +-# endif + + # include + # include +@@ -462,6 +456,7 @@ int ERR_load_SSL_strings(void); + /* + * SSL reason codes. + */ ++# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 + # define SSL_R_APP_DATA_IN_HANDSHAKE 100 + # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +@@ -561,7 +556,6 @@ int ERR_load_SSL_strings(void); + # define SSL_R_EXTRA_DATA_IN_MESSAGE 153 + # define SSL_R_EXT_LENGTH_MISMATCH 163 + # define SSL_R_FAILED_TO_INIT_ASYNC 405 +-# define SSL_R_ALGORITHM_FETCH_FAILED 295 + # define SSL_R_FRAGMENTED_CLIENT_HELLO 401 + # define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 + # define SSL_R_HTTPS_PROXY_REQUEST 155 +@@ -611,6 +605,8 @@ int ERR_load_SSL_strings(void); + # define SSL_R_MISSING_TMP_DH_KEY 171 + # define SSL_R_MISSING_TMP_ECDH_KEY 311 + # define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 ++# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 296 ++# define SSL_R_NESTED_GROUP 297 + # define SSL_R_NOT_ON_RECORD_BOUNDARY 182 + # define SSL_R_NOT_REPLACING_CERTIFICATE 289 + # define SSL_R_NOT_SERVER 284 +@@ -742,7 +738,9 @@ int ERR_load_SSL_strings(void); + # define SSL_R_UNEXPECTED_CCS_MESSAGE 262 + # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 + # define SSL_R_UNEXPECTED_EOF_WHILE_READING 294 ++# define SSL_R_UNEXPECTED_GROUP_CLOSE 299 + # define SSL_R_UNEXPECTED_MESSAGE 244 ++# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 305 + # define SSL_R_UNEXPECTED_RECORD 245 + # define SSL_R_UNINITIALIZED 276 + # define SSL_R_UNKNOWN_ALERT_TYPE 246 +diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c +index 26f19108ee..5402a57524 100644 +--- a/ssl/s3_lib.c ++++ b/ssl/s3_lib.c +@@ -169,7 +169,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_3DES, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -234,7 +234,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_AES128, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -298,7 +298,7 @@ static SSL_CIPHER ssl3_ciphers[] = { + SSL_aRSA, + SSL_AES256, + SSL_SHA1, +- SSL3_VERSION, TLS1_2_VERSION, ++ SSL3_VERSION, TLS1_VERSION, + DTLS1_BAD_VER, DTLS1_2_VERSION, + SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +@@ -4142,6 +4142,17 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) + return 1; + } + ++struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s) ++{ ++ if (s->cipher_list != NULL) ++ return (s->cipher_list); ++ ++ if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) ++ return (s->ctx->cipher_list); ++ ++ return NULL; ++} ++ + /* + * ssl3_choose_cipher - choose a cipher from those offered by the client + * @s: SSL connection +@@ -4151,16 +4162,24 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len) + * Returns the selected cipher or NULL when no common ciphers. + */ + const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, +- STACK_OF(SSL_CIPHER) *srvr) ++ struct ssl_cipher_preference_list_st ++ *server_pref) + { + const SSL_CIPHER *c, *ret = NULL; +- STACK_OF(SSL_CIPHER) *prio, *allow; +- int i, ii, ok, prefer_sha256 = 0; ++ STACK_OF(SSL_CIPHER) *srvr = server_pref->ciphers, *prio, *allow; ++ int i, ii, ok, prefer_sha256 = 0, safari_ec = 0; + unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0; + const EVP_MD *mdsha256 = EVP_sha256(); +-#ifndef OPENSSL_NO_CHACHA +- STACK_OF(SSL_CIPHER) *prio_chacha = NULL; +-#endif ++ ++ /* in_group_flags will either be NULL, or will point to an array of ++ * bytes which indicate equal-preference groups in the |prio| stack. ++ * See the comment about |in_group_flags| in the ++ * |ssl_cipher_preference_list_st| struct. */ ++ const uint8_t *in_group_flags; ++ ++ /* group_min contains the minimal index so far found in a group, or -1 ++ * if no such value exists yet. */ ++ int group_min = -1; + + /* Let's see which ciphers we can support */ + +@@ -4187,54 +4206,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + } OSSL_TRACE_END(TLS_CIPHER); + + /* SUITE-B takes precedence over server preference and ChaCha priortiy */ +- if (tls1_suiteb(s)) { ++ if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) { + prio = srvr; ++ in_group_flags = server_pref->in_group_flags; + allow = clnt; +- } else if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { +- prio = srvr; +- allow = clnt; +-#ifndef OPENSSL_NO_CHACHA +- /* If ChaCha20 is at the top of the client preference list, +- and there are ChaCha20 ciphers in the server list, then +- temporarily prioritize all ChaCha20 ciphers in the servers list. */ +- if (s->options & SSL_OP_PRIORITIZE_CHACHA && sk_SSL_CIPHER_num(clnt) > 0) { +- c = sk_SSL_CIPHER_value(clnt, 0); +- if (c->algorithm_enc == SSL_CHACHA20POLY1305) { +- /* ChaCha20 is client preferred, check server... */ +- int num = sk_SSL_CIPHER_num(srvr); +- int found = 0; +- for (i = 0; i < num; i++) { +- c = sk_SSL_CIPHER_value(srvr, i); +- if (c->algorithm_enc == SSL_CHACHA20POLY1305) { +- found = 1; +- break; +- } +- } +- if (found) { +- prio_chacha = sk_SSL_CIPHER_new_reserve(NULL, num); +- /* if reserve fails, then there's likely a memory issue */ +- if (prio_chacha != NULL) { +- /* Put all ChaCha20 at the top, starting with the one we just found */ +- sk_SSL_CIPHER_push(prio_chacha, c); +- for (i++; i < num; i++) { +- c = sk_SSL_CIPHER_value(srvr, i); +- if (c->algorithm_enc == SSL_CHACHA20POLY1305) +- sk_SSL_CIPHER_push(prio_chacha, c); +- } +- /* Pull in the rest */ +- for (i = 0; i < num; i++) { +- c = sk_SSL_CIPHER_value(srvr, i); +- if (c->algorithm_enc != SSL_CHACHA20POLY1305) +- sk_SSL_CIPHER_push(prio_chacha, c); +- } +- prio = prio_chacha; +- } +- } +- } +- } +-# endif + } else { + prio = clnt; ++ in_group_flags = NULL; + allow = srvr; + } + +@@ -4265,14 +4243,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + c = sk_SSL_CIPHER_value(prio, i); + ++ ok = 1; ++ + /* Skip ciphers not supported by the protocol version */ + if (!SSL_IS_DTLS(s) && + ((s->version < c->min_tls) || (s->version > c->max_tls))) +- continue; ++ ok = 0; + if (SSL_IS_DTLS(s) && + (DTLS_VERSION_LT(s->version, c->min_dtls) || + DTLS_VERSION_GT(s->version, c->max_dtls))) +- continue; ++ ok = 0; + + /* + * Since TLS 1.3 ciphersuites can be used with any auth or +@@ -4294,10 +4274,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + #ifndef OPENSSL_NO_PSK + /* with PSK there must be server callback set */ + if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL) +- continue; ++ ok = 0; + #endif /* OPENSSL_NO_PSK */ + +- ok = (alg_k & mask_k) && (alg_a & mask_a); ++ ok = ok && (alg_k & mask_k) && (alg_a & mask_a); + OSSL_TRACE7(TLS_CIPHER, + "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", + ok, alg_k, alg_a, mask_k, mask_a, (void *)c, c->name); +@@ -4313,6 +4293,14 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + + if (!ok) + continue; ++ ++ safari_ec = 0; ++#if !defined(OPENSSL_NO_EC) ++ if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA)) { ++ if (s->s3.is_probably_safari) ++ safari_ec = 1; ++ } ++#endif + } + ii = sk_SSL_CIPHER_find(allow, c); + if (ii >= 0) { +@@ -4320,14 +4308,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED, + c->strength_bits, 0, (void *)c)) + continue; +-#if !defined(OPENSSL_NO_EC) +- if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA) +- && s->s3.is_probably_safari) { +- if (!ret) +- ret = sk_SSL_CIPHER_value(allow, ii); +- continue; +- } +-#endif ++ + if (prefer_sha256) { + const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); + +@@ -4339,13 +4320,38 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + ret = tmp; + continue; + } +- ret = sk_SSL_CIPHER_value(allow, ii); ++ ++ if (in_group_flags != NULL && in_group_flags[i] == 1) { ++ /* This element of |prio| is in a group. Update ++ * the minimum index found so far and continue ++ * looking. */ ++ if (group_min == -1 || group_min > ii) ++ group_min = ii; ++ } else { ++ if (group_min != -1 && group_min < ii) ++ ii = group_min; ++ if (safari_ec) { ++ if (!ret) ++ ret = sk_SSL_CIPHER_value(allow, ii); ++ continue; ++ } ++ ret = sk_SSL_CIPHER_value(allow, ii); ++ break; ++ } ++ } ++ ++ if (in_group_flags != NULL && !in_group_flags[i] && group_min != -1) { ++ /* We are about to leave a group, but we found a match ++ * in it, so that's our answer. */ ++ if (safari_ec) { ++ if (!ret) ++ ret = sk_SSL_CIPHER_value(allow, group_min); ++ continue; ++ } ++ ret = sk_SSL_CIPHER_value(allow, group_min); + break; + } + } +-#ifndef OPENSSL_NO_CHACHA +- sk_SSL_CIPHER_free(prio_chacha); +-#endif + return ret; + } + +diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c +index 04ffae325c..b67369f639 100644 +--- a/ssl/ssl_ciph.c ++++ b/ssl/ssl_ciph.c +@@ -193,6 +193,7 @@ typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + int active; + int dead; ++ int in_group; + struct cipher_order_st *next, *prev; + } CIPHER_ORDER; + +@@ -298,6 +299,7 @@ static const SSL_CIPHER cipher_aliases[] = { + {0, SSL_TXT_TLSV1, NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, + {0, "TLSv1.0", NULL, 0, 0, 0, 0, 0, TLS1_VERSION}, + {0, SSL_TXT_TLSV1_2, NULL, 0, 0, 0, 0, 0, TLS1_2_VERSION}, ++ {0, "TLS13", NULL, 0, 0, 0, 0, 0, TLS1_3_VERSION}, + + /* strength classes */ + {0, SSL_TXT_LOW, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW}, +@@ -681,6 +683,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = 0; ++ co_list[co_list_num].in_group = 0; + co_list_num++; + } + +@@ -774,8 +777,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + uint32_t alg_auth, uint32_t alg_enc, + uint32_t alg_mac, int min_tls, + uint32_t algo_strength, int rule, +- int32_t strength_bits, CIPHER_ORDER **head_p, +- CIPHER_ORDER **tail_p) ++ int32_t strength_bits, int in_group, ++ CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) + { + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; +@@ -783,9 +786,9 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + + OSSL_TRACE_BEGIN(TLS_CIPHER){ + BIO_printf(trc_out, +- "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n", ++ "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d) g:%d\n", + rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls, +- algo_strength, strength_bits); ++ algo_strength, strength_bits, in_group); + } + + if (rule == CIPHER_DEL || rule == CIPHER_BUMP) +@@ -862,6 +865,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = 1; ++ curr->in_group = in_group; + } + } + /* Move the added cipher to this location */ +@@ -869,6 +873,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + /* reverse == 0 */ + if (curr->active) { + ll_append_tail(&head, curr, &tail); ++ curr->in_group = 0; + } + } else if (rule == CIPHER_DEL) { + /* reverse == 1 */ +@@ -880,6 +885,7 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, + */ + ll_append_head(&head, curr, &tail); + curr->active = 0; ++ curr->in_group = 0; + } + } else if (rule == CIPHER_BUMP) { + if (curr->active) +@@ -949,8 +955,8 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + */ + for (i = max_strength_bits; i >= 0; i--) + if (number_uses[i] > 0) +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, +- tail_p); ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, ++ head_p, tail_p); + + OPENSSL_free(number_uses); + return 1; +@@ -964,7 +970,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength; + int min_tls; + const char *l, *buf; +- int j, multi, found, rule, retval, ok, buflen; ++ int j, multi, found, rule, retval, ok, buflen, in_group = 0, has_group = 0; + uint32_t cipher_id = 0; + char ch; + +@@ -975,18 +981,66 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + + if (ch == '\0') + break; /* done */ +- if (ch == '-') { ++ if (in_group) { ++ if (ch == ']') { ++ if (!in_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_UNEXPECTED_GROUP_CLOSE); ++ retval = found = in_group = 0; ++ break; ++ } ++ if (*tail_p) ++ (*tail_p)->in_group = 0; ++ in_group = 0; ++ l++; ++ continue; ++ } ++ if (ch == '|') { ++ rule = CIPHER_ADD; ++ l++; ++ continue; ++ } else if (!(ch >= 'a' && ch <= 'z') ++ && !(ch >= 'A' && ch <= 'Z') ++ && !(ch >= '0' && ch <= '9')) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); ++ retval = found = in_group = 0; ++ break; ++ } else { ++ rule = CIPHER_ADD; ++ } ++ } else if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; ++ } else if (ch == '!' && has_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); ++ retval = found = in_group = 0; ++ break; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; ++ } else if (ch == '@' && has_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, ++ SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); ++ retval = found = in_group = 0; ++ break; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; ++ } else if (ch == '[') { ++ if (in_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_NESTED_GROUP); ++ retval = found = in_group = 0; ++ break; ++ } ++ in_group = 1; ++ has_group = 1; ++ l++; ++ continue; + } else { + rule = CIPHER_ADD; + } +@@ -1011,7 +1065,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + while (((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || +- (ch == '-') || (ch == '.') || (ch == '=')) ++ (ch == '-') || (ch == '.') || (ch == '=') || (ch == '_')) + #else + while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.') + || (ch == '=')) +@@ -1028,7 +1082,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + * alphanumeric, so we call this an error. + */ + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); +- retval = found = 0; ++ retval = found = in_group = 0; + l++; + break; + } +@@ -1207,8 +1261,8 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + } else if (found) { + ssl_cipher_apply_rule(cipher_id, + alg_mkey, alg_auth, alg_enc, alg_mac, +- min_tls, algo_strength, rule, -1, head_p, +- tail_p); ++ min_tls, algo_strength, rule, -1, in_group, ++ head_p, tail_p); + } else { + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; +@@ -1217,6 +1271,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, + break; /* done */ + } + ++ if (in_group) { ++ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); ++ retval = 0; ++ } ++ + return retval; + } + +@@ -1380,7 +1439,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) + int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str); + + if (ret && ctx->cipher_list != NULL) +- return update_cipher_list(&ctx->cipher_list, &ctx->cipher_list_by_id, ++ return update_cipher_list(&ctx->cipher_list->ciphers, &ctx->cipher_list_by_id, + ctx->tls13_ciphersuites); + + return ret; +@@ -1393,10 +1452,10 @@ int SSL_set_ciphersuites(SSL *s, const char *str) + + if (s->cipher_list == NULL) { + if ((cipher_list = SSL_get_ciphers(s)) != NULL) +- s->cipher_list = sk_SSL_CIPHER_dup(cipher_list); ++ s->cipher_list->ciphers = sk_SSL_CIPHER_dup(cipher_list); + } + if (ret && s->cipher_list != NULL) +- return update_cipher_list(&s->cipher_list, &s->cipher_list_by_id, ++ return update_cipher_list(&s->cipher_list->ciphers, &s->cipher_list_by_id, + s->tls13_ciphersuites); + + return ret; +@@ -1404,17 +1463,20 @@ int SSL_set_ciphersuites(SSL *s, const char *str) + + STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + STACK_OF(SSL_CIPHER) *tls13_ciphersuites, +- STACK_OF(SSL_CIPHER) **cipher_list, ++ struct ssl_cipher_preference_list_st **cipher_list, + STACK_OF(SSL_CIPHER) **cipher_list_by_id, + const char *rule_str, + CERT *c) + { +- int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases, i; ++ int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; + uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac; +- STACK_OF(SSL_CIPHER) *cipherstack; ++ STACK_OF(SSL_CIPHER) *cipherstack = NULL; + const char *rule_p; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + const SSL_CIPHER **ca_list = NULL; ++ uint8_t *in_group_flags = NULL; ++ unsigned int num_in_group_flags = 0; ++ struct ssl_cipher_preference_list_st *pref_list = NULL; + + /* + * Return with error if nothing to do. +@@ -1463,16 +1525,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * preference). + */ + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD, +- -1, &head, &tail); +- ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, +- &tail); +- ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, +- &tail); ++ -1, 0, &head, &tail); ++ ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, ++ &head, &tail); ++ ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, ++ &head, &tail); + + /* Within each strength group, we prefer GCM over CHACHA... */ +- ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1, ++ ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1, 0, + &head, &tail); +- ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1, ++ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1, 0, + &head, &tail); + + /* +@@ -1481,13 +1543,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * strength. + */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD, +- -1, &head, &tail); ++ -1, 0, &head, &tail); + + /* Temporarily enable everything else for sorting */ +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail); + + /* Low priority for MD5 */ +- ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + + /* +@@ -1495,16 +1557,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * disabled. (For applications that allow them, they aren't too bad, but + * we prefer authenticated ciphers.) + */ +- ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + +- ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); +- ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + + /* RC4 is sort-of broken -- move to the end */ +- ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, ++ ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, 0, &head, + &tail); + + /* +@@ -1520,7 +1582,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs. + * TODO(openssl-team): is there an easier way to accomplish all this? + */ +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1, ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1, 0, + &head, &tail); + + /* +@@ -1536,15 +1598,18 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + * Because we now bump ciphers to the top of the list, we proceed in + * reverse order of preference. + */ +- ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1, ++ ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1, 0, + &head, &tail); + ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0, +- CIPHER_BUMP, -1, &head, &tail); ++ CIPHER_BUMP, -1, 0, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0, +- CIPHER_BUMP, -1, &head, &tail); ++ CIPHER_BUMP, -1, 0, &head, &tail); ++ ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_3_VERSION, 0, CIPHER_BUMP, -1, 0, ++ &head, &tail); + + /* Now disable everything (maintaining the ordering!) */ +- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); ++ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, &head, &tail); + + /* + * We also need cipher aliases for selecting based on the rule_str. +@@ -1558,9 +1623,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; + ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max); + if (ca_list == NULL) { +- OPENSSL_free(co_list); + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); +- return NULL; /* Failure */ ++ goto err; /* Failure */ + } + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, + disabled_mkey, disabled_auth, disabled_enc, +@@ -1585,28 +1649,19 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + + OPENSSL_free(ca_list); /* Not needed anymore */ + +- if (!ok) { /* Rule processing failure */ +- OPENSSL_free(co_list); +- return NULL; +- } ++ if (!ok) ++ goto err; /* Rule processing failure */ + + /* + * Allocate new "cipherstack" for the result, return with error + * if we cannot get one. + */ +- if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { +- OPENSSL_free(co_list); +- return NULL; +- } ++ if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) ++ goto err; + +- /* Add TLSv1.3 ciphers first - we always prefer those if possible */ +- for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) { +- if (!sk_SSL_CIPHER_push(cipherstack, +- sk_SSL_CIPHER_value(tls13_ciphersuites, i))) { +- sk_SSL_CIPHER_free(cipherstack); +- return NULL; +- } +- } ++ in_group_flags = OPENSSL_malloc(num_of_ciphers); ++ if (!in_group_flags) ++ goto err; + + OSSL_TRACE_BEGIN(TLS_CIPHER) { + BIO_printf(trc_out, "cipher selection:\n"); +@@ -1618,26 +1673,51 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + for (curr = head; curr != NULL; curr = curr->next) { + if (curr->active) { + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { +- OPENSSL_free(co_list); +- sk_SSL_CIPHER_free(cipherstack); + OSSL_TRACE_CANCEL(TLS_CIPHER); +- return NULL; ++ goto err; + } ++ in_group_flags[num_in_group_flags++] = curr->in_group; + if (trc_out != NULL) + BIO_printf(trc_out, "<%s>\n", curr->cipher->name); + } + } + OPENSSL_free(co_list); /* Not needed any longer */ ++ co_list = NULL; + OSSL_TRACE_END(TLS_CIPHER); + +- if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) { +- sk_SSL_CIPHER_free(cipherstack); +- return NULL; +- } +- sk_SSL_CIPHER_free(*cipher_list); +- *cipher_list = cipherstack; ++ if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) ++ goto err; ++ ++ pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); ++ if (!pref_list) ++ goto err; ++ pref_list->ciphers = cipherstack; ++ pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags); ++ if (!pref_list->in_group_flags) ++ goto err; ++ memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags); ++ OPENSSL_free(in_group_flags); ++ in_group_flags = NULL; ++ if (*cipher_list != NULL) ++ ssl_cipher_preference_list_free(*cipher_list); ++ *cipher_list = pref_list; ++ pref_list = NULL; + + return cipherstack; ++ ++err: ++ if (co_list) ++ OPENSSL_free(co_list); ++ if (in_group_flags) ++ OPENSSL_free(in_group_flags); ++ if (cipherstack) ++ sk_SSL_CIPHER_free(cipherstack); ++ if (pref_list && pref_list->in_group_flags) ++ OPENSSL_free(pref_list->in_group_flags); ++ if (pref_list) ++ OPENSSL_free(pref_list); ++ return NULL; ++ + } + + char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c +index 85d9dd8448..64f7577a90 100644 +--- a/ssl/ssl_err.c ++++ b/ssl/ssl_err.c +@@ -14,6 +14,8 @@ + #ifndef OPENSSL_NO_ERR + + static const ERR_STRING_DATA SSL_str_reasons[] = { ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), ++ "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY), + "application data after close notify"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APP_DATA_IN_HANDSHAKE), +@@ -171,8 +173,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "ext length mismatch"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), + "failed to init async"}, +- {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ALGORITHM_FETCH_FAILED), +- "algorithm fetch failed"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), + "fragmented client hello"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_GOT_A_FIN_BEFORE_A_CCS), +@@ -257,6 +257,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "missing tmp ecdh key"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA), + "mixed handshake and non handshake data"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS), ++ "mixed special operator with groups"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NESTED_GROUP), "nested group"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY), + "not on record boundary"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE), +@@ -493,7 +496,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { + "unexpected end of early data"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING), + "unexpected eof while reading"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_GROUP_CLOSE), ++ "unexpected group close"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, ++ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP), ++ "unexpected operator in group"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_RECORD), "unexpected record"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index b5239d6eb2..fcd5547f48 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -1127,6 +1127,71 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) + return X509_VERIFY_PARAM_set1(ssl->param, vpm); + } + ++void ssl_cipher_preference_list_free(struct ssl_cipher_preference_list_st ++ *cipher_list) ++{ ++ sk_SSL_CIPHER_free(cipher_list->ciphers); ++ OPENSSL_free(cipher_list->in_group_flags); ++ OPENSSL_free(cipher_list); ++} ++ ++struct ssl_cipher_preference_list_st* ++ssl_cipher_preference_list_dup(struct ssl_cipher_preference_list_st ++ *cipher_list) ++{ ++ struct ssl_cipher_preference_list_st* ret = NULL; ++ size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers); ++ ++ ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); ++ if (!ret) ++ goto err; ++ ret->ciphers = NULL; ++ ret->in_group_flags = NULL; ++ ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers); ++ if (!ret->ciphers) ++ goto err; ++ ret->in_group_flags = OPENSSL_malloc(n); ++ if (!ret->in_group_flags) ++ goto err; ++ memcpy(ret->in_group_flags, cipher_list->in_group_flags, n); ++ return ret; ++ ++err: ++ if (ret->ciphers) ++ sk_SSL_CIPHER_free(ret->ciphers); ++ if (ret) ++ OPENSSL_free(ret); ++ return NULL; ++} ++ ++struct ssl_cipher_preference_list_st* ++ssl_cipher_preference_list_from_ciphers(STACK_OF(SSL_CIPHER) *ciphers) ++{ ++ struct ssl_cipher_preference_list_st* ret = NULL; ++ size_t n = sk_SSL_CIPHER_num(ciphers); ++ ++ ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st)); ++ if (!ret) ++ goto err; ++ ret->ciphers = NULL; ++ ret->in_group_flags = NULL; ++ ret->ciphers = sk_SSL_CIPHER_dup(ciphers); ++ if (!ret->ciphers) ++ goto err; ++ ret->in_group_flags = OPENSSL_malloc(n); ++ if (!ret->in_group_flags) ++ goto err; ++ memset(ret->in_group_flags, 0, n); ++ return ret; ++ ++err: ++ if (ret->ciphers) ++ sk_SSL_CIPHER_free(ret->ciphers); ++ if (ret) ++ OPENSSL_free(ret); ++ return NULL; ++} ++ + X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) + { + return ctx->param; +@@ -1171,7 +1236,8 @@ void SSL_free(SSL *s) + BUF_MEM_free(s->init_buf); + + /* add extra stuff */ +- sk_SSL_CIPHER_free(s->cipher_list); ++ if (s->cipher_list != NULL) ++ ssl_cipher_preference_list_free(s->cipher_list); + sk_SSL_CIPHER_free(s->cipher_list_by_id); + sk_SSL_CIPHER_free(s->tls13_ciphersuites); + sk_SSL_CIPHER_free(s->peer_ciphers); +@@ -2566,9 +2632,9 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) + { + if (s != NULL) { + if (s->cipher_list != NULL) { +- return s->cipher_list; ++ return (s->cipher_list->ciphers); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { +- return s->ctx->cipher_list; ++ return (s->ctx->cipher_list->ciphers); + } + } + return NULL; +@@ -2642,8 +2708,8 @@ const char *SSL_get_cipher_list(const SSL *s, int n) + * preference */ + STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) + { +- if (ctx != NULL) +- return ctx->cipher_list; ++ if (ctx != NULL && ctx->cipher_list != NULL) ++ return ctx->cipher_list->ciphers; + return NULL; + } + +@@ -3153,7 +3219,7 @@ SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, + ret->tls13_ciphersuites, + &ret->cipher_list, &ret->cipher_list_by_id, + OSSL_default_cipher_list(), ret->cert) +- || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { ++ || sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) { + SSLerr(0, SSL_R_LIBRARY_HAS_NO_CIPHERS); + goto err2; + } +@@ -3334,7 +3400,7 @@ void SSL_CTX_free(SSL_CTX *a) + #ifndef OPENSSL_NO_CT + CTLOG_STORE_free(a->ctlog_store); + #endif +- sk_SSL_CIPHER_free(a->cipher_list); ++ ssl_cipher_preference_list_free(a->cipher_list); + sk_SSL_CIPHER_free(a->cipher_list_by_id); + sk_SSL_CIPHER_free(a->tls13_ciphersuites); + ssl_cert_free(a->cert); +@@ -4012,13 +4078,15 @@ SSL *SSL_dup(SSL *s) + + /* dup the cipher_list and cipher_list_by_id stacks */ + if (s->cipher_list != NULL) { +- if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) ++ ret->cipher_list = ssl_cipher_preference_list_dup(s->cipher_list); ++ if (ret->cipher_list == NULL) + goto err; + } +- if (s->cipher_list_by_id != NULL) +- if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) +- == NULL) ++ if (s->cipher_list_by_id != NULL) { ++ ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id); ++ if (ret->cipher_list_by_id == NULL) + goto err; ++ } + + /* Dup the client_CA list */ + if (!dup_ca_names(&ret->ca_names, s->ca_names) +diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h +index f0f0a53ecf..56eed2c1c1 100644 +--- a/ssl/ssl_local.h ++++ b/ssl/ssl_local.h +@@ -763,11 +763,48 @@ int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, + size_t max_size); + size_t ssl_hmac_size(const SSL_HMAC *ctx); + ++/* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with ++ * equal-preference groups. For TLS clients, the groups are moot because the ++ * server picks the cipher and groups cannot be expressed on the wire. However, ++ * for servers, the equal-preference groups allow the client's preferences to ++ * be partially respected. (This only has an effect with ++ * SSL_OP_CIPHER_SERVER_PREFERENCE). ++ * ++ * The equal-preference groups are expressed by grouping SSL_CIPHERs together. ++ * All elements of a group have the same priority: no ordering is expressed ++ * within a group. ++ * ++ * The values in |ciphers| are in one-to-one correspondence with ++ * |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of ++ * bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to ++ * indicate that the corresponding SSL_CIPHER is not the last element of a ++ * group, or 0 to indicate that it is. ++ * ++ * For example, if |in_group_flags| contains all zeros then that indicates a ++ * traditional, fully-ordered preference. Every SSL_CIPHER is the last element ++ * of the group (i.e. they are all in a one-element group). ++ * ++ * For a more complex example, consider: ++ * ciphers: A B C D E F ++ * in_group_flags: 1 1 0 0 1 0 ++ * ++ * That would express the following, order: ++ * ++ * A E ++ * B -> D -> F ++ * C ++ */ ++struct ssl_cipher_preference_list_st { ++ STACK_OF(SSL_CIPHER) *ciphers; ++ uint8_t *in_group_flags; ++}; ++ ++ + struct ssl_ctx_st { + OPENSSL_CTX *libctx; + + const SSL_METHOD *method; +- STACK_OF(SSL_CIPHER) *cipher_list; ++ struct ssl_cipher_preference_list_st *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* TLSv1.3 specific ciphersuites */ +@@ -1350,7 +1387,7 @@ struct ssl_st { + SSL_DANE dane; + /* crypto */ + STACK_OF(SSL_CIPHER) *peer_ciphers; +- STACK_OF(SSL_CIPHER) *cipher_list; ++ struct ssl_cipher_preference_list_st *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* TLSv1.3 specific ciphersuites */ + STACK_OF(SSL_CIPHER) *tls13_ciphersuites; +@@ -2323,7 +2360,7 @@ __owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, + const SSL_CIPHER *const *bp); + __owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, + STACK_OF(SSL_CIPHER) *tls13_ciphersuites, +- STACK_OF(SSL_CIPHER) **cipher_list, ++ struct ssl_cipher_preference_list_st **cipher_list, + STACK_OF(SSL_CIPHER) **cipher_list_by_id, + const char *rule_str, + CERT *c); +@@ -2333,6 +2370,13 @@ __owur int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **scsvs, int sslv2format, + int fatal); + void ssl_update_cache(SSL *s, int mode); ++struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_dup( ++ struct ssl_cipher_preference_list_st *cipher_list); ++void ssl_cipher_preference_list_free( ++ struct ssl_cipher_preference_list_st *cipher_list); ++struct ssl_cipher_preference_list_st* ssl_cipher_preference_list_from_ciphers( ++ STACK_OF(SSL_CIPHER) *ciphers); ++struct ssl_cipher_preference_list_st* ssl_get_cipher_preferences(SSL *s); + __owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, + size_t *mac_secret_size, SSL_COMP **comp, +@@ -2418,7 +2462,7 @@ __owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, + CERT_PKEY *cpk); + __owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, + STACK_OF(SSL_CIPHER) *clnt, +- STACK_OF(SSL_CIPHER) *srvr); ++ struct ssl_cipher_preference_list_st *srvr); + __owur int ssl3_digest_cached_records(SSL *s, int keep); + __owur int ssl3_new(SSL *s); + void ssl3_free(SSL *s); +diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c +index a23187290e..6348f1f9b6 100644 +--- a/ssl/statem/statem_srvr.c ++++ b/ssl/statem/statem_srvr.c +@@ -1774,7 +1774,7 @@ static int tls_early_post_process_client_hello(SSL *s) + /* For TLSv1.3 we must select the ciphersuite *before* session resumption */ + if (SSL_IS_TLS13(s)) { + const SSL_CIPHER *cipher = +- ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s)); ++ ssl3_choose_cipher(s, ciphers, ssl_get_cipher_preferences(s)); + + if (cipher == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, +@@ -1957,7 +1957,7 @@ static int tls_early_post_process_client_hello(SSL *s) + /* check if some cipher was preferred by call back */ + if (pref_cipher == NULL) + pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers, +- SSL_get_ciphers(s)); ++ ssl_get_cipher_preferences(s)); + if (pref_cipher == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, +@@ -1966,8 +1966,9 @@ static int tls_early_post_process_client_hello(SSL *s) + } + + s->session->cipher = pref_cipher; +- sk_SSL_CIPHER_free(s->cipher_list); +- s->cipher_list = sk_SSL_CIPHER_dup(s->peer_ciphers); ++ ssl_cipher_preference_list_free(s->cipher_list); ++ s->cipher_list = ssl_cipher_preference_list_from_ciphers( ++ s->peer_ciphers); + sk_SSL_CIPHER_free(s->cipher_list_by_id); + s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->peer_ciphers); + } +@@ -2279,7 +2280,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) + /* In TLSv1.3 we selected the ciphersuite before resumption */ + if (!SSL_IS_TLS13(s)) { + cipher = +- ssl3_choose_cipher(s, s->peer_ciphers, SSL_get_ciphers(s)); ++ ssl3_choose_cipher(s, s->peer_ciphers, ssl_get_cipher_preferences(s)); + + if (cipher == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, +diff --git a/util/libcrypto.num b/util/libcrypto.num +index f81fefb9b2..7d36cf81fe 100644 +--- a/util/libcrypto.num ++++ b/util/libcrypto.num +@@ -3340,14 +3340,14 @@ CRYPTO_new_ex_data 3409 3_0_0 EXIST::FUNCTION: + PEM_read_PKCS8_PRIV_KEY_INFO 3410 3_0_0 EXIST::FUNCTION:STDIO + TS_VERIFY_CTX_new 3411 3_0_0 EXIST::FUNCTION:TS + BUF_MEM_new_ex 3412 3_0_0 EXIST::FUNCTION: +-RSA_padding_add_X931 3413 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_padding_add_X931 3413 3_0_0 EXIST::FUNCTION:RSA + BN_get0_nist_prime_256 3414 3_0_0 EXIST::FUNCTION: + CRYPTO_memcmp 3415 3_0_0 EXIST::FUNCTION: + DH_check_pub_key 3416 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH + ASN1_mbstring_copy 3417 3_0_0 EXIST::FUNCTION: + PKCS7_set_type 3418 3_0_0 EXIST::FUNCTION: + BIO_gets 3419 3_0_0 EXIST::FUNCTION: +-RSA_padding_check_PKCS1_type_1 3420 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_padding_check_PKCS1_type_1 3420 3_0_0 EXIST::FUNCTION:RSA + UI_ctrl 3421 3_0_0 EXIST::FUNCTION: + i2d_X509_REQ_fp 3422 3_0_0 EXIST::FUNCTION:STDIO + BN_BLINDING_convert_ex 3423 3_0_0 EXIST::FUNCTION: +@@ -4273,14 +4273,14 @@ EVP_PKEY_asn1_set_param_check 4368 3_0_0 EXIST::FUNCTION: + DH_check_ex 4369 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH + DH_check_pub_key_ex 4370 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH + DH_check_params_ex 4371 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH +-RSA_generate_multi_prime_key 4372 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_generate_multi_prime_key 4372 3_0_0 EXIST::FUNCTION:RSA + RSA_get_multi_prime_extra_count 4373 3_0_0 EXIST::FUNCTION:RSA + OCSP_resp_get0_signer 4374 3_0_0 EXIST::FUNCTION:OCSP + RSA_get0_multi_prime_crt_params 4375 3_0_0 EXIST::FUNCTION:RSA + RSA_set0_multi_prime_params 4376 3_0_0 EXIST::FUNCTION:RSA +-RSA_get_version 4377 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA +-RSA_meth_get_multi_prime_keygen 4378 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA +-RSA_meth_set_multi_prime_keygen 4379 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,RSA ++RSA_get_version 4377 3_0_0 EXIST::FUNCTION:RSA ++RSA_meth_get_multi_prime_keygen 4378 3_0_0 EXIST::FUNCTION:RSA ++RSA_meth_set_multi_prime_keygen 4379 3_0_0 EXIST::FUNCTION:RSA + RAND_DRBG_get0_master 4380 3_0_0 EXIST::FUNCTION: + RAND_DRBG_set_reseed_time_interval 4381 3_0_0 EXIST::FUNCTION: + PROFESSION_INFO_get0_addProfessionInfo 4382 3_0_0 EXIST::FUNCTION: