From 9cb91bd77030f81d2fecbf7ebfe4dc1d8665deb9 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 23 Nov 2023 10:22:36 +0100 Subject: [PATCH 01/17] IANA has assigned numbers for 2 hybrid PQ KEX widely used in tests Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22803) Signed-off-by: fly2x --- ssl/t1_trce.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index b05012f74f..29dce65e4f 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -545,6 +545,8 @@ static const ssl_trace_tbl ssl_groups_tbl[] = { {258, "ffdhe4096"}, {259, "ffdhe6144"}, {260, "ffdhe8192"}, + {25497, "X25519Kyber768Draft00"}, + {25498, "SecP256r1Kyber768Draft00"}, {0xFF01, "arbitrary_explicit_prime_curves"}, {0xFF02, "arbitrary_explicit_char2_curves"} }; -- Gitee From d61d72b2f4ba4584ffbdecf83a5fc45063e11d47 Mon Sep 17 00:00:00 2001 From: James Muir Date: Fri, 17 Nov 2023 18:02:51 -0500 Subject: [PATCH 02/17] openssl-speed: support KMAC128 & KMAC256, refactor mac setup/teardown Add ability to measure performance of the two kmac algorithms, and reduce code duplication in mac testing by introducing mac_setup() and mac_teardown(). Also, start accepting "cmac" as an algorithm string (similar to how "hmac" is accepted). We can now compare the performance of KMAC128, KMAC256 (mac algs) to KECCAK-KMAC128, KECCAK-KMAC256 (digest/xof algs). Fixes #22619 Testing: $ LD_LIBRARY_PATH=. ./apps/openssl speed kmac cmac hmac $ LD_LIBRARY_PATH=. ./apps/openssl speed kmac256 $ LD_LIBRARY_PATH=. ./apps/openssl speed -evp KECCAK-KMAC256 Reviewed-by: Hugo Landau Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22764) Signed-off-by: fly2x --- apps/speed.c | 166 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 117 insertions(+), 49 deletions(-) diff --git a/apps/speed.c b/apps/speed.c index d1c61d72d0..b978323f56 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -305,7 +305,8 @@ enum { D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST, D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES, D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML, - D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM + D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, D_KMAC128, D_KMAC256, + ALGOR_NUM }; /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */ static const char *names[ALGOR_NUM] = { @@ -315,7 +316,7 @@ static const char *names[ALGOR_NUM] = { "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc", "aes-128-cbc", "aes-192-cbc", "aes-256-cbc", "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc", - "evp", "ghash", "rand", "cmac" + "evp", "ghash", "rand", "cmac", "kmac128", "kmac256" }; /* list of configured algorithm (remaining), with some few alias */ @@ -356,7 +357,9 @@ static const OPT_PAIR doit_choices[] = { {"cast", D_CBC_CAST}, {"cast5", D_CBC_CAST}, {"ghash", D_GHASH}, - {"rand", D_RAND} + {"rand", D_RAND}, + {"kmac128", D_KMAC128}, + {"kmac256", D_KMAC256}, }; static double results[ALGOR_NUM][SIZE_NUM]; @@ -655,6 +658,41 @@ static int MD5_loop(void *args) return EVP_Digest_loop("md5", D_MD5, args); } +static int mac_setup(const char *name, + EVP_MAC **mac, OSSL_PARAM params[], + loopargs_t *loopargs, unsigned int loopargs_len) +{ + unsigned int i; + + *mac = EVP_MAC_fetch(app_get0_libctx(), name, app_get0_propq()); + if (*mac == NULL) + return 0; + + for (i = 0; i < loopargs_len; i++) { + loopargs[i].mctx = EVP_MAC_CTX_new(*mac); + if (loopargs[i].mctx == NULL) + return 0; + + if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params)) + return 0; + } + + return 1; +} + +static void mac_teardown(EVP_MAC **mac, + loopargs_t *loopargs, unsigned int loopargs_len) +{ + unsigned int i; + + for (i = 0; i < loopargs_len; i++) + EVP_MAC_CTX_free(loopargs[i].mctx); + EVP_MAC_free(*mac); + *mac = NULL; + + return; +} + static int EVP_MAC_loop(ossl_unused int algindex, void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -684,6 +722,16 @@ static int CMAC_loop(void *args) return EVP_MAC_loop(D_EVP_CMAC, args); } +static int KMAC128_loop(void *args) +{ + return EVP_MAC_loop(D_KMAC128, args); +} + +static int KMAC256_loop(void *args) +{ + return EVP_MAC_loop(D_KMAC256, args); +} + static int SHA1_loop(void *args) { return EVP_Digest_loop("sha1", D_SHA1, args); @@ -2222,6 +2270,14 @@ int speed_main(int argc, char **argv) do_sigs = 1; algo_found = 1; } + if (strcmp(algo, "kmac") == 0) { + doit[D_KMAC128] = doit[D_KMAC256] = 1; + algo_found = 1; + } + if (strcmp(algo, "cmac") == 0) { + doit[D_EVP_CMAC] = 1; + algo_found = 1; + } if (!algo_found) { BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo); @@ -2521,10 +2577,8 @@ int speed_main(int argc, char **argv) int len = strlen(hmac_key); OSSL_PARAM params[3]; - mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq()); - if (mac == NULL || evp_mac_mdname == NULL) + if (evp_mac_mdname == NULL) goto end; - evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname), "HMAC name"); sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname); @@ -2538,14 +2592,8 @@ int speed_main(int argc, char **argv) (char *)hmac_key, len); params[2] = OSSL_PARAM_construct_end(); - for (i = 0; i < loopargs_len; i++) { - loopargs[i].mctx = EVP_MAC_CTX_new(mac); - if (loopargs[i].mctx == NULL) - goto end; - - if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params)) - goto end; /* Digest not found */ - } + if (mac_setup("HMAC", &mac, params, loopargs, loopargs_len) < 1) + goto end; for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_HMAC], lengths[testnum], seconds.sym); Time_F(START); @@ -2555,10 +2603,7 @@ int speed_main(int argc, char **argv) if (count < 0) break; } - for (i = 0; i < loopargs_len; i++) - EVP_MAC_CTX_free(loopargs[i].mctx); - EVP_MAC_free(mac); - mac = NULL; + mac_teardown(&mac, loopargs, loopargs_len); } if (doit[D_CBC_DES]) { @@ -2677,25 +2722,22 @@ int speed_main(int argc, char **argv) } if (doit[D_GHASH]) { static const char gmac_iv[] = "0123456789ab"; - OSSL_PARAM params[3]; - - mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq()); - if (mac == NULL) - goto end; + OSSL_PARAM params[4]; params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER, "aes-128-gcm", 0); params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV, (char *)gmac_iv, sizeof(gmac_iv) - 1); - params[2] = OSSL_PARAM_construct_end(); + params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)key32, 16); + params[3] = OSSL_PARAM_construct_end(); + if (mac_setup("GMAC", &mac, params, loopargs, loopargs_len) < 1) + goto end; + /* b/c of the definition of GHASH_loop(), init() calls are needed here */ for (i = 0; i < loopargs_len; i++) { - loopargs[i].mctx = EVP_MAC_CTX_new(mac); - if (loopargs[i].mctx == NULL) - goto end; - - if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params)) + if (!EVP_MAC_init(loopargs[i].mctx, NULL, 0, NULL)) goto end; } for (testnum = 0; testnum < size_num; testnum++) { @@ -2707,10 +2749,7 @@ int speed_main(int argc, char **argv) if (count < 0) break; } - for (i = 0; i < loopargs_len; i++) - EVP_MAC_CTX_free(loopargs[i].mctx); - EVP_MAC_free(mac); - mac = NULL; + mac_teardown(&mac, loopargs, loopargs_len); } if (doit[D_RAND]) { @@ -2809,9 +2848,6 @@ int speed_main(int argc, char **argv) OSSL_PARAM params[3]; EVP_CIPHER *cipher = NULL; - mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq()); - if (mac == NULL || evp_mac_ciphername == NULL) - goto end; if (!opt_cipher(evp_mac_ciphername, &cipher)) goto end; @@ -2832,15 +2868,8 @@ int speed_main(int argc, char **argv) (char *)key32, keylen); params[2] = OSSL_PARAM_construct_end(); - for (i = 0; i < loopargs_len; i++) { - loopargs[i].mctx = EVP_MAC_CTX_new(mac); - if (loopargs[i].mctx == NULL) - goto end; - - if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params)) - goto end; - } - + if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1) + goto end; for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym); Time_F(START); @@ -2850,10 +2879,49 @@ int speed_main(int argc, char **argv) if (count < 0) break; } - for (i = 0; i < loopargs_len; i++) - EVP_MAC_CTX_free(loopargs[i].mctx); - EVP_MAC_free(mac); - mac = NULL; + mac_teardown(&mac, loopargs, loopargs_len); + } + + if (doit[D_KMAC128]) { + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)key32, 16); + params[1] = OSSL_PARAM_construct_end(); + + if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1) + goto end; + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_KMAC128], lengths[testnum], seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, KMAC128_loop, loopargs); + d = Time_F(STOP); + print_result(D_KMAC128, testnum, count, d); + if (count < 0) + break; + } + mac_teardown(&mac, loopargs, loopargs_len); + } + + if (doit[D_KMAC256]) { + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)key32, 32); + params[1] = OSSL_PARAM_construct_end(); + + if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1) + goto end; + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_KMAC256], lengths[testnum], seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, KMAC256_loop, loopargs); + d = Time_F(STOP); + print_result(D_KMAC256, testnum, count, d); + if (count < 0) + break; + } + mac_teardown(&mac, loopargs, loopargs_len); } for (i = 0; i < loopargs_len; i++) -- Gitee From d4e4f6ef4ebe7a53ff120d45d207b1ae7f85c8db Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 10 Nov 2023 16:06:16 +0100 Subject: [PATCH 03/17] When abidiff fails print out the XML diff This can be useful for fixing the CI if needed without the necessity to run abidw locally. Also rename the CI job to make its purpose clearer. Reviewed-by: Hugo Landau Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22689) Signed-off-by: fly2x --- .github/workflows/ci.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d90d0a2877..ac5d0956f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -264,7 +264,7 @@ jobs: - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - fips_and_ktls: + full_feat_w_abidiff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -287,9 +287,17 @@ jobs: cat /proc/cpuinfo ./util/opensslwrap.sh version -c - name: Check ABI compatibility for libcrypto - run: abidiff ./.github/workflows/libcrypto-abi.xml ./libcrypto.so + run: | + if ! abidiff ./.github/workflows/libcrypto-abi.xml ./libcrypto.so ; then + abidw --out-file libcrypto-abi-new.xml ./libcrypto.so + diff -u ./.github/workflows/libcrypto-abi.xml libcrypto-abi-new.xml + fi - name: Check ABI compatibility for libssl - run: abidiff ./.github/workflows/libssl-abi.xml ./libssl.so + run: | + if ! abidiff ./.github/workflows/libssl-abi.xml ./libssl.so ; then + abidw --out-file libssl-abi-new.xml ./libssl.so + diff -u ./.github/workflows/libssl-abi.xml libssl-abi-new.xml + fi - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} -- Gitee From 32d2d6c5c38ec72965f33709cbe304c48d558ddc Mon Sep 17 00:00:00 2001 From: Markus Minichmayr Date: Tue, 21 Nov 2023 20:42:12 +0100 Subject: [PATCH 04/17] Add option `SSL_OP_PREFER_NO_DHE_KEX`, allowing the server to prefer non-dhe psk key exchange over psk with dhe (config file option `PreferNoDHEKEX`, server option `prefer_no_dhe_kex`). Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22794) Signed-off-by: fly2x --- apps/include/opt.h | 6 +++- include/openssl/ssl.h.in | 2 ++ ssl/ssl_conf.c | 4 +++ ssl/statem/extensions.c | 17 +++++++--- ssl/statem/extensions_srvr.c | 21 +++++++++--- test/recipes/70-test_tls13kexmodes.t | 50 ++++++++++++++++++++++------ 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/apps/include/opt.h b/apps/include/opt.h index 5a2faa150b..2bd2fb2484 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -157,7 +157,8 @@ OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \ OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_CLIENTRENEG, \ OPT_S_LEGACYCONN, \ - OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \ + OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, \ + OPT_S_ALLOW_NO_DHE_KEX, OPT_S_PREFER_NO_DHE_KEX, \ OPT_S_PRIORITIZE_CHACHA, \ OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \ OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \ @@ -198,6 +199,8 @@ "Disallow initial connection to servers that don't support RI"}, \ {"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \ "In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \ + {"prefer_no_dhe_kex", OPT_S_PREFER_NO_DHE_KEX, '-', \ + "In TLSv1.3 prefer non-(ec)dhe over (ec)dhe-based key exchange on resumption"}, \ {"prioritize_chacha", OPT_S_PRIORITIZE_CHACHA, '-', \ "Prioritize ChaCha ciphers when preferred by clients"}, \ {"strict", OPT_S_STRICT, '-', \ @@ -248,6 +251,7 @@ case OPT_S_ONRESUMP: \ case OPT_S_NOLEGACYCONN: \ case OPT_S_ALLOW_NO_DHE_KEX: \ + case OPT_S_PREFER_NO_DHE_KEX: \ case OPT_S_PRIORITIZE_CHACHA: \ case OPT_S_STRICT: \ case OPT_S_SIGALGS: \ diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index 9f91039f8a..b22522d006 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -426,6 +426,8 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); /* Enable KTLS TX zerocopy on Linux */ # define SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE SSL_OP_BIT(34) +#define SSL_OP_PREFER_NO_DHE_KEX SSL_OP_BIT(35) + /* * Option "collections." */ diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 3142370016..b361719a5a 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -391,6 +391,7 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC), SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION), SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), + SSL_FLAG_TBL("PreferNoDHEKEX", SSL_OP_PREFER_NO_DHE_KEX), SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY), @@ -725,6 +726,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT), SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0), + SSL_CONF_CMD_SWITCH("prefer_no_dhe_kex", 0), SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("strict", 0), SSL_CONF_CMD_SWITCH("no_middlebox", 0), @@ -816,6 +818,8 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV}, /* allow_no_dhe_kex */ {SSL_OP_ALLOW_NO_DHE_KEX, 0}, + /* prefer_no_dhe_kex */ + {SSL_OP_PREFER_NO_DHE_KEX, 0}, /* chacha reprioritization */ {SSL_OP_PRIORITIZE_CHACHA, 0}, {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */ diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 0a64ca2246..e77ab2f3e5 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1393,7 +1393,8 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) * the client sent a key_share extension * AND * (we are not resuming - * OR the kex_mode allows key_share resumes) + * OR (the kex_mode allows key_share resumes + * AND (kex_mode doesn't allow non-dh resumes OR non-dh is not preferred))) * AND * a shared group exists * THEN @@ -1428,10 +1429,18 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) } } else { /* No suitable key_share */ + + /* Do DHE PSK? */ + int dhe_psk = + /* kex_mode allows key_share resume */ + (((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) != 0) + + /* and psk-only is not available or not explicitly preferred */ + && ((((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0) + || (s->options & SSL_OP_PREFER_NO_DHE_KEX) == 0))); + if (s->hello_retry_request == SSL_HRR_NONE && sent - && (!s->hit - || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) - != 0)) { + && (!s->hit || dhe_psk)) { const uint16_t *pgroups, *clntgroups; size_t num_groups, clnt_num_groups, i; unsigned int group_id = 0; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 64ccb3ed6d..2d28ea3b3d 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1645,12 +1645,25 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, } return EXT_RETURN_NOT_SENT; } - if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) { + if (s->hit) { + /* PSK ('hit') */ + /* - * PSK ('hit') and explicitly not doing DHE (if the client sent the - * DHE option we always take it); don't send key share. + * If we're doing PSK ('hit') but the client doesn't support psk-dhe, + * we don't need to send a key share. */ - return EXT_RETURN_NOT_SENT; + if ((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) + return EXT_RETURN_NOT_SENT; + + /* + * If both, psk_ke and psk_dh_ke are available, we do psk_dh_ke and + * send a key share by default, but not if the server is explicitly + * configured to prefer psk_ke. + */ + if (((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) != 0) + && ((s->options & SSL_OP_PREFER_NO_DHE_KEX) != 0)) { + return EXT_RETURN_NOT_SENT; + } } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) diff --git a/test/recipes/70-test_tls13kexmodes.t b/test/recipes/70-test_tls13kexmodes.t index c4711e442b..1f45edc7b7 100644 --- a/test/recipes/70-test_tls13kexmodes.t +++ b/test/recipes/70-test_tls13kexmodes.t @@ -191,7 +191,7 @@ $proxy->clientflags("-no_rx_cert_comp -sess_out ".$session); $proxy->serverflags("-no_rx_cert_comp -servername localhost"); $proxy->sessionfile($session); $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 11; +plan tests => 13; ok(TLSProxy::Message->success(), "Initial connection"); #Test 2: Attempt a resume with no kex modes extension. Should fail (server @@ -251,10 +251,11 @@ checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, | checkhandshake::PSK_CLI_EXTENSION, "Resume with unrecognized kex mode"); -#Test 7: Attempt a resume with both non-dhe and dhe kex mode. Should resume with -# a key_share +#Test 7: Attempt a resume with both, non-dhe and dhe kex mode. Should resume with +# a key_share, even though non-dhe is allowed, but not explicitly preferred. $proxy->clear(); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); +$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); +$proxy->serverflags("-allow_no_dhe_kex"); $testtype = BOTH_KEX_MODES; $proxy->start(); checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, @@ -263,9 +264,38 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, | checkhandshake::KEY_SHARE_SRV_EXTENSION | checkhandshake::PSK_CLI_EXTENSION | checkhandshake::PSK_SRV_EXTENSION, - "Resume with non-dhe kex mode"); + "Resume with both kex modes"); + +#Test 8: Attempt a resume with both, non-dhe and dhe kex mode, but with server-side +# preference for non-dhe. Should resume without a key_share. +$proxy->clear(); +$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); +$proxy->serverflags("-allow_no_dhe_kex -prefer_no_dhe_kex"); +$testtype = BOTH_KEX_MODES; +$proxy->start(); +checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes, preference for non-dhe"); + +#Test 9: Attempt a resume with both, non-dhe and dhe kex mode, with server-side +# preference for non-dhe, but non-dhe not allowed. Should resume with a key_share. +$proxy->clear(); +$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); +$proxy->serverflags("-prefer_no_dhe_kex"); +$testtype = BOTH_KEX_MODES; +$proxy->start(); +checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes, preference for but disabled non-dhe"); -#Test 8: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable +#Test 10: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable # initial key_share. Should resume with a key_share following an HRR $proxy->clear(); $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); @@ -281,7 +311,7 @@ checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, | checkhandshake::PSK_SRV_EXTENSION, "Resume with both kex modes and HRR"); -#Test 9: Attempt a resume with dhe kex mode only and an unacceptable initial +#Test 11: Attempt a resume with dhe kex mode only and an unacceptable initial # key_share. Should resume with a key_share following an HRR $proxy->clear(); $proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); @@ -297,7 +327,7 @@ checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, | checkhandshake::PSK_SRV_EXTENSION, "Resume with dhe kex mode and HRR"); -#Test 10: Attempt a resume with both non-dhe and dhe kex mode, unacceptable +#Test 12: Attempt a resume with both non-dhe and dhe kex mode, unacceptable # initial key_share and no overlapping groups. Should resume without a # key_share $proxy->clear(); @@ -312,7 +342,7 @@ checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, | checkhandshake::PSK_SRV_EXTENSION, "Resume with both kex modes, no overlapping groups"); -#Test 11: Attempt a resume with dhe kex mode only, unacceptable +#Test 13: Attempt a resume with dhe kex mode only, unacceptable # initial key_share and no overlapping groups. Should fail $proxy->clear(); $proxy->clientflags("-no_rx_cert_comp -curves P-384 -sess_in ".$session); @@ -351,7 +381,7 @@ sub modify_kex_modes_filter 0xfe, #unknown 0xff; #unknown } elsif ($testtype == BOTH_KEX_MODES) { - #We deliberately list psk_ke first...should still use psk_dhe_ke + #We deliberately list psk_ke first...should still use psk_dhe_ke, except if the server is configured otherwise. $ext = pack "C3", 0x02, #List length 0x00, #psk_ke -- Gitee From 361efaf173a0e9778a5d62b2843b309e8a154acc Mon Sep 17 00:00:00 2001 From: Markus Minichmayr Date: Tue, 21 Nov 2023 23:50:54 +0100 Subject: [PATCH 05/17] Document `SSL_OP_PREFER_NO_DHE_KEX` option. Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22794) Signed-off-by: fly2x --- doc/man1/openssl-s_client.pod.in | 1 + doc/man1/openssl-s_server.pod.in | 1 + doc/man3/SSL_CONF_cmd.pod | 11 +++++++++++ doc/man3/SSL_CTX_set_options.pod | 6 ++++++ doc/perlvars.pm | 4 +++- 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 84cf6fdd81..f8db2658be 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -93,6 +93,7 @@ B B [B<-legacy_server_connect>] [B<-no_legacy_server_connect>] [B<-allow_no_dhe_kex>] +[B<-prefer_no_dhe_kex>] [B<-sigalgs> I] [B<-curves> I] [B<-cipher> I] diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in index 611b410cfd..9726a5c871 100644 --- a/doc/man1/openssl-s_server.pod.in +++ b/doc/man1/openssl-s_server.pod.in @@ -102,6 +102,7 @@ B B [B<-no_renegotiation>] [B<-no_resumption_on_reneg>] [B<-allow_no_dhe_kex>] +[B<-prefer_no_dhe_kex>] [B<-prioritize_chacha>] [B<-strict>] [B<-sigalgs> I] diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index 7ffd731410..a0e4d52892 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -95,6 +95,12 @@ Only used by servers. Requires B<-serverpref>. In TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This means that there will be no forward secrecy for the resumed session. +=item B<-prefer_no_dhe_kex> + +In TLSv1.3, on resumption let the server prefer a non-(ec)dhe based key +exchange mode over an (ec)dhe based one. Requires B<-allow_no_dhe_kex>. +Equivalent to B. Only used by servers. + =item B<-strict> Enables strict mode protocol handling. Equivalent to setting @@ -523,6 +529,11 @@ B: In TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This means that there will be no forward secrecy for the resumed session. Equivalent to B. +B: In TLSv1.3, on resumption let the server prefer a +non-(ec)dhe based key exchange mode over an (ec)dhe based one. Requires +B. Equivalent to B. Only used by +servers. + B: If set then dummy Change Cipher Spec (CCS) messages are sent in TLSv1.3. This has the effect of making TLSv1.3 look more like TLSv1.2 so that middleboxes that do not understand TLSv1.3 will not drop the connection. This diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 56695e4abd..272b2a93e4 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -110,6 +110,12 @@ this option to enable it. In TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This means that there will be no forward secrecy for the resumed session. +=item SSL_OP_PREFER_NO_DHE_KEX + +In TLSv1.3, on resumption let the server prefer a non-(ec)dhe based key +exchange mode over an (ec)dhe based one. Ignored without B +being set as well. Always ignored on the client. + =item SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION Allow legacy insecure renegotiation between OpenSSL and unpatched clients or diff --git a/doc/perlvars.pm b/doc/perlvars.pm index f4c20aa392..06dac990cf 100644 --- a/doc/perlvars.pm +++ b/doc/perlvars.pm @@ -187,6 +187,7 @@ $OpenSSL::safe::opt_s_synopsis = "" . "[B<-no_legacy_server_connect>]\n" . "[B<-no_etm>]\n" . "[B<-allow_no_dhe_kex>]\n" +. "[B<-prefer_no_dhe_kex>]\n" . "[B<-prioritize_chacha>]\n" . "[B<-strict>]\n" . "[B<-sigalgs> I]\n" @@ -207,7 +208,8 @@ $OpenSSL::safe::opt_s_item = "" . "B<-legacy_renegotiation>, B<-no_renegotiation>,\n" . "B<-no_resumption_on_reneg>,\n" . "B<-legacy_server_connect>, B<-no_legacy_server_connect>, B<-no_etm>\n" -. "B<-allow_no_dhe_kex>, B<-prioritize_chacha>, B<-strict>, B<-sigalgs>\n" +. "B<-allow_no_dhe_kex>, B<-prefer_no_dhe_kex>,\n" +. "B<-prioritize_chacha>, B<-strict>, B<-sigalgs>\n" . "I, B<-client_sigalgs> I, B<-groups> I, B<-curves>\n" . "I, B<-named_curve> I, B<-cipher> I, B<-ciphersuites>\n" . "I<1.3ciphers>, B<-min_protocol> I, B<-max_protocol> I,\n" -- Gitee From 674f99bcbcee8f1fdde844a61112ea49d38d754e Mon Sep 17 00:00:00 2001 From: Markus Minichmayr Date: Wed, 22 Nov 2023 17:43:27 +0100 Subject: [PATCH 06/17] PreferNoDHEKEX changelog and history anticipating inclusion in OpenSSL version 3.3. Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22794) Signed-off-by: fly2x --- CHANGES.md | 6 ++++++ doc/man3/SSL_CONF_cmd.pod | 2 ++ 2 files changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 81044b3d70..93365619fa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,12 @@ OpenSSL 3.3 *Ahelenia ZiemiaƄska* + * New option `SSL_OP_PREFER_NO_DHE_KEX`, which allows configuring a TLS1.3 + server to prefer session resumption using PSK-only key exchange over PSK + with DHE, if both are available. + + *Markus Minichmayr, Tapkey GmbH* + OpenSSL 3.2 ----------- diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index a0e4d52892..54ab886af1 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -789,6 +789,8 @@ OpenSSL 3.0. The B and B options were added in OpenSSL 3.2. +B was added in OpenSSL 3.3. + =head1 COPYRIGHT Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved. -- Gitee From 37999fde90b011100f8f1219b9626bd2f3fe54a1 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 13 Nov 2023 12:17:43 +0100 Subject: [PATCH 07/17] x86_64-xlate.pl: Fix build with icx and nvc compilers Fixes #22594 Reviewed-by: Hugo Landau Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22714) Signed-off-by: fly2x --- crypto/perlasm/x86_64-xlate.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl index 359670a2da..6b93cfb84f 100755 --- a/crypto/perlasm/x86_64-xlate.pl +++ b/crypto/perlasm/x86_64-xlate.pl @@ -111,7 +111,12 @@ elsif (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` $gnuas=1; } elsif (`$ENV{CC} --version 2>/dev/null` - =~ /clang .*/) + =~ /(clang .*|Intel.*oneAPI .*)/) +{ + $gnuas=1; +} +elsif (`$ENV{CC} -V 2>/dev/null` + =~ /nvc .*/) { $gnuas=1; } -- Gitee From 54784471057837b858770da8062eec45efe4f384 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Thu, 2 Nov 2023 15:41:23 +0000 Subject: [PATCH 08/17] QUIC SRT GEN: Add SRT generator Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22599) Signed-off-by: fly2x --- include/internal/quic_srt_gen.h | 57 ++++++++++++++++++++ ssl/quic/build.info | 2 +- ssl/quic/quic_srt_gen.c | 83 +++++++++++++++++++++++++++++ test/build.info | 6 ++- test/quic_srt_gen_test.c | 83 +++++++++++++++++++++++++++++ test/recipes/75-test_quic_srt_gen.t | 19 +++++++ 6 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 include/internal/quic_srt_gen.h create mode 100644 ssl/quic/quic_srt_gen.c create mode 100644 test/quic_srt_gen_test.c create mode 100644 test/recipes/75-test_quic_srt_gen.t diff --git a/include/internal/quic_srt_gen.h b/include/internal/quic_srt_gen.h new file mode 100644 index 0000000000..a25e71aa81 --- /dev/null +++ b/include/internal/quic_srt_gen.h @@ -0,0 +1,57 @@ +/* +* Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#ifndef OSSL_INTERNAL_QUIC_SRT_GEN_H +# define OSSL_INTERNAL_QUIC_SRT_GEN_H +# pragma once + +# include "internal/e_os.h" +# include "internal/time.h" +# include "internal/quic_types.h" +# include "internal/quic_wire.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Stateless Reset Token Generator + * ==================================== + * + * This generates 16-byte QUIC Stateless Reset Tokens given a secret symmetric + * key and a DCID. Because the output is deterministic with regards to these + * inputs, assuming the same key is used between invocations of a process, we + * are able to generate the same stateless reset token in a subsequent process, + * thereby allowing us to achieve stateless reset of a peer which still thinks + * it is connected to a past process at the same UDP address. + */ +typedef struct quic_srt_gen_st QUIC_SRT_GEN; + +/* + * Create a new stateless reset token generator using the given key as input. + * The key may be of arbitrary length. + * + * The caller is responsible for performing domain separation with regards to + * the key; i.e., the caller is responsible for ensuring the key is never used + * in any other context. + */ +QUIC_SRT_GEN *ossl_quic_srt_gen_new(OSSL_LIB_CTX *libctx, const char *propq, + const unsigned char *key, size_t key_len); + +/* Free the stateless reset token generator. No-op if srt_gen is NULL. */ +void ossl_quic_srt_gen_free(QUIC_SRT_GEN *srt_gen); + +/* + * Calculates a token using the given DCID and writes it to *token. Returns 0 on + * failure. + */ +int ossl_quic_srt_gen_calculate_token(QUIC_SRT_GEN *srt_gen, + const QUIC_CONN_ID *dcid, + QUIC_STATELESS_RESET_TOKEN *token); + +# endif +#endif diff --git a/ssl/quic/build.info b/ssl/quic/build.info index 866f581fa9..b8d871848c 100644 --- a/ssl/quic/build.info +++ b/ssl/quic/build.info @@ -14,4 +14,4 @@ SOURCE[$LIBSSL]=quic_tserver.c SOURCE[$LIBSSL]=quic_tls.c SOURCE[$LIBSSL]=quic_thread_assist.c SOURCE[$LIBSSL]=quic_trace.c -SOURCE[$LIBSSL]=quic_srtm.c +SOURCE[$LIBSSL]=quic_srtm.c quic_srt_gen.c diff --git a/ssl/quic/quic_srt_gen.c b/ssl/quic/quic_srt_gen.c new file mode 100644 index 0000000000..e43a55b29e --- /dev/null +++ b/ssl/quic/quic_srt_gen.c @@ -0,0 +1,83 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include "internal/quic_srt_gen.h" +#include +#include + +struct quic_srt_gen_st { + EVP_MAC *mac; + EVP_MAC_CTX *mac_ctx; +}; + +/* + * Simple HMAC-SHA256-based stateless reset token generator. + */ + +QUIC_SRT_GEN *ossl_quic_srt_gen_new(OSSL_LIB_CTX *libctx, const char *propq, + const unsigned char *key, size_t key_len) +{ + QUIC_SRT_GEN *srt_gen; + OSSL_PARAM params[3], *p = params; + + if ((srt_gen = OPENSSL_zalloc(sizeof(*srt_gen))) == NULL) + return NULL; + + if ((srt_gen->mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL) + goto err; + + if ((srt_gen->mac_ctx = EVP_MAC_CTX_new(srt_gen->mac)) == NULL) + goto err; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "SHA256", 7); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, + (char *)propq, 0); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_init(srt_gen->mac_ctx, key, key_len, params)) + goto err; + + return srt_gen; + +err: + ossl_quic_srt_gen_free(srt_gen); + return NULL; +} + +void ossl_quic_srt_gen_free(QUIC_SRT_GEN *srt_gen) +{ + if (srt_gen == NULL) + return; + + EVP_MAC_CTX_free(srt_gen->mac_ctx); + EVP_MAC_free(srt_gen->mac); + OPENSSL_free(srt_gen); +} + +int ossl_quic_srt_gen_calculate_token(QUIC_SRT_GEN *srt_gen, + const QUIC_CONN_ID *dcid, + QUIC_STATELESS_RESET_TOKEN *token) +{ + size_t outl = 0; + unsigned char mac[32]; + + if (!EVP_MAC_init(srt_gen->mac_ctx, NULL, 0, NULL)) + return 0; + + if (!EVP_MAC_update(srt_gen->mac_ctx, (const unsigned char *)dcid->id, + dcid->id_len)) + return 0; + + if (!EVP_MAC_final(srt_gen->mac_ctx, mac, &outl, sizeof(mac)) + || outl != sizeof(mac)) + return 0; + + memcpy(token, mac, sizeof(*token)); + return 1; +} diff --git a/test/build.info b/test/build.info index cba48e6db0..a71ee13d1f 100644 --- a/test/build.info +++ b/test/build.info @@ -75,7 +75,7 @@ IF[{- !$disabled{tests} -}] IF[{- !$disabled{quic} -}] PROGRAMS{noinst}=priority_queue_test event_queue_test quicfaultstest quicapitest \ - quic_newcid_test + quic_newcid_test quic_srt_gen_test ENDIF IF[{- !$disabled{comp} && (!$disabled{brotli} || !$disabled{zstd} || !$disabled{zlib}) -}] @@ -850,6 +850,10 @@ IF[{- !$disabled{tests} -}] SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c $QUICTESTHELPERS INCLUDE[quic_newcid_test]=../include ../apps/include .. DEPEND[quic_newcid_test]=../libcrypto.a ../libssl.a libtestutil.a + + SOURCE[quic_srt_gen_test]=quic_srt_gen_test.c helpers/ssltestlib.c $QUICTESTHELPERS + INCLUDE[quic_srt_gen_test]=../include ../apps/include .. + DEPEND[quic_srt_gen_test]=../libcrypto.a ../libssl.a libtestutil.a ENDIF SOURCE[dhtest]=dhtest.c diff --git a/test/quic_srt_gen_test.c b/test/quic_srt_gen_test.c new file mode 100644 index 0000000000..6982f599c0 --- /dev/null +++ b/test/quic_srt_gen_test.c @@ -0,0 +1,83 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include +#include "internal/quic_srt_gen.h" + +#include "testutil.h" +#include "testutil/output.h" + +struct test_case { + const unsigned char *key; + size_t key_len; + QUIC_CONN_ID dcid; + QUIC_STATELESS_RESET_TOKEN expected; +}; + +static const unsigned char key_1[] = { 0x01, 0x02, 0x03 }; + +static const unsigned char key_2[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +static const struct test_case tests[] = { + { + key_1, sizeof(key_1), { 2, { 0x55, 0x66 } }, + {{ 0x02,0x9e,0x8f,0x3d,0x1e,0xa9,0x06,0x23,0xb2,0x43,0xd2,0x19,0x59,0x8a,0xa1,0x66 }} + }, + { + key_2, sizeof(key_2), { 0, { 0 } }, + {{ 0x93,0x10,0x2f,0xc7,0xaf,0x9d,0x9b,0x28,0x3f,0x84,0x95,0x6b,0xa3,0xdc,0x07,0x6b }} + }, + { + key_2, sizeof(key_2), + { 20, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }, + {{ 0x9a,0x98,0x98,0x61,0xbe,0xfd,0xe3,0x05,0x45,0xac,0x66,0xcf,0x3b,0x58,0xfb,0xab }} + } +}; + +static int test_srt_gen(int idx) +{ + int testresult = 0; + const struct test_case *t = &tests[idx]; + QUIC_SRT_GEN *srt_gen = NULL; + QUIC_STATELESS_RESET_TOKEN token; + size_t i; + + if (!TEST_ptr(srt_gen = ossl_quic_srt_gen_new(NULL, NULL, + t->key, t->key_len))) + goto err; + + for (i = 0; i < 2; ++i) { + memset(&token, 0xff, sizeof(token)); + + if (!TEST_true(ossl_quic_srt_gen_calculate_token(srt_gen, &t->dcid, + &token))) + goto err; + + if (!TEST_mem_eq(&token, sizeof(token), + &t->expected, sizeof(t->expected))) + goto err; + } + + testresult = 1; +err: + ossl_quic_srt_gen_free(srt_gen); + return testresult; +} + +int setup_tests(void) +{ + ADD_ALL_TESTS(test_srt_gen, OSSL_NELEM(tests)); + return 1; +} diff --git a/test/recipes/75-test_quic_srt_gen.t b/test/recipes/75-test_quic_srt_gen.t new file mode 100644 index 0000000000..64c2cae34f --- /dev/null +++ b/test/recipes/75-test_quic_srt_gen.t @@ -0,0 +1,19 @@ +#! /usr/bin/env perl +# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test qw/:DEFAULT/; +use OpenSSL::Test::Utils; + +setup("test_quic_srt_gen"); + +plan skip_all => "QUIC protocol is not supported by this OpenSSL build" + if disabled('quic'); + +plan tests => 1; + +ok(run(test(["quic_srt_gen_test"]))); -- Gitee From d03b40efa841fb3880a5925978e389e2d73242c3 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Thu, 23 Nov 2023 15:50:03 +0000 Subject: [PATCH 09/17] QUIC SRT GEN: Minor updates Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22599) Signed-off-by: fly2x --- ssl/quic/quic_srt_gen.c | 5 +++-- test/quic_srt_gen_test.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ssl/quic/quic_srt_gen.c b/ssl/quic/quic_srt_gen.c index e43a55b29e..233e4aa628 100644 --- a/ssl/quic/quic_srt_gen.c +++ b/ssl/quic/quic_srt_gen.c @@ -65,7 +65,7 @@ int ossl_quic_srt_gen_calculate_token(QUIC_SRT_GEN *srt_gen, QUIC_STATELESS_RESET_TOKEN *token) { size_t outl = 0; - unsigned char mac[32]; + unsigned char mac[SHA256_DIGEST_LENGTH]; if (!EVP_MAC_init(srt_gen->mac_ctx, NULL, 0, NULL)) return 0; @@ -78,6 +78,7 @@ int ossl_quic_srt_gen_calculate_token(QUIC_SRT_GEN *srt_gen, || outl != sizeof(mac)) return 0; - memcpy(token, mac, sizeof(*token)); + assert(sizeof(mac) >= sizeof(token->token)); + memcpy(token->token, mac, sizeof(token->token)); return 1; } diff --git a/test/quic_srt_gen_test.c b/test/quic_srt_gen_test.c index 6982f599c0..59f331d5af 100644 --- a/test/quic_srt_gen_test.c +++ b/test/quic_srt_gen_test.c @@ -65,7 +65,7 @@ static int test_srt_gen(int idx) &token))) goto err; - if (!TEST_mem_eq(&token, sizeof(token), + if (!TEST_mem_eq(token.token, sizeof(token.token), &t->expected, sizeof(t->expected))) goto err; } -- Gitee From 76c416301eaaee4c9fab64a571f7181f79ab0b3e Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 24 Nov 2023 10:03:30 +0000 Subject: [PATCH 10/17] Only include winsock2.h for struct timeval if needed Fixes #22811 Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Matthias St. Pierre (Merged from https://github.com/openssl/openssl/pull/22813) (cherry picked from commit ba58e9f1e22dd9ee2e37078640dcbe9f520a555d) Signed-off-by: fly2x --- include/openssl/e_ostime.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/openssl/e_ostime.h b/include/openssl/e_ostime.h index 8a7cc9880f..0e17487504 100644 --- a/include/openssl/e_ostime.h +++ b/include/openssl/e_ostime.h @@ -22,7 +22,15 @@ */ # if defined(OPENSSL_SYS_WINDOWS) -# include +# if !defined(_WINSOCKAPI_) + /* + * winsock2.h defines _WINSOCK2API_ and both winsock2.h and winsock.h define + * _WINSOCKAPI_. Both of these provide struct timeval. Don't include + * winsock2.h if either header has been included to avoid breakage with + * applications that prefer to use over . + */ +# include +# endif # else # include # endif -- Gitee From 0affa9233e28f9983fffb37f844e586a1624de1e Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 27 Nov 2023 07:51:33 +0000 Subject: [PATCH 11/17] Make ssl_cert_info read-only Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22828) Signed-off-by: fly2x --- ssl/ssl_cert.c | 6 +++--- ssl/ssl_cert_table.h | 2 +- ssl/ssl_ciph.c | 2 +- ssl/ssl_local.h | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 126be668fd..f11eb75827 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1240,13 +1240,13 @@ int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx) return 0; } -SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx) +const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx) { size_t i; /* check classic pk types */ for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { - SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; + const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { @@ -1270,7 +1270,7 @@ SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_C return NULL; } -SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx) +const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx) { if (idx >= (OSSL_NELEM(ssl_cert_info) + ctx->sigalg_list_len)) return NULL; diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h index 28918b9767..e4dc8063b1 100644 --- a/ssl/ssl_cert_table.h +++ b/ssl/ssl_cert_table.h @@ -10,7 +10,7 @@ /* * Certificate table information. NB: table entries must match SSL_PKEY indices */ -static SSL_CERT_LOOKUP ssl_cert_info [] = { +static const SSL_CERT_LOOKUP ssl_cert_info [] = { {EVP_PKEY_RSA, SSL_aRSA}, /* SSL_PKEY_RSA */ {EVP_PKEY_RSA_PSS, SSL_aRSA}, /* SSL_PKEY_RSA_PSS_SIGN */ {EVP_PKEY_DSA, SSL_aDSS}, /* SSL_PKEY_DSA_SIGN */ diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 8360991ce4..31c0d5af1d 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -2234,7 +2234,7 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx) { - SSL_CERT_LOOKUP *cl; + const SSL_CERT_LOOKUP *cl; /* A provider-loaded key type is always enabled */ if (idx >= SSL_PKEY_NUM) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index d1ef358932..ed9f54b06f 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2531,10 +2531,10 @@ __owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp); __owur int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx); -__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, - size_t *pidx, - SSL_CTX *ctx); -__owur SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx); +__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, + size_t *pidx, + SSL_CTX *ctx); +__owur const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx); int ssl_undefined_function(SSL *s); __owur int ssl_undefined_void_function(void); -- Gitee From f23d721c1816fe61eebd61106e10e8119da8c8a5 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 27 Nov 2023 07:52:24 +0000 Subject: [PATCH 12/17] Make bitmask table read only Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22828) Signed-off-by: fly2x --- ssl/statem/statem_dtls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index c674ddfb54..166e2075a4 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -39,9 +39,9 @@ if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ if (bitmask[ii] != 0xff) { is_complete = 0; break; } } -static unsigned char bitmask_start_values[] = +static const unsigned char bitmask_start_values[] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; -static unsigned char bitmask_end_values[] = +static const unsigned char bitmask_end_values[] = { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; static void dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, -- Gitee From fcbbbd1e5c1883d58397f8beedcb296475af5070 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 27 Nov 2023 07:52:54 +0000 Subject: [PATCH 13/17] Make nid_to_group read-only Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22828) Signed-off-by: fly2x --- ssl/t1_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 631e1fdef9..236c1b49a7 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -140,7 +140,7 @@ int tls1_clear(SSL *s) } /* Legacy NID to group_id mapping. Only works for groups we know about */ -static struct { +static const struct { int nid; uint16_t group_id; } nid_to_group[] = { -- Gitee From 3405abe3aebd847a9222a6687c54a5528931338a Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 27 Nov 2023 07:55:55 +0000 Subject: [PATCH 14/17] Make scsv read-only Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22828) Signed-off-by: fly2x --- ssl/statem/statem_clnt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 3b3c51e41c..caf9d7d11c 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -4146,7 +4146,7 @@ int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, if (totlen != 0) { if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { + static const SSL_CIPHER scsv = { 0, NULL, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (!ssl->method->put_cipher_by_char(&scsv, pkt, &len)) { @@ -4155,7 +4155,7 @@ int ssl_cipher_list_to_bytes(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *sk, } } if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { + static const SSL_CIPHER scsv = { 0, NULL, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (!ssl->method->put_cipher_by_char(&scsv, pkt, &len)) { -- Gitee From af686a81354fc7b68f55e6945d294324186c4d29 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 27 Nov 2023 07:57:32 +0000 Subject: [PATCH 15/17] QUIC TSERVER: Fix erroneously static variable Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/22828) Signed-off-by: fly2x --- ssl/quic/quic_tserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssl/quic/quic_tserver.c b/ssl/quic/quic_tserver.c index 3fc51b4a77..130733821c 100644 --- a/ssl/quic/quic_tserver.c +++ b/ssl/quic/quic_tserver.c @@ -53,7 +53,7 @@ static int alpn_select_cb(SSL *ssl, const unsigned char **out, static const unsigned char alpndeflt[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' }; - static const unsigned char *alpn; + const unsigned char *alpn; size_t alpnlen; if (srv->args.alpn == NULL) { -- Gitee From a615bcc193dcaad7644b337cb139de92377dc252 Mon Sep 17 00:00:00 2001 From: Xi Ruoyao Date: Fri, 24 Nov 2023 16:14:05 +0800 Subject: [PATCH 16/17] Do not define L_ENDIAN (for now) when we guessed linux64-loongarch64 In 160f48941d14 I made L_ENDIAN defined when the system is guessed to be linux64-loongarch64. Unfortunately now I found it problematic: 1. This should be added into Configurations/10-main.conf, not here. Having it here causes a different configuration when linux64-loongarch64 is explicitly specified than guessed. 2. With LTO enabled, this causes many test failures on linux64-loongarch64 due to #12247. So I think we should remove it for now (master and 3.2 branch), and reintroduce it to Configurations/10-main.conf when we finally sort out #12247. Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22812) Signed-off-by: fly2x --- util/perl/OpenSSL/config.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/util/perl/OpenSSL/config.pm b/util/perl/OpenSSL/config.pm index 8125f48b14..cda764b4ed 100755 --- a/util/perl/OpenSSL/config.pm +++ b/util/perl/OpenSSL/config.pm @@ -691,7 +691,6 @@ EOF $disable = []; } return { target => "linux64-loongarch64", - defines => [ 'L_ENDIAN' ], disable => $disable, }; } ], -- Gitee From 4ed44e8d4418cc6d23ad9c9d7f87358dba71e0c3 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 17 Nov 2023 14:47:36 +0100 Subject: [PATCH 17/17] Fix a possible memory leak in ct_move_scts Instead of trying to move the doomed sct back to the src stack, which may fail as well, simply free the sct object, as the src list will be deleted anyway. Reviewed-by: Paul Yang Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22762) Signed-off-by: fly2x --- ssl/ssl_lib.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 70d3b17c19..b9858be937 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -6056,6 +6056,8 @@ IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); * If |dst| points to a NULL pointer, a new stack will be created and owned by * the caller. * Returns the number of SCTs moved, or a negative integer if an error occurs. + * The |dst| stack is created and possibly partially populated even in case + * of error, likewise the |src| stack may be left in an intermediate state. */ static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src, sct_source_t origin) @@ -6075,15 +6077,14 @@ static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src, if (SCT_set_source(sct, origin) != 1) goto err; - if (sk_SCT_push(*dst, sct) <= 0) + if (!sk_SCT_push(*dst, sct)) goto err; scts_moved += 1; } return scts_moved; err: - if (sct != NULL) - sk_SCT_push(src, sct); /* Put the SCT back */ + SCT_free(sct); return -1; } -- Gitee