aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ctags.d/add-dir.ctags11
-rw-r--r--.ctags.d/exclude.ctags13
-rw-r--r--.ctags.d/openssl-stage1/10extrac-macrodefs.ctags18
-rw-r--r--.ctags.d/openssl-stage2/10expand-macros.ctags9
-rw-r--r--CHANGES.md36
-rw-r--r--Configurations/unix-Makefile.tmpl8
-rwxr-xr-xConfigure1
-rw-r--r--HACKING.md87
-rw-r--r--NEWS.md16
-rw-r--r--NOTES-WINDOWS.md5
-rw-r--r--VERSION.dat4
-rw-r--r--apps/CA.pl.in262
-rw-r--r--apps/asn1parse.c2
-rw-r--r--apps/cmp.c4
-rw-r--r--apps/genpkey.c6
-rw-r--r--apps/lib/s_socket.c10
-rw-r--r--apps/pkeyutl.c1
-rw-r--r--apps/rand.c4
-rw-r--r--apps/s_time.c6
-rw-r--r--apps/speed.c14
-rw-r--r--apps/storeutl.c6
-rw-r--r--apps/x509.c68
-rwxr-xr-xcrypto/aes/asm/aesv8-armx.pl2
-rw-r--r--crypto/bio/bio_dump.c4
-rw-r--r--crypto/bio/bio_print.c25
-rw-r--r--crypto/bn/asm/rsaz-2k-avxifma.pl16
-rw-r--r--crypto/bn/asm/rsaz-3k-avxifma.pl22
-rw-r--r--crypto/bn/asm/rsaz-4k-avxifma.pl26
-rwxr-xr-xcrypto/chacha/asm/chacha-armv8-sve.pl22
-rw-r--r--crypto/cmp/cmp_http.c4
-rw-r--r--crypto/core_namemap.c2
-rw-r--r--crypto/dh/dh_check.c36
-rw-r--r--crypto/dh/dh_pmeth.c4
-rw-r--r--crypto/ec/ecp_nistp384.c54
-rw-r--r--crypto/encode_decode/decoder_lib.c28
-rw-r--r--crypto/encode_decode/decoder_pkey.c72
-rw-r--r--crypto/encode_decode/encoder_local.h2
-rw-r--r--crypto/err/openssl.txt6
-rw-r--r--crypto/evp/asymcipher.c33
-rw-r--r--crypto/evp/bio_enc.c3
-rw-r--r--crypto/evp/ctrl_params_translate.c455
-rw-r--r--crypto/evp/evp_err.c14
-rw-r--r--crypto/evp/evp_rand.c13
-rw-r--r--crypto/evp/keymgmt_meth.c17
-rw-r--r--crypto/evp/legacy_sha.c4
-rw-r--r--crypto/evp/m_sigver.c122
-rw-r--r--crypto/evp/pmeth_lib.c9
-rw-r--r--crypto/evp/signature.c264
-rw-r--r--crypto/hmac/hmac_s390x.c13
-rw-r--r--crypto/http/http_lib.c10
-rw-r--r--crypto/ml_kem/ml_kem.c58
-rw-r--r--crypto/params_dup.c10
-rw-r--r--crypto/params_from_text.c8
-rwxr-xr-xcrypto/perlasm/x86_64-xlate.pl26
-rw-r--r--crypto/pkcs7/pk7_smime.c6
-rw-r--r--crypto/property/property.c2
-rw-r--r--crypto/provider_conf.c2
-rw-r--r--crypto/provider_core.c28
-rw-r--r--crypto/rand/rand_lib.c49
-rw-r--r--crypto/rsa/rsa_gen.c15
-rw-r--r--crypto/slh_dsa/slh_hash.c3
-rw-r--r--crypto/sm2/sm2_sign.c6
-rw-r--r--crypto/sm3/asm/sm3-armv8.pl4
-rwxr-xr-xcrypto/sm4/asm/sm4-armv8.pl8
-rw-r--r--crypto/store/store_lib.c25
-rw-r--r--crypto/store/store_result.c15
-rw-r--r--crypto/threads_none.c33
-rw-r--r--crypto/threads_pthread.c4
-rw-r--r--crypto/ts/ts_rsp_sign.c16
-rw-r--r--crypto/ui/ui_lib.c52
-rw-r--r--crypto/x509/by_store.c118
-rw-r--r--crypto/x509/v3_lib.c8
-rw-r--r--crypto/x509/x_crl.c15
-rw-r--r--demos/bio/sconnect.c6
-rw-r--r--demos/cms/cms_ddec.c4
-rw-r--r--demos/cms/cms_denc.c4
-rw-r--r--demos/guide/tls-client-block.c4
-rw-r--r--demos/sslecho/main.c17
-rw-r--r--doc/designs/fetching-composite-algorithms.md86
-rw-r--r--doc/designs/functions-for-explicitly-fetched-signature-algorithms.md205
-rw-r--r--doc/internal/man3/ossl_namemap_new.pod15
-rw-r--r--doc/man1/openssl-fipsinstall.pod.in10
-rw-r--r--doc/man1/openssl-pkeyutl.pod.in124
-rw-r--r--doc/man1/openssl-s_client.pod.in4
-rw-r--r--doc/man3/CMS_get0_SignerInfos.pod4
-rw-r--r--doc/man3/CMS_sign.pod4
-rw-r--r--doc/man3/DTLS_set_timer_cb.pod13
-rw-r--r--doc/man3/EVP_PKEY_CTX_new.pod9
-rw-r--r--doc/man3/EVP_PKEY_encapsulate.pod4
-rw-r--r--doc/man3/EVP_PKEY_new.pod18
-rw-r--r--doc/man3/EVP_PKEY_sign.pod4
-rw-r--r--doc/man3/EVP_RAND.pod11
-rw-r--r--doc/man3/OPENSSL_secure_malloc.pod9
-rw-r--r--doc/man3/OSSL_CMP_CTX_new.pod150
-rw-r--r--doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod2
-rw-r--r--doc/man3/OSSL_PARAM.pod4
-rw-r--r--doc/man3/OSSL_PARAM_int.pod25
-rw-r--r--doc/man3/PEM_read_CMS.pod8
-rw-r--r--doc/man3/PKCS7_sign.pod4
-rw-r--r--doc/man3/SSL_CONF_cmd.pod2
-rw-r--r--doc/man3/SSL_CTX_set_min_proto_version.pod7
-rw-r--r--doc/man3/SSL_CTX_set_options.pod4
-rw-r--r--doc/man3/SSL_key_update.pod6
-rw-r--r--doc/man3/SSL_new_listener.pod8
-rw-r--r--doc/man3/SSL_set1_host.pod60
-rw-r--r--doc/man3/SSL_set_quic_tls_cbs.pod2
-rw-r--r--doc/man3/X509_STORE_CTX_new.pod4
-rw-r--r--doc/man3/X509_check_purpose.pod2
-rw-r--r--doc/man5/fips_config.pod16
-rw-r--r--doc/man7/EVP_ASYM_CIPHER-RSA.pod5
-rw-r--r--doc/man7/OSSL_PROVIDER-FIPS.pod101
-rw-r--r--doc/man7/ossl-guide-tls-introduction.pod4
-rw-r--r--doc/man7/provider-base.pod31
-rw-r--r--doc/man7/provider-cipher.pod4
-rw-r--r--doc/man7/provider-keymgmt.pod2
-rw-r--r--doc/man7/provider-signature.pod51
-rw-r--r--fuzz/dtlsserver.c5
-rw-r--r--include/crypto/dh.h4
-rw-r--r--include/crypto/rsa.h6
-rw-r--r--include/internal/common.h6
-rw-r--r--include/internal/constant_time.h18
-rw-r--r--include/internal/e_os.h13
-rw-r--r--include/internal/hashfunc.h1
-rw-r--r--include/internal/json_enc.h5
-rw-r--r--include/internal/provider.h3
-rw-r--r--include/internal/quic_ackm.h4
-rw-r--r--include/internal/quic_ssl.h4
-rw-r--r--include/internal/quic_tls.h2
-rw-r--r--include/openssl/core_dispatch.h4
-rw-r--r--include/openssl/evperr.h8
-rw-r--r--include/openssl/pem.h1
-rw-r--r--include/openssl/self_test.h1
-rw-r--r--include/openssl/ssl.h.in4
-rw-r--r--providers/fips-sources.checksums92
-rw-r--r--providers/fips.checksum2
-rw-r--r--providers/fips/fipsprov.c19
-rw-r--r--providers/fips/self_test_data.inc87
-rw-r--r--providers/implementations/ciphers/cipher_chacha20_poly1305.c20
-rw-r--r--providers/implementations/digests/sha3_prov.c4
-rw-r--r--providers/implementations/encode_decode/decode_pem2der.c1
-rw-r--r--providers/implementations/kdfs/hkdf.c14
-rw-r--r--providers/implementations/kem/ml_kem_kem.c2
-rw-r--r--providers/implementations/keymgmt/dh_kmgmt.c18
-rw-r--r--providers/implementations/keymgmt/ec_kmgmt.c17
-rw-r--r--providers/implementations/keymgmt/ecx_kmgmt.c30
-rw-r--r--providers/implementations/keymgmt/mac_legacy_kmgmt.c3
-rw-r--r--providers/implementations/keymgmt/ml_dsa_kmgmt.c19
-rw-r--r--providers/implementations/keymgmt/ml_kem_kmgmt.c3
-rw-r--r--providers/implementations/keymgmt/rsa_kmgmt.c18
-rw-r--r--providers/implementations/keymgmt/slh_dsa_kmgmt.c36
-rw-r--r--providers/implementations/keymgmt/template_kmgmt.c5
-rw-r--r--providers/implementations/rands/drbg_ctr.c3
-rw-r--r--providers/implementations/rands/drbg_local.h20
-rw-r--r--providers/implementations/rands/test_rng.c9
-rw-r--r--providers/implementations/storemgmt/winstore_store.c19
-rw-r--r--providers/legacyprov.c11
-rw-r--r--ssl/quic/json_enc.c30
-rw-r--r--ssl/quic/quic_ackm.c33
-rw-r--r--ssl/quic/quic_channel.c3
-rw-r--r--ssl/quic/quic_channel_local.h5
-rw-r--r--ssl/quic/quic_impl.c81
-rw-r--r--ssl/quic/quic_method.c4
-rw-r--r--ssl/quic/quic_port.c42
-rw-r--r--ssl/quic/quic_rx_depack.c28
-rw-r--r--ssl/quic/quic_tls.c9
-rw-r--r--ssl/record/methods/dtls_meth.c8
-rw-r--r--ssl/record/rec_layer_d1.c11
-rw-r--r--ssl/record/rec_layer_s3.c11
-rw-r--r--ssl/rio/poll_builder.c7
-rw-r--r--ssl/rio/poll_builder.h4
-rw-r--r--ssl/rio/poll_method.h5
-rw-r--r--ssl/s3_lib.c7
-rw-r--r--ssl/ssl_cert.c4
-rw-r--r--ssl/ssl_lib.c80
-rw-r--r--ssl/ssl_local.h9
-rw-r--r--ssl/ssl_sess.c3
-rw-r--r--ssl/statem/extensions.c9
-rw-r--r--ssl/statem/extensions_cust.c96
-rw-r--r--ssl/statem/statem_clnt.c29
-rw-r--r--ssl/statem/statem_dtls.c20
-rw-r--r--ssl/statem/statem_lib.c42
-rw-r--r--ssl/statem/statem_srvr.c2
-rw-r--r--ssl/t1_lib.c4
-rw-r--r--ssl/tls13_enc.c36
-rw-r--r--test/bio_comp_test.c8
-rw-r--r--test/bio_enc_test.c73
-rw-r--r--test/bioprinttest.c156
-rw-r--r--test/cmp_client_test.c3
-rw-r--r--test/crltest.c127
-rw-r--r--test/dhtest.c12
-rw-r--r--test/dtlstest.c102
-rw-r--r--test/ectest.c12
-rw-r--r--test/evp_extra_test.c3
-rw-r--r--test/evp_pkey_provided_test.c50
-rw-r--r--test/evp_test.c6
-rw-r--r--test/fake_rsaprov.c548
-rw-r--r--test/helpers/quictestlib.c76
-rw-r--r--test/helpers/ssltestlib.c68
-rw-r--r--test/helpers/ssltestlib.h7
-rw-r--r--test/hmactest.c26
-rw-r--r--test/http_test.c11
-rw-r--r--test/json_test.c3
-rw-r--r--test/ossl_store_test.c74
-rw-r--r--test/pairwise_fail_test.c35
-rw-r--r--test/params_api_test.c38
-rw-r--r--test/provider_pkey_test.c289
-rw-r--r--test/quic-openssl-docker/hq-interop/quic-hq-interop.c3
-rw-r--r--test/quic_ackm_test.c5
-rw-r--r--test/quic_fifd_test.c5
-rw-r--r--test/quic_multistream_test.c10
-rw-r--r--test/quic_txp_test.c3
-rw-r--r--test/quicapitest.c178
-rw-r--r--test/radix/quic_ops.c40
-rw-r--r--test/radix/quic_tests.c63
-rw-r--r--test/rand_test.c40
-rw-r--r--test/recipes/15-test_ec.t14
-rw-r--r--test/recipes/25-test_verify.t39
-rw-r--r--test/recipes/25-test_x509.t12
-rw-r--r--test/recipes/30-test_evp_data/evpciph_des3_common.txt4
-rw-r--r--test/recipes/30-test_evp_data/evppkey_slh_dsa_keygen.txt2
-rw-r--r--test/recipes/30-test_evp_data/evppkey_slh_dsa_siggen.txt2
-rw-r--r--test/recipes/30-test_evp_data/evppkey_slh_dsa_sigver.txt2
-rw-r--r--test/recipes/30-test_pairwise_fail.t46
-rw-r--r--test/recipes/70-test_sslkeylogfile.t15
-rw-r--r--test/recipes/70-test_sslrecords.t59
-rw-r--r--test/recipes/70-test_tls13downgrade.t158
-rw-r--r--test/recipes/80-test_ca.t13
-rw-r--r--test/recipes/90-test_store_cases.t26
-rw-r--r--test/recipes/90-test_store_cases_data/test-BER.p12bin0 -> 2126 bytes
-rw-r--r--test/sslapitest.c264
-rw-r--r--test/testec-sm2.pem5
-rw-r--r--test/testutil/testutil_init.c3
-rw-r--r--test/threadstest.c24
-rw-r--r--tools/c_rehash.in8
-rw-r--r--util/check-format-test-negatives.c24
-rw-r--r--util/check-format-test-positives.c18
-rwxr-xr-xutil/check-format.pl32
-rw-r--r--util/perl/TLSProxy/Proxy.pm65
-rw-r--r--util/platform_symbols/unix-symbols.txt1
-rw-r--r--util/platform_symbols/windows-symbols.txt2
-rw-r--r--util/wrap.pl.in39
241 files changed, 5861 insertions, 1694 deletions
diff --git a/.ctags.d/add-dir.ctags b/.ctags.d/add-dir.ctags
new file mode 100644
index 000000000000..ec20b51bd4ca
--- /dev/null
+++ b/.ctags.d/add-dir.ctags
@@ -0,0 +1,11 @@
+#
+# 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
+#
+
+# Allow ctags to load configuration file under the sub directories.
+--optlib-dir=+./.ctags.d
diff --git a/.ctags.d/exclude.ctags b/.ctags.d/exclude.ctags
new file mode 100644
index 000000000000..c932464e6dbd
--- /dev/null
+++ b/.ctags.d/exclude.ctags
@@ -0,0 +1,13 @@
+#
+# 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
+#
+
+# List file names or patterns you want ctags to ignore.
+--exclude=.ctags.d
+--exclude=test
+--exclude=check-format-test-positives.c
diff --git a/.ctags.d/openssl-stage1/10extrac-macrodefs.ctags b/.ctags.d/openssl-stage1/10extrac-macrodefs.ctags
new file mode 100644
index 000000000000..ddd4fd54bd04
--- /dev/null
+++ b/.ctags.d/openssl-stage1/10extrac-macrodefs.ctags
@@ -0,0 +1,18 @@
+#
+# 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
+#
+
+# This file is only for extracting macro definitions.
+--langmap=C:+.h
+-o -
+--sort=no
+--languages=C
+-R
+
+--fields-C=+{macrodef}
+--fields=+{signature}
diff --git a/.ctags.d/openssl-stage2/10expand-macros.ctags b/.ctags.d/openssl-stage2/10expand-macros.ctags
new file mode 100644
index 000000000000..5cf5000df3af
--- /dev/null
+++ b/.ctags.d/openssl-stage2/10expand-macros.ctags
@@ -0,0 +1,9 @@
+#
+# 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
+#
+--param-CPreProcessor._expand=1
diff --git a/CHANGES.md b/CHANGES.md
index aaf3fea1ca5e..c9682a863ff6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -28,6 +28,36 @@ OpenSSL Releases
OpenSSL 3.5
-----------
+### Changes between 3.5.1 and 3.5.2 [5 Aug 2025]
+
+ * The FIPS provider now performs a PCT on key import for RSA, EC and ECX.
+ This is mandated by FIPS 140-3 IG 10.3.A additional comment 1.
+
+ *Dr Paul Dale*
+
+### Changes between 3.5.0 and 3.5.1 [1 Jul 2025]
+
+ * Fix x509 application adds trusted use instead of rejected use.
+
+ Issue summary: Use of -addreject option with the openssl x509 application adds
+ a trusted use instead of a rejected use for a certificate.
+
+ Impact summary: If a user intends to make a trusted certificate rejected for
+ a particular use it will be instead marked as trusted for that use.
+
+ ([CVE-2025-4575])
+
+ *Tomas Mraz*
+
+ * Aligned the behaviour of TLS and DTLS in the event of a no_renegotiation
+ alert being received. Older versions of OpenSSL failed with DTLS if a
+ no_renegotiation alert was received. All versions of OpenSSL do this for TLS.
+ From 3.2 a bug was exposed that meant that DTLS ignored no_rengotiation. We
+ have now restored the original behaviour and brought DTLS back into line with
+ TLS.
+
+ *Matt Caswell*
+
### Changes between 3.4 and 3.5.0 [8 Apr 2025]
* Added server side support for QUIC
@@ -6586,6 +6616,11 @@ OpenSSL 1.1.0
*Rob Percival <robpercival@google.com>*
+ * SSLv3 is by default disabled at build-time. Builds that are not
+ configured with "enable-ssl3" will not support SSLv3.
+
+ *Kurt Roeckx*
+
OpenSSL 1.0.2
-------------
@@ -21199,6 +21234,7 @@ ndif
<!-- Links -->
+[CVE-2025-4575]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-4575
[CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176
[CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143
[CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119
diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
index e85763ccf835..a6f666957ec0 100644
--- a/Configurations/unix-Makefile.tmpl
+++ b/Configurations/unix-Makefile.tmpl
@@ -135,7 +135,7 @@ GENERATED_PODS={- # common0.tmpl provides @generated
fill_lines(" ", $COLUMNS - 15,
map { my $x = $_;
(
- grep {
+ grep {
$unified_info{attributes}->{depends}
->{$x}->{$_}->{pod} // 0
}
@@ -809,12 +809,12 @@ install_dev: install_runtime_libs
cp $$e "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
chmod 644 "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
done
- @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(CMAKECONFIGDIR)
+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(CMAKECONFIGDIR)"
@for e in $(INSTALL_EXPORTERS_CMAKE); do \
fn=`basename $$e`; \
$(ECHO) "install $$e -> $(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
- cp $$e $(DESTDIR)$(CMAKECONFIGDIR)/$$fn; \
- chmod 644 $(DESTDIR)$(CMAKECONFIGDIR)/$$fn; \
+ cp $$e "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
+ chmod 644 "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
done
uninstall_dev: uninstall_runtime_libs
diff --git a/Configure b/Configure
index 15054f94034a..499585438a16 100755
--- a/Configure
+++ b/Configure
@@ -171,6 +171,7 @@ my @gcc_devteam_warn = qw(
-Wextra
-Wno-unused-parameter
-Wno-missing-field-initializers
+ -Wno-unterminated-string-initialization
-Wswitch
-Wsign-compare
-Wshadow
diff --git a/HACKING.md b/HACKING.md
index 9a1f7b9f5036..b58f08a2dc9a 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -1,33 +1,80 @@
MODIFYING OPENSSL SOURCE
========================
-This document describes the way to add custom modifications to OpenSSL sources.
+This document describes the way to add custom modifications to OpenSSL
+sources.
- If you are adding new public functions to the custom library build, you need to
- either add a prototype in one of the existing OpenSSL header files;
- or provide a new header file and edit
- [Configurations/unix-Makefile.tmpl](Configurations/unix-Makefile.tmpl)
- to pick up that file.
+If you are adding new C source files
+------------------------------------
- After that, perform the following steps:
+Please update the `build.info` files in the directories where you placed the
+C source files, to include a line like this for each new C source file:
+
+- In `crypto/` or any of its subdirectories (intended for `libcrypto`):
+
+ SOURCE[../libcrypto]={name-of-C-source-file}
+
+- In `ssl/` or any of its subdirectories (intended for `libssl`):
+
+ SOURCE[../libssl]={name-of-C-source-file}
+
+Do note that the path given as the `SOURCE` attribute must be adapted
+appropriately for the location of the `build.info` file, as it's a relative
+path to where the library itself is built, for example:
+
+- For `crypto/build.info`, the library path should be `../libcrypto`
+- For `crypto/evp/build.info`, the library path should be
+ `../../libcrypto`
+- For `ssl/build.info`, the library path should be `../libssl`
+- For `ssl/quic/build.info`, the library path should be `../../libssl`
+
+To know more about `build.info` files, please read [doc/internal/man7/build.info.pod].
+For better viewing, consider converting it to HTML or PDF using `pod2html`
+or `pod2pdf`.
+
+Adding new public functions
+---------------------------
+
+If you are adding new public functions to the custom library build, you need to
+either add a prototype in one of the existing OpenSSL header files, or
+provide a new header file and edit.
+
+Only headers in the `include/openssl` subdirectory are considered for public
+functions. If you're creating a new header file, it must be located in that
+directory.
+
+Functions declared in `include/openssl` header files are assumed to be part
+of the `libcrypto` library unless specified otherwise. *If your new
+functions are meant for the `libssl` library*, you will need to edit
+[Configurations/unix-Makefile.tmpl] and add the header file name in the
+array `my @sslheaders_tmpl`.
+
+Updating OpenSSL's bookkeeping files
+------------------------------------
+
+OpenSSL has a few bookkeeping files to keep track of exposed functions, most
+importantly `util/libcrypto.num` and `util/libssl.num`. Any time a new
+public function - as defined above - is added, these files must be updated.
+
+To make such an update, please do the following:
./Configure -Werror --strict-warnings [your-options]
make update
- make
- make test
- `make update` ensures that your functions declarations are added to
- `util/libcrypto.num` or `util/libssl.num`.
- If you plan to submit the changes you made to OpenSSL
- (see [CONTRIBUTING.md](CONTRIBUTING.md)), it's worth running:
+If you plan to submit the changes you made to OpenSSL (see
+[CONTRIBUTING.md]), it's also worth running the following after running
+`make update`, to ensure that documentation has correct format.
make doc-nits
- after running `make update` to ensure that documentation has correct format.
+Do note that `make update` also generates files related to OIDs (in the
+`crypto/objects/` folder) and errors messages.
+
+If a git merge error occurs in one of these generated files, then the
+generated files need to be removed and regenerated using `make update`.
+To aid in this process, the generated files can be committed separately
+so they can be removed easily by reverting that commit.
- `make update` also generates files related to OIDs (in the `crypto/objects/`
- folder) and errors.
- If a merge error occurs in one of these generated files, then the
- generated files need to be removed and regenerated using `make update`.
- To aid in this process, the generated files can be committed separately
- so they can be removed easily.
+[doc/internal/man7/build.info.pod]: ./doc/internal/man7/build.info.pod
+[Configurations/unix-Makefile.tmpl]: ./Configurations/unix-Makefile.tmpl
+[CONTRIBUTING.md]: ./CONTRIBUTING.md
diff --git a/NEWS.md b/NEWS.md
index 62c52a852714..0d7cf139fa2d 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -23,6 +23,20 @@ OpenSSL Releases
OpenSSL 3.5
-----------
+### Major changes between OpenSSL 3.5.1 and OpenSSL 3.5.2 [5 Aug 2025]
+
+ * none
+
+### Major changes between OpenSSL 3.5.0 and OpenSSL 3.5.1 [1 Jul 2025]
+
+OpenSSL 3.5.1 is a security patch release. The most severe CVE fixed in this
+release is Low.
+
+This release incorporates the following bug fixes and mitigations:
+
+ * Fix x509 application adds trusted use instead of rejected use.
+ ([CVE-2025-4575])
+
### Major changes between OpenSSL 3.4 and OpenSSL 3.5.0 [8 Apr 2025]
OpenSSL 3.5.0 is a feature release adding significant new functionality to
@@ -1889,7 +1903,7 @@ OpenSSL 0.9.x
* Support for various new platforms
<!-- Links -->
-
+[CVE-2025-4575]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-4575
[CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176
[CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143
[CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119
diff --git a/NOTES-WINDOWS.md b/NOTES-WINDOWS.md
index 9beeb79be758..e903376db530 100644
--- a/NOTES-WINDOWS.md
+++ b/NOTES-WINDOWS.md
@@ -87,6 +87,11 @@ Quick start
on the Universal CRT or
- `perl Configure` to let Configure figure out the platform
+ a. If you don't plan to develop OpenSSL yourself and don't need to rebuild,
+ in other words, if you always do a new build, turning off the build
+ dependency feature can speed up build times by up to 50%:
+ `perl Configure no-makedepend`
+
6. `nmake`
7. `nmake test`
diff --git a/VERSION.dat b/VERSION.dat
index 9d13b630cc71..a5925c8d5338 100644
--- a/VERSION.dat
+++ b/VERSION.dat
@@ -1,7 +1,7 @@
MAJOR=3
MINOR=5
-PATCH=0
+PATCH=2
PRE_RELEASE_TAG=
BUILD_METADATA=
-RELEASE_DATE="8 Apr 2025"
+RELEASE_DATE="5 Aug 2025"
SHLIB_VERSION=3
diff --git a/apps/CA.pl.in b/apps/CA.pl.in
index 2c31ee6c8de1..0bad37d46955 100644
--- a/apps/CA.pl.in
+++ b/apps/CA.pl.in
@@ -1,5 +1,5 @@
#!{- $config{HASHBANGPERL} -}
-# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2000-2025 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
@@ -19,14 +19,17 @@ my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify");
my $openssl = $ENV{'OPENSSL'} // "openssl";
$ENV{'OPENSSL'} = $openssl;
+my @openssl = split_val($openssl);
+
my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} // "";
+my @OPENSSL_CONFIG = split_val($OPENSSL_CONFIG);
# Command invocations.
-my $REQ = "$openssl req $OPENSSL_CONFIG";
-my $CA = "$openssl ca $OPENSSL_CONFIG";
-my $VERIFY = "$openssl verify";
-my $X509 = "$openssl x509";
-my $PKCS12 = "$openssl pkcs12";
+my @REQ = (@openssl, "req", @OPENSSL_CONFIG);
+my @CA = (@openssl, "ca", @OPENSSL_CONFIG);
+my @VERIFY = (@openssl, "verify");
+my @X509 = (@openssl, "x509");
+my @PKCS12 = (@openssl, "pkcs12");
# Default values for various configuration settings.
my $CATOP = "./demoCA";
@@ -34,10 +37,10 @@ my $CAKEY = "cakey.pem";
my $CAREQ = "careq.pem";
my $CACERT = "cacert.pem";
my $CACRL = "crl.pem";
-my $DAYS = "-days 365";
-my $CADAYS = "-days 1095"; # 3 years
-my $EXTENSIONS = "-extensions v3_ca";
-my $POLICY = "-policy policy_anything";
+my @DAYS = qw(-days 365);
+my @CADAYS = qw(-days 1095); # 3 years
+my @EXTENSIONS = qw(-extensions v3_ca);
+my @POLICY = qw(-policy policy_anything);
my $NEWKEY = "newkey.pem";
my $NEWREQ = "newreq.pem";
my $NEWCERT = "newcert.pem";
@@ -45,31 +48,177 @@ my $NEWP12 = "newcert.p12";
# Commandline parsing
my %EXTRA;
-my $WHAT = shift @ARGV || "";
+my $WHAT = shift @ARGV // "";
@ARGV = parse_extra(@ARGV);
my $RET = 0;
+sub split_val {
+ return split_val_win32(@_) if ($^O eq 'MSWin32');
+ my ($val) = @_;
+ my (@ret, @frag);
+
+ # Skip leading whitespace
+ $val =~ m{\A[ \t]*}ogc;
+
+ # Unix shell-compatible split
+ #
+ # Handles backslash escapes outside quotes and
+ # in double-quoted strings. Parameter and
+ # command-substitution is silently ignored.
+ # Bare newlines outside quotes and (trailing) backslashes are disallowed.
+
+ while (1) {
+ last if (pos($val) == length($val));
+
+ # The first char is never a SPACE or TAB. Possible matches are:
+ # 1. Ordinary string fragment
+ # 2. Single-quoted string
+ # 3. Double-quoted string
+ # 4. Backslash escape
+ # 5. Bare backlash or newline (rejected)
+ #
+ if ($val =~ m{\G([^'" \t\n\\]+)}ogc) {
+ # Ordinary string
+ push @frag, $1;
+ } elsif ($val =~ m{\G'([^']*)'}ogc) {
+ # Single-quoted string
+ push @frag, $1;
+ } elsif ($val =~ m{\G"}ogc) {
+ # Double-quoted string
+ push @frag, "";
+ while (1) {
+ last if ($val =~ m{\G"}ogc);
+ if ($val =~ m{\G([^"\\]+)}ogcs) {
+ # literals
+ push @frag, $1;
+ } elsif ($val =~ m{\G.(["\`\$\\])}ogc) {
+ # backslash-escaped special
+ push @frag, $1;
+ } elsif ($val =~ m{\G.(.)}ogcs) {
+ # backslashed non-special
+ push @frag, "\\$1" unless $1 eq "\n";
+ } else {
+ die sprintf("Malformed quoted string: %s\n", $val);
+ }
+ }
+ } elsif ($val =~ m{\G\\(.)}ogc) {
+ # Backslash is unconditional escape outside quoted strings
+ push @frag, $1 unless $1 eq "\n";
+ } else {
+ die sprintf("Bare backslash or newline in: '%s'\n", $val);
+ }
+ # Done if at SPACE, TAB or end, otherwise continue current fragment
+ #
+ next unless ($val =~ m{\G(?:[ \t]+|\z)}ogcs);
+ push @ret, join("", splice(@frag)) if (@frag > 0);
+ }
+ # Handle final fragment
+ push @ret, join("", splice(@frag)) if (@frag > 0);
+ return @ret;
+}
+
+sub split_val_win32 {
+ my ($val) = @_;
+ my (@ret, @frag);
+
+ # Skip leading whitespace
+ $val =~ m{\A[ \t]*}ogc;
+
+ # Windows-compatible split
+ # See: "Parsing C++ command-line arguments" in:
+ # https://learn.microsoft.com/en-us/cpp/cpp/main-function-command-line-args?view=msvc-170
+ #
+ # Backslashes are special only when followed by a double-quote
+ # Pairs of double-quotes make a single double-quote.
+ # Closing double-quotes may be omitted.
+
+ while (1) {
+ last if (pos($val) == length($val));
+
+ # The first char is never a SPACE or TAB.
+ # 1. Ordinary string fragment
+ # 2. Double-quoted string
+ # 3. Backslashes preceding a double-quote
+ # 4. Literal backslashes
+ # 5. Bare newline (rejected)
+ #
+ if ($val =~ m{\G([^" \t\n\\]+)}ogc) {
+ # Ordinary string
+ push @frag, $1;
+ } elsif ($val =~ m{\G"}ogc) {
+ # Double-quoted string
+ push @frag, "";
+ while (1) {
+ if ($val =~ m{\G("+)}ogc) {
+ # Two double-quotes make one literal double-quote
+ my $l = length($1);
+ push @frag, q{"} x int($l/2) if ($l > 1);
+ next if ($l % 2 == 0);
+ last;
+ }
+ if ($val =~ m{\G([^"\\]+)}ogc) {
+ push @frag, $1;
+ } elsif ($val =~ m{\G((?>[\\]+))(?=")}ogc) {
+ # Backslashes before a double-quote are escapes
+ my $l = length($1);
+ push @frag, q{\\} x int($l / 2);
+ if ($l % 2 == 1) {
+ ++pos($val);
+ push @frag, q{"};
+ }
+ } elsif ($val =~ m{\G((?:(?>[\\]+)[^"\\]+)+)}ogc) {
+ # Backslashes not before a double-quote are not special
+ push @frag, $1;
+ } else {
+ # Tolerate missing closing double-quote
+ last;
+ }
+ }
+ } elsif ($val =~ m{\G((?>[\\]+))(?=")}ogc) {
+ my $l = length($1);
+ push @frag, q{\\} x int($l / 2);
+ if ($l % 2 == 1) {
+ ++pos($val);
+ push @frag, q{"};
+ }
+ } elsif ($val =~ m{\G([\\]+)}ogc) {
+ # Backslashes not before a double-quote are not special
+ push @frag, $1;
+ } else {
+ die sprintf("Bare newline in: '%s'\n", $val);
+ }
+ # Done if at SPACE, TAB or end, otherwise continue current fragment
+ #
+ next unless ($val =~ m{\G(?:[ \t]+|\z)}ogcs);
+ push @ret, join("", splice(@frag)) if (@frag > 0);
+ }
+ # Handle final fragment
+ push @ret, join("", splice(@frag)) if (@frag);
+ return @ret;
+}
+
# Split out "-extra-CMD value", and return new |@ARGV|. Fill in
# |EXTRA{CMD}| with list of values.
sub parse_extra
{
+ my @args;
foreach ( @OPENSSL_CMDS ) {
- $EXTRA{$_} = '';
+ $EXTRA{$_} = [];
}
-
- my @result;
- while ( scalar(@_) > 0 ) {
- my $arg = shift;
- if ( $arg !~ m/-extra-([a-z0-9]+)/ ) {
- push @result, $arg;
+ while (@_) {
+ my $arg = shift(@_);
+ if ( $arg !~ m{^-extra-(\w+)$} ) {
+ push @args, split_val($arg);
next;
}
- $arg =~ s/-extra-//;
- die("Unknown \"-${arg}-extra\" option, exiting")
- unless scalar grep { $arg eq $_ } @OPENSSL_CMDS;
- $EXTRA{$arg} .= " " . shift;
+ $arg = $1;
+ die "Unknown \"-extra-${arg}\" option, exiting\n"
+ unless grep { $arg eq $_ } @OPENSSL_CMDS;
+ die "Missing \"-extra-${arg}\" option value, exiting\n"
+ unless (@_ > 0);
+ push @{$EXTRA{$arg}}, split_val(shift(@_));
}
- return @result;
+ return @args;
}
@@ -112,9 +261,9 @@ sub copy_pemfile
# Wrapper around system; useful for debugging. Returns just the exit status
sub run
{
- my $cmd = shift;
- print "====\n$cmd\n" if $verbose;
- my $status = system($cmd);
+ my ($cmd, @args) = @_;
+ print "====\n$cmd @args\n" if $verbose;
+ my $status = system {$cmd} $cmd, @args;
print "==> $status\n====\n" if $verbose;
return $status >> 8;
}
@@ -133,17 +282,15 @@ EOF
if ($WHAT eq '-newcert' ) {
# create a certificate
- $RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS"
- . " $EXTRA{req}");
+ $RET = run(@REQ, qw(-new -x509 -keyout), $NEWKEY, "-out", $NEWCERT, @DAYS, @{$EXTRA{req}});
print "Cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-precert' ) {
# create a pre-certificate
- $RET = run("$REQ -x509 -precert -keyout $NEWKEY -out $NEWCERT $DAYS"
- . " $EXTRA{req}");
+ $RET = run(@REQ, qw(-x509 -precert -keyout), $NEWKEY, "-out", $NEWCERT, @DAYS, @{$EXTRA{req}});
print "Pre-cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT =~ /^\-newreq(\-nodes)?$/ ) {
# create a certificate request
- $RET = run("$REQ -new $1 -keyout $NEWKEY -out $NEWREQ $DAYS $EXTRA{req}");
+ $RET = run(@REQ, "-new", (defined $1 ? ($1,) : ()), "-keyout", $NEWKEY, "-out", $NEWREQ, @{$EXTRA{req}});
print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-newca' ) {
# create the directory hierarchy
@@ -176,48 +323,45 @@ if ($WHAT eq '-newcert' ) {
copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
} else {
print "Making CA certificate ...\n";
- $RET = run("$REQ -new -keyout ${CATOP}/private/$CAKEY"
- . " -out ${CATOP}/$CAREQ $EXTRA{req}");
- $RET = run("$CA -create_serial"
- . " -out ${CATOP}/$CACERT $CADAYS -batch"
- . " -keyfile ${CATOP}/private/$CAKEY -selfsign"
- . " $EXTENSIONS"
- . " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0;
+ $RET = run(@REQ, qw(-new -keyout), "${CATOP}/private/$CAKEY",
+ "-out", "${CATOP}/$CAREQ", @{$EXTRA{req}});
+ $RET = run(@CA, qw(-create_serial -out), "${CATOP}/$CACERT", @CADAYS,
+ qw(-batch -keyfile), "${CATOP}/private/$CAKEY", "-selfsign",
+ @EXTENSIONS, "-infiles", "${CATOP}/$CAREQ", @{$EXTRA{ca}})
+ if $RET == 0;
print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0;
}
} elsif ($WHAT eq '-pkcs12' ) {
my $cname = $ARGV[0];
$cname = "My Certificate" unless defined $cname;
- $RET = run("$PKCS12 -in $NEWCERT -inkey $NEWKEY"
- . " -certfile ${CATOP}/$CACERT -out $NEWP12"
- . " -export -name \"$cname\" $EXTRA{pkcs12}");
- print "PKCS #12 file is in $NEWP12\n" if $RET == 0;
+ $RET = run(@PKCS12, "-in", $NEWCERT, "-inkey", $NEWKEY,
+ "-certfile", "${CATOP}/$CACERT", "-out", $NEWP12,
+ qw(-export -name), $cname, @{$EXTRA{pkcs12}});
+ print "PKCS#12 file is in $NEWP12\n" if $RET == 0;
} elsif ($WHAT eq '-xsign' ) {
- $RET = run("$CA $POLICY -infiles $NEWREQ $EXTRA{ca}");
+ $RET = run(@CA, @POLICY, "-infiles", $NEWREQ, @{$EXTRA{ca}});
} elsif ($WHAT eq '-sign' ) {
- $RET = run("$CA $POLICY -out $NEWCERT"
- . " -infiles $NEWREQ $EXTRA{ca}");
+ $RET = run(@CA, @POLICY, "-out", $NEWCERT,
+ "-infiles", $NEWREQ, @{$EXTRA{ca}});
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-signCA' ) {
- $RET = run("$CA $POLICY -out $NEWCERT"
- . " $EXTENSIONS -infiles $NEWREQ $EXTRA{ca}");
+ $RET = run(@CA, @POLICY, "-out", $NEWCERT, @EXTENSIONS,
+ "-infiles", $NEWREQ, @{$EXTRA{ca}});
print "Signed CA certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-signcert' ) {
- $RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ"
- . " -out tmp.pem $EXTRA{x509}");
- $RET = run("$CA $POLICY -out $NEWCERT"
- . "-infiles tmp.pem $EXTRA{ca}") if $RET == 0;
+ $RET = run(@X509, qw(-x509toreq -in), $NEWREQ, "-signkey", $NEWREQ,
+ qw(-out tmp.pem), @{$EXTRA{x509}});
+ $RET = run(@CA, @POLICY, "-out", $NEWCERT,
+ qw(-infiles tmp.pem), @{$EXTRA{ca}}) if $RET == 0;
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-verify' ) {
my @files = @ARGV ? @ARGV : ( $NEWCERT );
foreach my $file (@files) {
- # -CAfile quoted for VMS, since the C RTL downcases all unquoted
- # arguments to C programs
- my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file $EXTRA{verify}");
+ my $status = run(@VERIFY, "-CAfile", "${CATOP}/$CACERT", $file, @{$EXTRA{verify}});
$RET = $status if $status != 0;
}
} elsif ($WHAT eq '-crl' ) {
- $RET = run("$CA -gencrl -out ${CATOP}/crl/$CACRL $EXTRA{ca}");
+ $RET = run(@CA, qw(-gencrl -out), "${CATOP}/crl/$CACRL", @{$EXTRA{ca}});
print "Generated CRL is in ${CATOP}/crl/$CACRL\n" if $RET == 0;
} elsif ($WHAT eq '-revoke' ) {
my $cname = $ARGV[0];
@@ -225,10 +369,10 @@ if ($WHAT eq '-newcert' ) {
print "Certificate filename is required; reason optional.\n";
exit 1;
}
- my $reason = $ARGV[1];
- $reason = " -crl_reason $reason"
- if defined $reason && crl_reason_ok($reason);
- $RET = run("$CA -revoke \"$cname\"" . $reason . $EXTRA{ca});
+ my @reason;
+ @reason = ("-crl_reason", $ARGV[1])
+ if defined $ARGV[1] && crl_reason_ok($ARGV[1]);
+ $RET = run(@CA, "-revoke", $cname, @reason, @{$EXTRA{ca}});
} else {
print STDERR "Unknown arg \"$WHAT\"\n";
print STDERR "Use -help for help.\n";
diff --git a/apps/asn1parse.c b/apps/asn1parse.c
index 4f882396d03d..4540d5f5fb6e 100644
--- a/apps/asn1parse.c
+++ b/apps/asn1parse.c
@@ -40,8 +40,8 @@ const OPTIONS asn1parse_options[] = {
{"length", OPT_LENGTH, 'p', "length of section in file"},
{"strparse", OPT_STRPARSE, 'p',
"offset; a series of these can be used to 'dig'"},
- {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"},
{OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"},
+ {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"},
{"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"},
{"strictpem", OPT_STRICTPEM, 0,
"equivalent to '-inform pem' (obsolete)"},
diff --git a/apps/cmp.c b/apps/cmp.c
index 291d62bfcb80..2b4340d9fb45 100644
--- a/apps/cmp.c
+++ b/apps/cmp.c
@@ -955,7 +955,7 @@ static int set_name(const char *str,
OSSL_CMP_CTX *ctx, const char *desc)
{
if (str != NULL) {
- X509_NAME *n = parse_name(str, MBSTRING_ASC, 1, desc);
+ X509_NAME *n = parse_name(str, MBSTRING_UTF8, 1, desc);
if (n == NULL)
return 0;
@@ -2506,6 +2506,7 @@ static int save_template(const char *file, const OSSL_CRMF_CERTTEMPLATE *tmpl)
bio, tmpl)) {
CMP_err1("error saving certTemplate from genp: cannot write file %s",
file);
+ BIO_free(bio);
return 0;
} else {
CMP_info1("stored certTemplate from genp to file '%s'", file);
@@ -2525,6 +2526,7 @@ static int save_keyspec(const char *file, const OSSL_CMP_ATAVS *keyspec)
if (!ASN1_i2d_bio_of(OSSL_CMP_ATAVS, i2d_OSSL_CMP_ATAVS, bio, keyspec)) {
CMP_err1("error saving keySpec from genp: cannot write file %s", file);
+ BIO_free(bio);
return 0;
} else {
CMP_info1("stored keySpec from genp to file '%s'", file);
diff --git a/apps/genpkey.c b/apps/genpkey.c
index eaca1e0dea63..b37a1526b441 100644
--- a/apps/genpkey.c
+++ b/apps/genpkey.c
@@ -302,12 +302,14 @@ int genpkey_main(int argc, char **argv)
if (mem_outpubkey != NULL) {
rv = mem_bio_to_file(mem_outpubkey, outpubkeyfile, outformat, private);
if (!rv)
- BIO_printf(bio_err, "Error writing to outpubkey: '%s'. Error: %s\n", outpubkeyfile, strerror(errno));
+ BIO_printf(bio_err, "Error writing to outpubkey: '%s'. Error: %s\n",
+ outpubkeyfile, strerror(errno));
}
if (mem_out != NULL) {
rv = mem_bio_to_file(mem_out, outfile, outformat, private);
if (!rv)
- BIO_printf(bio_err, "Error writing to outfile: '%s'. Error: %s\n", outpubkeyfile, strerror(errno));
+ BIO_printf(bio_err, "Error writing to outfile: '%s'. Error: %s\n",
+ outfile, strerror(errno));
}
}
EVP_PKEY_free(pkey);
diff --git a/apps/lib/s_socket.c b/apps/lib/s_socket.c
index f61b1b5c8268..b2a1e3e51a4b 100644
--- a/apps/lib/s_socket.c
+++ b/apps/lib/s_socket.c
@@ -173,8 +173,16 @@ int init_client(int *sock, const char *host, const char *port,
}
/* Save the address */
- if (tfo || !doconn)
+ if (tfo || !doconn) {
+ if (ba_ret == NULL) {
+ BIO_printf(bio_err, "Internal error\n");
+ BIO_closesocket(*sock);
+ *sock = INVALID_SOCKET;
+ goto out;
+ }
+
*ba_ret = BIO_ADDR_dup(BIO_ADDRINFO_address(ai));
+ }
/* Success, don't try any more addresses */
break;
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index 2d3fd6314476..79ad4c6f29f5 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -426,6 +426,7 @@ int pkeyutl_main(int argc, char **argv)
if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) {
BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",
prog, opt);
+ OPENSSL_free(passwd);
goto end;
}
OPENSSL_free(passwd);
diff --git a/apps/rand.c b/apps/rand.c
index b123a151ea74..da747c1783e4 100644
--- a/apps/rand.c
+++ b/apps/rand.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2025 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
@@ -199,7 +199,7 @@ int rand_main(int argc, char **argv)
int chunk;
chunk = scaled_num > buflen ? (int)buflen : (int)scaled_num;
- r = RAND_bytes(buf, chunk);
+ r = RAND_bytes_ex(app_get0_libctx(), buf, chunk, 0);
if (r <= 0)
goto end;
if (format != FORMAT_TEXT) {
diff --git a/apps/s_time.c b/apps/s_time.c
index 0d5bd1228729..598e1069ed05 100644
--- a/apps/s_time.c
+++ b/apps/s_time.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -323,8 +323,10 @@ int s_time_main(int argc, char **argv)
*/
next:
- if (!(perform & 2))
+ if (!(perform & 2)) {
+ ret = 0;
goto end;
+ }
printf("\n\nNow timing with session id reuse.\n");
/* Get an SSL object so we can reuse the session id */
diff --git a/apps/speed.c b/apps/speed.c
index f52f2c839d0d..6c1eb59e91ee 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -507,7 +507,7 @@ static size_t kems_algs_len = 0;
static char *kems_algname[MAX_KEM_NUM] = { NULL };
static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
-#define MAX_SIG_NUM 111
+#define MAX_SIG_NUM 256
static size_t sigs_algs_len = 0;
static char *sigs_algname[MAX_SIG_NUM] = { NULL };
static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
@@ -573,12 +573,12 @@ typedef struct loopargs_st {
unsigned char *kem_out[MAX_KEM_NUM];
unsigned char *kem_send_secret[MAX_KEM_NUM];
unsigned char *kem_rcv_secret[MAX_KEM_NUM];
- EVP_PKEY_CTX *sig_gen_ctx[MAX_KEM_NUM];
- EVP_PKEY_CTX *sig_sign_ctx[MAX_KEM_NUM];
- EVP_PKEY_CTX *sig_verify_ctx[MAX_KEM_NUM];
- size_t sig_max_sig_len[MAX_KEM_NUM];
- size_t sig_act_sig_len[MAX_KEM_NUM];
- unsigned char *sig_sig[MAX_KEM_NUM];
+ EVP_PKEY_CTX *sig_gen_ctx[MAX_SIG_NUM];
+ EVP_PKEY_CTX *sig_sign_ctx[MAX_SIG_NUM];
+ EVP_PKEY_CTX *sig_verify_ctx[MAX_SIG_NUM];
+ size_t sig_max_sig_len[MAX_SIG_NUM];
+ size_t sig_act_sig_len[MAX_SIG_NUM];
+ unsigned char *sig_sig[MAX_SIG_NUM];
} loopargs_t;
static int run_benchmark(int async_jobs, int (*loop_function) (void *),
loopargs_t *loopargs);
diff --git a/apps/storeutl.c b/apps/storeutl.c
index b131278a8592..62f0e6135640 100644
--- a/apps/storeutl.c
+++ b/apps/storeutl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -201,9 +201,7 @@ int storeutl_main(int argc, char *argv[])
}
break;
case OPT_CRITERION_FINGERPRINT:
- if (criterion != 0
- || (criterion == OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT
- && fingerprint != NULL)) {
+ if (criterion != 0) {
BIO_printf(bio_err, "%s: criterion already given.\n",
prog);
goto end;
diff --git a/apps/x509.c b/apps/x509.c
index fdae8f383a66..3bd6564ec815 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -447,26 +447,26 @@ int x509_main(int argc, char **argv)
break;
case OPT_ADDTRUST:
if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL)
- goto end;
+ goto err;
if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
BIO_printf(bio_err, "%s: Invalid trust object value %s\n",
prog, opt_arg());
goto opthelp;
}
if (!sk_ASN1_OBJECT_push(trust, objtmp))
- goto end;
+ goto err;
trustout = 1;
break;
case OPT_ADDREJECT:
if (reject == NULL && (reject = sk_ASN1_OBJECT_new_null()) == NULL)
- goto end;
+ goto err;
if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
BIO_printf(bio_err, "%s: Invalid reject object value %s\n",
prog, opt_arg());
goto opthelp;
}
- if (!sk_ASN1_OBJECT_push(trust, objtmp))
- goto end;
+ if (!sk_ASN1_OBJECT_push(reject, objtmp))
+ goto err;
trustout = 1;
break;
case OPT_SETALIAS:
@@ -618,7 +618,7 @@ int x509_main(int argc, char **argv)
goto opthelp;
if (!app_RAND_load())
- goto end;
+ goto err;
if (!opt_check_md(digest))
goto opthelp;
@@ -647,7 +647,7 @@ int x509_main(int argc, char **argv)
if (!X509_STORE_set_default_paths_ex(ctx, app_get0_libctx(),
app_get0_propq()))
- goto end;
+ goto err;
if (newcert && infile != NULL) {
BIO_printf(bio_err, "The -in option cannot be used with -new\n");
@@ -660,12 +660,12 @@ int x509_main(int argc, char **argv)
if (privkeyfile != NULL) {
privkey = load_key(privkeyfile, keyformat, 0, passin, e, "private key");
if (privkey == NULL)
- goto end;
+ goto err;
}
if (pubkeyfile != NULL) {
if ((pubkey = load_pubkey(pubkeyfile, keyformat, 0, NULL, e,
"explicitly set public key")) == NULL)
- goto end;
+ goto err;
}
if (newcert) {
@@ -682,10 +682,10 @@ int x509_main(int argc, char **argv)
}
if (issu != NULL
&& (fissu = parse_name(issu, chtype, multirdn, "issuer")) == NULL)
- goto end;
+ goto err;
if (subj != NULL
&& (fsubj = parse_name(subj, chtype, multirdn, "subject")) == NULL)
- goto end;
+ goto err;
if (CAkeyfile == NULL)
CAkeyfile = CAfile;
@@ -717,7 +717,7 @@ int x509_main(int argc, char **argv)
X509V3_CTX ctx2;
if ((extconf = app_load_config(extfile)) == NULL)
- goto end;
+ goto err;
if (extsect == NULL) {
extsect = app_conf_try_string(extconf, "default", "extensions");
if (extsect == NULL)
@@ -739,7 +739,7 @@ int x509_main(int argc, char **argv)
req = load_csr_autofmt(infile, informat, vfyopts,
"certificate request input");
if (req == NULL)
- goto end;
+ goto err;
if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
BIO_printf(bio_err, "Error unpacking public key from CSR\n");
@@ -770,11 +770,11 @@ int x509_main(int argc, char **argv)
goto err;
}
if ((x = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
- goto end;
+ goto err;
if (CAfile == NULL && sno == NULL) {
sno = ASN1_INTEGER_new();
if (sno == NULL || !rand_serial(NULL, sno))
- goto end;
+ goto err;
}
if (req != NULL && ext_copy != EXT_COPY_UNSET) {
if (clrext && ext_copy != EXT_COPY_NONE) {
@@ -791,27 +791,27 @@ int x509_main(int argc, char **argv)
"Warning: Reading certificate from stdin since no -in or -new option is given\n");
x = load_cert_pass(infile, informat, 1, passin, "certificate");
if (x == NULL)
- goto end;
+ goto err;
}
if ((fsubj != NULL || req != NULL)
&& !X509_set_subject_name(x, fsubj != NULL ? fsubj :
X509_REQ_get_subject_name(req)))
- goto end;
+ goto err;
if ((pubkey != NULL || privkey != NULL || req != NULL)
&& !X509_set_pubkey(x, pubkey != NULL ? pubkey :
privkey != NULL ? privkey :
X509_REQ_get0_pubkey(req)))
- goto end;
+ goto err;
if (CAfile != NULL) {
xca = load_cert_pass(CAfile, CAformat, 1, passin, "CA certificate");
if (xca == NULL)
- goto end;
+ goto err;
}
out = bio_open_default(outfile, 'w', outformat);
if (out == NULL)
- goto end;
+ goto err;
if (alias)
X509_alias_set1(x, (unsigned char *)alias, -1);
@@ -847,9 +847,9 @@ int x509_main(int argc, char **argv)
if (sno == NULL)
sno = x509_load_serial(CAfile, CAserial, CA_createserial);
if (sno == NULL)
- goto end;
+ goto err;
if (!x509toreq && !reqfile && !newcert && !self_signed(ctx, x))
- goto end;
+ goto err;
} else {
if (privkey != NULL && !cert_matches_key(x, privkey))
BIO_printf(bio_err,
@@ -857,17 +857,17 @@ int x509_main(int argc, char **argv)
}
if (sno != NULL && !X509_set_serialNumber(x, sno))
- goto end;
+ goto err;
if (reqfile || newcert || privkey != NULL || CAfile != NULL) {
if (!preserve_dates && !set_cert_times(x, not_before, not_after, days, 1))
- goto end;
+ goto err;
if (fissu != NULL) {
if (!X509_set_issuer_name(x, fissu))
- goto end;
+ goto err;
} else {
if (!X509_set_issuer_name(x, X509_get_subject_name(issuer_cert)))
- goto end;
+ goto err;
}
}
@@ -875,7 +875,7 @@ int x509_main(int argc, char **argv)
/* prepare fallback for AKID, but only if issuer cert equals subject cert */
if (CAfile == NULL) {
if (!X509V3_set_issuer_pkey(&ext_ctx, privkey))
- goto end;
+ goto err;
}
if (extconf != NULL && !x509toreq) {
X509V3_set_nconf(&ext_ctx, extconf);
@@ -904,7 +904,7 @@ int x509_main(int argc, char **argv)
goto err;
}
if ((rq = x509_to_req(x, ext_copy, ext_names)) == NULL)
- goto end;
+ goto err;
if (extconf != NULL) {
X509V3_set_nconf(&ext_ctx, extconf);
if (!X509V3_EXT_REQ_add_nconf(extconf, &ext_ctx, extsect, rq)) {
@@ -914,7 +914,7 @@ int x509_main(int argc, char **argv)
}
}
if (!do_X509_REQ_sign(rq, privkey, digest, sigopts))
- goto end;
+ goto err;
if (!noout) {
if (outformat == FORMAT_ASN1) {
X509_REQ_print_ex(out, rq, get_nameopt(), X509_FLAG_COMPAT);
@@ -932,7 +932,7 @@ int x509_main(int argc, char **argv)
} else if (CAfile != NULL) {
if ((CAkey = load_key(CAkeyfile, CAkeyformat,
0, passin, e, "CA private key")) == NULL)
- goto end;
+ goto err;
if (!X509_check_private_key(xca, CAkey)) {
BIO_printf(bio_err,
"CA certificate and CA private key do not match\n");
@@ -940,10 +940,10 @@ int x509_main(int argc, char **argv)
}
if (!do_X509_sign(x, 0, CAkey, digest, sigopts, &ext_ctx))
- goto end;
+ goto err;
} else if (privkey != NULL) {
if (!do_X509_sign(x, 0, privkey, digest, sigopts, &ext_ctx))
- goto end;
+ goto err;
}
if (badsig) {
const ASN1_BIT_STRING *signature;
@@ -967,11 +967,11 @@ int x509_main(int argc, char **argv)
BIGNUM *bnser = ASN1_INTEGER_to_BN(X509_get0_serialNumber(x), NULL);
if (bnser == NULL)
- goto end;
+ goto err;
if (!BN_add_word(bnser, 1)
|| (ser = BN_to_ASN1_INTEGER(bnser, NULL)) == NULL) {
BN_free(bnser);
- goto end;
+ goto err;
}
BN_free(bnser);
i2a_ASN1_INTEGER(out, ser);
diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl
index 4f503a31ca67..af501f8ff573 100755
--- a/crypto/aes/asm/aesv8-armx.pl
+++ b/crypto/aes/asm/aesv8-armx.pl
@@ -152,7 +152,7 @@ $code.=<<___ if ($flavour =~ /64/);
adrp $ptr,.Lrcon
add $ptr,$ptr,:lo12:.Lrcon
___
-$code.=<<___ if ($flavour =~ /32/);
+$code.=<<___ if ($flavour !~ /64/);
adr $ptr,.Lrcon
___
$code.=<<___;
diff --git a/crypto/bio/bio_dump.c b/crypto/bio/bio_dump.c
index 40c18410e4cf..cd489142bb70 100644
--- a/crypto/bio/bio_dump.c
+++ b/crypto/bio/bio_dump.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -47,6 +47,8 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
for (i = 0; i < rows; i++) {
n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "",
i * dump_width);
+ if (n < 0)
+ return -1;
for (j = 0; j < dump_width; j++) {
if (SPACE(buf, n, 3)) {
if (((i * dump_width) + j) >= len) {
diff --git a/crypto/bio/bio_print.c b/crypto/bio/bio_print.c
index 5f2543030e54..55fb4877b4c5 100644
--- a/crypto/bio/bio_print.c
+++ b/crypto/bio/bio_print.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -535,6 +535,10 @@ static LDOUBLE abs_val(LDOUBLE value)
LDOUBLE result = value;
if (value < 0)
result = -value;
+ if (result > 0 && result / 2 == result) /* INF */
+ result = 0;
+ else if (result != result) /* NAN */
+ result = 0;
return result;
}
@@ -590,6 +594,9 @@ fmtfp(char **sbuffer,
signvalue = '+';
else if (flags & DP_F_SPACE)
signvalue = ' ';
+ ufvalue = abs_val(fvalue);
+ if (ufvalue == 0 && fvalue != 0) /* INF or NAN? */
+ signvalue = '?';
/*
* G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
@@ -597,12 +604,12 @@ fmtfp(char **sbuffer,
* that from here on.
*/
if (style == G_FORMAT) {
- if (fvalue == 0.0) {
+ if (ufvalue == 0.0) {
realstyle = F_FORMAT;
- } else if (fvalue < 0.0001) {
+ } else if (ufvalue < 0.0001) {
realstyle = E_FORMAT;
- } else if ((max == 0 && fvalue >= 10)
- || (max > 0 && fvalue >= pow_10(max))) {
+ } else if ((max == 0 && ufvalue >= 10)
+ || (max > 0 && ufvalue >= pow_10(max))) {
realstyle = E_FORMAT;
} else {
realstyle = F_FORMAT;
@@ -612,9 +619,9 @@ fmtfp(char **sbuffer,
}
if (style != F_FORMAT) {
- tmpvalue = fvalue;
+ tmpvalue = ufvalue;
/* Calculate the exponent */
- if (fvalue != 0.0) {
+ if (ufvalue != 0.0) {
while (tmpvalue < 1) {
tmpvalue *= 10;
exp--;
@@ -651,9 +658,9 @@ fmtfp(char **sbuffer,
}
}
if (realstyle == E_FORMAT)
- fvalue = tmpvalue;
+ ufvalue = tmpvalue;
}
- ufvalue = abs_val(fvalue);
+
/*
* By subtracting 65535 (2^16-1) we cancel the low order 15 bits
* of ULONG_MAX to avoid using imprecise floating point values.
diff --git a/crypto/bn/asm/rsaz-2k-avxifma.pl b/crypto/bn/asm/rsaz-2k-avxifma.pl
index 65710eac3ec4..0c962f248dd9 100644
--- a/crypto/bn/asm/rsaz-2k-avxifma.pl
+++ b/crypto/bn/asm/rsaz-2k-avxifma.pl
@@ -27,7 +27,6 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-# TODO: Find out the version of NASM that supports VEX-encoded AVX-IFMA instructions
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$avxifma = ($1>=2.40);
@@ -39,6 +38,11 @@ if (!$avxifma && `$ENV{CC} -v 2>&1`
$avxifma = ($ver>=16.0);
}
+if ($win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
+ `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?(rc[0-9]+)?/) {
+ $avxifma = ($1>2.16) + ($1==2.16 && ((!defined($2) && !defined($3)) || (defined($2))));
+}
+
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -296,34 +300,34 @@ $code.=<<___;
and \$0xf, %r14
vpsubq .Lmask52x4(%rip), $_R0, $T0
shl \$5, %r14
- vmovapd (%rdx, %r14), $T1
+ vmovapd (%rdx,%r14), $T1
vblendvpd $T1, $T0, $_R0, $_R0
shr \$4, %r13b
and \$0xf, %r13
vpsubq .Lmask52x4(%rip), $_R0h, $T0
shl \$5, %r13
- vmovapd (%rdx, %r13), $T1
+ vmovapd (%rdx,%r13), $T1
vblendvpd $T1, $T0, $_R0h, $_R0h
mov %r12b, %r11b
and \$0xf, %r12
vpsubq .Lmask52x4(%rip), $_R1, $T0
shl \$5, %r12
- vmovapd (%rdx, %r12), $T1
+ vmovapd (%rdx,%r12), $T1
vblendvpd $T1, $T0, $_R1, $_R1
shr \$4, %r11b
and \$0xf, %r11
vpsubq .Lmask52x4(%rip), $_R1h, $T0
shl \$5, %r11
- vmovapd (%rdx, %r11), $T1
+ vmovapd (%rdx,%r11), $T1
vblendvpd $T1, $T0, $_R1h, $_R1h
and \$0xf, %r10
vpsubq .Lmask52x4(%rip), $_R2, $T0
shl \$5, %r10
- vmovapd (%rdx, %r10), $T1
+ vmovapd (%rdx,%r10), $T1
vblendvpd $T1, $T0, $_R2, $_R2
# Add carries according to the obtained mask
diff --git a/crypto/bn/asm/rsaz-3k-avxifma.pl b/crypto/bn/asm/rsaz-3k-avxifma.pl
index 64c00c10e325..a19cb5aaa309 100644
--- a/crypto/bn/asm/rsaz-3k-avxifma.pl
+++ b/crypto/bn/asm/rsaz-3k-avxifma.pl
@@ -27,7 +27,6 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-# TODO: Find out the version of NASM that supports VEX-encoded AVX-IFMA instructions
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$avxifma = ($1>=2.40);
@@ -39,6 +38,11 @@ if (!$avxifma && `$ENV{CC} -v 2>&1`
$avxifma = ($ver>=16.0);
}
+if ($win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
+ `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?(rc[0-9]+)?/) {
+ $avxifma = ($1>2.16) + ($1==2.16 && ((!defined($2) && !defined($3)) || (defined($2))));
+}
+
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -355,56 +359,56 @@ $code.=<<___;
and \$0xf, %r14
vpsubq .Lmask52x4(%rip), $_R0, $T0
shl \$5, %r14
- vmovapd (%rdx, %r14), $T1
+ vmovapd (%rdx,%r14), $T1
vblendvpd $T1, $T0, $_R0, $_R0
shr \$4, %r10b
and \$0xf, %r10
vpsubq .Lmask52x4(%rip), $_R0h, $T0
shl \$5, %r10
- vmovapd (%rdx, %r10), $T1
+ vmovapd (%rdx,%r10), $T1
vblendvpd $T1, $T0, $_R0h, $_R0h
mov %r13b, %r10b
and \$0xf, %r13
vpsubq .Lmask52x4(%rip), $_R1, $T0
shl \$5, %r13
- vmovapd (%rdx, %r13), $T1
+ vmovapd (%rdx,%r13), $T1
vblendvpd $T1, $T0, $_R1, $_R1
shr \$4, %r10b
and \$0xf, %r10
vpsubq .Lmask52x4(%rip), $_R1h, $T0
shl \$5, %r10
- vmovapd (%rdx, %r10), $T1
+ vmovapd (%rdx,%r10), $T1
vblendvpd $T1, $T0, $_R1h, $_R1h
mov %r12b, %r10b
and \$0xf, %r12
vpsubq .Lmask52x4(%rip), $_R2, $T0
shl \$5, %r12
- vmovapd (%rdx, %r12), $T1
+ vmovapd (%rdx,%r12), $T1
vblendvpd $T1, $T0, $_R2, $_R2
shr \$4, %r10b
and \$0xf, %r10
vpsubq .Lmask52x4(%rip), $_R2h, $T0
shl \$5, %r10
- vmovapd (%rdx, %r10), $T1
+ vmovapd (%rdx,%r10), $T1
vblendvpd $T1, $T0, $_R2h, $_R2h
mov %r11b, %r10b
and \$0xf, %r11
vpsubq .Lmask52x4(%rip), $_R3, $T0
shl \$5, %r11
- vmovapd (%rdx, %r11), $T1
+ vmovapd (%rdx,%r11), $T1
vblendvpd $T1, $T0, $_R3, $_R3
shr \$4, %r10b
and \$0xf, %r10
vpsubq .Lmask52x4(%rip), $_R3h, $T0
shl \$5, %r10
- vmovapd (%rdx, %r10), $T1
+ vmovapd (%rdx,%r10), $T1
vblendvpd $T1, $T0, $_R3h, $_R3h
vpand .Lmask52x4(%rip), $_R0, $_R0
diff --git a/crypto/bn/asm/rsaz-4k-avxifma.pl b/crypto/bn/asm/rsaz-4k-avxifma.pl
index 5de6a4c4c2b2..f15e2d74118c 100644
--- a/crypto/bn/asm/rsaz-4k-avxifma.pl
+++ b/crypto/bn/asm/rsaz-4k-avxifma.pl
@@ -27,7 +27,6 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-# TODO: Find out the version of NASM that supports VEX-encoded AVX-IFMA instructions
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
$avxifma = ($1>=2.40);
@@ -39,6 +38,11 @@ if (!$avxifma && `$ENV{CC} -v 2>&1`
$avxifma = ($ver>=16.0);
}
+if ($win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
+ `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?(rc[0-9]+)?/) {
+ $avxifma = ($1>2.16) + ($1==2.16 && ((!defined($2) && !defined($3)) || (defined($2))));
+}
+
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -424,70 +428,70 @@ $code.=<<___;
and \$0xf, %r14
vpsubq .Lmask52x4(%rip), $_R0, $tmp
shl \$5, %r14
- vmovapd (%r8, %r14), $tmp2
+ vmovapd (%r8,%r14), $tmp2
vblendvpd $tmp2, $tmp, $_R0, $_R0
shr \$4, %r9b
and \$0xf, %r9
vpsubq .Lmask52x4(%rip), $_R0h, $tmp
shl \$5, %r9
- vmovapd (%r8, %r9), $tmp2
+ vmovapd (%r8,%r9), $tmp2
vblendvpd $tmp2, $tmp, $_R0h, $_R0h
movb %r13b,%r9b
and \$0xf, %r13
vpsubq .Lmask52x4(%rip), $_R1, $tmp
shl \$5, %r13
- vmovapd (%r8, %r13), $tmp2
+ vmovapd (%r8,%r13), $tmp2
vblendvpd $tmp2, $tmp, $_R1, $_R1
shr \$4, %r9b
and \$0xf, %r9
vpsubq .Lmask52x4(%rip), $_R1h, $tmp
shl \$5, %r9
- vmovapd (%r8, %r9), $tmp2
+ vmovapd (%r8,%r9), $tmp2
vblendvpd $tmp2, $tmp, $_R1h, $_R1h
movb %r12b,%r9b
and \$0xf, %r12
vpsubq .Lmask52x4(%rip), $_R2, $tmp
shl \$5, %r12
- vmovapd (%r8, %r12), $tmp2
+ vmovapd (%r8,%r12), $tmp2
vblendvpd $tmp2, $tmp, $_R2, $_R2
shr \$4, %r9b
and \$0xf, %r9
vpsubq .Lmask52x4(%rip), $_R2h, $tmp
shl \$5, %r9
- vmovapd (%r8, %r9), $tmp2
+ vmovapd (%r8,%r9), $tmp2
vblendvpd $tmp2, $tmp, $_R2h, $_R2h
movb %r11b,%r9b
and \$0xf, %r11
vpsubq .Lmask52x4(%rip), $_R3, $tmp
shl \$5, %r11
- vmovapd (%r8, %r11), $tmp2
+ vmovapd (%r8,%r11), $tmp2
vblendvpd $tmp2, $tmp, $_R3, $_R3
shr \$4, %r9b
and \$0xf, %r9
vpsubq .Lmask52x4(%rip), $_R3h, $tmp
shl \$5, %r9
- vmovapd (%r8, %r9), $tmp2
+ vmovapd (%r8,%r9), $tmp2
vblendvpd $tmp2, $tmp, $_R3h, $_R3h
movb %r10b,%r9b
and \$0xf, %r10
vpsubq .Lmask52x4(%rip), $_R4, $tmp
shl \$5, %r10
- vmovapd (%r8, %r10), $tmp2
+ vmovapd (%r8,%r10), $tmp2
vblendvpd $tmp2, $tmp, $_R4, $_R4
shr \$4, %r9b
and \$0xf, %r9
vpsubq .Lmask52x4(%rip), $_R4h, $tmp
shl \$5, %r9
- vmovapd (%r8, %r9), $tmp2
+ vmovapd (%r8,%r9), $tmp2
vblendvpd $tmp2, $tmp, $_R4h, $_R4h
pop %r8
diff --git a/crypto/chacha/asm/chacha-armv8-sve.pl b/crypto/chacha/asm/chacha-armv8-sve.pl
index 705917fb52c5..62a8be6fe12c 100755
--- a/crypto/chacha/asm/chacha-armv8-sve.pl
+++ b/crypto/chacha/asm/chacha-armv8-sve.pl
@@ -248,9 +248,6 @@ sub load_regs() {
my $next_offset = $offset + 1;
$code.=<<___;
ld1w {$reg.s},p0/z,[$inp,#$offset,MUL VL]
-#ifdef __AARCH64EB__
- revb $reg.s,p0/m,$reg.s
-#endif
___
if (@_) {
&load_regs($next_offset, @_);
@@ -272,9 +269,6 @@ sub store_regs() {
my $reg = shift;
my $next_offset = $offset + 1;
$code.=<<___;
-#ifdef __AARCH64EB__
- revb $reg.s,p0/m,$reg.s
-#endif
st1w {$reg.s},p0,[$outp,#$offset,MUL VL]
___
if (@_) {
@@ -480,13 +474,29 @@ sub SVE_TRANSFORMS() {
$code.=<<___;
#ifdef __AARCH64EB__
rev @sxx[0],@sxx[0]
+ revb @mx[0].s,p0/m,@mx[0].s
+ revb @mx[1].s,p0/m,@mx[1].s
rev @sxx[2],@sxx[2]
+ revb @mx[2].s,p0/m,@mx[2].s
+ revb @mx[3].s,p0/m,@mx[3].s
rev @sxx[4],@sxx[4]
+ revb @mx[4].s,p0/m,@mx[4].s
+ revb @mx[5].s,p0/m,@mx[5].s
rev @sxx[6],@sxx[6]
+ revb @mx[6].s,p0/m,@mx[6].s
+ revb @mx[7].s,p0/m,@mx[7].s
rev @sxx[8],@sxx[8]
+ revb @mx[8].s,p0/m,@mx[8].s
+ revb @mx[9].s,p0/m,@mx[9].s
rev @sxx[10],@sxx[10]
+ revb @mx[10].s,p0/m,@mx[10].s
+ revb @mx[11].s,p0/m,@mx[11].s
rev @sxx[12],@sxx[12]
+ revb @mx[12].s,p0/m,@mx[12].s
+ revb @mx[13].s,p0/m,@mx[13].s
rev @sxx[14],@sxx[14]
+ revb @mx[14].s,p0/m,@mx[14].s
+ revb @mx[15].s,p0/m,@mx[15].s
#endif
.if mixin == 1
add @K[6],@K[6],#1
diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c
index c0226e562a32..d20ea618d84f 100644
--- a/crypto/cmp/cmp_http.c
+++ b/crypto/cmp/cmp_http.c
@@ -81,11 +81,11 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
path++;
if (bios == NULL)
ossl_cmp_log4(DEBUG, ctx,
- "connecting to CMP server via http%s://%s:%s%s/%s",
+ "connecting to CMP server via http%s://%s:%s/%s",
tls_used ? "s" : "", ctx->server, server_port, path);
else
ossl_cmp_log3(DEBUG, ctx,
- "using existing connection with CMP server %s%s and HTTP path /%s",
+ "using existing connection with CMP server %s:%s and HTTP path /%s",
ctx->server, server_port, path);
}
diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index f36f070fa2ab..4b1380a6f2dc 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -13,7 +13,7 @@
#include "internal/sizes.h"
#include "crypto/context.h"
-#define NAMEMAP_HT_BUCKETS 2048
+#define NAMEMAP_HT_BUCKETS 512
HT_START_KEY_DEFN(namenum_key)
HT_DEF_KEY_FIELD_CHAR_ARRAY(name, 64)
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index ae23f61839ea..2d899dc96f67 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -16,6 +16,7 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/bn.h>
+#include <openssl/self_test.h>
#include "dh_local.h"
#include "crypto/dh.h"
@@ -329,17 +330,27 @@ end:
* FFC pairwise check from SP800-56A R3.
* Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency
*/
-int ossl_dh_check_pairwise(const DH *dh)
+int ossl_dh_check_pairwise(const DH *dh, int return_on_null_numbers)
{
int ret = 0;
BN_CTX *ctx = NULL;
BIGNUM *pub_key = NULL;
+ OSSL_SELF_TEST *st = NULL;
+ OSSL_CALLBACK *stcb = NULL;
+ void *stcbarg = NULL;
if (dh->params.p == NULL
|| dh->params.g == NULL
|| dh->priv_key == NULL
|| dh->pub_key == NULL)
- return 0;
+ return return_on_null_numbers;
+
+ OSSL_SELF_TEST_get_callback(dh->libctx, &stcb, &stcbarg);
+ st = OSSL_SELF_TEST_new(stcb, stcbarg);
+ if (st == NULL)
+ goto err;
+ OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
+ OSSL_SELF_TEST_DESC_PCT_DH);
ctx = BN_CTX_new_ex(dh->libctx);
if (ctx == NULL)
@@ -351,10 +362,27 @@ int ossl_dh_check_pairwise(const DH *dh)
/* recalculate the public key = (g ^ priv) mod p */
if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key))
goto err;
+
+#ifdef FIPS_MODULE
+ {
+ int len;
+ unsigned char bytes[1024] = {0}; /* Max key size of 8192 bits */
+
+ if (BN_num_bytes(pub_key) > (int)sizeof(bytes))
+ goto err;
+ len = BN_bn2bin(pub_key, bytes);
+ OSSL_SELF_TEST_oncorrupt_byte(st, bytes);
+ if (BN_bin2bn(bytes, len, pub_key) == NULL)
+ goto err;
+ }
+#endif
/* check it matches the existing public_key */
ret = BN_cmp(pub_key, dh->pub_key) == 0;
-err:
+ err:
BN_free(pub_key);
BN_CTX_free(ctx);
+
+ OSSL_SELF_TEST_onend(st, ret);
+ OSSL_SELF_TEST_free(st);
return ret;
}
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
index c11ada98267c..3b75a537b3e0 100644
--- a/crypto/dh/dh_pmeth.c
+++ b/crypto/dh/dh_pmeth.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2025 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
@@ -422,7 +422,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
ret = DH_compute_key_padded(key, dhpubbn, dh);
else
ret = DH_compute_key(key, dhpubbn, dh);
- if (ret < 0)
+ if (ret <= 0)
return ret;
*keylen = ret;
return 1;
diff --git a/crypto/ec/ecp_nistp384.c b/crypto/ec/ecp_nistp384.c
index 2ceb94fe33b7..9d682f5a02cc 100644
--- a/crypto/ec/ecp_nistp384.c
+++ b/crypto/ec/ecp_nistp384.c
@@ -684,6 +684,22 @@ static void felem_reduce_ref(felem out, const widefelem in)
out[i] = acc[i];
}
+static ossl_inline void felem_square_reduce_ref(felem out, const felem in)
+{
+ widefelem tmp;
+
+ felem_square_ref(tmp, in);
+ felem_reduce_ref(out, tmp);
+}
+
+static ossl_inline void felem_mul_reduce_ref(felem out, const felem in1, const felem in2)
+{
+ widefelem tmp;
+
+ felem_mul_ref(tmp, in1, in2);
+ felem_reduce_ref(out, tmp);
+}
+
#if defined(ECP_NISTP384_ASM)
static void felem_square_wrapper(widefelem out, const felem in);
static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2);
@@ -695,10 +711,18 @@ static void (*felem_mul_p)(widefelem out, const felem in1, const felem in2) =
static void (*felem_reduce_p)(felem out, const widefelem in) = felem_reduce_ref;
+static void (*felem_square_reduce_p)(felem out, const felem in) =
+ felem_square_reduce_ref;
+static void (*felem_mul_reduce_p)(felem out, const felem in1, const felem in2) =
+ felem_mul_reduce_ref;
+
void p384_felem_square(widefelem out, const felem in);
void p384_felem_mul(widefelem out, const felem in1, const felem in2);
void p384_felem_reduce(felem out, const widefelem in);
+void p384_felem_square_reduce(felem out, const felem in);
+void p384_felem_mul_reduce(felem out, const felem in1, const felem in2);
+
# if defined(_ARCH_PPC64)
# include "crypto/ppc_arch.h"
# endif
@@ -710,6 +734,8 @@ static void felem_select(void)
felem_square_p = p384_felem_square;
felem_mul_p = p384_felem_mul;
felem_reduce_p = p384_felem_reduce;
+ felem_square_reduce_p = p384_felem_square_reduce;
+ felem_mul_reduce_p = p384_felem_mul_reduce;
return;
}
@@ -718,7 +744,9 @@ static void felem_select(void)
/* Default */
felem_square_p = felem_square_ref;
felem_mul_p = felem_mul_ref;
- felem_reduce_p = p384_felem_reduce;
+ felem_reduce_p = felem_reduce_ref;
+ felem_square_reduce_p = felem_square_reduce_ref;
+ felem_mul_reduce_p = felem_mul_reduce_ref;
}
static void felem_square_wrapper(widefelem out, const felem in)
@@ -737,31 +765,15 @@ static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2)
# define felem_mul felem_mul_p
# define felem_reduce felem_reduce_p
-void p384_felem_square_reduce(felem out, const felem in);
-void p384_felem_mul_reduce(felem out, const felem in1, const felem in2);
-
-# define felem_square_reduce p384_felem_square_reduce
-# define felem_mul_reduce p384_felem_mul_reduce
+# define felem_square_reduce felem_square_reduce_p
+# define felem_mul_reduce felem_mul_reduce_p
#else
# define felem_square felem_square_ref
# define felem_mul felem_mul_ref
# define felem_reduce felem_reduce_ref
-static ossl_inline void felem_square_reduce(felem out, const felem in)
-{
- widefelem tmp;
-
- felem_square(tmp, in);
- felem_reduce(out, tmp);
-}
-
-static ossl_inline void felem_mul_reduce(felem out, const felem in1, const felem in2)
-{
- widefelem tmp;
-
- felem_mul(tmp, in1, in2);
- felem_reduce(out, tmp);
-}
+# define felem_square_reduce felem_square_reduce_ref
+# define felem_mul_reduce felem_mul_reduce_ref
#endif
/*-
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
index ffcf3cde1155..dedfb24e569e 100644
--- a/crypto/encode_decode/decoder_lib.c
+++ b/crypto/encode_decode/decoder_lib.c
@@ -537,6 +537,14 @@ static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg)
}
}
+static int decoder_sk_cmp(const OSSL_DECODER_INSTANCE *const *a,
+ const OSSL_DECODER_INSTANCE *const *b)
+{
+ if ((*a)->score == (*b)->score)
+ return (*a)->order - (*b)->order;
+ return (*a)->score - (*b)->score;
+}
+
int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
OSSL_LIB_CTX *libctx, const char *propq)
{
@@ -595,6 +603,26 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders);
numdecoders = sk_OSSL_DECODER_num(skdecoders);
+ /*
+ * If there are provided or default properties, sort the initial decoder list
+ * by property matching score so that the highest scored provider is selected
+ * first.
+ */
+ if (propq != NULL || ossl_ctx_global_properties(libctx, 0) != NULL) {
+ int num_decoder_insts = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+ int i;
+ OSSL_DECODER_INSTANCE *di;
+ sk_OSSL_DECODER_INSTANCE_compfunc old_cmp =
+ sk_OSSL_DECODER_INSTANCE_set_cmp_func(ctx->decoder_insts, decoder_sk_cmp);
+
+ for (i = 0; i < num_decoder_insts; i++) {
+ di = sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+ di->order = i;
+ }
+ sk_OSSL_DECODER_INSTANCE_sort(ctx->decoder_insts);
+ sk_OSSL_DECODER_INSTANCE_set_cmp_func(ctx->decoder_insts, old_cmp);
+ }
+
memset(&data, 0, sizeof(data));
data.ctx = ctx;
data.w_prev_start = 0;
diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c
index f99566bde744..9fc4e2312331 100644
--- a/crypto/encode_decode/decoder_pkey.c
+++ b/crypto/encode_decode/decoder_pkey.c
@@ -222,15 +222,21 @@ struct collect_data_st {
int total; /* number of matching results */
char error_occurred;
char keytype_resolved;
+ OSSL_PROPERTY_LIST *pq;
STACK_OF(EVP_KEYMGMT) *keymgmts;
};
-static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
- void *provctx, struct collect_data_st *data)
+/*
+ * Add decoder instance to the decoder context if it is compatible. Returns 1
+ * if a decoder was added, 0 otherwise.
+ */
+static int collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
+ void *provctx, struct collect_data_st *data)
{
void *decoderctx = NULL;
OSSL_DECODER_INSTANCE *di = NULL;
+ const OSSL_PROPERTY_LIST *props;
/*
* We already checked the EVP_KEYMGMT is applicable in check_keymgmt so we
@@ -239,17 +245,17 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
if (keymgmt->name_id != decoder->base.id)
/* Mismatch is not an error, continue. */
- return;
+ return 0;
if ((decoderctx = decoder->newctx(provctx)) == NULL) {
data->error_occurred = 1;
- return;
+ return 0;
}
if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) {
decoder->freectx(decoderctx);
data->error_occurred = 1;
- return;
+ return 0;
}
/*
@@ -263,7 +269,7 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
|| OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) {
/* Mismatch is not an error, continue. */
ossl_decoder_instance_free(di);
- return;
+ return 0;
}
OSSL_TRACE_BEGIN(DECODER) {
@@ -275,13 +281,30 @@ static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder,
OSSL_DECODER_get0_properties(decoder));
} OSSL_TRACE_END(DECODER);
+ /*
+ * Get the property match score so the decoders can be prioritized later.
+ */
+ props = ossl_decoder_parsed_properties(decoder);
+ if (data->pq != NULL && props != NULL) {
+ di->score = ossl_property_match_count(data->pq, props);
+ /*
+ * Mismatch of mandatory properties is not an error, the decoder is just
+ * ignored, continue.
+ */
+ if (di->score < 0) {
+ ossl_decoder_instance_free(di);
+ return 0;
+ }
+ }
+
if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) {
ossl_decoder_instance_free(di);
data->error_occurred = 1;
- return;
+ return 0;
}
++data->total;
+ return 1;
}
static void collect_decoder(OSSL_DECODER *decoder, void *arg)
@@ -321,7 +344,9 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
for (i = 0; i < end_i; ++i) {
keymgmt = sk_EVP_KEYMGMT_value(keymgmts, i);
- collect_decoder_keymgmt(keymgmt, decoder, provctx, data);
+ /* Only add this decoder once */
+ if (collect_decoder_keymgmt(keymgmt, decoder, provctx, data))
+ break;
if (data->error_occurred)
return;
}
@@ -407,6 +432,8 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
struct decoder_pkey_data_st *process_data = NULL;
struct collect_data_st collect_data = { NULL };
STACK_OF(EVP_KEYMGMT) *keymgmts = NULL;
+ OSSL_PROPERTY_LIST **plp;
+ OSSL_PROPERTY_LIST *pq = NULL, *p2 = NULL;
OSSL_TRACE_BEGIN(DECODER) {
const char *input_type = ctx->start_input_type;
@@ -443,6 +470,25 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
process_data->keymgmts = keymgmts;
/*
+ * Collect passed and default properties to prioritize the decoders.
+ */
+ if (propquery != NULL)
+ p2 = pq = ossl_parse_query(libctx, propquery, 1);
+
+ plp = ossl_ctx_global_properties(libctx, 0);
+ if (plp != NULL && *plp != NULL) {
+ if (pq == NULL) {
+ pq = *plp;
+ } else {
+ p2 = ossl_property_merge(pq, *plp);
+ ossl_property_free(pq);
+ if (p2 == NULL)
+ goto err;
+ pq = p2;
+ }
+ }
+
+ /*
* Enumerate all keymgmts into a stack.
*
* We could nest EVP_KEYMGMT_do_all_provided inside
@@ -457,10 +503,11 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
* upfront, as this ensures that the names for all loaded providers have
* been registered by the time we try to resolve the keytype string.
*/
- collect_data.ctx = ctx;
- collect_data.libctx = libctx;
- collect_data.keymgmts = keymgmts;
- collect_data.keytype = keytype;
+ collect_data.ctx = ctx;
+ collect_data.libctx = libctx;
+ collect_data.keymgmts = keymgmts;
+ collect_data.keytype = keytype;
+ collect_data.pq = pq;
EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, &collect_data);
if (collect_data.error_occurred)
@@ -496,6 +543,7 @@ static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx,
ok = 1;
err:
decoder_clean_pkey_construct_arg(process_data);
+ ossl_property_free(p2);
return ok;
}
diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h
index a2846d309ea8..11e52cfeec75 100644
--- a/crypto/encode_decode/encoder_local.h
+++ b/crypto/encode_decode/encoder_local.h
@@ -109,6 +109,8 @@ struct ossl_decoder_instance_st {
const char *input_type; /* Never NULL */
const char *input_structure; /* May be NULL */
int input_type_id;
+ int order; /* For stable ordering of decoders wrt proqs */
+ int score; /* For ordering decoders wrt proqs */
unsigned int flag_input_structure_was_set : 1;
};
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 17981605c028..355b20d627db 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -803,6 +803,12 @@ EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
pkey application asn1 method already registered
EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error
EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error
+EVP_R_PROVIDER_ASYM_CIPHER_FAILURE:232:provider asym cipher failure
+EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED:235:provider asym cipher not supported
+EVP_R_PROVIDER_KEYMGMT_FAILURE:233:provider keymgmt failure
+EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED:236:provider keymgmt not supported
+EVP_R_PROVIDER_SIGNATURE_FAILURE:234:provider signature failure
+EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED:237:provider signature not supported
EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
EVP_R_SETTING_XOF_FAILED:227:setting xof failed
EVP_R_SET_DEFAULT_PROPERTY_FAILURE:209:set default property failure
diff --git a/crypto/evp/asymcipher.c b/crypto/evp/asymcipher.c
index ded0a9245121..c97ce338fdf8 100644
--- a/crypto/evp/asymcipher.c
+++ b/crypto/evp/asymcipher.c
@@ -33,6 +33,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
int ret = 0;
void *provkey = NULL;
EVP_ASYM_CIPHER *cipher = NULL;
+ const char *desc;
EVP_KEYMGMT *tmp_keymgmt = NULL;
const OSSL_PROVIDER *tmp_prov = NULL;
const char *supported_ciph = NULL;
@@ -159,10 +160,12 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
goto err;
}
+ desc = cipher->description != NULL ? cipher->description : "";
switch (operation) {
case EVP_PKEY_OP_ENCRYPT:
if (cipher->encrypt_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED,
+ "%s encrypt_init:%s", cipher->type_name, desc);
ret = -2;
goto err;
}
@@ -170,7 +173,8 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation,
break;
case EVP_PKEY_OP_DECRYPT:
if (cipher->decrypt_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED,
+ "%s decrypt_init:%s", cipher->type_name, desc);
ret = -2;
goto err;
}
@@ -238,6 +242,8 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
+ EVP_ASYM_CIPHER *cipher;
+ const char *desc;
int ret;
if (ctx == NULL) {
@@ -253,8 +259,14 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
if (ctx->op.ciph.algctx == NULL)
goto legacy;
- ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.algctx, out, outlen,
- (out == NULL ? 0 : *outlen), in, inlen);
+ cipher = ctx->op.ciph.cipher;
+ desc = cipher->description != NULL ? cipher->description : "";
+ ERR_set_mark();
+ ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
+ if (ret <= 0 && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
+ "%s encrypt:%s", cipher->type_name, desc);
+ ERR_clear_last_mark();
return ret;
legacy:
@@ -280,6 +292,8 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
+ EVP_ASYM_CIPHER *cipher;
+ const char *desc;
int ret;
if (ctx == NULL) {
@@ -295,8 +309,15 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
if (ctx->op.ciph.algctx == NULL)
goto legacy;
- ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.algctx, out, outlen,
- (out == NULL ? 0 : *outlen), in, inlen);
+ cipher = ctx->op.ciph.cipher;
+ desc = cipher->description != NULL ? cipher->description : "";
+ ERR_set_mark();
+ ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
+ if (ret <= 0 && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
+ "%s decrypt:%s", cipher->type_name, desc);
+ ERR_clear_last_mark();
+
return ret;
legacy:
diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c
index ffe4b5bb02e3..2f272deadd7b 100644
--- a/crypto/evp/bio_enc.c
+++ b/crypto/evp/bio_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -161,6 +161,7 @@ static int enc_read(BIO *b, char *out, int outl)
/* Should be continue next time we are called? */
if (!BIO_should_retry(next)) {
ctx->cont = i;
+ ctx->finished = 1;
i = EVP_CipherFinal_ex(ctx->cipher,
ctx->buf, &(ctx->buf_len));
ctx->ok = i;
diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c
index 13240db611b3..ed73fc0fbb8d 100644
--- a/crypto/evp/ctrl_params_translate.c
+++ b/crypto/evp/ctrl_params_translate.c
@@ -78,11 +78,11 @@ struct translation_st; /* Forwarding */
* With the PRE_CTRL_TO_PARAMS state, the
* fixup_args function is expected to modify
* the passed |*params| in whatever way
- * necessary, when |action_type == SET|.
+ * necessary, when |action_type == OSSL_ACTION_SET|.
* With the POST_CTRL_TO_PARAMS state, the
* fixup_args function is expected to modify
* the passed |p2| in whatever way necessary,
- * when |action_type == GET|.
+ * when |action_type == OSSL_ACTION_GET|.
*
* The return value from the fixup_args call
* with the POST_CTRL_TO_PARAMS state becomes
@@ -107,7 +107,7 @@ struct translation_st; /* Forwarding */
* With the PRE_CTRL_STR_TO_PARAMS state,
* the fixup_args function is expected to
* modify the passed |*params| in whatever
- * way necessary, when |action_type == SET|.
+ * way necessary, when |action_type == OSSL_ACTION_SET|.
* With the POST_CTRL_STR_TO_PARAMS state,
* the fixup_args function is only expected
* to return a value.
@@ -132,11 +132,11 @@ struct translation_st; /* Forwarding */
* With the PRE_PARAMS_TO_CTRL state, the
* fixup_args function is expected to modify
* the passed |p1| and |p2| in whatever way
- * necessary, when |action_type == SET|.
+ * necessary, when |action_type == OSSL_ACTION_SET|.
* With the POST_PARAMS_TO_CTRL state, the
* fixup_args function is expected to
* modify the passed |*params| in whatever
- * way necessary, when |action_type == GET|.
+ * way necessary, when |action_type == OSSL_ACTION_GET|.
*
* CLEANUP_PARAMS_TO_CTRL The cleanup_args functions has been called
* from EVP_PKEY_CTX_get_params() or
@@ -150,7 +150,7 @@ enum state {
PRE_PARAMS_TO_CTRL, POST_PARAMS_TO_CTRL, CLEANUP_PARAMS_TO_CTRL
};
enum action {
- NONE = 0, GET = 1, SET = 2
+ OSSL_ACTION_NONE = 0, OSSL_ACTION_GET = 1, OSSL_ACTION_SET = 2
};
typedef int fixup_args_fn(enum state state,
const struct translation_st *translation,
@@ -166,7 +166,7 @@ struct translation_ctx_st {
*/
EVP_PKEY_CTX *pctx;
/*
- * The action type (GET or SET). This may be 0 in some cases, and should
+ * The action type (OSSL_ACTION_GET or OSSL_ACTION_SET). This may be 0 in some cases, and should
* be modified by the fixup_args function in the PRE states. It should
* otherwise remain untouched once set.
*/
@@ -215,7 +215,7 @@ struct translation_st {
/*-
* What this table item does.
*
- * If the item has this set to 0, it means that both GET and SET are
+ * If the item has this set to 0, it means that both OSSL_ACTION_GET and OSSL_ACTION_SET are
* supported, and |fixup_args| will determine which it is. This is to
* support translations of ctrls where the action type depends on the
* value of |p1| or |p2| (ctrls are really bi-directional, but are
@@ -271,7 +271,7 @@ struct translation_st {
/*
* Fixer functions
*
- * |fixup_args| is always called before (for SET) or after (for GET)
+ * |fixup_args| is always called before (for OSSL_ACTION_SET) or after (for OSSL_ACTION_GET)
* the actual ctrl / OSSL_PARAM function.
*/
fixup_args_fn *fixup_args;
@@ -312,7 +312,7 @@ static int default_check(enum state state,
* function will have to deal with it carefully.
*/
if (translation != NULL) {
- if (!ossl_assert(translation->action_type != GET)) {
+ if (!ossl_assert(translation->action_type != OSSL_ACTION_GET)) {
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
@@ -344,7 +344,7 @@ static int default_check(enum state state,
* default_fixup_args fixes up all sorts of arguments, governed by the
* diverse attributes in the translation item. It covers all "standard"
* base ctrl functionality, meaning it can handle basic conversion of
- * data between p1+p2 (SET) or return value+p2 (GET) as long as the values
+ * data between p1+p2 (OSSL_ACTION_SET) or return value+p2 (OSSL_ACTION_GET) as long as the values
* don't have extra semantics (such as NIDs, OIDs, that sort of stuff).
* Extra semantics must be handled via specific fixup_args functions.
*
@@ -353,33 +353,36 @@ static int default_check(enum state state,
*
* PRE_CTRL_TO_PARAMS, 0 - ERROR. action type must be
* determined by a fixup function.
- * PRE_CTRL_TO_PARAMS, SET | GET - |p1| and |p2| are converted to an
+ * PRE_CTRL_TO_PARAMS, OSSL_ACTION_SET
+ * | OSSL_ACTION_GET - |p1| and |p2| are converted to an
* OSSL_PARAM according to the data
* type given in |translattion|.
* For OSSL_PARAM_UNSIGNED_INTEGER,
* a BIGNUM passed as |p2| is accepted.
- * POST_CTRL_TO_PARAMS, GET - If the OSSL_PARAM data type is a
+ * POST_CTRL_TO_PARAMS, OSSL_ACTION_GET - If the OSSL_PARAM data type is a
* STRING or PTR type, |p1| is set
* to the OSSL_PARAM return size, and
* |p2| is set to the string.
- * PRE_CTRL_STR_TO_PARAMS, !SET - ERROR. That combination is not
+ * PRE_CTRL_STR_TO_PARAMS,
+ * !OSSL_ACTION_SET - ERROR. That combination is not
* supported.
- * PRE_CTRL_STR_TO_PARAMS, SET - |p2| is taken as a string, and is
+ * PRE_CTRL_STR_TO_PARAMS,
+ * OSSL_ACTION_SET - |p2| is taken as a string, and is
* converted to an OSSL_PARAM in a
* standard manner, guided by the
* param key and data type from
* |translation|.
- * PRE_PARAMS_TO_CTRL, SET - the OSSL_PARAM is converted to
+ * PRE_PARAMS_TO_CTRL, OSSL_ACTION_SET - the OSSL_PARAM is converted to
* |p1| and |p2| according to the
* data type given in |translation|
* For OSSL_PARAM_UNSIGNED_INTEGER,
* if |p2| is non-NULL, then |*p2|
* is assigned a BIGNUM, otherwise
* |p1| is assigned an unsigned int.
- * POST_PARAMS_TO_CTRL, GET - |p1| and |p2| are converted to
+ * POST_PARAMS_TO_CTRL, OSSL_ACTION_GET - |p1| and |p2| are converted to
* an OSSL_PARAM, in the same manner
* as for the combination of
- * PRE_CTRL_TO_PARAMS, SET.
+ * PRE_CTRL_TO_PARAMS, OSSL_ACTION_SET.
*/
static int default_fixup_args(enum state state,
const struct translation_st *translation,
@@ -405,7 +408,7 @@ static int default_fixup_args(enum state state,
*/
case PRE_CTRL_TO_PARAMS:
/* This is ctrl to params translation, so we need an OSSL_PARAM key */
- if (ctx->action_type == NONE) {
+ if (ctx->action_type == OSSL_ACTION_NONE) {
/*
* No action type is an error here. That's a case for a
* special fixup function.
@@ -439,7 +442,7 @@ static int default_fixup_args(enum state state,
}
/*
- * OSSL_PARAM_construct_TYPE() works equally well for both SET and GET.
+ * OSSL_PARAM_construct_TYPE() works equally well for OSSL_ACTION_SET and OSSL_ACTION_GET.
*/
switch (translation->param_data_type) {
case OSSL_PARAM_INTEGER:
@@ -456,7 +459,7 @@ static int default_fixup_args(enum state state,
* must deallocate.
*/
if (ctx->p2 != NULL) {
- if (ctx->action_type == SET) {
+ if (ctx->action_type == OSSL_ACTION_SET) {
ctx->buflen = BN_num_bytes(ctx->p2);
if ((ctx->allocated_buf
= OPENSSL_malloc(ctx->buflen)) == NULL)
@@ -516,7 +519,7 @@ static int default_fixup_args(enum state state,
* as its return value, we need to ensure that we do it here as well,
* for the OSSL_PARAM data types where this makes sense.
*/
- if (ctx->action_type == GET) {
+ if (ctx->action_type == OSSL_ACTION_GET) {
switch (translation->param_data_type) {
case OSSL_PARAM_UTF8_STRING:
case OSSL_PARAM_UTF8_PTR:
@@ -544,7 +547,7 @@ static int default_fixup_args(enum state state,
int exists = 0;
/* Only setting is supported here */
- if (ctx->action_type != SET) {
+ if (ctx->action_type != OSSL_ACTION_SET) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED,
"[action:%d, state:%d] only setting allowed",
ctx->action_type, state);
@@ -610,7 +613,7 @@ static int default_fixup_args(enum state state,
case PRE_PARAMS_TO_CTRL:
{
/* This is params to ctrl translation */
- if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET) {
+ if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_SET) {
/* For the PRE state, only setting needs some work to be done */
/* When setting, we populate |p1| and |p2| from |*params| */
@@ -648,7 +651,7 @@ static int default_fixup_args(enum state state,
return 0;
}
} else if ((state == POST_PARAMS_TO_CTRL || state == PKEY)
- && ctx->action_type == GET) {
+ && ctx->action_type == OSSL_ACTION_GET) {
/* For the POST state, only getting needs some work to be done */
unsigned int param_data_type = translation->param_data_type;
size_t size = (size_t)ctx->p1;
@@ -693,7 +696,7 @@ static int default_fixup_args(enum state state,
translation->param_data_type);
return 0;
}
- } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == GET) {
+ } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET) {
if (translation->param_data_type == OSSL_PARAM_OCTET_PTR)
ctx->p2 = &ctx->bufp;
}
@@ -716,8 +719,8 @@ cleanup_translation_ctx(enum state state,
}
/*
- * fix_cipher_md fixes up an EVP_CIPHER / EVP_MD to its name on SET,
- * and cipher / md name to EVP_MD on GET.
+ * fix_cipher_md fixes up an EVP_CIPHER / EVP_MD to its name on OSSL_ACTION_SET,
+ * and cipher / md name to EVP_MD on OSSL_ACTION_GET.
*/
static const char *get_cipher_name(void *cipher)
{
@@ -751,7 +754,7 @@ static int fix_cipher_md(enum state state,
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == GET) {
+ if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET) {
/*
* |ctx->p2| contains the address to an EVP_CIPHER or EVP_MD pointer
* to be filled in. We need to remember it, then make |ctx->p2|
@@ -762,7 +765,7 @@ static int fix_cipher_md(enum state state,
ctx->orig_p2 = ctx->p2;
ctx->p2 = ctx->name_buf;
ctx->p1 = sizeof(ctx->name_buf);
- } else if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) {
+ } else if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_SET) {
/*
* In different parts of OpenSSL, this ctrl command is used
* differently. Some calls pass a NID as p1, others pass an
@@ -772,7 +775,7 @@ static int fix_cipher_md(enum state state,
? OBJ_nid2sn(ctx->p1)
: get_name(ctx->p2));
ctx->p1 = strlen(ctx->p2);
- } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET) {
+ } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET) {
ctx->p2 = (ctx->p2 == NULL ? "" : (char *)get_name(ctx->p2));
ctx->p1 = strlen(ctx->p2);
}
@@ -780,7 +783,7 @@ static int fix_cipher_md(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET) {
+ if (state == POST_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET) {
/*
* Here's how we reuse |ctx->orig_p2| that was set in the
* PRE_CTRL_TO_PARAMS state above.
@@ -788,7 +791,7 @@ static int fix_cipher_md(enum state state,
*(void **)ctx->orig_p2 =
(void *)get_algo_by_name(ctx->pctx->libctx, ctx->p2);
ctx->p1 = 1;
- } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET) {
+ } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_SET) {
ctx->p2 = (void *)get_algo_by_name(ctx->pctx->libctx, ctx->p2);
ctx->p1 = 0;
}
@@ -821,7 +824,7 @@ static int fix_distid_len(enum state state,
if (ret > 0) {
ret = 0;
if ((state == POST_CTRL_TO_PARAMS
- || state == POST_CTRL_STR_TO_PARAMS) && ctx->action_type == GET) {
+ || state == POST_CTRL_STR_TO_PARAMS) && ctx->action_type == OSSL_ACTION_GET) {
*(size_t *)ctx->p2 = ctx->sz;
ret = 1;
}
@@ -854,9 +857,9 @@ static int fix_kdf_type(enum state state,
if (state == PRE_CTRL_TO_PARAMS) {
/*
* In |translations|, the initial value for |ctx->action_type| must
- * be NONE.
+ * be OSSL_ACTION_NONE.
*/
- if (!ossl_assert(ctx->action_type == NONE))
+ if (!ossl_assert(ctx->action_type == OSSL_ACTION_NONE))
return 0;
/* The action type depends on the value of *p1 */
@@ -871,17 +874,17 @@ static int fix_kdf_type(enum state state,
*/
ctx->p2 = ctx->name_buf;
ctx->p1 = sizeof(ctx->name_buf);
- ctx->action_type = GET;
+ ctx->action_type = OSSL_ACTION_GET;
} else {
- ctx->action_type = SET;
+ ctx->action_type = OSSL_ACTION_SET;
}
}
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if ((state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET)
- || (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET)) {
+ if ((state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_SET)
+ || (state == POST_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET)) {
ret = -2;
/* Convert KDF type numbers to strings */
for (; kdf_type_map->kdf_type_str != NULL; kdf_type_map++)
@@ -898,8 +901,8 @@ static int fix_kdf_type(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if ((state == POST_CTRL_TO_PARAMS && ctx->action_type == GET)
- || (state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET)) {
+ if ((state == POST_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET)
+ || (state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_SET)) {
ctx->p1 = ret = -1;
/* Convert KDF type strings to numbers */
@@ -910,7 +913,7 @@ static int fix_kdf_type(enum state state,
break;
}
ctx->p2 = NULL;
- } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == GET) {
+ } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET) {
ctx->p1 = -2;
}
end:
@@ -955,8 +958,8 @@ static int fix_oid(enum state state,
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if ((state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET)
- || (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET)) {
+ if ((state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_SET)
+ || (state == POST_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET)) {
/*
* We're translating from ctrl to params and setting the OID, or
* we're translating from params to ctrl and getting the OID.
@@ -973,8 +976,8 @@ static int fix_oid(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if ((state == PRE_PARAMS_TO_CTRL && ctx->action_type == SET)
- || (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET)) {
+ if ((state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_SET)
+ || (state == POST_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET)) {
/*
* We're translating from ctrl to params and setting the OID name,
* or we're translating from params to ctrl and getting the OID
@@ -999,7 +1002,7 @@ static int fix_dh_nid(enum state state,
return ret;
/* This is only settable */
- if (ctx->action_type != SET)
+ if (ctx->action_type != OSSL_ACTION_SET)
return 0;
if (state == PRE_CTRL_TO_PARAMS) {
@@ -1025,7 +1028,7 @@ static int fix_dh_nid5114(enum state state,
return ret;
/* This is only settable */
- if (ctx->action_type != SET)
+ if (ctx->action_type != OSSL_ACTION_SET)
return 0;
switch (state) {
@@ -1069,7 +1072,7 @@ static int fix_dh_paramgen_type(enum state state,
return ret;
/* This is only settable */
- if (ctx->action_type != SET)
+ if (ctx->action_type != OSSL_ACTION_SET)
return 0;
if (state == PRE_CTRL_STR_TO_PARAMS) {
@@ -1095,7 +1098,7 @@ static int fix_ec_param_enc(enum state state,
return ret;
/* This is currently only settable */
- if (ctx->action_type != SET)
+ if (ctx->action_type != OSSL_ACTION_SET)
return 0;
if (state == PRE_CTRL_TO_PARAMS) {
@@ -1144,7 +1147,7 @@ static int fix_ec_paramgen_curve_nid(enum state state,
return ret;
/* This is currently only settable */
- if (ctx->action_type != SET)
+ if (ctx->action_type != OSSL_ACTION_SET)
return 0;
if (state == PRE_CTRL_TO_PARAMS) {
@@ -1194,28 +1197,28 @@ static int fix_ecdh_cofactor(enum state state,
* The initial value for |ctx->action_type| must be zero.
* evp_pkey_ctrl_to_params() takes it from the translation item.
*/
- if (!ossl_assert(ctx->action_type == NONE))
+ if (!ossl_assert(ctx->action_type == OSSL_ACTION_NONE))
return 0;
/* The action type depends on the value of ctx->p1 */
if (ctx->p1 == -2)
- ctx->action_type = GET;
+ ctx->action_type = OSSL_ACTION_GET;
else
- ctx->action_type = SET;
+ ctx->action_type = OSSL_ACTION_SET;
} else if (state == PRE_CTRL_STR_TO_PARAMS) {
- ctx->action_type = SET;
+ ctx->action_type = OSSL_ACTION_SET;
} else if (state == PRE_PARAMS_TO_CTRL) {
/* The initial value for |ctx->action_type| must not be zero. */
- if (!ossl_assert(ctx->action_type != NONE))
+ if (!ossl_assert(ctx->action_type != OSSL_ACTION_NONE))
return 0;
- } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == NONE) {
- ctx->action_type = GET;
+ } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_NONE) {
+ ctx->action_type = OSSL_ACTION_GET;
}
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) {
+ if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_SET) {
if (ctx->p1 < -1 || ctx->p1 > 1) {
/* Uses the same return value of pkey_ec_ctrl() */
return -2;
@@ -1225,7 +1228,7 @@ static int fix_ecdh_cofactor(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if (state == POST_CTRL_TO_PARAMS && ctx->action_type == GET) {
+ if (state == POST_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET) {
if (ctx->p1 < 0 || ctx->p1 > 1) {
/*
* The provider should return either 0 or 1, any other value is a
@@ -1233,9 +1236,9 @@ static int fix_ecdh_cofactor(enum state state,
*/
ctx->p1 = ret = -1;
}
- } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == GET) {
+ } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET) {
ctx->p1 = -2;
- } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET) {
+ } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET) {
ctx->p1 = ret;
}
@@ -1262,7 +1265,7 @@ static int fix_rsa_padding_mode(enum state state,
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == GET) {
+ if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET) {
/*
* EVP_PKEY_CTRL_GET_RSA_PADDING returns the padding mode in the
* weirdest way for a ctrl. Instead of doing like all other ctrls
@@ -1271,13 +1274,13 @@ static int fix_rsa_padding_mode(enum state state,
* returned. We must therefore remember |ctx->p2|, then make
* |ctx->p2| point at a buffer to be filled in with the name, and
* |ctx->p1| with its size. default_fixup_args() will take care
- * of the rest for us, along with the POST_CTRL_TO_PARAMS && GET
+ * of the rest for us, along with the POST_CTRL_TO_PARAMS && OSSL_ACTION_GET
* code section further down.
*/
ctx->orig_p2 = ctx->p2;
ctx->p2 = ctx->name_buf;
ctx->p1 = sizeof(ctx->name_buf);
- } else if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == SET) {
+ } else if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_SET) {
/*
* Ideally, we should use utf8 strings for the diverse padding modes.
* We only came here because someone called EVP_PKEY_CTX_ctrl(),
@@ -1298,7 +1301,7 @@ static int fix_rsa_padding_mode(enum state state,
ctx->params[0] = OSSL_PARAM_construct_int(translation->param_key,
&ctx->p1);
return 1;
- } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == GET) {
+ } else if (state == POST_PARAMS_TO_CTRL && ctx->action_type == OSSL_ACTION_GET) {
size_t i;
/*
@@ -1341,8 +1344,8 @@ static int fix_rsa_padding_mode(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if ((ctx->action_type == SET && state == PRE_PARAMS_TO_CTRL)
- || (ctx->action_type == GET && state == POST_CTRL_TO_PARAMS)) {
+ if ((ctx->action_type == OSSL_ACTION_SET && state == PRE_PARAMS_TO_CTRL)
+ || (ctx->action_type == OSSL_ACTION_GET && state == POST_CTRL_TO_PARAMS)) {
size_t i;
for (i = 0; i < OSSL_NELEM(str_value_map); i++) {
@@ -1382,7 +1385,7 @@ static int fix_rsa_pss_saltlen(enum state state,
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == GET) {
+ if (state == PRE_CTRL_TO_PARAMS && ctx->action_type == OSSL_ACTION_GET) {
/*
* EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN returns the saltlen by filling
* in the int pointed at by p2. This is potentially as weird as
@@ -1392,14 +1395,14 @@ static int fix_rsa_pss_saltlen(enum state state,
* In any case, we must therefore remember |ctx->p2|, then make
* |ctx->p2| point at a buffer to be filled in with the name, and
* |ctx->p1| with its size. default_fixup_args() will take care
- * of the rest for us, along with the POST_CTRL_TO_PARAMS && GET
+ * of the rest for us, along with the POST_CTRL_TO_PARAMS && OSSL_ACTION_GET
* code section further down.
*/
ctx->orig_p2 = ctx->p2;
ctx->p2 = ctx->name_buf;
ctx->p1 = sizeof(ctx->name_buf);
- } else if ((ctx->action_type == SET && state == PRE_CTRL_TO_PARAMS)
- || (ctx->action_type == GET && state == POST_PARAMS_TO_CTRL)) {
+ } else if ((ctx->action_type == OSSL_ACTION_SET && state == PRE_CTRL_TO_PARAMS)
+ || (ctx->action_type == OSSL_ACTION_GET && state == POST_PARAMS_TO_CTRL)) {
size_t i;
for (i = 0; i < OSSL_NELEM(str_value_map); i++) {
@@ -1420,8 +1423,8 @@ static int fix_rsa_pss_saltlen(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if ((ctx->action_type == SET && state == PRE_PARAMS_TO_CTRL)
- || (ctx->action_type == GET && state == POST_CTRL_TO_PARAMS)) {
+ if ((ctx->action_type == OSSL_ACTION_SET && state == PRE_PARAMS_TO_CTRL)
+ || (ctx->action_type == OSSL_ACTION_GET && state == POST_CTRL_TO_PARAMS)) {
size_t i;
int val;
@@ -1462,8 +1465,8 @@ static int fix_hkdf_mode(enum state state,
if ((ret = default_check(state, translation, ctx)) <= 0)
return ret;
- if ((ctx->action_type == SET && state == PRE_CTRL_TO_PARAMS)
- || (ctx->action_type == GET && state == POST_PARAMS_TO_CTRL)) {
+ if ((ctx->action_type == OSSL_ACTION_SET && state == PRE_CTRL_TO_PARAMS)
+ || (ctx->action_type == OSSL_ACTION_GET && state == POST_PARAMS_TO_CTRL)) {
size_t i;
for (i = 0; i < OSSL_NELEM(str_value_map); i++) {
@@ -1479,8 +1482,8 @@ static int fix_hkdf_mode(enum state state,
if ((ret = default_fixup_args(state, translation, ctx)) <= 0)
return ret;
- if ((ctx->action_type == SET && state == PRE_PARAMS_TO_CTRL)
- || (ctx->action_type == GET && state == POST_CTRL_TO_PARAMS)) {
+ if ((ctx->action_type == OSSL_ACTION_SET && state == PRE_PARAMS_TO_CTRL)
+ || (ctx->action_type == OSSL_ACTION_GET && state == POST_CTRL_TO_PARAMS)) {
size_t i;
for (i = 0; i < OSSL_NELEM(str_value_map); i++) {
@@ -1504,7 +1507,7 @@ static int fix_hkdf_mode(enum state state,
* ===============
*
* These all get the data they want, then call default_fixup_args() as
- * a post-ctrl GET fixup. They all get NULL ctx, ctrl_cmd, ctrl_str,
+ * a post-ctrl OSSL_ACTION_GET fixup. They all get NULL ctx, ctrl_cmd, ctrl_str,
* p1, sz
*/
@@ -2047,7 +2050,7 @@ static int fix_group_ecx(enum state state,
case PRE_PARAMS_TO_CTRL:
if (!EVP_PKEY_CTX_IS_GEN_OP(ctx->pctx))
return 0;
- ctx->action_type = NONE;
+ ctx->action_type = OSSL_ACTION_NONE;
return 1;
case POST_PARAMS_TO_CTRL:
if (OSSL_PARAM_get_utf8_string_ptr(ctx->params, &value) == 0 ||
@@ -2077,13 +2080,13 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* that has no separate counterpart in OSSL_PARAM terms, since we get
* the length of the DistID automatically when getting the DistID itself.
*/
- { SET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_SET1_ID, "distid", "hexdistid",
OSSL_PKEY_PARAM_DIST_ID, OSSL_PARAM_OCTET_STRING, NULL },
- { GET, -1, -1, -1,
+ { OSSL_ACTION_GET, -1, -1, -1,
EVP_PKEY_CTRL_GET1_ID, "distid", "hexdistid",
OSSL_PKEY_PARAM_DIST_ID, OSSL_PARAM_OCTET_PTR, NULL },
- { GET, -1, -1, -1,
+ { OSSL_ACTION_GET, -1, -1, -1,
EVP_PKEY_CTRL_GET1_ID_LEN, NULL, NULL,
OSSL_PKEY_PARAM_DIST_ID, OSSL_PARAM_OCTET_PTR, fix_distid_len },
@@ -2096,74 +2099,74 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* EVP_PKEY_CTRL_DH_KDF_TYPE is used both for setting and getting. The
* fixup function has to handle this...
*/
- { NONE, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_NONE, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_KDF_TYPE, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_TYPE, OSSL_PARAM_UTF8_STRING,
fix_dh_kdf_type },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_KDF_MD, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_DH_KDF_MD, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_KDF_OUTLEN, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_KDF_UKM, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_STRING, NULL },
- { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_DH_KDF_UKM, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_KDF_OID, NULL, NULL,
OSSL_KDF_PARAM_CEK_ALG, OSSL_PARAM_UTF8_STRING, fix_oid },
- { GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_DH_KDF_OID, NULL, NULL,
OSSL_KDF_PARAM_CEK_ALG, OSSL_PARAM_UTF8_STRING, fix_oid },
/* DHX Keygen Parameters that are shared with DH */
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL,
OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, "dh_paramgen_prime_len", NULL,
OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_DH_NID, "dh_param", NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, NULL },
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid5114 },
/* DH Keygen Parameters that are shared with DHX */
- { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, "dh_paramgen_type", NULL,
OSSL_PKEY_PARAM_FFC_TYPE, OSSL_PARAM_UTF8_STRING, fix_dh_paramgen_type },
- { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, "dh_paramgen_prime_len", NULL,
OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_DH_NID, "dh_param", NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid },
- { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_DH_RFC5114, "dh_rfc5114", NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_dh_nid5114 },
/* DH specific Keygen Parameters */
- { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, "dh_paramgen_generator", NULL,
OSSL_PKEY_PARAM_DH_GENERATOR, OSSL_PARAM_INTEGER, NULL },
/* DHX specific Keygen Parameters */
- { SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DHX, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, "dh_paramgen_subprime_len", NULL,
OSSL_PKEY_PARAM_FFC_QBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_DH, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_DH_PAD, "dh_pad", NULL,
OSSL_EXCHANGE_PARAM_PAD, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
@@ -2171,13 +2174,13 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* DSA
* ===
*/
- { SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, "dsa_paramgen_bits", NULL,
OSSL_PKEY_PARAM_FFC_PBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, "dsa_paramgen_q_bits", NULL,
OSSL_PKEY_PARAM_FFC_QBITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_DSA, 0, EVP_PKEY_OP_PARAMGEN,
EVP_PKEY_CTRL_DSA_PARAMGEN_MD, "dsa_paramgen_md", NULL,
OSSL_PKEY_PARAM_FFC_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
@@ -2185,10 +2188,10 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* EC
* ==
*/
- { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_EC_PARAM_ENC, "ec_param_enc", NULL,
OSSL_PKEY_PARAM_EC_ENCODING, OSSL_PARAM_UTF8_STRING, fix_ec_param_enc },
- { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, "ec_paramgen_curve", NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING,
fix_ec_paramgen_curve_nid },
@@ -2196,29 +2199,29 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* EVP_PKEY_CTRL_EC_ECDH_COFACTOR and EVP_PKEY_CTRL_EC_KDF_TYPE are used
* both for setting and getting. The fixup function has to handle this...
*/
- { NONE, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_NONE, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_ECDH_COFACTOR, "ecdh_cofactor_mode", NULL,
OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, OSSL_PARAM_INTEGER,
fix_ecdh_cofactor },
- { NONE, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_NONE, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_TYPE, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_TYPE, OSSL_PARAM_UTF8_STRING, fix_ec_kdf_type },
- { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_MD, "ecdh_kdf_md", NULL,
OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_MD, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_OUTLEN, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_UKM, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_STRING, NULL },
- { GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_EC, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_UKM, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL },
@@ -2226,10 +2229,10 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* SM2
* ==
*/
- { SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_EC_PARAM_ENC, "ec_param_enc", NULL,
OSSL_PKEY_PARAM_EC_ENCODING, OSSL_PARAM_UTF8_STRING, fix_ec_param_enc },
- { SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, "ec_paramgen_curve", NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING,
fix_ec_paramgen_curve_nid },
@@ -2237,29 +2240,29 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* EVP_PKEY_CTRL_EC_ECDH_COFACTOR and EVP_PKEY_CTRL_EC_KDF_TYPE are used
* both for setting and getting. The fixup function has to handle this...
*/
- { NONE, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_NONE, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_ECDH_COFACTOR, "ecdh_cofactor_mode", NULL,
OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, OSSL_PARAM_INTEGER,
fix_ecdh_cofactor },
- { NONE, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_NONE, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_TYPE, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_TYPE, OSSL_PARAM_UTF8_STRING, fix_ec_kdf_type },
- { SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_MD, "ecdh_kdf_md", NULL,
OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { GET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_MD, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_OUTLEN, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { GET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_OUTLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_EC_KDF_UKM, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_STRING, NULL },
- { GET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_GET, EVP_PKEY_SM2, 0, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_GET_EC_KDF_UKM, NULL, NULL,
OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL },
/*-
@@ -2273,20 +2276,20 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* fix_rsa_padding_mode() does the work when the caller has a different
* idea.
*/
- { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_RSA_PADDING, "rsa_padding_mode", NULL,
OSSL_PKEY_PARAM_PAD_MODE, OSSL_PARAM_UTF8_STRING, fix_rsa_padding_mode },
- { GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
+ { OSSL_ACTION_GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_GET_RSA_PADDING, NULL, NULL,
OSSL_PKEY_PARAM_PAD_MODE, OSSL_PARAM_UTF8_STRING, fix_rsa_padding_mode },
- { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_RSA_MGF1_MD, "rsa_mgf1_md", NULL,
OSSL_PKEY_PARAM_MGF1_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
+ { OSSL_ACTION_GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_GET_RSA_MGF1_MD, NULL, NULL,
OSSL_PKEY_PARAM_MGF1_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
@@ -2297,19 +2300,19 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* OSSL_PARAM allows both forms.
* fix_rsa_pss_saltlen() takes care of the distinction.
*/
- { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_TYPE_SIG,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_RSA_PSS_SALTLEN, "rsa_pss_saltlen", NULL,
OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, OSSL_PARAM_UTF8_STRING,
fix_rsa_pss_saltlen },
- { GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_TYPE_SIG,
+ { OSSL_ACTION_GET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, NULL, NULL,
OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, OSSL_PARAM_UTF8_STRING,
fix_rsa_pss_saltlen },
- { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_RSA_OAEP_MD, "rsa_oaep_md", NULL,
OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
+ { OSSL_ACTION_GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_GET_RSA_OAEP_MD, NULL, NULL,
OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
/*
@@ -2318,35 +2321,35 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* expectation for any translation item where |ctrl_str| is NULL and
* |ctrl_hexstr| is non-NULL.
*/
- { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_RSA_OAEP_LABEL, NULL, "rsa_oaep_label",
OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_STRING, NULL },
- { GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
+ { OSSL_ACTION_GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, NULL, NULL,
OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR, NULL },
- { SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_RSA_IMPLICIT_REJECTION, NULL,
"rsa_pkcs1_implicit_rejection",
OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, OSSL_PARAM_UNSIGNED_INTEGER,
NULL },
- { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
EVP_PKEY_CTRL_MD, "rsa_pss_keygen_md", NULL,
OSSL_ALG_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
EVP_PKEY_CTRL_RSA_MGF1_MD, "rsa_pss_keygen_mgf1_md", NULL,
OSSL_PKEY_PARAM_MGF1_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
EVP_PKEY_CTRL_RSA_PSS_SALTLEN, "rsa_pss_keygen_saltlen", NULL,
OSSL_SIGNATURE_PARAM_PSS_SALTLEN, OSSL_PARAM_INTEGER, NULL },
- { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_RSA_KEYGEN_BITS, "rsa_keygen_bits", NULL,
OSSL_PKEY_PARAM_RSA_BITS, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, "rsa_keygen_pubexp", NULL,
OSSL_PKEY_PARAM_RSA_E, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, "rsa_keygen_primes", NULL,
OSSL_PKEY_PARAM_RSA_PRIMES, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
@@ -2354,7 +2357,7 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* SipHash
* ======
*/
- { SET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_SET_DIGEST_SIZE, "digestsize", NULL,
OSSL_MAC_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
@@ -2362,13 +2365,13 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* TLS1-PRF
* ========
*/
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_TLS_MD, "md", NULL,
OSSL_KDF_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_TLS_SECRET, "secret", "hexsecret",
OSSL_KDF_PARAM_SECRET, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_TLS_SEED, "seed", "hexseed",
OSSL_KDF_PARAM_SEED, OSSL_PARAM_OCTET_STRING, NULL },
@@ -2376,19 +2379,19 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* HKDF
* ====
*/
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_MD, "md", NULL,
OSSL_KDF_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_SALT, "salt", "hexsalt",
OSSL_KDF_PARAM_SALT, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_KEY, "key", "hexkey",
OSSL_KDF_PARAM_KEY, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_INFO, "info", "hexinfo",
OSSL_KDF_PARAM_INFO, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_HKDF_MODE, "mode", NULL,
OSSL_KDF_PARAM_MODE, OSSL_PARAM_INTEGER, fix_hkdf_mode },
@@ -2396,36 +2399,36 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* Scrypt
* ======
*/
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_PASS, "pass", "hexpass",
OSSL_KDF_PARAM_PASSWORD, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_SCRYPT_SALT, "salt", "hexsalt",
OSSL_KDF_PARAM_SALT, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_SCRYPT_N, "N", NULL,
OSSL_KDF_PARAM_SCRYPT_N, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_SCRYPT_R, "r", NULL,
OSSL_KDF_PARAM_SCRYPT_R, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_SCRYPT_P, "p", NULL,
OSSL_KDF_PARAM_SCRYPT_P, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, -1, -1, EVP_PKEY_OP_DERIVE,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_DERIVE,
EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, "maxmem_bytes", NULL,
OSSL_KDF_PARAM_SCRYPT_MAXMEM, OSSL_PARAM_UNSIGNED_INTEGER, NULL },
- { SET, -1, -1, EVP_PKEY_OP_KEYGEN | EVP_PKEY_OP_TYPE_CRYPT,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_KEYGEN | EVP_PKEY_OP_TYPE_CRYPT,
EVP_PKEY_CTRL_CIPHER, NULL, NULL,
OSSL_PKEY_PARAM_CIPHER, OSSL_PARAM_UTF8_STRING, fix_cipher },
- { SET, -1, -1, EVP_PKEY_OP_KEYGEN,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_SET_MAC_KEY, "key", "hexkey",
OSSL_PKEY_PARAM_PRIV_KEY, OSSL_PARAM_OCTET_STRING, NULL },
- { SET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
+ { OSSL_ACTION_SET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_MD, NULL, NULL,
OSSL_SIGNATURE_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
- { GET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
+ { OSSL_ACTION_GET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_GET_MD, NULL, NULL,
OSSL_SIGNATURE_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
@@ -2433,13 +2436,13 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
* ECX
* ===
*/
- { SET, EVP_PKEY_X25519, EVP_PKEY_X25519, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL,
+ { OSSL_ACTION_SET, EVP_PKEY_X25519, EVP_PKEY_X25519, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx },
- { SET, EVP_PKEY_X25519, EVP_PKEY_X25519, EVP_PKEY_OP_PARAMGEN, -1, NULL, NULL,
+ { OSSL_ACTION_SET, EVP_PKEY_X25519, EVP_PKEY_X25519, EVP_PKEY_OP_PARAMGEN, -1, NULL, NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx },
- { SET, EVP_PKEY_X448, EVP_PKEY_X448, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL,
+ { OSSL_ACTION_SET, EVP_PKEY_X448, EVP_PKEY_X448, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx },
- { SET, EVP_PKEY_X448, EVP_PKEY_X448, EVP_PKEY_OP_PARAMGEN, -1, NULL, NULL,
+ { OSSL_ACTION_SET, EVP_PKEY_X448, EVP_PKEY_X448, EVP_PKEY_OP_PARAMGEN, -1, NULL, NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx },
};
@@ -2452,134 +2455,134 @@ static const struct translation_st evp_pkey_translations[] = {
*/
/* DH, DSA & EC */
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING,
get_payload_group_name },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_PRIV_KEY, OSSL_PARAM_UNSIGNED_INTEGER,
get_payload_private_key },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_PUB_KEY,
0 /* no data type, let get_payload_public_key() handle that */,
get_payload_public_key },
- { GET, -1, -1, -1, 0, NULL, NULL,
- OSSL_PKEY_PARAM_EC_PUB_X, OSSL_PARAM_UNSIGNED_INTEGER,
- get_payload_public_key_ec },
- { GET, -1, -1, -1, 0, NULL, NULL,
- OSSL_PKEY_PARAM_EC_PUB_Y, OSSL_PARAM_UNSIGNED_INTEGER,
- get_payload_public_key_ec },
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
+ OSSL_PKEY_PARAM_EC_PUB_X, OSSL_PARAM_UNSIGNED_INTEGER,
+ get_payload_public_key_ec },
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
+ OSSL_PKEY_PARAM_EC_PUB_Y, OSSL_PARAM_UNSIGNED_INTEGER,
+ get_payload_public_key_ec },
/* DH and DSA */
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_FFC_P, OSSL_PARAM_UNSIGNED_INTEGER,
get_dh_dsa_payload_p },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_FFC_G, OSSL_PARAM_UNSIGNED_INTEGER,
get_dh_dsa_payload_g },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_FFC_Q, OSSL_PARAM_UNSIGNED_INTEGER,
get_dh_dsa_payload_q },
/* RSA */
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_N, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_n },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_E, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_D, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_d },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR1, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f1 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR2, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f2 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR3, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f3 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR4, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f4 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR5, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f5 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR6, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f6 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR7, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f7 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR8, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f8 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR9, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f9 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_FACTOR10, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_f10 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT1, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e1 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT2, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e2 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT3, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e3 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT4, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e4 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT5, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e5 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT6, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e6 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT7, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e7 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT8, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e8 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT9, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e9 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_EXPONENT10, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_e10 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT1, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c1 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT2, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c2 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT3, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c3 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT4, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c4 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT5, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c5 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT6, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c6 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT7, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c7 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT8, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c8 },
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_RSA_COEFFICIENT9, OSSL_PARAM_UNSIGNED_INTEGER,
get_rsa_payload_c9 },
/* EC */
- { GET, -1, -1, -1, 0, NULL, NULL,
+ { OSSL_ACTION_GET, -1, -1, -1, 0, NULL, NULL,
OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, OSSL_PARAM_INTEGER,
get_ec_decoded_from_explicit_params },
};
@@ -2636,8 +2639,8 @@ lookup_translation(struct translation_st *tmpl,
* for setting, never for getting. Therefore, we only look at
* the setter items.
*/
- if (item->action_type != NONE
- && item->action_type != SET)
+ if (item->action_type != OSSL_ACTION_NONE
+ && item->action_type != OSSL_ACTION_SET)
continue;
/*
* At least one of the ctrl cmd names must be match the ctrl
@@ -2673,7 +2676,7 @@ lookup_translation(struct translation_st *tmpl,
* key name can therefore be used in both directions. We must
* therefore take the action type into account in this case.
*/
- if ((item->action_type != NONE
+ if ((item->action_type != OSSL_ACTION_NONE
&& tmpl->action_type != item->action_type)
|| (item->param_key != NULL
&& OPENSSL_strcasecmp(tmpl->param_key,
@@ -2748,10 +2751,10 @@ int evp_pkey_ctx_ctrl_to_param(EVP_PKEY_CTX *pctx,
default:
/* fixup_args is expected to make sure this is dead code */
break;
- case GET:
+ case OSSL_ACTION_GET:
ret = evp_pkey_ctx_get_params_strict(pctx, ctx.params);
break;
- case SET:
+ case OSSL_ACTION_SET:
ret = evp_pkey_ctx_set_params_strict(pctx, ctx.params);
break;
}
@@ -2785,7 +2788,7 @@ int evp_pkey_ctx_ctrl_str_to_param(EVP_PKEY_CTX *pctx,
int ret;
fixup_args_fn *fixup = default_fixup_args;
- tmpl.action_type = SET;
+ tmpl.action_type = OSSL_ACTION_SET;
tmpl.keytype1 = tmpl.keytype2 = keytype;
tmpl.optype = optype;
tmpl.ctrl_str = name;
@@ -2799,7 +2802,7 @@ int evp_pkey_ctx_ctrl_str_to_param(EVP_PKEY_CTX *pctx,
ctx.ishex = (tmpl.ctrl_hexstr != NULL);
} else {
/* String controls really only support setting */
- ctx.action_type = SET;
+ ctx.action_type = OSSL_ACTION_SET;
}
ctx.ctrl_str = name;
ctx.p1 = (int)strlen(value);
@@ -2814,13 +2817,13 @@ int evp_pkey_ctx_ctrl_str_to_param(EVP_PKEY_CTX *pctx,
default:
/* fixup_args is expected to make sure this is dead code */
break;
- case GET:
+ case OSSL_ACTION_GET:
/*
* this is dead code, but must be present, or some compilers
* will complain
*/
break;
- case SET:
+ case OSSL_ACTION_SET:
ret = evp_pkey_ctx_set_params_strict(pctx, ctx.params);
break;
}
@@ -2865,7 +2868,7 @@ static int evp_pkey_ctx_setget_params_to_ctrl(EVP_PKEY_CTX *pctx,
ret = fixup(PRE_PARAMS_TO_CTRL, translation, &ctx);
- if (ret > 0 && ctx.action_type != NONE)
+ if (ret > 0 && ctx.action_type != OSSL_ACTION_NONE)
ret = EVP_PKEY_CTX_ctrl(pctx, keytype, optype,
ctx.ctrl_cmd, ctx.p1, ctx.p2);
@@ -2897,14 +2900,14 @@ int evp_pkey_ctx_set_params_to_ctrl(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params)
{
if (ctx->keymgmt != NULL)
return 0;
- return evp_pkey_ctx_setget_params_to_ctrl(ctx, SET, (OSSL_PARAM *)params);
+ return evp_pkey_ctx_setget_params_to_ctrl(ctx, OSSL_ACTION_SET, (OSSL_PARAM *)params);
}
int evp_pkey_ctx_get_params_to_ctrl(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
{
if (ctx->keymgmt != NULL)
return 0;
- return evp_pkey_ctx_setget_params_to_ctrl(ctx, GET, params);
+ return evp_pkey_ctx_setget_params_to_ctrl(ctx, OSSL_ACTION_GET, params);
}
/* This must ONLY be called for legacy EVP_PKEYs */
@@ -2938,7 +2941,7 @@ static int evp_pkey_setget_params_to_ctrl(const EVP_PKEY *pkey,
* support getting.
*/
if (!ossl_assert(translation != NULL)
- || !ossl_assert(translation->action_type == GET)
+ || !ossl_assert(translation->action_type == OSSL_ACTION_GET)
|| !ossl_assert(translation->fixup_args != NULL)) {
return -2;
}
@@ -2952,5 +2955,5 @@ static int evp_pkey_setget_params_to_ctrl(const EVP_PKEY *pkey,
int evp_pkey_get_params_to_ctrl(const EVP_PKEY *pkey, OSSL_PARAM *params)
{
- return evp_pkey_setget_params_to_ctrl(pkey, GET, params);
+ return evp_pkey_setget_params_to_ctrl(pkey, OSSL_ACTION_GET, params);
}
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index d8440fc76d13..028f8202c867 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -151,6 +151,18 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
"private key decode error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR),
"private key encode error"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE),
+ "provider asym cipher failure"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED),
+ "provider asym cipher not supported"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_FAILURE),
+ "provider keymgmt failure"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED),
+ "provider keymgmt not supported"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_FAILURE),
+ "provider signature failure"},
+ {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED),
+ "provider signature not supported"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SETTING_XOF_FAILED), "setting xof failed"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SET_DEFAULT_PROPERTY_FAILURE),
diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c
index 50334042a9cc..fd2aeb3bcf1f 100644
--- a/crypto/evp/evp_rand.c
+++ b/crypto/evp/evp_rand.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -646,10 +646,8 @@ static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out,
{
unsigned int str = evp_rand_strength_locked(ctx);
- if (ctx->meth->nonce == NULL)
- return 0;
- if (ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen))
- return 1;
+ if (ctx->meth->nonce != NULL)
+ return ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen) > 0;
return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0);
}
@@ -657,6 +655,11 @@ int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen)
{
int res;
+ if (ctx == NULL || out == NULL || outlen == 0) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
if (!evp_rand_lock(ctx))
return 0;
res = evp_rand_nonce_locked(ctx, out, outlen);
diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c
index 108bbf957973..f57153b2c1a1 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -451,9 +451,22 @@ const OSSL_PARAM *EVP_KEYMGMT_gen_gettable_params(const EVP_KEYMGMT *keymgmt)
void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
OSSL_CALLBACK *cb, void *cbarg)
{
- if (keymgmt->gen == NULL)
+ void *ret;
+ const char *desc = keymgmt->description != NULL ? keymgmt->description : "";
+
+ if (keymgmt->gen == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED,
+ "%s key generation:%s", keymgmt->type_name, desc);
return NULL;
- return keymgmt->gen(genctx, cb, cbarg);
+ }
+
+ ERR_set_mark();
+ ret = keymgmt->gen(genctx, cb, cbarg);
+ if (ret == NULL && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE,
+ "%s key generation:%s", keymgmt->type_name, desc);
+ ERR_clear_last_mark();
+ return ret;
}
void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)
diff --git a/crypto/evp/legacy_sha.c b/crypto/evp/legacy_sha.c
index 38423ff540f5..a9894d4d2abc 100644
--- a/crypto/evp/legacy_sha.c
+++ b/crypto/evp/legacy_sha.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -216,7 +216,7 @@ const EVP_MD *EVP_shake##bitlen(void) \
NID_shake##bitlen, \
0, \
bitlen / 8, \
- EVP_MD_FLAG_XOF, \
+ EVP_MD_FLAG_XOF | EVP_MD_FLAG_DIGALGID_ABSENT, \
EVP_ORIG_GLOBAL, \
LEGACY_EVP_MD_METH_TABLE(shake_init, sha3_int_update, sha3_int_final, \
shake_ctrl, (KECCAK1600_WIDTH - bitlen * 2) / 8), \
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 2d1839fedb2f..c27ed6dbe9b2 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -42,6 +42,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
{
EVP_PKEY_CTX *locpctx = NULL;
EVP_SIGNATURE *signature = NULL;
+ const char *desc;
EVP_KEYMGMT *tmp_keymgmt = NULL;
const OSSL_PROVIDER *tmp_prov = NULL;
const char *supported_sig = NULL;
@@ -251,16 +252,19 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
}
+ desc = signature->description != NULL ? signature->description : "";
if (ver) {
if (signature->digest_verify_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s digest_verify_init:%s", signature->type_name, desc);
goto err;
}
ret = signature->digest_verify_init(locpctx->op.sig.algctx,
mdname, provkey, params);
} else {
if (signature->digest_sign_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s digest_sign_init:%s", signature->type_name, desc);
goto err;
}
ret = signature->digest_sign_init(locpctx->op.sig.algctx,
@@ -275,6 +279,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
goto end;
if (type == NULL) /* This check is redundant but clarifies matters */
ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ ver ? "%s digest_verify_init:%s" : "%s digest_sign_init:%s",
+ signature->type_name, desc);
err:
evp_pkey_ctx_free_old_ops(locpctx);
@@ -395,7 +402,10 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
EVP_PKEY_CTX *pctx = ctx->pctx;
+ int ret;
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
@@ -408,13 +418,21 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|| pctx->op.sig.signature == NULL)
goto legacy;
- if (pctx->op.sig.signature->digest_sign_update == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ signature = pctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->digest_sign_update == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s digest_sign_update:%s", signature->type_name, desc);
return 0;
}
- return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.algctx,
- data, dsize);
+ ERR_set_mark();
+ ret = signature->digest_sign_update(pctx->op.sig.algctx, data, dsize);
+ if (ret <= 0 && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_sign_update:%s", signature->type_name, desc);
+ ERR_clear_last_mark();
+ return ret;
legacy:
if (pctx != NULL) {
@@ -430,7 +448,10 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
EVP_PKEY_CTX *pctx = ctx->pctx;
+ int ret;
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
@@ -443,13 +464,21 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|| pctx->op.sig.signature == NULL)
goto legacy;
- if (pctx->op.sig.signature->digest_verify_update == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ signature = pctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->digest_verify_update == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s digest_verify_update:%s", signature->type_name, desc);
return 0;
}
- return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.algctx,
- data, dsize);
+ ERR_set_mark();
+ ret = signature->digest_verify_update(pctx->op.sig.algctx, data, dsize);
+ if (ret <= 0 && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_verify_update:%s", signature->type_name, desc);
+ ERR_clear_last_mark();
+ return ret;
legacy:
if (pctx != NULL) {
@@ -466,6 +495,8 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
size_t *siglen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
int sctx = 0;
int r = 0;
EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
@@ -481,15 +512,28 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
|| pctx->op.sig.signature == NULL)
goto legacy;
+ signature = pctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->digest_sign_final == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s digest_sign_final:%s", signature->type_name, desc);
+ return 0;
+ }
+
if (sigret != NULL && (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
/* try dup */
dctx = EVP_PKEY_CTX_dup(pctx);
if (dctx != NULL)
pctx = dctx;
}
- r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
- sigret, siglen,
- sigret == NULL ? 0 : *siglen);
+
+ ERR_set_mark();
+ r = signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen,
+ sigret == NULL ? 0 : *siglen);
+ if (!r && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_sign_final:%s", signature->type_name, desc);
+ ERR_clear_last_mark();
if (dctx == NULL && sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@@ -574,6 +618,7 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
{
EVP_PKEY_CTX *pctx = ctx->pctx;
+ int ret;
if (pctx == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
@@ -588,13 +633,21 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
if (pctx->operation == EVP_PKEY_OP_SIGNCTX
&& pctx->op.sig.algctx != NULL
&& pctx->op.sig.signature != NULL) {
- if (pctx->op.sig.signature->digest_sign != NULL) {
+ EVP_SIGNATURE *signature = pctx->op.sig.signature;
+
+ if (signature->digest_sign != NULL) {
+ const char *desc = signature->description != NULL ? signature->description : "";
+
if (sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
- return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx,
- sigret, siglen,
- sigret == NULL ? 0 : *siglen,
- tbs, tbslen);
+ ERR_set_mark();
+ ret = signature->digest_sign(pctx->op.sig.algctx, sigret, siglen,
+ sigret == NULL ? 0 : *siglen, tbs, tbslen);
+ if (ret <= 0 && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_sign:%s", signature->type_name, desc);
+ ERR_clear_last_mark();
+ return ret;
}
} else {
/* legacy */
@@ -610,6 +663,8 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
int vctx = 0;
unsigned int mdlen = 0;
unsigned char md[EVP_MAX_MD_SIZE];
@@ -627,14 +682,27 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|| pctx->op.sig.signature == NULL)
goto legacy;
+ signature = pctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->digest_verify_final == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s digest_verify_final:%s", signature->type_name, desc);
+ return 0;
+ }
+
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
/* try dup */
dctx = EVP_PKEY_CTX_dup(pctx);
if (dctx != NULL)
pctx = dctx;
}
- r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
- sig, siglen);
+
+ ERR_set_mark();
+ r = signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen);
+ if (!r && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_verify_final:%s", signature->type_name, desc);
+ ERR_clear_last_mark();
if (dctx == NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@@ -702,10 +770,18 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
&& pctx->op.sig.algctx != NULL
&& pctx->op.sig.signature != NULL) {
if (pctx->op.sig.signature->digest_verify != NULL) {
+ EVP_SIGNATURE *signature = pctx->op.sig.signature;
+ const char *desc = signature->description != NULL ? signature->description : "";
+ int ret;
+
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
- return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx,
- sigret, siglen,
- tbs, tbslen);
+ ERR_set_mark();
+ ret = signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen);
+ if (ret <= 0 && ERR_count_to_mark() == 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_verify:%s", signature->type_name, desc);
+ ERR_clear_last_mark();
+ return ret;
}
} else {
/* legacy */
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 665cafbc21a7..08c0d6a7b2b7 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -480,6 +480,12 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
}
rctx->legacy_keytype = pctx->legacy_keytype;
+ if (pctx->keymgmt != NULL) {
+ if (!EVP_KEYMGMT_up_ref(pctx->keymgmt))
+ goto err;
+ rctx->keymgmt = pctx->keymgmt;
+ }
+
if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {
if (pctx->op.kex.exchange != NULL) {
rctx->op.kex.exchange = pctx->op.kex.exchange;
@@ -584,6 +590,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
EVP_KEYMGMT *tmp_keymgmt = pctx->keymgmt;
void *provkey;
+ if (pctx->pkey == NULL)
+ return rctx;
+
provkey = evp_pkey_export_to_provider(pctx->pkey, pctx->libctx,
&tmp_keymgmt, pctx->propquery);
if (provkey == NULL)
diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c
index e5bb7da255f3..d01df3282fa4 100644
--- a/crypto/evp/signature.c
+++ b/crypto/evp/signature.c
@@ -55,6 +55,7 @@ static void *evp_signature_from_algorithm(int name_id,
{
const OSSL_DISPATCH *fns = algodef->implementation;
EVP_SIGNATURE *signature = NULL;
+ const char *desc;
/* Counts newctx / freectx */
int ctxfncnt = 0;
/* Counts all init functions */
@@ -72,6 +73,7 @@ static void *evp_signature_from_algorithm(int name_id,
if ((signature->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
goto err;
signature->description = algodef->algorithm_description;
+ desc = signature->description != NULL ? signature->description : "";
for (; fns->function_id != 0; fns++) {
switch (fns->function_id) {
@@ -290,23 +292,30 @@ static void *evp_signature_from_algorithm(int name_id,
*/
valid = 1;
/* Start with the ones where counters say enough */
- if (ctxfncnt != 2)
- /* newctx or freectx missing */
+ if (ctxfncnt != 2) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s newctx or freectx:%s", signature->type_name, desc);
valid = 0;
+ }
if (valid
&& ((gparamfncnt != 0 && gparamfncnt != 2)
|| (sparamfncnt != 0 && sparamfncnt != 2)
|| (gmdparamfncnt != 0 && gmdparamfncnt != 2)
- || (smdparamfncnt != 0 && smdparamfncnt != 2)))
+ || (smdparamfncnt != 0 && smdparamfncnt != 2))) {
/*
* Params functions are optional, but if defined, they must
* be pairwise complete sets, i.e. a getter must have an
* associated gettable, etc
*/
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s params getter or setter:%s", signature->type_name, desc);
valid = 0;
- if (valid && initfncnt == 0)
- /* No init functions */
+ }
+ if (valid && initfncnt == 0) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s init:%s", signature->type_name, desc);
valid = 0;
+ }
/* Now we check for function combinations */
if (valid
@@ -315,17 +324,23 @@ static void *evp_signature_from_algorithm(int name_id,
|| (signature->sign_message_init != NULL
&& signature->sign == NULL
&& (signature->sign_message_update == NULL
- || signature->sign_message_final == NULL))))
- /* sign_init functions with no signing function? That's weird */
+ || signature->sign_message_final == NULL)))) {
+ /* sign_init function(s) with no signing function? That's weird */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s signing function:%s", signature->type_name, desc);
valid = 0;
+ }
if (valid
&& (signature->sign != NULL
|| signature->sign_message_update != NULL
|| signature->sign_message_final != NULL)
&& signature->sign_init == NULL
- && signature->sign_message_init == NULL)
- /* signing functions with no sign_init? That's odd */
+ && signature->sign_message_init == NULL) {
+ /* signing function(s) with no sign_init? That's odd */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s sign_init or sign_message_init:%s", signature->type_name, desc);
valid = 0;
+ }
if (valid
&& ((signature->verify_init != NULL
@@ -333,46 +348,105 @@ static void *evp_signature_from_algorithm(int name_id,
|| (signature->verify_message_init != NULL
&& signature->verify == NULL
&& (signature->verify_message_update == NULL
- || signature->verify_message_final == NULL))))
- /* verify_init functions with no verification function? That's weird */
+ || signature->verify_message_final == NULL)))) {
+ /* verify_init function(s) with no verification function? That's weird */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s verification function:%s", signature->type_name, desc);
valid = 0;
+ }
if (valid
&& (signature->verify != NULL
|| signature->verify_message_update != NULL
|| signature->verify_message_final != NULL)
&& signature->verify_init == NULL
- && signature->verify_message_init == NULL)
- /* verification functions with no verify_init? That's odd */
+ && signature->verify_message_init == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s verify_init or verify_message_init:%s",
+ signature->type_name, desc);
+ /* verification function(s) with no verify_init? That's odd */
valid = 0;
+ }
if (valid
&& (signature->verify_recover_init != NULL)
- && (signature->verify_recover == NULL))
- /* verify_recover_init functions with no verify_recover? How quaint */
+ && (signature->verify_recover == NULL)) {
+ /* verify_recover_init function with no verify_recover? How quaint */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s verify_recover:%s", signature->type_name, desc);
valid = 0;
+ }
if (valid
&& (signature->digest_sign_init != NULL
&& signature->digest_sign == NULL
&& (signature->digest_sign_update == NULL
- || signature->digest_sign_final == NULL)))
- /*
- * You can't have a digest_sign_init without *some* performing functions
- */
+ || signature->digest_sign_final == NULL))) {
+ /* You can't have a digest_sign_init without *some* performing functions */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s digest_sign function:%s", signature->type_name, desc);
valid = 0;
+ }
if (valid
&& ((signature->digest_verify_init != NULL
&& signature->digest_verify == NULL
&& (signature->digest_verify_update == NULL
- || signature->digest_verify_final == NULL))))
- /*
- * You can't have a digest_verify_init without *some* performing functions
- */
+ || signature->digest_verify_final == NULL)))) {
+ /* You can't have a digest_verify_init without *some* performing functions */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s digest_verify function:%s", signature->type_name, desc);
valid = 0;
+ }
- if (!valid) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
+ if (!valid)
+ goto err;
+
+ if ((signature->digest_sign != NULL
+ || signature->digest_sign_update != NULL
+ || signature->digest_sign_final != NULL)
+ && signature->digest_sign_init == NULL) {
+ /* digest signing function(s) with no digest_sign_init? That's odd */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s digest_sign_init:%s", signature->type_name, desc);
+ goto err;
+ }
+
+ if ((signature->digest_verify != NULL
+ || signature->digest_verify_update != NULL
+ || signature->digest_verify_final != NULL)
+ && signature->digest_verify_init == NULL) {
+ /* digest verification function(s) with no digest_verify_init? That's odd */
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "missing %s digest_verify_init:%s", signature->type_name, desc);
+ goto err;
+ }
+
+ if ((signature->sign_message_update == NULL) !=
+ (signature->sign_message_final == NULL)) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "only one of %s message signing update and final available:%s",
+ signature->type_name, desc);
+ goto err;
+ }
+ if ((signature->verify_message_update == NULL) !=
+ (signature->verify_message_final == NULL)) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "only one of %s message verification update and final available:%s",
+ signature->type_name, desc);
+ goto err;
+ }
+ if ((signature->digest_sign_update == NULL) !=
+ (signature->digest_sign_final == NULL)) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "only one of %s digest signing update and final available:%s",
+ signature->type_name, desc);
+ goto err;
+ }
+ if ((signature->digest_verify_update == NULL) !=
+ (signature->digest_verify_final == NULL)) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS,
+ "only one of %s digest verification update and final available:%s",
+ signature->type_name, desc);
goto err;
}
@@ -499,6 +573,7 @@ const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig)
static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
int operation, const OSSL_PARAM params[])
{
+ const char *desc;
int ret = 0;
void *provkey = NULL;
EVP_KEYMGMT *tmp_keymgmt = NULL;
@@ -557,7 +632,7 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
* ensured that the key is at least exported to a provider (above).
*/
if (signature->query_key_types != NULL) {
- /* This is expect to be a NULL terminated array */
+ /* This is expected to be a NULL-terminated array */
const char **keytypes;
keytypes = signature->query_key_types();
@@ -708,6 +783,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
/* No more legacy from here down to legacy: */
ctx->op.sig.signature = signature;
+ desc = signature->description != NULL ? signature->description : "";
+
ctx->op.sig.algctx =
signature->newctx(ossl_provider_ctx(signature->prov), ctx->propquery);
if (ctx->op.sig.algctx == NULL) {
@@ -719,7 +796,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
switch (operation) {
case EVP_PKEY_OP_SIGN:
if (signature->sign_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s sign_init:%s", signature->type_name, desc);
ret = -2;
goto err;
}
@@ -727,7 +805,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
break;
case EVP_PKEY_OP_SIGNMSG:
if (signature->sign_message_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s sign_message_init:%s", signature->type_name, desc);
ret = -2;
goto err;
}
@@ -735,7 +814,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
break;
case EVP_PKEY_OP_VERIFY:
if (signature->verify_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify_init:%s", signature->type_name, desc);
ret = -2;
goto err;
}
@@ -743,7 +823,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
break;
case EVP_PKEY_OP_VERIFYMSG:
if (signature->verify_message_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify_message_init:%s", signature->type_name, desc);
ret = -2;
goto err;
}
@@ -751,7 +832,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
break;
case EVP_PKEY_OP_VERIFYRECOVER:
if (signature->verify_recover_init == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify_recover_init:%s", signature->type_name, desc);
ret = -2;
goto err;
}
@@ -849,6 +931,10 @@ int EVP_PKEY_sign_message_init(EVP_PKEY_CTX *ctx,
int EVP_PKEY_sign_message_update(EVP_PKEY_CTX *ctx,
const unsigned char *in, size_t inlen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
+ int ret;
+
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return -1;
@@ -859,18 +945,28 @@ int EVP_PKEY_sign_message_update(EVP_PKEY_CTX *ctx,
return -1;
}
- if (ctx->op.sig.signature->sign_message_update == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->sign_message_update == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s sign_message_update:%s", signature->type_name, desc);
return -2;
}
- return ctx->op.sig.signature->sign_message_update(ctx->op.sig.algctx,
- in, inlen);
+ ret = signature->sign_message_update(ctx->op.sig.algctx, in, inlen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s sign_message_update:%s", signature->type_name, desc);
+ return ret;
}
int EVP_PKEY_sign_message_final(EVP_PKEY_CTX *ctx,
unsigned char *sig, size_t *siglen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
+ int ret;
+
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return -1;
@@ -881,20 +977,28 @@ int EVP_PKEY_sign_message_final(EVP_PKEY_CTX *ctx,
return -1;
}
- if (ctx->op.sig.signature->sign_message_final == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->sign_message_final == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s sign_message_final:%s", signature->type_name, desc);
return -2;
}
- return ctx->op.sig.signature->sign_message_final(ctx->op.sig.algctx,
- sig, siglen,
- (sig == NULL) ? 0 : *siglen);
+ ret = signature->sign_message_final(ctx->op.sig.algctx, sig, siglen,
+ (sig == NULL) ? 0 : *siglen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s sign_message_final:%s", signature->type_name, desc);
+ return ret;
}
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
int ret;
if (ctx == NULL) {
@@ -911,14 +1015,19 @@ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
if (ctx->op.sig.algctx == NULL)
goto legacy;
- if (ctx->op.sig.signature->sign == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->sign == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s sign:%s", signature->type_name, desc);
return -2;
}
- ret = ctx->op.sig.signature->sign(ctx->op.sig.algctx, sig, siglen,
- (sig == NULL) ? 0 : *siglen, tbs, tbslen);
-
+ ret = signature->sign(ctx->op.sig.algctx, sig, siglen,
+ (sig == NULL) ? 0 : *siglen, tbs, tbslen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s sign:%s", signature->type_name, desc);
return ret;
legacy:
@@ -977,6 +1086,10 @@ int EVP_PKEY_CTX_set_signature(EVP_PKEY_CTX *ctx,
int EVP_PKEY_verify_message_update(EVP_PKEY_CTX *ctx,
const unsigned char *in, size_t inlen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
+ int ret;
+
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return -1;
@@ -987,17 +1100,27 @@ int EVP_PKEY_verify_message_update(EVP_PKEY_CTX *ctx,
return -1;
}
- if (ctx->op.sig.signature->verify_message_update == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->verify_message_update == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify_message_update:%s", signature->type_name, desc);
return -2;
}
- return ctx->op.sig.signature->verify_message_update(ctx->op.sig.algctx,
- in, inlen);
+ ret = signature->verify_message_update(ctx->op.sig.algctx, in, inlen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s verify_message_update:%s", signature->type_name, desc);
+ return ret;
}
int EVP_PKEY_verify_message_final(EVP_PKEY_CTX *ctx)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
+ int ret;
+
if (ctx == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return -1;
@@ -1008,19 +1131,28 @@ int EVP_PKEY_verify_message_final(EVP_PKEY_CTX *ctx)
return -1;
}
- if (ctx->op.sig.signature->verify_message_final == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->verify_message_final == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify_message_final:%s", signature->type_name, desc);
return -2;
}
/* The signature must have been set with EVP_PKEY_CTX_set_signature() */
- return ctx->op.sig.signature->verify_message_final(ctx->op.sig.algctx);
+ ret = signature->verify_message_final(ctx->op.sig.algctx);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s verify_message_final:%s", signature->type_name, desc);
+ return ret;
}
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
const unsigned char *sig, size_t siglen,
const unsigned char *tbs, size_t tbslen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
int ret;
if (ctx == NULL) {
@@ -1037,13 +1169,19 @@ int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
if (ctx->op.sig.algctx == NULL)
goto legacy;
- if (ctx->op.sig.signature->verify == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->verify == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify:%s", signature->type_name, desc);
return -2;
}
ret = ctx->op.sig.signature->verify(ctx->op.sig.algctx, sig, siglen,
tbs, tbslen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s verify:%s", signature->type_name, desc);
return ret;
legacy:
@@ -1076,6 +1214,8 @@ int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
unsigned char *rout, size_t *routlen,
const unsigned char *sig, size_t siglen)
{
+ EVP_SIGNATURE *signature;
+ const char *desc;
int ret;
if (ctx == NULL) {
@@ -1091,15 +1231,19 @@ int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
if (ctx->op.sig.algctx == NULL)
goto legacy;
- if (ctx->op.sig.signature->verify_recover == NULL) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ signature = ctx->op.sig.signature;
+ desc = signature->description != NULL ? signature->description : "";
+ if (signature->verify_recover == NULL) {
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED,
+ "%s verify_recover:%s", signature->type_name, desc);
return -2;
}
- ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.algctx, rout,
- routlen,
- (rout == NULL ? 0 : *routlen),
- sig, siglen);
+ ret = signature->verify_recover(ctx->op.sig.algctx, rout, routlen,
+ (rout == NULL ? 0 : *routlen), sig, siglen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s verify_recover:%s", signature->type_name, desc);
return ret;
legacy:
if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) {
diff --git a/crypto/hmac/hmac_s390x.c b/crypto/hmac/hmac_s390x.c
index 02e1cd1dd650..70a17a7664af 100644
--- a/crypto/hmac/hmac_s390x.c
+++ b/crypto/hmac/hmac_s390x.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2025 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
@@ -14,6 +14,7 @@
#include "hmac_local.h"
#include "openssl/obj_mac.h"
#include "openssl/evp.h"
+#include "openssl/err.h"
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
# include <openssl/engine.h>
#endif
@@ -189,6 +190,11 @@ int s390x_HMAC_update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
{
size_t remain, num;
+ if (ctx->plat.s390x.iimp != 1) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
+ return 0;
+ }
+
if (len == 0)
return 1;
@@ -250,6 +256,11 @@ int s390x_HMAC_final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
void *result;
unsigned int res_len;
+ if (ctx->plat.s390x.iimp != 1) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+ return 0;
+ }
+
ctx->plat.s390x.iimp = 0; /* last block */
s390x_call_kmac(ctx, ctx->plat.s390x.buf, ctx->plat.s390x.num);
diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c
index 725ec1908499..fcf8a69e07a8 100644
--- a/crypto/http/http_lib.c
+++ b/crypto/http/http_lib.c
@@ -59,7 +59,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
const char *user, *user_end;
const char *host, *host_end;
const char *port, *port_end;
- unsigned int portnum;
+ unsigned int portnum = 0;
const char *path, *path_end;
const char *query, *query_end;
const char *frag, *frag_end;
@@ -107,13 +107,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
p = ++host_end;
} else {
/* look for start of optional port, path, query, or fragment */
- host_end = strchr(host, ':');
- if (host_end == NULL)
- host_end = strchr(host, '/');
- if (host_end == NULL)
- host_end = strchr(host, '?');
- if (host_end == NULL)
- host_end = strchr(host, '#');
+ host_end = strpbrk(host, ":/?#");
if (host_end == NULL) /* the remaining string is just the hostname */
host_end = host + strlen(host);
p = host_end;
diff --git a/crypto/ml_kem/ml_kem.c b/crypto/ml_kem/ml_kem.c
index ec7523343584..4474af0f87cb 100644
--- a/crypto/ml_kem/ml_kem.c
+++ b/crypto/ml_kem/ml_kem.c
@@ -9,6 +9,7 @@
#include <openssl/byteorder.h>
#include <openssl/rand.h>
+#include <openssl/proverr.h>
#include "crypto/ml_kem.h"
#include "internal/common.h"
#include "internal/constant_time.h"
@@ -1278,16 +1279,26 @@ static int parse_pubkey(const uint8_t *in, EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
const ML_KEM_VINFO *vinfo = key->vinfo;
/* Decode and check |t| */
- if (!vector_decode_12(key->t, in, vinfo->rank))
+ if (!vector_decode_12(key->t, in, vinfo->rank)) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
+ "%s invalid public 't' vector",
+ vinfo->algorithm_name);
return 0;
+ }
/* Save the matrix |m| recovery seed |rho| */
memcpy(key->rho, in + vinfo->vector_bytes, ML_KEM_RANDOM_BYTES);
/*
* Pre-compute the public key hash, needed for both encap and decap.
* Also pre-compute the matrix expansion, stored with the public key.
*/
- return hash_h(key->pkhash, in, vinfo->pubkey_bytes, mdctx, key)
- && matrix_expand(mdctx, key);
+ if (!hash_h(key->pkhash, in, vinfo->pubkey_bytes, mdctx, key)
+ || !matrix_expand(mdctx, key)) {
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
+ "internal error while parsing %s public key",
+ vinfo->algorithm_name);
+ return 0;
+ }
+ return 1;
}
/*
@@ -1301,8 +1312,12 @@ static int parse_prvkey(const uint8_t *in, EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
const ML_KEM_VINFO *vinfo = key->vinfo;
/* Decode and check |s|. */
- if (!vector_decode_12(key->s, in, vinfo->rank))
+ if (!vector_decode_12(key->s, in, vinfo->rank)) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
+ "%s invalid private 's' vector",
+ vinfo->algorithm_name);
return 0;
+ }
in += vinfo->vector_bytes;
if (!parse_pubkey(in, mdctx, key))
@@ -1310,8 +1325,12 @@ static int parse_prvkey(const uint8_t *in, EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
in += vinfo->pubkey_bytes;
/* Check public key hash. */
- if (memcmp(key->pkhash, in, ML_KEM_PKHASH_BYTES) != 0)
+ if (memcmp(key->pkhash, in, ML_KEM_PKHASH_BYTES) != 0) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
+ "%s public key hash mismatch",
+ vinfo->algorithm_name);
return 0;
+ }
in += ML_KEM_PKHASH_BYTES;
memcpy(key->z, in, ML_KEM_RANDOM_BYTES);
@@ -1405,6 +1424,11 @@ int genkey(const uint8_t seed[ML_KEM_SEED_BYTES],
end:
OPENSSL_cleanse((void *)augmented_seed, ML_KEM_RANDOM_BYTES);
OPENSSL_cleanse((void *)sigma, ML_KEM_RANDOM_BYTES);
+ if (ret == 0) {
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
+ "internal error while generating %s private key",
+ vinfo->algorithm_name);
+ }
return ret;
}
@@ -1430,10 +1454,14 @@ int encap(uint8_t *ctext, uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
memcpy(input + ML_KEM_RANDOM_BYTES, key->pkhash, ML_KEM_PKHASH_BYTES);
ret = hash_g(Kr, input, sizeof(input), mdctx, key)
&& encrypt_cpa(ctext, entropy, r, tmp, mdctx, key);
+ OPENSSL_cleanse((void *)input, sizeof(input));
if (ret)
memcpy(secret, Kr, ML_KEM_SHARED_SECRET_BYTES);
- OPENSSL_cleanse((void *)input, sizeof(input));
+ else
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
+ "internal error while performing %s encapsulation",
+ key->vinfo->algorithm_name);
return ret;
}
@@ -1477,8 +1505,12 @@ int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
* The same action is taken, if also |encrypt_cpa| should catastrophically
* fail, due to failure of the |PRF| underlying the CBD functions.
*/
- if (!kdf(failure_key, key->z, ctext, vinfo->ctext_bytes, mdctx, key))
+ if (!kdf(failure_key, key->z, ctext, vinfo->ctext_bytes, mdctx, key)) {
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
+ "internal error while performing %s decapsulation",
+ vinfo->algorithm_name);
return 0;
+ }
decrypt_cpa(decrypted, ctext, tmp, key);
memcpy(decrypted + ML_KEM_SHARED_SECRET_BYTES, pkhash, ML_KEM_PKHASH_BYTES);
if (!hash_g(Kr, decrypted, sizeof(decrypted), mdctx, key)
@@ -1550,7 +1582,7 @@ ossl_ml_kem_key_reset(ML_KEM_KEY *key)
*/
if (ossl_ml_kem_have_prvkey(key))
OPENSSL_cleanse(key->s,
- key->vinfo->vector_bytes + 2 * ML_KEM_RANDOM_BYTES);
+ key->vinfo->rank * sizeof(scalar) + 2 * ML_KEM_RANDOM_BYTES);
OPENSSL_free(key->t);
key->d = key->z = (uint8_t *)(key->s = key->m = key->t = NULL);
}
@@ -1582,8 +1614,11 @@ ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx, const char *properties,
const ML_KEM_VINFO *vinfo = ossl_ml_kem_get_vinfo(evp_type);
ML_KEM_KEY *key;
- if (vinfo == NULL)
+ if (vinfo == NULL) {
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT,
+ "unsupported ML-KEM key type: %d", evp_type);
return NULL;
+ }
if ((key = OPENSSL_malloc(sizeof(*key))) == NULL)
return NULL;
@@ -1602,9 +1637,12 @@ ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx, const char *properties,
&& key->shake256_md != NULL
&& key->sha3_256_md != NULL
&& key->sha3_512_md != NULL)
- return key;
+ return key;
ossl_ml_kem_key_free(key);
+ ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
+ "missing SHA3 digest algorithms while creating %s key",
+ vinfo->algorithm_name);
return NULL;
}
diff --git a/crypto/params_dup.c b/crypto/params_dup.c
index 769629bbf324..362a0e62faaa 100644
--- a/crypto/params_dup.c
+++ b/crypto/params_dup.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2021-2025 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
@@ -190,18 +190,18 @@ OSSL_PARAM *OSSL_PARAM_merge(const OSSL_PARAM *p1, const OSSL_PARAM *p2)
while (1) {
/* If list1 is finished just tack list2 onto the end */
if (*p1cur == NULL) {
- do {
+ while (*p2cur != NULL) {
*dst++ = **p2cur;
p2cur++;
- } while (*p2cur != NULL);
+ }
break;
}
/* If list2 is finished just tack list1 onto the end */
if (*p2cur == NULL) {
- do {
+ while (*p1cur != NULL) {
*dst++ = **p1cur;
p1cur++;
- } while (*p1cur != NULL);
+ }
break;
}
/* consume the list element with the smaller key */
diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c
index 7532d4d43923..f408717849f4 100644
--- a/crypto/params_from_text.c
+++ b/crypto/params_from_text.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -220,9 +220,9 @@ int OSSL_PARAM_print_to_bio(const OSSL_PARAM *p, BIO *bio, int print_values)
BIGNUM *bn;
#ifndef OPENSSL_SYS_UEFI
double d;
+ int dok;
#endif
int ok = -1;
- int dok;
/*
* Iterate through each key in the array printing its key and value
@@ -280,16 +280,16 @@ int OSSL_PARAM_print_to_bio(const OSSL_PARAM *p, BIO *bio, int print_values)
case OSSL_PARAM_OCTET_STRING:
ok = BIO_dump(bio, (char *)p->data, p->data_size);
break;
+#ifndef OPENSSL_SYS_UEFI
case OSSL_PARAM_REAL:
dok = 0;
-#ifndef OPENSSL_SYS_UEFI
dok = OSSL_PARAM_get_double(p, &d);
-#endif
if (dok == 1)
ok = BIO_printf(bio, "%f\n", d);
else
ok = BIO_printf(bio, "error getting value\n");
break;
+#endif
default:
ok = BIO_printf(bio, "unknown type (%u) of %zu bytes\n",
p->data_type, p->data_size);
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index 2cd9a219c239..d677963c6176 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -218,6 +218,25 @@ my @segment_stack = ();
my $current_function;
my %globals;
+{ package vex_prefix; # pick up vex prefixes, example: {vex} vpmadd52luq m256, %ymm, %ymm
+ sub re {
+ my ($class, $line) = @_;
+ my $self = {};
+ my $ret;
+
+ if ($$line =~ /(^\{vex\})/) {
+ bless $self,$class;
+ $self->{value} = $1;
+ $ret = $self;
+ $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
+ }
+ $ret;
+ }
+ sub out {
+ my $self = shift;
+ $self->{value};
+ }
+}
{ package opcode; # pick up opcodes
sub re {
my ($class, $line) = @_;
@@ -1396,7 +1415,11 @@ while(defined(my $line=<>)) {
if (my $directive=directive->re(\$line)) {
printf "%s",$directive->out();
- } elsif (my $opcode=opcode->re(\$line)) {
+ } else {
+ if (my $vex_prefix=vex_prefix->re(\$line)) {
+ printf "%s",$vex_prefix->out();
+ }
+ if (my $opcode=opcode->re(\$line)) {
my $asm = eval("\$".$opcode->mnemonic());
if ((ref($asm) eq 'CODE') && scalar(my @bytes=&$asm($line))) {
@@ -1446,6 +1469,7 @@ while(defined(my $line=<>)) {
} else {
printf "\t%s",$opcode->out();
}
+ }
}
print $line,"\n";
diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c
index 3f9ba3b7d6df..99f3b9eb9719 100644
--- a/crypto/pkcs7/pk7_smime.c
+++ b/crypto/pkcs7/pk7_smime.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2025 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
@@ -333,10 +333,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
if (flags & PKCS7_TEXT) {
if (!SMIME_text(tmpout, out)) {
ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR);
- BIO_free(tmpout);
goto err;
}
- BIO_free(tmpout);
}
/* Now Verify All Signatures */
@@ -354,6 +352,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
ret = 1;
err:
+ if (flags & PKCS7_TEXT)
+ BIO_free(tmpout);
X509_STORE_CTX_free(cert_ctx);
OPENSSL_free(buf);
if (indata != NULL)
diff --git a/crypto/property/property.c b/crypto/property/property.c
index 2c35222f76f8..4141c1760300 100644
--- a/crypto/property/property.c
+++ b/crypto/property/property.c
@@ -348,7 +348,7 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
/* Insert into the hash table if required */
if (!ossl_property_write_lock(store)) {
- OPENSSL_free(impl);
+ impl_free(impl);
return 0;
}
diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c
index 5ec50f97e4a5..9649517dd264 100644
--- a/crypto/provider_conf.c
+++ b/crypto/provider_conf.c
@@ -379,7 +379,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
ok = provider_conf_params(NULL, &entry, NULL, value, cnf);
if (ok >= 1 && (entry.path != NULL || entry.parameters != NULL)) {
ok = ossl_provider_info_add_to_store(libctx, &entry);
- added = 1;
+ added = ok;
}
if (added == 0)
ossl_provider_info_clear(&entry);
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 490991b5e58b..ce5cf36eef9d 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -1511,6 +1511,16 @@ static int provider_activate_fallbacks(struct provider_store_st *store)
return ret;
}
+int ossl_provider_activate_fallbacks(OSSL_LIB_CTX *ctx)
+{
+ struct provider_store_st *store = get_provider_store(ctx);
+
+ if (store == NULL)
+ return 0;
+
+ return provider_activate_fallbacks(store);
+}
+
int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
int (*cb)(OSSL_PROVIDER *provider,
void *cbdata),
@@ -1948,12 +1958,12 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
BIO_printf(trc_out,
"(provider %s) names %s, prop_def %s, desc %s\n",
prov->name,
- res->algorithm_names == NULL ? "none" :
- res->algorithm_names,
- res->property_definition == NULL ? "none" :
- res->property_definition,
- res->algorithm_description == NULL ? "none" :
- res->algorithm_description);
+ idx->algorithm_names == NULL ? "none" :
+ idx->algorithm_names,
+ idx->property_definition == NULL ? "none" :
+ idx->property_definition,
+ idx->algorithm_description == NULL ? "none" :
+ idx->algorithm_description);
}
} else {
BIO_printf(trc_out, "(provider %s) query_operation failed\n", prov->name);
@@ -2409,6 +2419,11 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
return ERR_pop_to_mark();
}
+static int core_count_to_mark(const OSSL_CORE_HANDLE *handle)
+{
+ return ERR_count_to_mark();
+}
+
static void core_indicator_get_callback(OPENSSL_CORE_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb)
{
@@ -2590,6 +2605,7 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK,
(void (*)(void))core_clear_last_error_mark },
{ OSSL_FUNC_CORE_POP_ERROR_TO_MARK, (void (*)(void))core_pop_error_to_mark },
+ { OSSL_FUNC_CORE_COUNT_TO_MARK, (void (*)(void))core_count_to_mark },
{ OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))ossl_core_bio_new_file },
{ OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))ossl_core_bio_new_mem_buf },
{ OSSL_FUNC_BIO_READ_EX, (void (*)(void))ossl_core_bio_read_ex },
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 9233322b5ff5..5b9713eda629 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -289,6 +289,9 @@ const RAND_METHOD *RAND_get_rand_method(void)
if (!RUN_ONCE(&rand_init, do_rand_init))
return NULL;
+ if (rand_meth_lock == NULL)
+ return NULL;
+
if (!CRYPTO_THREAD_read_lock(rand_meth_lock))
return NULL;
tmp_meth = default_RAND_meth;
@@ -755,7 +758,7 @@ static EVP_RAND_CTX *rand_new_crngt(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent)
*/
static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
{
- EVP_RAND_CTX *ret;
+ EVP_RAND_CTX *ret, *seed, *newseed = NULL, *primary;
if (dgbl == NULL)
return NULL;
@@ -764,34 +767,26 @@ static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
return NULL;
ret = dgbl->primary;
+ seed = dgbl->seed;
CRYPTO_THREAD_unlock(dgbl->lock);
if (ret != NULL)
return ret;
- if (!CRYPTO_THREAD_write_lock(dgbl->lock))
- return NULL;
-
- ret = dgbl->primary;
- if (ret != NULL) {
- CRYPTO_THREAD_unlock(dgbl->lock);
- return ret;
- }
-
#if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
/* Create a seed source for libcrypto or jitter enabled FIPS provider */
- if (dgbl->seed == NULL) {
+ if (seed == NULL) {
ERR_set_mark();
- dgbl->seed = rand_new_seed(ctx);
+ seed = newseed = rand_new_seed(ctx);
ERR_pop_to_mark();
}
#endif /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */
#if defined(FIPS_MODULE)
/* The FIPS provider has entropy health tests instead of the primary */
- ret = rand_new_crngt(ctx, dgbl->seed);
+ ret = rand_new_crngt(ctx, seed);
#else /* FIPS_MODULE */
- ret = rand_new_drbg(ctx, dgbl->seed, PRIMARY_RESEED_INTERVAL,
+ ret = rand_new_drbg(ctx, seed, PRIMARY_RESEED_INTERVAL,
PRIMARY_RESEED_TIME_INTERVAL);
#endif /* FIPS_MODULE */
@@ -799,12 +794,30 @@ static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
* The primary DRBG may be shared between multiple threads so we must
* enable locking.
*/
- dgbl->primary = ret;
- if (ret != NULL && !EVP_RAND_enable_locking(ret)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING);
+ if (ret == NULL || !EVP_RAND_enable_locking(ret)) {
+ if (ret != NULL) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING);
+ EVP_RAND_CTX_free(ret);
+ }
+ if (newseed == NULL)
+ return NULL;
+ /* else carry on and store seed */
+ ret = NULL;
+ }
+
+ if (!CRYPTO_THREAD_write_lock(dgbl->lock))
+ return NULL;
+
+ primary = dgbl->primary;
+ if (primary != NULL) {
+ CRYPTO_THREAD_unlock(dgbl->lock);
EVP_RAND_CTX_free(ret);
- ret = dgbl->primary = NULL;
+ EVP_RAND_CTX_free(newseed);
+ return primary;
}
+ if (newseed != NULL)
+ dgbl->seed = newseed;
+ dgbl->primary = ret;
CRYPTO_THREAD_unlock(dgbl->lock);
return ret;
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index f76bb7748369..32084a822cac 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -734,3 +734,18 @@ err:
return ret;
}
+
+#ifdef FIPS_MODULE
+int ossl_rsa_key_pairwise_test(RSA *rsa)
+{
+ OSSL_CALLBACK *stcb;
+ void *stcbarg;
+ int res;
+
+ OSSL_SELF_TEST_get_callback(rsa->libctx, &stcb, &stcbarg);
+ res = rsa_keygen_pairwise_test(rsa, stcb, stcbarg);
+ if (res <= 0)
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
+ return res;
+}
+#endif /* FIPS_MODULE */
diff --git a/crypto/slh_dsa/slh_hash.c b/crypto/slh_dsa/slh_hash.c
index 6a8d6bab03c1..8eb8ab4e8604 100644
--- a/crypto/slh_dsa/slh_hash.c
+++ b/crypto/slh_dsa/slh_hash.c
@@ -158,6 +158,9 @@ slh_hmsg_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
int sz = EVP_MD_get_size(hctx->key->md_big);
size_t seed_len = (size_t)sz + 2 * n;
+ if (sz <= 0)
+ return 0;
+
memcpy(seed, r, n);
memcpy(seed + n, pk_seed, n);
return digest_4(hctx->md_big_ctx, r, n, pk_seed, n, pk_root, n, msg, msg_len,
diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c
index 28cf95cc48c9..7c49128b47db 100644
--- a/crypto/sm2/sm2_sign.c
+++ b/crypto/sm2/sm2_sign.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2017 Ribose Inc. All Rights Reserved.
* Ported from Ribose contributions from Botan.
*
@@ -220,6 +220,10 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
BIGNUM *tmp = NULL;
OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key);
+ if (dA == NULL) {
+ ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY);
+ goto done;
+ }
kG = EC_POINT_new(group);
if (kG == NULL) {
ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB);
diff --git a/crypto/sm3/asm/sm3-armv8.pl b/crypto/sm3/asm/sm3-armv8.pl
index 1437f028922c..f36e0e2be98c 100644
--- a/crypto/sm3/asm/sm3-armv8.pl
+++ b/crypto/sm3/asm/sm3-armv8.pl
@@ -153,13 +153,13 @@ $code.=<<___;
.Loop:
// load input
- ld1 {$s0.16b-$s3.16b}, [$pdata], #64
+ ld1 {$s0.4s-$s3.4s}, [$pdata], #64
sub $num, $num, #1
mov $bkstate1.16b, $state1.16b
mov $bkstate2.16b, $state2.16b
-#ifndef __ARMEB__
+#ifndef __AARCH64EB__
rev32 $s0.16b, $s0.16b
rev32 $s1.16b, $s1.16b
rev32 $s2.16b, $s2.16b
diff --git a/crypto/sm4/asm/sm4-armv8.pl b/crypto/sm4/asm/sm4-armv8.pl
index 8003df41ab29..1fe12dead49b 100755
--- a/crypto/sm4/asm/sm4-armv8.pl
+++ b/crypto/sm4/asm/sm4-armv8.pl
@@ -32,7 +32,7 @@ sub rev32() {
my $dst = shift;
my $src = shift;
$code.=<<___;
-#ifndef __ARMEB__
+#ifndef __AARCH64EB__
rev32 $dst.16b,$src.16b
#endif
___
@@ -404,7 +404,7 @@ ___
&enc_blk($ivec);
&rev32($ivec,$ivec);
$code.=<<___;
- st1 {$ivec.16b},[$out],#16
+ st1 {$ivec.4s},[$out],#16
b.ne 1b
b 3f
.Ldec:
@@ -485,11 +485,11 @@ ___
$code.=<<___;
eor @dat[0].16b,@dat[0].16b,$ivec.16b
mov $ivec.16b,@in[0].16b
- st1 {@dat[0].16b},[$out],#16
+ st1 {@dat[0].4s},[$out],#16
b.ne 1b
3:
// save back IV
- st1 {$ivec.16b},[$ivp]
+ st1 {$ivec.4s},[$ivp]
ldp d8,d9,[sp],#16
ret
.size ${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt
diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c
index 505d606f4a9b..ebf170c3e8f1 100644
--- a/crypto/store/store_lib.c
+++ b/crypto/store/store_lib.c
@@ -428,12 +428,6 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
if (ctx->loader != NULL)
OSSL_TRACE(STORE, "Loading next object\n");
- if (ctx->cached_info != NULL
- && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) {
- sk_OSSL_STORE_INFO_free(ctx->cached_info);
- ctx->cached_info = NULL;
- }
-
if (ctx->cached_info != NULL) {
v = sk_OSSL_STORE_INFO_shift(ctx->cached_info);
} else {
@@ -556,14 +550,23 @@ int OSSL_STORE_error(OSSL_STORE_CTX *ctx)
int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)
{
- int ret = 1;
+ int ret = 0;
- if (ctx->fetched_loader != NULL)
- ret = ctx->loader->p_eof(ctx->loader_ctx);
+ if (ctx->cached_info != NULL
+ && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) {
+ sk_OSSL_STORE_INFO_free(ctx->cached_info);
+ ctx->cached_info = NULL;
+ }
+
+ if (ctx->cached_info == NULL) {
+ ret = 1;
+ if (ctx->fetched_loader != NULL)
+ ret = ctx->loader->p_eof(ctx->loader_ctx);
#ifndef OPENSSL_NO_DEPRECATED_3_0
- if (ctx->fetched_loader == NULL)
- ret = ctx->loader->eof(ctx->loader_ctx);
+ if (ctx->fetched_loader == NULL)
+ ret = ctx->loader->eof(ctx->loader_ctx);
#endif
+ }
return ret != 0;
}
diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c
index b5e50557c238..9944d353dc60 100644
--- a/crypto/store/store_result.c
+++ b/crypto/store/store_result.c
@@ -153,8 +153,19 @@ int ossl_store_handle_load_result(const OSSL_PARAM params[], void *arg)
goto err;
ERR_pop_to_mark();
- if (*v == NULL)
- ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_UNSUPPORTED);
+ if (*v == NULL) {
+ const char *hint = "";
+
+ if (!OSSL_PROVIDER_available(libctx, "default"))
+ hint = ":maybe need to load the default provider?";
+ if (provider != NULL)
+ ERR_raise_data(ERR_LIB_OSSL_STORE, ERR_R_UNSUPPORTED, "provider=%s%s",
+ OSSL_PROVIDER_get0_name(provider), hint);
+ else if (hint[0] != '\0')
+ ERR_raise_data(ERR_LIB_OSSL_STORE, ERR_R_UNSUPPORTED, "%s", hint);
+ else
+ ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_UNSUPPORTED);
+ }
return (*v != NULL);
err:
diff --git a/crypto/threads_none.c b/crypto/threads_none.c
index 240b7d9fdcfe..ac61f384501f 100644
--- a/crypto/threads_none.c
+++ b/crypto/threads_none.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -153,18 +153,28 @@ int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
# define OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX 256
-static void *thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
+struct thread_local_storage_entry {
+ void *data;
+ uint8_t used;
+};
+
+static struct thread_local_storage_entry thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
{
- static unsigned int thread_local_key = 0;
+ int entry_idx = 0;
- if (thread_local_key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
- return 0;
+ for (entry_idx = 0; entry_idx < OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX; entry_idx++) {
+ if (!thread_local_storage[entry_idx].used)
+ break;
+ }
- *key = thread_local_key++;
+ if (entry_idx == OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
+ return 0;
- thread_local_storage[*key] = NULL;
+ *key = entry_idx;
+ thread_local_storage[*key].used = 1;
+ thread_local_storage[*key].data = NULL;
return 1;
}
@@ -174,7 +184,7 @@ void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
return NULL;
- return thread_local_storage[*key];
+ return thread_local_storage[*key].data;
}
int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
@@ -182,13 +192,18 @@ int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
return 0;
- thread_local_storage[*key] = val;
+ thread_local_storage[*key].data = val;
return 1;
}
int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
{
+ if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
+ return 0;
+
+ thread_local_storage[*key].used = 0;
+ thread_local_storage[*key].data = NULL;
*key = OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX + 1;
return 1;
}
diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c
index 750ef201210b..44d6ebe09231 100644
--- a/crypto/threads_pthread.c
+++ b/crypto/threads_pthread.c
@@ -624,7 +624,7 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
{
# ifdef USE_RWLOCK
- if (pthread_rwlock_rdlock(lock) != 0)
+ if (!ossl_assert(pthread_rwlock_rdlock(lock) == 0))
return 0;
# else
if (pthread_mutex_lock(lock) != 0) {
@@ -639,7 +639,7 @@ __owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
{
# ifdef USE_RWLOCK
- if (pthread_rwlock_wrlock(lock) != 0)
+ if (!ossl_assert(pthread_rwlock_wrlock(lock) == 0))
return 0;
# else
if (pthread_mutex_lock(lock) != 0) {
diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c
index 2465aede8560..0547736aa04f 100644
--- a/crypto/ts/ts_rsp_sign.c
+++ b/crypto/ts/ts_rsp_sign.c
@@ -648,8 +648,12 @@ static int ossl_ess_add1_signing_cert(PKCS7_SIGNER_INFO *si,
}
OPENSSL_free(pp);
- return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate,
- V_ASN1_SEQUENCE, seq);
+ if (!PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate,
+ V_ASN1_SEQUENCE, seq)) {
+ ASN1_STRING_free(seq);
+ return 0;
+ }
+ return 1;
}
static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si,
@@ -671,8 +675,12 @@ static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si,
}
OPENSSL_free(pp);
- return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2,
- V_ASN1_SEQUENCE, seq);
+ if (!PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2,
+ V_ASN1_SEQUENCE, seq)) {
+ ASN1_STRING_free(seq);
+ return 0;
+ }
+ return 1;
}
static int ts_RESP_sign(TS_RESP_CTX *ctx)
diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c
index a8756af1cdea..160e4c80c6e6 100644
--- a/crypto/ui/ui_lib.c
+++ b/crypto/ui/ui_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2025 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
@@ -205,6 +205,7 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags,
char *result_buf, int minsize, int maxsize)
{
char *prompt_copy = NULL;
+ int ret;
if (prompt != NULL) {
prompt_copy = OPENSSL_strdup(prompt);
@@ -212,9 +213,13 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags,
return 0;
}
- return general_allocate_string(ui, prompt_copy, 1,
- UIT_PROMPT, flags, result_buf, minsize,
- maxsize, NULL);
+ ret = general_allocate_string(ui, prompt_copy, 1,
+ UIT_PROMPT, flags, result_buf, minsize,
+ maxsize, NULL);
+ if (ret <= 0)
+ OPENSSL_free(prompt_copy);
+
+ return ret;
}
int UI_add_verify_string(UI *ui, const char *prompt, int flags,
@@ -231,6 +236,7 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
const char *test_buf)
{
char *prompt_copy = NULL;
+ int ret;
if (prompt != NULL) {
prompt_copy = OPENSSL_strdup(prompt);
@@ -238,9 +244,12 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
return -1;
}
- return general_allocate_string(ui, prompt_copy, 1,
- UIT_VERIFY, flags, result_buf, minsize,
- maxsize, test_buf);
+ ret = general_allocate_string(ui, prompt_copy, 1,
+ UIT_VERIFY, flags, result_buf, minsize,
+ maxsize, test_buf);
+ if (ret <= 0)
+ OPENSSL_free(prompt_copy);
+ return ret;
}
int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
@@ -260,6 +269,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
char *action_desc_copy = NULL;
char *ok_chars_copy = NULL;
char *cancel_chars_copy = NULL;
+ int ret;
if (prompt != NULL) {
prompt_copy = OPENSSL_strdup(prompt);
@@ -285,9 +295,14 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
goto err;
}
- return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
- ok_chars_copy, cancel_chars_copy, 1,
- UIT_BOOLEAN, flags, result_buf);
+ ret = general_allocate_boolean(ui, prompt_copy, action_desc_copy,
+ ok_chars_copy, cancel_chars_copy, 1,
+ UIT_BOOLEAN, flags, result_buf);
+ if (ret <= 0)
+ goto err;
+
+ return ret;
+
err:
OPENSSL_free(prompt_copy);
OPENSSL_free(action_desc_copy);
@@ -305,6 +320,7 @@ int UI_add_info_string(UI *ui, const char *text)
int UI_dup_info_string(UI *ui, const char *text)
{
char *text_copy = NULL;
+ int ret;
if (text != NULL) {
text_copy = OPENSSL_strdup(text);
@@ -312,8 +328,11 @@ int UI_dup_info_string(UI *ui, const char *text)
return -1;
}
- return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
- 0, 0, NULL);
+ ret = general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
+ 0, 0, NULL);
+ if (ret <= 0)
+ OPENSSL_free(text_copy);
+ return ret;
}
int UI_add_error_string(UI *ui, const char *text)
@@ -325,14 +344,19 @@ int UI_add_error_string(UI *ui, const char *text)
int UI_dup_error_string(UI *ui, const char *text)
{
char *text_copy = NULL;
+ int ret;
if (text != NULL) {
text_copy = OPENSSL_strdup(text);
if (text_copy == NULL)
return -1;
}
- return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
- 0, 0, NULL);
+
+ ret = general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
+ 0, 0, NULL);
+ if (ret <= 0)
+ OPENSSL_free(text_copy);
+ return ret;
}
char *UI_construct_prompt(UI *ui, const char *phrase_desc,
diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c
index d1e186f4fc2d..def06be1fe8c 100644
--- a/crypto/x509/by_store.c
+++ b/crypto/x509/by_store.c
@@ -7,23 +7,34 @@
* https://www.openssl.org/source/license.html
*/
+#include <openssl/safestack.h>
#include <openssl/store.h>
#include "internal/cryptlib.h"
#include "crypto/x509.h"
#include "x509_local.h"
+typedef struct cached_store_st {
+ char *uri;
+ OSSL_LIB_CTX *libctx;
+ char *propq;
+ OSSL_STORE_CTX *ctx;
+} CACHED_STORE;
+
+DEFINE_STACK_OF(CACHED_STORE)
+
/* Generic object loader, given expected type and criterion */
-static int cache_objects(X509_LOOKUP *lctx, const char *uri,
- const OSSL_STORE_SEARCH *criterion,
- int depth, OSSL_LIB_CTX *libctx, const char *propq)
+static int cache_objects(X509_LOOKUP *lctx, CACHED_STORE *store,
+ const OSSL_STORE_SEARCH *criterion, int depth)
{
int ok = 0;
- OSSL_STORE_CTX *ctx = NULL;
+ OSSL_STORE_CTX *ctx = store->ctx;
X509_STORE *xstore = X509_LOOKUP_get_store(lctx);
- if ((ctx = OSSL_STORE_open_ex(uri, libctx, propq, NULL, NULL, NULL,
- NULL, NULL)) == NULL)
+ if (ctx == NULL
+ && (ctx = OSSL_STORE_open_ex(store->uri, store->libctx, store->propq,
+ NULL, NULL, NULL, NULL, NULL)) == NULL)
return 0;
+ store->ctx = ctx;
/*
* We try to set the criterion, but don't care if it was valid or not.
@@ -62,9 +73,15 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri,
* This is an entry in the "directory" represented by the current
* uri. if |depth| allows, dive into it.
*/
- if (depth > 0)
- ok = cache_objects(lctx, OSSL_STORE_INFO_get0_NAME(info),
- criterion, depth - 1, libctx, propq);
+ if (depth > 0) {
+ CACHED_STORE substore;
+
+ substore.uri = (char *)OSSL_STORE_INFO_get0_NAME(info);
+ substore.libctx = store->libctx;
+ substore.propq = store->propq;
+ substore.ctx = NULL;
+ ok = cache_objects(lctx, &substore, criterion, depth - 1);
+ }
} else {
/*
* We know that X509_STORE_add_{cert|crl} increments the object's
@@ -88,21 +105,26 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri,
break;
}
OSSL_STORE_close(ctx);
+ store->ctx = NULL;
return ok;
}
-/* Because OPENSSL_free is a macro and for C type match */
-static void free_uri(OPENSSL_STRING data)
+static void free_store(CACHED_STORE *store)
{
- OPENSSL_free(data);
+ if (store != NULL) {
+ OSSL_STORE_close(store->ctx);
+ OPENSSL_free(store->uri);
+ OPENSSL_free(store->propq);
+ OPENSSL_free(store);
+ }
}
static void by_store_free(X509_LOOKUP *ctx)
{
- STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx);
- sk_OPENSSL_STRING_pop_free(uris, free_uri);
+ STACK_OF(CACHED_STORE) *stores = X509_LOOKUP_get_method_data(ctx);
+ sk_CACHED_STORE_pop_free(stores, free_store);
}
static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp,
@@ -112,27 +134,49 @@ static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp,
switch (cmd) {
case X509_L_ADD_STORE:
if (argp != NULL) {
- STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx);
- char *data = OPENSSL_strdup(argp);
+ STACK_OF(CACHED_STORE) *stores = X509_LOOKUP_get_method_data(ctx);
+ CACHED_STORE *store = OPENSSL_zalloc(sizeof(*store));
- if (data == NULL) {
+ if (store == NULL) {
return 0;
}
- if (uris == NULL) {
- uris = sk_OPENSSL_STRING_new_null();
- X509_LOOKUP_set_method_data(ctx, uris);
+
+ store->uri = OPENSSL_strdup(argp);
+ store->libctx = libctx;
+ if (propq != NULL)
+ store->propq = OPENSSL_strdup(propq);
+ store->ctx = OSSL_STORE_open_ex(argp, libctx, propq, NULL, NULL,
+ NULL, NULL, NULL);
+ if (store->ctx == NULL
+ || (propq != NULL && store->propq == NULL)
+ || store->uri == NULL) {
+ free_store(store);
+ return 0;
+ }
+
+ if (stores == NULL) {
+ stores = sk_CACHED_STORE_new_null();
+ if (stores != NULL)
+ X509_LOOKUP_set_method_data(ctx, stores);
}
- if (sk_OPENSSL_STRING_push(uris, data) <= 0) {
- OPENSSL_free(data);
+ if (stores == NULL || sk_CACHED_STORE_push(stores, store) <= 0) {
+ free_store(store);
return 0;
}
return 1;
}
/* NOP if no URI is given. */
return 1;
- case X509_L_LOAD_STORE:
+ case X509_L_LOAD_STORE: {
/* This is a shortcut for quick loading of specific containers */
- return cache_objects(ctx, argp, NULL, 0, libctx, propq);
+ CACHED_STORE store;
+
+ store.uri = (char *)argp;
+ store.libctx = libctx;
+ store.propq = (char *)propq;
+ store.ctx = NULL;
+ return cache_objects(ctx, &store, NULL, 0);
+ }
default:
/* Unsupported command */
return 0;
@@ -146,16 +190,15 @@ static int by_store_ctrl(X509_LOOKUP *ctx, int cmd,
}
static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
- const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret,
- OSSL_LIB_CTX *libctx, const char *propq)
+ const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret)
{
- STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx);
+ STACK_OF(CACHED_STORE) *stores = X509_LOOKUP_get_method_data(ctx);
int i;
int ok = 0;
- for (i = 0; i < sk_OPENSSL_STRING_num(uris); i++) {
- ok = cache_objects(ctx, sk_OPENSSL_STRING_value(uris, i), criterion,
- 1 /* depth */, libctx, propq);
+ for (i = 0; i < sk_CACHED_STORE_num(stores); i++) {
+ ok = cache_objects(ctx, sk_CACHED_STORE_value(stores, i), criterion,
+ 1 /* depth */);
if (ok)
break;
@@ -163,13 +206,12 @@ static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
return ok;
}
-static int by_store_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
- const X509_NAME *name, X509_OBJECT *ret,
- OSSL_LIB_CTX *libctx, const char *propq)
+static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, X509_OBJECT *ret)
{
OSSL_STORE_SEARCH *criterion =
OSSL_STORE_SEARCH_by_name((X509_NAME *)name); /* won't modify it */
- int ok = by_store(ctx, type, criterion, ret, libctx, propq);
+ int ok = by_store(ctx, type, criterion, ret);
STACK_OF(X509_OBJECT) *store_objects =
X509_STORE_get0_objects(X509_LOOKUP_get_store(ctx));
X509_OBJECT *tmp = NULL;
@@ -217,12 +259,6 @@ static int by_store_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
return ok;
}
-static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
- const X509_NAME *name, X509_OBJECT *ret)
-{
- return by_store_subject_ex(ctx, type, name, ret, NULL, NULL);
-}
-
/*
* We lack the implementations for get_by_issuer_serial, get_by_fingerprint
* and get_by_alias. There's simply not enough support in the X509_LOOKUP
@@ -240,7 +276,7 @@ static X509_LOOKUP_METHOD x509_store_lookup = {
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
- by_store_subject_ex,
+ NULL, /* get_by_subject_ex */
by_store_ctrl_ex
};
diff --git a/crypto/x509/v3_lib.c b/crypto/x509/v3_lib.c
index 077b22c863ec..86d8721b6060 100644
--- a/crypto/x509/v3_lib.c
+++ b/crypto/x509/v3_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2025 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
@@ -100,7 +100,11 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from)
*tmpext = *ext;
tmpext->ext_nid = nid_to;
tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
- return X509V3_EXT_add(tmpext);
+ if (!X509V3_EXT_add(tmpext)) {
+ OPENSSL_free(tmpext);
+ return 0;
+ }
+ return 1;
}
void X509V3_EXT_cleanup(void)
diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c
index 2601a019f87e..7af3e9a7e7f2 100644
--- a/crypto/x509/x_crl.c
+++ b/crypto/x509/x_crl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -289,6 +289,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
{
int idp_only = 0;
+ int ret = 0;
/* Set various flags according to IDP */
crl->idp_flags |= IDP_PRESENT;
@@ -320,7 +321,17 @@ static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
crl->idp_reasons &= CRLDP_ALL_REASONS;
}
- return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+ ret = DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+
+ /*
+ * RFC5280 specifies that if onlyContainsUserCerts, onlyContainsCACerts,
+ * indirectCRL, and OnlyContainsAttributeCerts are all FALSE, there must
+ * be either a distributionPoint field or an onlySomeReasons field present.
+ */
+ if (crl->idp_flags == IDP_PRESENT && idp->distpoint == NULL)
+ crl->idp_flags |= IDP_INVALID;
+
+ return ret;
}
ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
diff --git a/demos/bio/sconnect.c b/demos/bio/sconnect.c
index b4ad3df14b37..69954f5cde56 100644
--- a/demos/bio/sconnect.c
+++ b/demos/bio/sconnect.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2025 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
@@ -74,8 +74,10 @@ int main(int argc, char *argv[])
/* The BIO has parsed the host:port and even IPv6 literals in [] */
hostname = BIO_get_conn_hostname(out);
- if (!hostname || SSL_set1_host(ssl, hostname) <= 0)
+ if (!hostname || SSL_set1_host(ssl, hostname) <= 0) {
+ BIO_free(ssl_bio);
goto err;
+ }
BIO_set_nbio(out, 1);
out = BIO_push(ssl_bio, out);
diff --git a/demos/cms/cms_ddec.c b/demos/cms/cms_ddec.c
index d119e9722226..dd8ef90b6e3f 100644
--- a/demos/cms/cms_ddec.c
+++ b/demos/cms/cms_ddec.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2025 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
@@ -58,7 +58,7 @@ int main(int argc, char **argv)
/* Open file containing detached content */
dcont = BIO_new_file("smencr.out", "rb");
- if (!in)
+ if (dcont == NULL)
goto err;
out = BIO_new_file("encrout.txt", "w");
diff --git a/demos/cms/cms_denc.c b/demos/cms/cms_denc.c
index 53b680f67484..e451a108fd46 100644
--- a/demos/cms/cms_denc.c
+++ b/demos/cms/cms_denc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2025 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
@@ -57,7 +57,7 @@ int main(int argc, char **argv)
dout = BIO_new_file("smencr.out", "wb");
- if (!in)
+ if (in == NULL || dout == NULL)
goto err;
/* encrypt content */
diff --git a/demos/guide/tls-client-block.c b/demos/guide/tls-client-block.c
index c6ba5850f7ff..602c9eebcc98 100644
--- a/demos/guide/tls-client-block.c
+++ b/demos/guide/tls-client-block.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2025 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
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
*/
bio = create_socket_bio(hostname, port, ipv6 ? AF_INET6 : AF_INET);
if (bio == NULL) {
- printf("Failed to crete the BIO\n");
+ printf("Failed to create the BIO\n");
goto end;
}
SSL_set_bio(ssl, bio, bio);
diff --git a/demos/sslecho/main.c b/demos/sslecho/main.c
index 3e5bcadce3ee..115074d6d1bf 100644
--- a/demos/sslecho/main.c
+++ b/demos/sslecho/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -23,7 +23,7 @@
static const int server_port = 4433;
-typedef unsigned char bool;
+typedef unsigned char flag;
#define true 1
#define false 0
@@ -31,9 +31,9 @@ typedef unsigned char bool;
* This flag won't be useful until both accept/read (TCP & SSL) methods
* can be called with a timeout. TBD.
*/
-static volatile bool server_running = true;
+static volatile flag server_running = true;
-static int create_socket(bool isServer)
+static int create_socket(flag isServer)
{
int s;
int optval = 1;
@@ -71,7 +71,7 @@ static int create_socket(bool isServer)
return s;
}
-static SSL_CTX* create_context(bool isServer)
+static SSL_CTX *create_context(flag isServer)
{
const SSL_METHOD *method;
SSL_CTX *ctx;
@@ -135,7 +135,7 @@ static void usage(void)
#define BUFFERSIZE 1024
int main(int argc, char **argv)
{
- bool isServer;
+ flag isServer;
int result;
SSL_CTX *ssl_ctx = NULL;
@@ -264,6 +264,11 @@ int main(int argc, char **argv)
SSL_shutdown(ssl);
SSL_free(ssl);
close(client_skt);
+ /*
+ * Set client_skt to -1 to avoid double close when
+ * server_running become false before next accept
+ */
+ client_skt = -1;
}
}
printf("Server exiting...\n");
diff --git a/doc/designs/fetching-composite-algorithms.md b/doc/designs/fetching-composite-algorithms.md
index 1e3fa9996876..c381aa7ccb0b 100644
--- a/doc/designs/fetching-composite-algorithms.md
+++ b/doc/designs/fetching-composite-algorithms.md
@@ -20,19 +20,19 @@ Public API - Add variants of `EVP_PKEY_CTX` initializers
As far as this design is concerned, these API sets are affected:
-- SIGNATURE (DigestSign and DigestVerify)
+- SIGNATURE
- ASYM_CIPHER
- KEYEXCH
-The proposal is to add these functions:
+The proposal is to add these initializer functions:
``` C
-EVP_DigestSignInit_ex2(EVP_PKEY_CTX **pctx,
- EVP_SIGNATURE *sig, EVP_PKEY *pkey,
- OSSL_LIB_CTX *libctx, const OSSL_PARAM params[]);
-EVP_DigestVerifyInit_ex2(EVP_PKEY_CTX **pctx,
- EVP_SIGNATURE *sig, EVP_PKEY *pkey,
- OSSL_LIB_CTX *libctx, const OSSL_PARAM params[]);
+int EVP_PKEY_sign_init_ex2(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo, const OSSL_PARAM params[]);
+int EVP_PKEY_verify_init_ex2(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo, const OSSL_PARAM params[]);
+int EVP_PKEY_verify_recover_init_ex2(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo, const OSSL_PARAM params[]);
int EVP_PKEY_encrypt_init_ex2(EVP_PKEY_CTX *ctx, EVP_ASYM_CIPHER *asymciph,
const OSSL_PARAM params[]);
@@ -43,68 +43,12 @@ int EVP_PKEY_derive_init_ex2(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange,
const OSSL_PARAM params[]);
```
-Because `EVP_SIGNATURE`, `EVP_ASYM_CIPHER` and `EVP_KEYEXCH` aren't limited
-to composite algorithms, these functions can be used just as well with
-explicit fetches of simple algorithms, say "RSA". In that case, the caller
-will need to pass necessary auxiliary parameters through the `OSSL_PARAM` or
-a call to a corresponding `set_params` function.
+Detailed proposal for these APIs will be or are prepared in other design
+documents:
-Requirements on the providers
------------------------------
-
-Because it's not immediately obvious from a composite algorithm name what
-key type it requires / supports, at least in code, allowing the use of an
-explicitly fetched implementation of a composite algorithm requires that
-providers cooperate by declaring what key type is required / supported by
-each algorithm.
-
-For non-composite operation algorithms (like "RSA"), this is not necessary,
-see the fallback strategies below.
-
-There are two ways this could be implemented:
-
-1. through an added provider function that would work like keymgmt's
- `query_operation_name` function, but would return a key type name
- instead:
-
- ``` C
- # define OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPE 26
- OSSL_CORE_MAKE_FUNC(const char *, signature_query_key_type, (void))
-
- # define OSSL_FUNC ASYM_CIPHER_QUERY_KEY_TYPE 12
- OSSL_CORE_MAKE_FUNC(const char *, asym_cipher_query_key_type, (void))
-
- # define OSSL_FUNC_KEYEXCH_QUERY_KEY_TYPE 11
- OSSL_CORE_MAKE_FUNC(const char *, keyexch_query_key_type, (void))
- ```
-
-2. through a gettable `OSSL_PARAM`, using the param identity "keytype"
-
-Fallback strategies
--------------------
-
-Because existing providers haven't been updated to declare composite
-algorithms, or to respond to the key type query, some fallback strategies
-will be needed to find out if the `EVP_PKEY` key type is possible to use
-with the fetched algorithm:
-
-- Check if the fetched operation name matches the key type (keymgmt name)
- of the `EVP_PKEY` that's involved in the operation. For example, this
- is useful when someone fetched the `EVP_SIGNATURE` "RSA".
-- Check if the fetched algorithm name matches the name returned by the
- keymgmt's `query_operation_name` function. For example, this is useful
- when someone fetched the `EVP_SIGNATURE` "ECDSA", for which the key type
- to use is "EC".
-- libcrypto currently has knowledge of some composite algorithm names and
- what they are composed of, accessible with `OBJ_find_sigid_algs` and
- similar functionality. This knowledge is regarded legacy, but can be
- used to figure out the key type.
-
-If none of these strategies work out, the operation initialization should
-fail.
-
-These strategies have their limitations, but the built-in legacy knowledge
-we currently have in libcrypto should be enough to cover most bases.
+- [Functions for explicitly fetched signature algorithms]
+- [Functions for explicitly fetched asym-cipher algorithms] (not yet designed)
+- [Functions for explicitly fetched keyexch algorithms] (not yet designed)
-----
@@ -185,3 +129,7 @@ This is hurtful in multiple ways:
use the result.
- It fails discoverability, for example through the `openssl list`
command.
+
+<!-- links -->
+[Functions for explicitly fetched signature algorithms]:
+ functions-for-explicitly-fetched-signature-algorithms.md
diff --git a/doc/designs/functions-for-explicitly-fetched-signature-algorithms.md b/doc/designs/functions-for-explicitly-fetched-signature-algorithms.md
new file mode 100644
index 000000000000..cb4df1a40c38
--- /dev/null
+++ b/doc/designs/functions-for-explicitly-fetched-signature-algorithms.md
@@ -0,0 +1,205 @@
+Functions for explicitly fetched PKEY algorithms
+================================================
+
+Quick background
+----------------
+
+There are several proposed designs that end up revolving around the same
+basic need, explicitly fetched signature algorithms. The following method
+type is affected by this document:
+
+- `EVP_SIGNATURE`
+
+Public API - Add variants of `EVP_PKEY_CTX` functionality
+---------------------------------------------------------
+
+Through OTC discussions, it's been determined that the most suitable APIs to
+touch are the of `EVP_PKEY_` functions.
+Specifically, `EVP_PKEY_sign()`, `EVP_PKEY_verify()`, `EVP_PKEY_verify_recover()`
+and related functions.
+They can be extended to accept an explicitly fetched algorithm of the right
+type, and to be able to incrementally process indefinite length data streams
+when the fetched algorithm permits it (for example, RSA-SHA256).
+
+It must be made clear that the added functionality cannot be used to compose
+an algorithm from different parts. For example, it's not possible to specify
+a `EVP_SIGNATURE` "RSA" and combine it with a parameter that specifies the
+hash "SHA256" to get the "RSA-SHA256" functionality. For an `EVP_SIGNATURE`
+"RSA", the input is still expected to be a digest, or some other input that's
+limited to the modulus size of the RSA pkey.
+
+### Making things less confusing with distinct function names
+
+Until now, `EVP_PKEY_sign()` and friends were only expected to act on the
+pre-computed digest of a message (under the condition that proper flags
+and signature md are specified using functions like
+`EVP_PKEY_CTX_set_rsa_padding()` and `EVP_PKEY_CTX_set_signature_md()`),
+or to act as "primitive" [^1] functions (under the condition that proper
+flags are specified, like `RSA_NO_PADDING` for RSA signatures).
+
+This design proposes an extension to also allow full (not pre-hashed)
+messages to be passed, in a streaming style through an *update* and a
+*final* function.
+
+Discussions have revealed that it is potentially confusing to conflate the
+current functionality with streaming style functionality into the same name,
+so this design separates those out with specific init / update / final
+functions for that purpose. For oneshot functionality, `EVP_PKEY_sign()`
+and `EVP_PKEY_verify()` remain supported.
+
+[^1]: the term "primitive" is borrowed from [PKCS#1](https://www.rfc-editor.org/rfc/rfc8017#section-5)
+
+### Making it possible to verify with an early signature
+
+Some more recent verification algorithms need to obtain the signature
+before processing the data.
+This is particularly important for streaming modes of operation.
+This design proposes a mechanism to accomodate these algorithms
+and modes of operation.
+
+New public API - API Reference
+------------------------------
+
+### For limited input size / oneshot signing with `EVP_SIGNATURE`
+
+``` C
+int EVP_PKEY_sign_init_ex2(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo,
+ const OSSL_PARAM params[]);
+```
+
+### For signing a stream with `EVP_SIGNATURE`
+
+``` C
+int EVP_PKEY_sign_message_init(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo,
+ const OSSL_PARAM params[]);
+int EVP_PKEY_sign_message_update(EVP_PKEY_CTX *ctx,
+ const unsigned char *in,
+ size_t inlen);
+int EVP_PKEY_sign_message_final(EVP_PKEY_CTX *ctx,
+ unsigned char *sig,
+ size_t *siglen);
+#define EVP_PKEY_sign_message(ctx,sig,siglen,tbs,tbslen) \
+ EVP_PKEY_sign(ctx,sig,siglen,tbs,tbslen)
+```
+
+### For limited input size / oneshot verification with `EVP_SIGNATURE`
+
+``` C
+int EVP_PKEY_verify_init_ex2(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo,
+ const OSSL_PARAM params[]);
+```
+
+### For verifying a stream with `EVP_SIGNATURE`
+
+``` C
+/* Initializers */
+int EVP_PKEY_verify_message_init(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo,
+ const OSSL_PARAM params[]);
+/* Signature setter */
+int EVP_PKEY_CTX_set_signature(EVP_PKEY_CTX *pctx,
+ unsigned char *sig, size_t siglen,
+ size_t sigsize);
+/* Update and final */
+int EVP_PKEY_verify_message_update(EVP_PKEY_CTX *ctx,
+ const unsigned char *in,
+ size_t inlen);
+int EVP_PKEY_verify_message_final(EVP_PKEY_CTX *ctx);
+
+#define EVP_PKEY_verify_message(ctx,sig,siglen,tbs,tbslen) \
+ EVP_PKEY_verify(ctx,sig,siglen,tbs,tbslen)
+```
+
+### For verify_recover with `EVP_SIGNATURE`
+
+Preliminary feedback suggests that a streaming interface is uninteresting for
+verify_recover, so we only specify a new init function.
+
+``` C
+/* Initializers */
+int EVP_PKEY_verify_recover_init_ex2(EVP_PKEY_CTX *pctx,
+ EVP_SIGNATURE *algo,
+ const OSSL_PARAM params[]);
+```
+
+Requirements on the providers
+-----------------------------
+
+Because it's not immediately obvious from a composite algorithm name what
+key type ("RSA", "EC", ...) it requires / supports, at least in code, allowing
+the use of an explicitly fetched implementation of a composite algorithm
+requires that providers cooperate by declaring what key type is required /
+supported by each algorithm.
+
+For non-composite operation algorithms (like "RSA"), this is not necessary,
+see the fallback strategies below.
+
+This is to be implemented through an added provider function that would work
+like keymgmt's `query_operation_name` function, but would return a NULL
+terminated array of key type name instead:
+
+``` C
+# define OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPE 26
+OSSL_CORE_MAKE_FUNC(const char **, signature_query_key_type, (void))
+```
+
+Furthermore, the distinction of intent, i.e. whether the input is expected
+to be a pre-hashed digest or the original message, must be passed on to the
+provider. Because we already distinguish that with function names in the
+public API, we use the same mapping in the provider interface.
+
+The already existing `signature_sign` and `signature_verify` remain as they
+are, and can be combined with message init calls.
+
+``` C
+# define OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT 27
+# define OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE 28
+# define OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL 29
+OSSL_CORE_MAKE_FUNC(int, signature_sign_message_init,
+ (void *ctx, void *provkey, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, signature_sign_message_update,
+ (void *ctx, const unsigned char *in, size_t inlen))
+OSSL_CORE_MAKE_FUNC(int, signature_sign_message_final,
+ (void *ctx, unsigned char *sig, size_t *siglen, size_t sigsize))
+
+# define OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT 30
+# define OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE 31
+# define OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL 32
+OSSL_CORE_MAKE_FUNC(int, signature_verify_message_init,
+ (void *ctx, void *provkey, const OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(int, signature_verify_message_update,
+ (void *ctx, const unsigned char *in, size_t inlen))
+/*
+ * signature_verify_message_final requires that the signature to be verified
+ * against is specified via an OSSL_PARAM.
+ */
+OSSL_CORE_MAKE_FUNC(int, signature_verify_message_final, (void *ctx))
+```
+
+Fallback strategies
+-------------------
+
+Because existing providers haven't been updated to respond to the key type
+query, some fallback strategies will be needed for the init calls that take
+an explicitly fetched `EVP_SIGNATURE` argument (they can at least be used
+for pre-hashed digest operations). To find out if the `EVP_PKEY` key type
+is possible to use with the explicitly fetched algorithm, the following
+fallback strategies may be used.
+
+- Check if the fetched operation name matches the key type (keymgmt name)
+ of the `EVP_PKEY` that's involved in the operation. For example, this
+ is useful when someone fetched the `EVP_SIGNATURE` "RSA". This requires
+ very little modification, as this is already done with the initializer
+ functions that fetch the algorithm implicitly.
+- Check if the fetched algorithm name matches the name returned by the
+ keymgmt's `query_operation_name` function. For example, this is useful
+ when someone fetched the `EVP_SIGNATURE` "ECDSA", for which the key type
+ to use is "EC". This requires very little modification, as this is
+ already done with the initializer functions that fetch the algorithm
+ implicitly.
+
+If none of these strategies work out, the operation initialization should
+fail.
diff --git a/doc/internal/man3/ossl_namemap_new.pod b/doc/internal/man3/ossl_namemap_new.pod
index 7f4940fc9341..8879c592106b 100644
--- a/doc/internal/man3/ossl_namemap_new.pod
+++ b/doc/internal/man3/ossl_namemap_new.pod
@@ -4,7 +4,7 @@
ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, ossl_namemap_empty,
ossl_namemap_add_name, ossl_namemap_add_names,
-ossl_namemap_name2num, ossl_namemap_name2num_n,
+ossl_namemap_name2num, ossl_namemap_name2num_n, ossl_namemap_num2name,
ossl_namemap_doall_names
- internal number E<lt>-E<gt> name map
@@ -23,6 +23,8 @@ ossl_namemap_doall_names
int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name);
int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap,
const char *name, size_t name_len);
+ const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number,
+ int idx);
int ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number,
void (*fn)(const char *name, void *data),
void *data);
@@ -64,6 +66,9 @@ ossl_namemap_name2num_n() does the same thing as
ossl_namemap_name2num(), but takes a string length I<name_len> as well,
allowing the caller to use a fragment of a string as a name.
+ossl_namemap_num2name() finds the I<idx>th name associated with the
+id I<number>.
+
ossl_namemap_doall_names() walks through all names associated with
I<number> in the given I<namemap> and calls the function I<fn> for
each of them.
@@ -88,9 +93,9 @@ to lock).
ossl_namemap_add_name() returns the number associated with the added
string, or zero on error.
-ossl_namemap_num2names() returns a pointer to a NULL-terminated list of
-pointers to the names corresponding to the given number, or NULL if
-it's undefined in the given B<OSSL_NAMEMAP>.
+ossl_namemap_num2name() returns a pointer to I<idx>th name associated
+with id I<number>, or NULL if it's undefined in the given
+B<OSSL_NAMEMAP>.
ossl_namemap_name2num() and ossl_namemap_name2num_n() return the number
corresponding to the given name, or 0 if it's undefined in the given
@@ -116,7 +121,7 @@ The functions described here were all added in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2025 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
diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in
index 9dd4f5a49ffe..d44b4a7dac85 100644
--- a/doc/man1/openssl-fipsinstall.pod.in
+++ b/doc/man1/openssl-fipsinstall.pod.in
@@ -237,9 +237,7 @@ explicitly permitted by the various standards.
=item B<-hkdf_digest_check>
-Configure the module to enable a run-time digest check when deriving a key by
-HKDF.
-See NIST SP 800-56Cr2 for details.
+This option is deprecated.
=item B<-tls13_kdf_digest_check>
@@ -261,9 +259,7 @@ See NIST SP 800-135r1 for details.
=item B<-sskdf_digest_check>
-Configure the module to enable a run-time digest check when deriving a key by
-SSKDF.
-See NIST SP 800-56Cr2 for details.
+This option is deprecated.
=item B<-x963kdf_digest_check>
@@ -493,7 +489,7 @@ B<-ecdh_cofactor_check>
=head1 COPYRIGHT
-Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2025 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
diff --git a/doc/man1/openssl-pkeyutl.pod.in b/doc/man1/openssl-pkeyutl.pod.in
index 3c59957b8d8a..c5fb8378e8b1 100644
--- a/doc/man1/openssl-pkeyutl.pod.in
+++ b/doc/man1/openssl-pkeyutl.pod.in
@@ -437,10 +437,100 @@ for the B<-pkeyopt> B<digest> option.
The X25519 and X448 algorithms support key derivation only. Currently there are
no additional options.
+=head2 SLH-DSA ALGORITHMS
+
+The SLH-DSA algorithms (SLH-DSA-SHA2-128s, SLH-DSA-SHA2-128f, SLH-DSA-SHA2-192s, SLH-DSA-SHA2-192f, SLH-DSA-SHA2-256s, SLH-DSA-SHA2-256f) are post-quantum signature algorithms. When using SLH-DSA with pkeyutl, the following options are available:
+
+=over 4
+
+=item B<-sign>
+
+Sign the input data using an SLH-DSA private key. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey slhdsa.pem -out sig
+
+=item B<-verify>
+
+Verify the signature using an SLH-DSA public key. For example:
+
+ $ openssl pkeyutl -verify -in file.txt -inkey slhdsa.pem -sigfile sig
+
+=back
+
+See L<EVP_PKEY-SLH-DSA(7)> and L<EVP_SIGNATURE-SLH-DSA(7)> for additional details about the SLH-DSA algorithm and its implementation.
+
=head1 ML-DSA-44, ML-DSA-65 AND ML-DSA-87 ALGORITHMS
-The B<ML-DSA> algorithms support signing and verification of "raw" messages.
-No preliminary hashing is performed.
+The ML-DSA algorithms are post-quantum signature algorithms that support signing and verification of "raw" messages.
+No preliminary hashing is performed. When using ML-DSA with pkeyutl, the following options are available:
+
+=over 4
+
+=item B<-sign>
+
+Sign the input data using an ML-DSA private key. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig
+
+=item B<-verify>
+
+Verify the signature using an ML-DSA public key. For example:
+
+ $ openssl pkeyutl -verify -in file.txt -inkey mldsa65.pem -sigfile sig
+
+=item B<-pkeyopt> I<opt>:I<value>
+
+Additional options for ML-DSA signing and verification:
+
+=over 4
+
+=item B<message-encoding>:I<value>
+
+Specifies the message encoding mode used for signing. This controls how the input message is processed before signing. Valid values are described in L<EVP_SIGNATURE-ML-DSA(7)>. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt message-encoding:1
+
+=item B<test-entropy>:I<value>
+
+Specifies a test entropy value for deterministic signing. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt test-entropy:abcdefghijklmnopqrstuvwxyz012345
+
+=item B<hextest-entropy>:I<value>
+
+Specifies a test entropy value in hex format. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt hextest-entropy:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+
+=item B<deterministic>:I<value>
+
+Enables deterministic signing. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt deterministic:1
+
+=item B<mu>:I<value>
+
+Specifies the mu parameter. For example:
+
+ $ echo -n "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" >file.txt
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt mu:1
+
+=back
+
+=item B<context-string>:I<string>
+
+Specifies a context string for both signing and verification operations. The context string must be the same for verification to succeed. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt context-string:mycontext
+ $ openssl pkeyutl -verify -in file.txt -inkey mldsa65.pem -sigfile sig -pkeyopt context-string:mycontext
+
+=item B<hexcontext-string>:I<string>
+
+Specifies a context string in hex format, allowing binary control values. For example:
+
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt hexcontext-string:6d79636f6e74657874
+
+=back
The signing operation supports a B<deterministic>:I<bool> option,
with I<bool> set to C<1> if a deterministic signature is to be generated
@@ -450,7 +540,7 @@ A deterministic result can also be obtained by specifying an explicit
entropy value via the B<hextest-entropy>:I<value> parameter.
Deterministic B<ML-DSA> signing should only be used in tests.
-See L<EVP_SIGNATURE-ML-DSA(7)> for additional options and detail.
+See L<EVP_SIGNATURE-ML-DSA(7)> for additional details about the ML-DSA algorithms and their implementation.
=head1 ML-KEM-512, ML-KEM-768 AND ML-KEM-1024 ALGORITHMS
@@ -549,6 +639,34 @@ Decrypt some data using a private key with OAEP padding using SHA256:
openssl pkeyutl -decrypt -in file -inkey key.pem -out secret \
-pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256
+Create an ML-DSA key pair and sign data with a specific context string:
+
+ $ openssl genpkey -algorithm ML-DSA-65 -out mldsa65.pem
+ $ openssl pkeyutl -sign -in file.txt -inkey mldsa65.pem -out sig -pkeyopt context-string:example
+
+Verify a signature using ML-DSA with the same context string:
+
+ $ openssl pkeyutl -verify -in file.txt -inkey mldsa65.pem -sigfile sig -pkeyopt context-string:example
+
+Generate an ML-KEM key pair and use it for encapsulation:
+
+ $ openssl genpkey -algorithm ML-KEM-768 -out mlkem768.pem
+ $ openssl pkey -in mlkem768.pem -pubout -out mlkem768_pub.pem
+ $ openssl pkeyutl -encap -inkey mlkem768_pub.pem -pubin -out ciphertext -secret shared_secret.bin
+
+Decapsulate a shared secret using an ML-KEM private key:
+
+ $ openssl pkeyutl -decap -inkey mlkem768.pem -in ciphertext -secret decapsulated_secret.bin
+
+Create an SLH-DSA key pair and sign data:
+
+ $ openssl genpkey -algorithm SLH-DSA-SHA2-128s -out slh-dsa.pem
+ $ openssl pkeyutl -sign -in file.txt -inkey slh-dsa.pem -out sig
+
+Verify a signature using SLH-DSA:
+
+ $ openssl pkeyutl -verify -in file.txt -inkey slh-dsa.pem -sigfile sig
+
=head1 SEE ALSO
L<openssl(1)>,
diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in
index d089bc60d80d..82c5917f6081 100644
--- a/doc/man1/openssl-s_client.pod.in
+++ b/doc/man1/openssl-s_client.pod.in
@@ -507,12 +507,12 @@ by some servers.
=item B<-ign_eof>
Inhibit shutting down the connection when end of file is reached in the
-input.
+input. This implicitly turns on B<-nocommands> as well.
=item B<-quiet>
Inhibit printing of session and certificate information. This implicitly
-turns on B<-ign_eof> as well.
+turns on B<-ign_eof> and B<-nocommands> as well.
=item B<-no_ign_eof>
diff --git a/doc/man3/CMS_get0_SignerInfos.pod b/doc/man3/CMS_get0_SignerInfos.pod
index 385726ced35f..46dba9cde082 100644
--- a/doc/man3/CMS_get0_SignerInfos.pod
+++ b/doc/man3/CMS_get0_SignerInfos.pod
@@ -38,7 +38,7 @@ CMS_SignerInfo_cert_cmp() compares the certificate B<cert> against the signer
identifier B<si>. It returns zero if the comparison is successful and non zero
if not.
-CMS_SignerInfo_set1_signer_cert() sets the signers certificate of B<si> to
+CMS_SignerInfo_set1_signer_cert() sets the signer's certificate of B<si> to
B<signer>.
=head1 NOTES
@@ -80,7 +80,7 @@ L<ERR_get_error(3)>, L<CMS_verify(3)>
=head1 COPYRIGHT
-Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2008-2025 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
diff --git a/doc/man3/CMS_sign.pod b/doc/man3/CMS_sign.pod
index 3380b1a1dd95..ce4f39f885c2 100644
--- a/doc/man3/CMS_sign.pod
+++ b/doc/man3/CMS_sign.pod
@@ -97,7 +97,7 @@ can be performed by obtaining the streaming ASN1 B<BIO> directly using
BIO_new_CMS().
If a signer is specified it will use the default digest for the signing
-algorithm. This is B<SHA1> for both RSA and DSA keys.
+algorithm. This is B<SHA256> for both RSA and DSA keys.
If B<signcert> and B<pkey> are NULL then a certificates only CMS structure is
output.
@@ -136,7 +136,7 @@ certificates in their I<certs> argument and no longer throw an error for them.
=head1 COPYRIGHT
-Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2008-2025 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
diff --git a/doc/man3/DTLS_set_timer_cb.pod b/doc/man3/DTLS_set_timer_cb.pod
index 5014e77d0fc8..618fd1f6ff0e 100644
--- a/doc/man3/DTLS_set_timer_cb.pod
+++ b/doc/man3/DTLS_set_timer_cb.pod
@@ -20,6 +20,17 @@ This function sets an optional callback function for controlling the
timeout interval on the DTLS protocol. The callback function will be
called by DTLS for every new DTLS packet that is sent.
+The callback should return the timeout interval in micro seconds.
+
+The I<timer_us> parameter of the callback is the last set timeout
+interval returned. On the first invocation of the callback,
+this value will be 0.
+
+At the beginning of the connection, if no timeout callback has been
+set via DTLS_set_timer_cb(), the default timeout value is 1 second.
+For all subsequent timeouts, the default behavior is to double the
+duration up to a maximum of 1 minute.
+
=head1 RETURN VALUES
Returns void.
@@ -30,7 +41,7 @@ The DTLS_set_timer_cb() function was added in OpenSSL 1.1.1.
=head1 COPYRIGHT
-Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2025 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
diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod
index d7ac221f7c19..a15abc2c3e17 100644
--- a/doc/man3/EVP_PKEY_CTX_new.pod
+++ b/doc/man3/EVP_PKEY_CTX_new.pod
@@ -49,8 +49,11 @@ used when no B<EVP_PKEY> structure is associated with the operations,
for example during parameter generation or key generation for some
algorithms.
-EVP_PKEY_CTX_dup() duplicates the context I<ctx>. It is not supported for a
-keygen operation.
+EVP_PKEY_CTX_dup() duplicates the context I<ctx>.
+It is not supported for a keygen operation.
+It is however possible to duplicate a context freshly created via any of the
+above C<new> functions, provided L<EVP_PKEY_keygen_init(3)> has not yet been
+called on the source context, and then use the copy for key generation.
EVP_PKEY_CTX_free() frees up the context I<ctx>.
If I<ctx> is NULL, nothing is done.
@@ -122,7 +125,7 @@ added in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2025 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
diff --git a/doc/man3/EVP_PKEY_encapsulate.pod b/doc/man3/EVP_PKEY_encapsulate.pod
index a82eaded592f..e37599c4c417 100644
--- a/doc/man3/EVP_PKEY_encapsulate.pod
+++ b/doc/man3/EVP_PKEY_encapsulate.pod
@@ -30,14 +30,14 @@ key that is used during encapsulation.
The EVP_PKEY_encapsulate() function performs a public key encapsulation
operation using I<ctx>.
-The shared secret writen to I<genkey> can be used as an input for key
+The shared secret written to I<genkey> can be used as an input for key
derivation, typically for various symmetric algorithms.
Its size is written to I<genkeylen>, which must be initialised to the
size of the provided buffer.
The ciphertext written to I<wrappedkey> is an encapsulated form, which
is expected to be only usable by the holder of the private key corresponding
-to wthe public key associated with I<ctx>.
+to the public key associated with I<ctx>.
This ciphertext is then communicated to the private-key holder, who can use
L<EVP_PKEY_decapsulate(3)> to securely recover the same shared secret.
diff --git a/doc/man3/EVP_PKEY_new.pod b/doc/man3/EVP_PKEY_new.pod
index eccc21aac63f..0a56600c2b60 100644
--- a/doc/man3/EVP_PKEY_new.pod
+++ b/doc/man3/EVP_PKEY_new.pod
@@ -174,7 +174,7 @@ C<ML-DSA-87>,
B<ML-KEM-512>,
B<ML-KEM-768> and
B<ML-KEM-1024>
-keys, which don't have legacy numeric I<NID> assigments, but their raw form is
+keys, which don't have legacy numeric I<NID> assignments, but their raw form is
nevertheless available.
@@ -198,7 +198,7 @@ C<ML-DSA-87>,
B<ML-KEM-512>,
B<ML-KEM-768> and
B<ML-KEM-1024>
-keys, which don't have legacy numeric I<NID> assigments, but their raw form is
+keys, which don't have legacy numeric I<NID> assignments, but their raw form is
nevertheless available.
EVP_PKEY_new_CMAC_key() works in the same way as EVP_PKEY_new_raw_private_key()
@@ -219,7 +219,19 @@ general private key without reference to any particular algorithm.
The structure returned by EVP_PKEY_new() is empty. To add a private or public
key to this empty structure use the appropriate functions described in
L<EVP_PKEY_set1_RSA(3)>, L<EVP_PKEY_set1_DSA(3)>, L<EVP_PKEY_set1_DH(3)> or
-L<EVP_PKEY_set1_EC_KEY(3)>.
+L<EVP_PKEY_set1_EC_KEY(3)> for legacy key types implemented in internal
+OpenSSL providers.
+
+For fully provider-managed key types (see L<provider-keymgmt(7)>),
+possibly implemented in external providers, use functions such as
+L<EVP_PKEY_set1_encoded_public_key(3)> or L<EVP_PKEY_fromdata(3)>
+to populate key data.
+
+Generally caution is advised for using an B<EVP_PKEY> structure across
+different library contexts: In order for an B<EVP_PKEY> to be shared by
+multiple library contexts the providers associated with the library contexts
+must have key managers that support the key type and implement the
+OSSL_FUNC_keymgmt_import() and OSSL_FUNC_keymgmt_export() functions.
=head1 RETURN VALUES
diff --git a/doc/man3/EVP_PKEY_sign.pod b/doc/man3/EVP_PKEY_sign.pod
index b88a9893f52f..300f77889fd8 100644
--- a/doc/man3/EVP_PKEY_sign.pod
+++ b/doc/man3/EVP_PKEY_sign.pod
@@ -40,7 +40,7 @@ signing a pre-computed message digest using the algorithm given by I<algo> and
the key given through L<EVP_PKEY_CTX_new(3)> or L<EVP_PKEY_CTX_new_from_pkey(3)>.
A context I<ctx> without a pre-loaded key cannot be used with this function.
This function provides almost the same functionality as EVP_PKEY_sign_init_ex(),
-but is uniquely intended to be used with a pre-computed messsage digest, and
+but is uniquely intended to be used with a pre-computed message digest, and
allows pre-determining the exact conditions for that message digest, if a
composite signature algorithm (such as RSA-SHA256) was fetched.
Following a call to this function, setting parameters that modifies the digest
@@ -358,7 +358,7 @@ where added in OpenSSL 3.4.
=head1 COPYRIGHT
-Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2025 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
diff --git a/doc/man3/EVP_RAND.pod b/doc/man3/EVP_RAND.pod
index fdb9ef9dcfd1..b9abd245cd7e 100644
--- a/doc/man3/EVP_RAND.pod
+++ b/doc/man3/EVP_RAND.pod
@@ -152,11 +152,8 @@ operating system. If I<prediction_resistance> is specified, fresh entropy
from a live source will be sought. This call operates as per NIST SP 800-90A
and SP 800-90C.
-EVP_RAND_nonce() creates a nonce in I<out> of maximum length I<outlen>
-bytes from the RAND I<ctx>. The function returns the length of the generated
-nonce. If I<out> is NULL, the length is still returned but no generation
-takes place. This allows a caller to dynamically allocate a buffer of the
-appropriate size.
+EVP_RAND_nonce() creates a nonce in I<out> of length I<outlen>
+bytes from the RAND I<ctx>.
EVP_RAND_enable_locking() enables locking for the RAND I<ctx> and all of
its parents. After this I<ctx> will operate in a thread safe manner, albeit
@@ -385,7 +382,7 @@ EVP_RAND_CTX_free() does not return a value.
EVP_RAND_CTX_up_ref() returns 1 on success, 0 on error.
-EVP_RAND_nonce() returns the length of the nonce.
+EVP_RAND_nonce() returns 1 on success, 0 on error.
EVP_RAND_get_strength() returns the strength of the random number generator
in bits.
@@ -417,7 +414,7 @@ The remaining functions were added in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2020-2025 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
diff --git a/doc/man3/OPENSSL_secure_malloc.pod b/doc/man3/OPENSSL_secure_malloc.pod
index 1bddd7737069..dbc7073aac18 100644
--- a/doc/man3/OPENSSL_secure_malloc.pod
+++ b/doc/man3/OPENSSL_secure_malloc.pod
@@ -45,7 +45,12 @@ the program's dynamic memory area, where keys and other sensitive
information might be stored, OpenSSL supports the concept of a "secure heap."
The level and type of security guarantees depend on the operating system.
It is a good idea to review the code and see if it addresses your
-threat model and concerns.
+threat model and concerns. It should be noted that the secure heap
+uses a single read/write lock, and therefore any operations
+that involve allocation or freeing of secure heap memory are serialised,
+blocking other threads. With that in mind, highly concurrent applications
+should enable the secure heap with caution and be aware of the performance
+implications for multi-threaded code.
If a secure heap is used, then private key B<BIGNUM> values are stored there.
This protects long-term storage of private keys, but will not necessarily
@@ -135,7 +140,7 @@ a B<size_t> in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2015-2025 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
diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod
index 0df0e78367e9..53e8166228da 100644
--- a/doc/man3/OSSL_CMP_CTX_new.pod
+++ b/doc/man3/OSSL_CMP_CTX_new.pod
@@ -106,7 +106,7 @@ OSSL_CMP_CTX_set1_senderNonce
/* server authentication: */
int OSSL_CMP_CTX_set1_srvCert(OSSL_CMP_CTX *ctx, X509 *cert);
int OSSL_CMP_CTX_set1_expected_sender(OSSL_CMP_CTX *ctx,
- const X509_NAME *name);
+ const X509_NAME *name);
#define OSSL_CMP_CTX_set0_trusted OSSL_CMP_CTX_set0_trustedStore
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store);
#define OSSL_CMP_CTX_get0_trusted OSSL_CMP_CTX_get0_trustedStore
@@ -214,147 +214,147 @@ The following options can be set:
=item B<OSSL_CMP_OPT_LOG_VERBOSITY>
- The level of severity needed for actually outputting log messages
- due to errors, warnings, general info, debugging, etc.
- Default is OSSL_CMP_LOG_INFO. See also L<OSSL_CMP_log_open(3)>.
+The level of severity needed for actually outputting log messages
+due to errors, warnings, general info, debugging, etc.
+Default is OSSL_CMP_LOG_INFO. See also L<OSSL_CMP_log_open(3)>.
=item B<OSSL_CMP_OPT_KEEP_ALIVE>
- If the given value is 0 then HTTP connections are not kept open
- after receiving a response, which is the default behavior for HTTP 1.0.
- If the value is 1 or 2 then persistent connections are requested.
- If the value is 2 then persistent connections are required,
- i.e., in case the server does not grant them an error occurs.
- The default value is 1: prefer to keep the connection open.
+If the given value is 0 then HTTP connections are not kept open
+after receiving a response, which is the default behavior for HTTP 1.0.
+If the value is 1 or 2 then persistent connections are requested.
+If the value is 2 then persistent connections are required,
+i.e., in case the server does not grant them an error occurs.
+The default value is 1: prefer to keep the connection open.
=item B<OSSL_CMP_OPT_MSG_TIMEOUT>
- Number of seconds a CMP request-response message round trip
- is allowed to take before a timeout error is returned.
- A value <= 0 means no limitation (waiting indefinitely).
- Default is to use the B<OSSL_CMP_OPT_TOTAL_TIMEOUT> setting.
+Number of seconds a CMP request-response message round trip
+is allowed to take before a timeout error is returned.
+A value <= 0 means no limitation (waiting indefinitely).
+Default is to use the B<OSSL_CMP_OPT_TOTAL_TIMEOUT> setting.
=item B<OSSL_CMP_OPT_TOTAL_TIMEOUT>
- Maximum total number of seconds a transaction may take,
- including polling etc.
- A value <= 0 means no limitation (waiting indefinitely).
- Default is 0.
+Maximum total number of seconds a transaction may take,
+including polling etc.
+A value <= 0 means no limitation (waiting indefinitely).
+Default is 0.
=item B<OSSL_CMP_OPT_USE_TLS>
- Use this option to indicate to the HTTP implementation
- whether TLS is going to be used for the connection (resulting in HTTPS).
- The value 1 indicates that TLS is used for client-side HTTP connections,
- which needs to be implemented via a callback function set by
- OSSL_CMP_CTX_set_http_cb().
- The value 0 indicates that TLS is not used.
- Default is -1 for backward compatibility: TLS is used by the client side
- if and only if OSSL_CMP_CTX_set_http_cb_arg() sets a non-NULL I<arg>.
+Use this option to indicate to the HTTP implementation
+whether TLS is going to be used for the connection (resulting in HTTPS).
+The value 1 indicates that TLS is used for client-side HTTP connections,
+which needs to be implemented via a callback function set by
+OSSL_CMP_CTX_set_http_cb().
+The value 0 indicates that TLS is not used.
+Default is -1 for backward compatibility: TLS is used by the client side
+if and only if OSSL_CMP_CTX_set_http_cb_arg() sets a non-NULL I<arg>.
=item B<OSSL_CMP_OPT_VALIDITY_DAYS>
- Number of days new certificates are asked to be valid for.
+Number of days new certificates are asked to be valid for.
=item B<OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT>
- Do not take default Subject Alternative Names
- from the reference certificate.
+Do not take default Subject Alternative Names
+from the reference certificate.
=item B<OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL>
- Demand that the given Subject Alternative Names are flagged as critical.
+Demand that the given Subject Alternative Names are flagged as critical.
=item B<OSSL_CMP_OPT_POLICIES_CRITICAL>
- Demand that the given policies are flagged as critical.
+Demand that the given policies are flagged as critical.
=item B<OSSL_CMP_OPT_POPO_METHOD>
- Select the proof of possession method to use. Possible values are:
+Select the proof of possession method to use. Possible values are:
- OSSL_CRMF_POPO_NONE - ProofOfPossession field omitted,
- which implies central key generation
- OSSL_CRMF_POPO_RAVERIFIED - assert that the RA has already
- verified the PoPo
- OSSL_CRMF_POPO_SIGNATURE - sign a value with private key,
- which is the default.
- OSSL_CRMF_POPO_KEYENC - decrypt the encrypted certificate
- ("indirect method")
+ OSSL_CRMF_POPO_NONE - ProofOfPossession field omitted,
+ which implies central key generation
+ OSSL_CRMF_POPO_RAVERIFIED - assert that the RA has already
+ verified the PoPo
+ OSSL_CRMF_POPO_SIGNATURE - sign a value with private key,
+ which is the default.
+ OSSL_CRMF_POPO_KEYENC - decrypt the encrypted certificate
+ ("indirect method")
- Note that a signature-based POPO can only be produced if a private key
- is provided as the newPkey or client's pkey component of the CMP context.
+Note that a signature-based POPO can only be produced if a private key
+is provided as the newPkey or client's pkey component of the CMP context.
=item B<OSSL_CMP_OPT_DIGEST_ALGNID>
- The NID of the digest algorithm to be used in RFC 4210's MSG_SIG_ALG
- for signature-based message protection and Proof-of-Possession (POPO).
- Default is SHA256.
+The NID of the digest algorithm to be used in RFC 4210's MSG_SIG_ALG
+for signature-based message protection and Proof-of-Possession (POPO).
+Default is SHA256.
=item B<OSSL_CMP_OPT_OWF_ALGNID>
- The NID of the digest algorithm to be used as one-way function (OWF)
- for MAC-based message protection with password-based MAC (PBM).
- See RFC 4210 section 5.1.3.1 for details.
- Default is SHA256.
+The NID of the digest algorithm to be used as one-way function (OWF)
+for MAC-based message protection with password-based MAC (PBM).
+See RFC 4210 section 5.1.3.1 for details.
+Default is SHA256.
=item B<OSSL_CMP_OPT_MAC_ALGNID>
- The NID of the MAC algorithm to be used for message protection with PBM.
- Default is HMAC-SHA1 as per RFC 4210.
+The NID of the MAC algorithm to be used for message protection with PBM.
+Default is HMAC-SHA1 as per RFC 4210.
=item B<OSSL_CMP_OPT_REVOCATION_REASON>
- The reason code to be included in a Revocation Request (RR);
- values: 0..10 (RFC 5210, 5.3.1) or -1 for none, which is the default.
+The reason code to be included in a Revocation Request (RR);
+values: 0..10 (RFC 5210, 5.3.1) or -1 for none, which is the default.
=item B<OSSL_CMP_OPT_IMPLICIT_CONFIRM>
- Request server to enable implicit confirm mode, where the client
- does not need to send confirmation upon receiving the
- certificate. If the server does not enable implicit confirmation
- in the return message, then confirmation is sent anyway.
+Request server to enable implicit confirm mode, where the client
+does not need to send confirmation upon receiving the
+certificate. If the server does not enable implicit confirmation
+in the return message, then confirmation is sent anyway.
=item B<OSSL_CMP_OPT_DISABLE_CONFIRM>
- Do not confirm enrolled certificates, to cope with broken servers
- not supporting implicit confirmation correctly.
+Do not confirm enrolled certificates, to cope with broken servers
+not supporting implicit confirmation correctly.
B<WARNING:> This setting leads to unspecified behavior and it is meant
exclusively to allow interoperability with server implementations violating
RFC 4210.
=item B<OSSL_CMP_OPT_UNPROTECTED_SEND>
- Send request or response messages without CMP-level protection.
+Send request or response messages without CMP-level protection.
=item B<OSSL_CMP_OPT_UNPROTECTED_ERRORS>
- Accept unprotected error responses which are either explicitly
- unprotected or where protection verification failed. Applies to regular
- error messages as well as certificate responses (IP/CP/KUP) and
- revocation responses (RP) with rejection.
+Accept unprotected error responses which are either explicitly
+unprotected or where protection verification failed. Applies to regular
+error messages as well as certificate responses (IP/CP/KUP) and
+revocation responses (RP) with rejection.
B<WARNING:> This setting leads to unspecified behavior and it is meant
exclusively to allow interoperability with server implementations violating
RFC 4210.
=item B<OSSL_CMP_OPT_IGNORE_KEYUSAGE>
- Ignore key usage restrictions in the signer's certificate when
- validating signature-based protection in received CMP messages.
- Else, 'digitalSignature' must be allowed by CMP signer certificates.
+Ignore key usage restrictions in the signer's certificate when
+validating signature-based protection in received CMP messages.
+Else, 'digitalSignature' must be allowed by CMP signer certificates.
=item B<OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR>
- Allow retrieving a trust anchor from extraCerts and using that
- to validate the certificate chain of an IP message.
- This is a quirk option added to support 3GPP TS 33.310.
+Allow retrieving a trust anchor from extraCerts and using that
+to validate the certificate chain of an IP message.
+This is a quirk option added to support 3GPP TS 33.310.
- Note that using this option is dangerous as the certificate obtained
- this way has not been authenticated (at least not at CMP level).
- Taking it over as a trust anchor implements trust-on-first-use (TOFU).
+Note that using this option is dangerous as the certificate obtained
+this way has not been authenticated (at least not at CMP level).
+Taking it over as a trust anchor implements trust-on-first-use (TOFU).
=item B<OSSL_CMP_OPT_NO_CACHE_EXTRACERTS>
- Do not cache certificates received in the extraCerts CMP message field.
- Otherwise they are stored to potentially help validate further messages.
+Do not cache certificates received in the extraCerts CMP message field.
+Otherwise they are stored to potentially help validate further messages.
=back
diff --git a/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod b/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
index 6c095c0ee0e8..0f700c118f55 100644
--- a/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
+++ b/doc/man3/OSSL_CRMF_MSG_get0_tmpl.pod
@@ -109,7 +109,7 @@ On success, the function verifies the decrypted data as signed data,
using the trust store I<ts> and any untrusted certificates in I<extra>.
Doing so, it checks for the purpose "CMP Key Generation Authority" (cmKGA).
-OSSL_CRMF_ENCRYPTEDKEY_init_envdata() returns I<OSSL_CRMF_ENCRYPTEDKEY>, intialized with
+OSSL_CRMF_ENCRYPTEDKEY_init_envdata() returns I<OSSL_CRMF_ENCRYPTEDKEY>, initialized with
the enveloped data I<envdata>.
OSSL_CRMF_ENCRYPTEDVALUE_decrypt() decrypts the encrypted value in the given
diff --git a/doc/man3/OSSL_PARAM.pod b/doc/man3/OSSL_PARAM.pod
index 22fd0f0d7dd7..8a50db2b94d4 100644
--- a/doc/man3/OSSL_PARAM.pod
+++ b/doc/man3/OSSL_PARAM.pod
@@ -356,7 +356,7 @@ could fill in the parameters like this:
=head1 SEE ALSO
-L<openssl-core.h(7)>, L<OSSL_PARAM_get_int(3)>, L<OSSL_PARAM_dup(3)>
+L<openssl-core.h(7)>, L<OSSL_PARAM_get_int(3)>, L<OSSL_PARAM_dup(3)>, L<OSSL_PARAM_construct_utf8_string(3)>
=head1 HISTORY
@@ -364,7 +364,7 @@ B<OSSL_PARAM> was added in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2025 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
diff --git a/doc/man3/OSSL_PARAM_int.pod b/doc/man3/OSSL_PARAM_int.pod
index dae0de083a62..a2bcd535b014 100644
--- a/doc/man3/OSSL_PARAM_int.pod
+++ b/doc/man3/OSSL_PARAM_int.pod
@@ -392,6 +392,29 @@ could fill in the parameters like this:
if ((p = OSSL_PARAM_locate(params, "cookie")) != NULL)
OSSL_PARAM_set_utf8_ptr(p, "cookie value");
+=head2 Example 3
+
+This example shows a special case where
+I<-Wincompatible-pointer-types-discards-qualifiers> may be set during
+compilation. The value for I<buf> cannot be a I<const char *> type string. An
+alternative in this case would be to use B<OSSL_PARAM> macro abbreviated calls
+rather than the specific callers which allows you to define the sha1 argument
+as a standard character array (I<char[]>).
+
+For example, this code:
+
+ OSSL_PARAM params[2];
+ params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
+ params[1] = OSSL_PARAM_construct_end();
+
+Can be made compatible with the following version:
+
+ char sha1[] = "SHA1"; /* sha1 is defined as char[] in this case */
+ OSSL_PARAM params[2];
+
+ params[0] = OSSL_PARAM_construct_utf8_string("digest", sha1, 0);
+ params[1] = OSSL_PARAM_construct_end();
+
=head1 SEE ALSO
L<openssl-core.h(7)>, L<OSSL_PARAM(3)>
@@ -402,7 +425,7 @@ These APIs were introduced in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2025 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
diff --git a/doc/man3/PEM_read_CMS.pod b/doc/man3/PEM_read_CMS.pod
index dbccf26cd893..880e31481029 100644
--- a/doc/man3/PEM_read_CMS.pod
+++ b/doc/man3/PEM_read_CMS.pod
@@ -84,9 +84,9 @@ see L<openssl_user_macros(7)>:
=head1 DESCRIPTION
-All of the functions described on this page are deprecated.
-Applications should use OSSL_ENCODER_to_bio() and OSSL_DECODER_from_bio()
-instead.
+To replace the deprecated functions listed above, applications should use the
+B<EVP_PKEY> type and OSSL_DECODER_from_bio() and OSSL_ENCODER_to_bio() to
+read and write PEM data containing key parameters or private and public keys.
In the description below, B<I<TYPE>> is used
as a placeholder for any of the OpenSSL datatypes, such as B<X509>.
@@ -142,7 +142,7 @@ were deprecated in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 1998-2025 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
diff --git a/doc/man3/PKCS7_sign.pod b/doc/man3/PKCS7_sign.pod
index 1d997045fe14..5c55aa191def 100644
--- a/doc/man3/PKCS7_sign.pod
+++ b/doc/man3/PKCS7_sign.pod
@@ -80,7 +80,7 @@ can be performed by obtaining the streaming ASN1 B<BIO> directly using
BIO_new_PKCS7().
If a signer is specified it will use the default digest for the signing
-algorithm. This is B<SHA1> for both RSA and DSA keys.
+algorithm. This is B<SHA256> for both RSA and DSA keys.
The I<certs>, I<signcert> and I<pkey> parameters can all be
NULL if the B<PKCS7_PARTIAL> flag is set. One or more signers can be added
@@ -122,7 +122,7 @@ The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0.
=head1 COPYRIGHT
-Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2002-2025 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
diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod
index e2c1e6984703..9338ffc01ddf 100644
--- a/doc/man3/SSL_CONF_cmd.pod
+++ b/doc/man3/SSL_CONF_cmd.pod
@@ -74,7 +74,7 @@ B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>.
=item B<-no_renegotiation>
-Disables all attempts at renegotiation in TLSv1.2 and earlier, same as setting
+Disables all attempts at renegotiation in (D)TLSv1.2 and earlier, same as setting
B<SSL_OP_NO_RENEGOTIATION>.
=item B<-no_resumption_on_reneg>
diff --git a/doc/man3/SSL_CTX_set_min_proto_version.pod b/doc/man3/SSL_CTX_set_min_proto_version.pod
index 9a2da37ab729..d9b61dcce9fd 100644
--- a/doc/man3/SSL_CTX_set_min_proto_version.pod
+++ b/doc/man3/SSL_CTX_set_min_proto_version.pod
@@ -31,9 +31,10 @@ L<SSL_CTX_set_options(3)> that also make it possible to disable
specific protocol versions.
Use these functions instead of disabling specific protocol versions.
-Setting the minimum or maximum version to 0, will enable protocol
+Setting the minimum or maximum version to 0 (default), will enable protocol
versions down to the lowest version, or up to the highest version
-supported by the library, respectively.
+supported by the library, respectively. The supported versions might be
+controlled by system configuration.
Getters return 0 in case B<ctx> or B<ssl> have been configured to
automatically use the lowest or highest version supported by the library.
@@ -67,7 +68,7 @@ were added in OpenSSL 1.1.1.
=head1 COPYRIGHT
-Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2025 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
diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod
index a6c922ecf92c..fa344337b5f8 100644
--- a/doc/man3/SSL_CTX_set_options.pod
+++ b/doc/man3/SSL_CTX_set_options.pod
@@ -286,7 +286,7 @@ Do not query the MTU. Only affects DTLS connections.
=item SSL_OP_NO_RENEGOTIATION
-Disable all renegotiation in TLSv1.2 and earlier. Do not send HelloRequest
+Disable all renegotiation in (D)TLSv1.2 and earlier. Do not send HelloRequest
messages, and ignore renegotiation requests via ClientHello.
=item SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
@@ -542,7 +542,7 @@ whether these macros are defined or not.
=head1 COPYRIGHT
-Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2001-2025 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
diff --git a/doc/man3/SSL_key_update.pod b/doc/man3/SSL_key_update.pod
index 6238e67649e0..6f9f9b92365c 100644
--- a/doc/man3/SSL_key_update.pod
+++ b/doc/man3/SSL_key_update.pod
@@ -53,7 +53,9 @@ such as SSL_read_ex() or SSL_write_ex() takes place on the connection a check
will be performed to confirm that it is a suitable time to start a
renegotiation. If so, then it will be initiated immediately. OpenSSL will not
attempt to resume any session associated with the connection in the new
-handshake.
+handshake. Note that some servers will respond to reneogitation attempts with
+a "no_renegotiation" alert. An OpenSSL will immediately fail the connection in
+this case.
When called from the client side, SSL_renegotiate_abbreviated() works in the
same was as SSL_renegotiate() except that OpenSSL will attempt to resume the
@@ -118,7 +120,7 @@ OpenSSL 1.1.1.
=head1 COPYRIGHT
-Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2017-2025 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
diff --git a/doc/man3/SSL_new_listener.pod b/doc/man3/SSL_new_listener.pod
index b830bd11bd17..291c103381e7 100644
--- a/doc/man3/SSL_new_listener.pod
+++ b/doc/man3/SSL_new_listener.pod
@@ -130,6 +130,14 @@ connection is created and returned on success. If no incoming connection is
available and the listener SSL object is configured in nonblocking mode, NULL is
returned.
+The new SSL object returned from SSL_accept_connection() may or may not have
+completed its handshake at the point it is returned. Optionally, you may use the
+function L<SSL_is_init_finished(3)> to determine this. You may call the
+functions L<SSL_accept(3)>, L<SSL_do_handshake(3)> or L<SSL_handle_events(3)> to
+progress the state of the SSL object towards handshake completion. Other "I/O"
+functions may also implicitly progress the state of the handshake such as
+L<SSL_poll(3)>, L<SSL_read(3)> and L<SSL_write(3)>.
+
The B<SSL_ACCEPT_CONNECTION_NO_BLOCK> flag may be specified to
SSL_accept_connection(). If specified, the call does not block even if the
listener SSL object is configured in blocking mode.
diff --git a/doc/man3/SSL_set1_host.pod b/doc/man3/SSL_set1_host.pod
index c91a075a6a60..b65116a53f5f 100644
--- a/doc/man3/SSL_set1_host.pod
+++ b/doc/man3/SSL_set1_host.pod
@@ -9,8 +9,8 @@ SSL server verification parameters
#include <openssl/ssl.h>
- int SSL_set1_host(SSL *s, const char *hostname);
- int SSL_add1_host(SSL *s, const char *hostname);
+ int SSL_set1_host(SSL *s, const char *host);
+ int SSL_add1_host(SSL *s, const char *host);
void SSL_set_hostflags(SSL *s, unsigned int flags);
const char *SSL_get0_peername(SSL *s);
@@ -18,29 +18,36 @@ SSL server verification parameters
These functions configure server hostname checks in the SSL client.
-SSL_set1_host() sets the expected DNS hostname to B<name> clearing
-any previously specified hostname. If B<name> is NULL
-or the empty string, the list of hostnames is cleared and name
-checks are not performed on the peer certificate. When a nonempty
-B<name> is specified, certificate verification automatically checks
-the peer hostname via L<X509_check_host(3)> with B<flags> as specified
+SSL_set1_host() sets in the verification parameters of I<s>
+the expected DNS hostname or IP address to I<host>,
+clearing any previously specified IP address and hostnames.
+If I<host> is NULL or the empty string, IP address
+and hostname checks are not performed on the peer certificate.
+When a nonempty I<host> is specified, certificate verification automatically
+checks the peer hostname via L<X509_check_host(3)> with I<flags> as specified
via SSL_set_hostflags(). Clients that enable DANE TLSA authentication
via L<SSL_dane_enable(3)> should leave it to that function to set
the primary reference identifier of the peer, and should not call
SSL_set1_host().
-SSL_add1_host() adds B<name> as an additional reference identifier
-that can match the peer's certificate. Any previous names set via
-SSL_set1_host() or SSL_add1_host() are retained, no change is made
-if B<name> is NULL or empty. When multiple names are configured,
-the peer is considered verified when any name matches. This function
-is required for DANE TLSA in the presence of service name indirection
-via CNAME, MX or SRV records as specified in RFC7671, RFC7672 or
-RFC7673.
-
-SSL_set_hostflags() sets the B<flags> that will be passed to
+SSL_add1_host() adds I<host> as an additional reference identifier
+that can match the peer's certificate. Any previous hostnames
+set via SSL_set1_host() or SSL_add1_host() are retained.
+Adding an IP address is allowed only if no IP address has been set before.
+No change is made if I<host> is NULL or empty.
+When an IP address and/or multiple hostnames are configured,
+the peer is considered verified when any of these matches.
+This function is required for DANE TLSA in the presence of service name indirection
+via CNAME, MX or SRV records as specified in RFCs 7671, 7672, and 7673.
+
+TLS clients are recommended to use SSL_set1_host() or SSL_add1_host()
+for server hostname or IP address validation,
+as well as L<SSL_set_tlsext_host_name(3)> for Server Name Indication (SNI),
+which may be crucial also for correct routing of the connection request.
+
+SSL_set_hostflags() sets the I<flags> that will be passed to
L<X509_check_host(3)> when name checks are applicable, by default
-the B<flags> value is 0. See L<X509_check_host(3)> for the list
+the I<flags> value is 0. See L<X509_check_host(3)> for the list
of available flags and their meaning.
SSL_get0_peername() returns the DNS hostname or subject CommonName
@@ -51,13 +58,13 @@ of the reference identifiers configured via SSL_set1_host() or
SSL_add1_host() starts with ".", which indicates a parent domain prefix
rather than a fixed name, the matched peer name may be a sub-domain
of the reference identifier. The returned string is allocated by
-the library and is no longer valid once the associated B<ssl> handle
+the library and is no longer valid once the associated I<ssl> handle
is cleared or freed, or a renegotiation takes place. Applications
must not free the return value.
SSL clients are advised to use these functions in preference to
explicitly calling L<X509_check_host(3)>. Hostname checks may be out
-of scope with the RFC7671 DANE-EE(3) certificate usage, and the
+of scope with the RFC 7671 DANE-EE(3) certificate usage, and the
internal check will be suppressed as appropriate when DANE is
enabled.
@@ -66,8 +73,10 @@ enabled.
SSL_set1_host() and SSL_add1_host() return 1 for success and 0 for
failure.
+SSL_set_hostflags() returns nothing at all.
+
SSL_get0_peername() returns NULL if peername verification is not
-applicable (as with RFC7671 DANE-EE(3)), or no trusted peername was
+applicable (as with RFC 7671 DANE-EE(3)), or no trusted peername was
matched. Otherwise, it returns the matched peername. To determine
whether verification succeeded call L<SSL_get_verify_result(3)>.
@@ -99,9 +108,8 @@ the lifetime of the SSL connection.
=head1 SEE ALSO
L<ssl(7)>,
-L<X509_check_host(3)>,
-L<SSL_get_verify_result(3)>.
-L<SSL_dane_enable(3)>.
+L<X509_check_host(3)>, L<SSL_set_tlsext_host_name(3)>,
+L<SSL_get_verify_result(3)>, L<SSL_dane_enable(3)>
=head1 HISTORY
@@ -109,7 +117,7 @@ These functions were added in OpenSSL 1.1.0.
=head1 COPYRIGHT
-Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2025 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
diff --git a/doc/man3/SSL_set_quic_tls_cbs.pod b/doc/man3/SSL_set_quic_tls_cbs.pod
index 618cc29bc74d..75d217bdeaa6 100644
--- a/doc/man3/SSL_set_quic_tls_cbs.pod
+++ b/doc/man3/SSL_set_quic_tls_cbs.pod
@@ -110,7 +110,7 @@ ever be read by OpenSSL.
The OSSL_FUNC_SSL_QUIC_TLS_yield_secret_fn callback (function id
B<OSSL_FUNC_SSL_QUIC_TLS_YIELD_SECRET>) is called when a new secret has been
-established. The I<prot_level> argument identies the TLS protection level and
+established. The I<prot_level> argument identities the TLS protection level and
will be one of B<OSSL_RECORD_PROTECTION_LEVEL_NONE>,
B<OSSL_RECORD_PROTECTION_LEVEL_EARLY>, B<OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE>
or B<OSSL_RECORD_PROTECTION_LEVEL_APPLICATION>. The I<direction> will either be
diff --git a/doc/man3/X509_STORE_CTX_new.pod b/doc/man3/X509_STORE_CTX_new.pod
index c219cee9d621..76cb7000c289 100644
--- a/doc/man3/X509_STORE_CTX_new.pod
+++ b/doc/man3/X509_STORE_CTX_new.pod
@@ -85,7 +85,7 @@ If I<ctx> is NULL nothing is done.
X509_STORE_CTX_init() sets up I<ctx> for a subsequent verification operation.
X509_STORE_CTX_init() initializes the internal state and resources of the
-given I<ctx>. Among others, it sets the verification parameters associcated
+given I<ctx>. Among others, it sets the verification parameters associated
with the method name C<default>, which includes the C<any> purpose,
and takes over callback function pointers from I<trust_store> (unless NULL).
It must be called before each call to L<X509_verify_cert(3)> or
@@ -319,7 +319,7 @@ There is no need to call X509_STORE_CTX_cleanup() explicitly since OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2009-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2009-2025 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
diff --git a/doc/man3/X509_check_purpose.pod b/doc/man3/X509_check_purpose.pod
index 4e152be8fa5d..59440dc013d7 100644
--- a/doc/man3/X509_check_purpose.pod
+++ b/doc/man3/X509_check_purpose.pod
@@ -80,7 +80,7 @@ Unless the id stays the same for an existing entry, I<id> must be fresh,
which can be achieved by using the result of X509_PURPOSE_get_unused_id().
The function also sets in the entry the trust id I<trust>, the given I<flags>,
the purpose (long) name I<name>, the short name I<sname>, the purpose checking
-funktion I<ck> of type B<int (*) (const X509_PURPOSE *, const X509 *, int)>,
+function I<ck> of type B<int (*) (const X509_PURPOSE *, const X509 *, int)>,
and its user data I<arg> which may be retrieved via the B<X509_PURPOSE> pointer.
X509_PURPOSE_cleanup() removes all purposes that are not pre-defined.
diff --git a/doc/man5/fips_config.pod b/doc/man5/fips_config.pod
index a25ced338393..c3f7b8f3ab6b 100644
--- a/doc/man5/fips_config.pod
+++ b/doc/man5/fips_config.pod
@@ -62,17 +62,11 @@ A version number for the fips install process. Should be 1.
=item B<install-status>
-An indicator that the self-tests were successfully run.
-This should only be written after the module has
-successfully passed its self tests during installation.
-If this field is not present, then the self tests will run when the module
-loads.
+This field is deprecated and is no longer used.
=item B<install-mac>
-A MAC of the value of the B<install-status> option, to prevent accidental
-changes to that value.
-It is written-to at the same time as B<install-status> is updated.
+This field is deprecated and is no longer used.
=back
@@ -112,7 +106,7 @@ See L<openssl-fipsinstall(1)/OPTIONS> B<-signature_digest_check>
=item B<hkdf-digest-check>
-See L<openssl-fipsinstall(1)/OPTIONS> B<-hkdf_digest_check>
+This option is deprecated.
=item B<tls13-kdf-digest-check>
@@ -128,7 +122,7 @@ See L<openssl-fipsinstall(1)/OPTIONS> B<-sshkdf_digest_check>
=item B<sskdf-digest-check>
-See L<openssl-fipsinstall(1)/OPTIONS> B<-sskdf_digest_check>
+This option is deprecated.
=item B<x963kdf-digest-check>
@@ -233,7 +227,7 @@ This functionality was added in OpenSSL 3.0.
=head1 COPYRIGHT
-Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2025 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
diff --git a/doc/man7/EVP_ASYM_CIPHER-RSA.pod b/doc/man7/EVP_ASYM_CIPHER-RSA.pod
index 171a3d130ec0..2b8cf1c12fb8 100644
--- a/doc/man7/EVP_ASYM_CIPHER-RSA.pod
+++ b/doc/man7/EVP_ASYM_CIPHER-RSA.pod
@@ -27,7 +27,8 @@ The default provider understands these RSA padding modes in string form:
This padding mode is no longer supported by the FIPS provider for key
agreement and key transport.
-(This is a FIPS 140-3 requirement)
+(This is a FIPS 140-3 requirement).
+See L<openssl-fipsinstall(1)/OPTIONS> B<-rsa_pkcs15_pad_disabled>.
=item "x931" (B<OSSL_PKEY_RSA_PAD_MODE_X931>)
@@ -109,7 +110,7 @@ L<OSSL_PROVIDER-FIPS(7)>
=head1 COPYRIGHT
-Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2022-2025 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
diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod
index 20d35fada87f..b338d1c35f1b 100644
--- a/doc/man7/OSSL_PROVIDER-FIPS.pod
+++ b/doc/man7/OSSL_PROVIDER-FIPS.pod
@@ -14,7 +14,7 @@ accredited testing laboratory.
=head2 Properties
The implementations in this provider specifically have these properties
-defined:
+defined for approved algorithms:
=over 4
@@ -41,20 +41,17 @@ query. Including C<provider=fips> in your property query guarantees
that the OpenSSL FIPS provider is used for cryptographic operations
rather than other FIPS capable providers.
-=head2 Provider parameters
-
-See L<provider-base(7)/Provider parameters> for a list of base parameters.
-Additionally the OpenSSL FIPS provider also supports the following gettable
-parameters:
-
-=over 4
+=head2 Approved algorithms
-=item "security-checks" (B<OSSL_OSSL_PROV_PARAM_SECURITY_CHECKS>) <unsigned integer>
+Algorithms that are fetched using "fips=yes" may still be unapproved if certain
+conditions are not met. See L<fips_module(7)/FIPS indicators> for additional
+information.
-For further information refer to the L<openssl-fipsinstall(1)> option
-B<-no_security_checks>.
+=head2 Provider parameters
-=back
+See L<provider-base(7)/Provider parameters> for a list of base parameters.
+The OpenSSL FIPS provider also handles FIPS indicator related parameters as
+specified by L<fips_config(5)/FIPS indicator options>.
=head1 OPERATIONS AND ALGORITHMS
@@ -84,8 +81,6 @@ The OpenSSL FIPS provider supports these operations and algorithms:
=item 3DES, see L<EVP_CIPHER-DES(7)>
-This is an unapproved algorithm.
-
=back
=head2 Message Authentication Code (MAC)
@@ -212,21 +207,21 @@ for signature generation, but may be used for verification for legacy use cases.
=item EC, see L<EVP_KEYMGMT-EC(7)>
-=item X25519, see L<EVP_KEYMGMT-X25519(7)>
-
-This is an unapproved algorithm.
-
-=item X448, see L<EVP_KEYMGMT-X448(7)>
+=item ED25519, see L<EVP_KEYMGMT-ED25519(7)>
-This is an unapproved algorithm.
+=item ED448, see L<EVP_KEYMGMT-ED448(7)>
-=item ED25519, see L<EVP_KEYMGMT-ED25519(7)>
+=item X25519, see L<EVP_KEYMGMT-X25519(7)>
This is an unapproved algorithm.
+The FIPS 140-3 IG states that "Curves that are included in SP 800-186 but not
+included in SP 800-56Arev3 are not approved for key agreement".
-=item ED448, see L<EVP_KEYMGMT-ED448(7)>
+=item X448, see L<EVP_KEYMGMT-X448(7)>
This is an unapproved algorithm.
+The FIPS 140-3 IG states that "Curves that are included in SP 800-186 but not"
+included in SP 800-56Arev3 are not approved for key agreement".
=item TLS1-PRF
@@ -288,8 +283,11 @@ TEST-RAND is an unapproved algorithm.
=head1 SELF TESTING
-One of the requirements for the FIPS module is self testing. An optional callback
-mechanism is available to return information to the user using
+A requirement of FIPS modules is to run cryptographic algorithm self tests.
+FIPS 140-3 requires known answer tests to be run on startup as well as
+conditional tests that run during cryptographic operations.
+
+An optional callback mechanism is available to return information to the user using
L<OSSL_SELF_TEST_set_callback(3)>.
The parameters passed to the callback are described in L<OSSL_SELF_TEST_new(3)>
@@ -311,12 +309,10 @@ Uses HMAC SHA256 on the module file to validate that the module has not been
modified. The integrity value is compared to a value written to a configuration
file during installation.
-=item "Install_Integrity" (B<OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY>)
+=item "KAT_Integrity" (B<OSSL_SELF_TEST_TYPE_KAT_INTEGRITY>)
-Uses HMAC SHA256 on a fixed string to validate that the installation process
-has already been performed and the self test KATS have already been tested,
-The integrity value is compared to a value written to a configuration
-file after successfully running the self tests during installation.
+Used during the Module Integrity test to perform a known answer test on
+HMAC SHA256 prior to using it.
=item "KAT_Cipher" (B<OSSL_SELF_TEST_TYPE_KAT_CIPHER>)
@@ -362,22 +358,22 @@ Known answer test for a Deterministic Random Bit Generator.
Conditional test that is run during the generation or importing of key pairs.
+=item "Conditional_KAT" (B<OSSL_SELF_TEST_TYPE_PCT_KAT>)
+
+Conditional test run during generation that derive the public key from the
+private key and checks that the public key matches. This is a SP 800-56A requirement.
+
=item "Continuous_RNG_Test" (B<OSSL_SELF_TEST_TYPE_CRNG>)
Continuous random number generator test.
-=back
-
-The "Module_Integrity" self test is always run at startup.
-The "Install_Integrity" self test is used to check if the self tests have
-already been run at installation time. If they have already run then the
-self tests are not run on subsequent startups.
-All other self test categories are run once at installation time, except for the
-"Pairwise_Consistency_Test".
+=item "Install_Integrity" (B<OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY>)
-There is only one instance of the "Module_Integrity" and "Install_Integrity"
-self tests. All other self tests may have multiple instances.
+This is deprecated. The option is no longer used since FIPS 140-3 requires
+self tests to always run on startup. Previous FIPS 140-2 validations allowed
+the self tests to be run just once.
+=back
The FIPS module passes the following descriptions(s) to OSSL_SELF_TEST_onbegin().
@@ -385,7 +381,7 @@ The FIPS module passes the following descriptions(s) to OSSL_SELF_TEST_onbegin()
=item "HMAC" (B<OSSL_SELF_TEST_DESC_INTEGRITY_HMAC>)
-"Module_Integrity" and "Install_Integrity" use this.
+"Module_Integrity" uses this.
=item "RSA" (B<OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1>)
@@ -559,19 +555,18 @@ validated versions alongside F<libcrypto> and F<libssl> compiled from any
release within the same major release series. This flexibility enables
you to address bug fixes and CVEs that fall outside the FIPS boundary.
-The FIPS provider in OpenSSL 3.1 includes some non-FIPS validated algorithms,
-consequently the property query C<fips=yes> is mandatory for applications that
-want to operate in a FIPS approved manner. The algorithms are:
-
-=over 4
-
-=item Triple DES ECB
-
-=item Triple DES CBC
-
-=item EdDSA
-
-=back
+You can load the FIPS provider into multiple library contexts as any other
+provider. However the following restriction applies. The FIPS provider cannot
+be used by multiple copies of OpenSSL libcrypto in a single process.
+
+As the provider saves core callbacks to the libcrypto obtained in the
+OSSL_provider_init() call to global data it will fail if subsequent
+invocations of its OSSL_provider_init() function yield different addresses
+of these callbacks than in the initial call. This happens when different
+copies of libcrypto are present in the memory of the process and both try
+to load the same FIPS provider. A workaround is to have a different copy
+of the FIPS provider loaded for each of the libcrypto instances in the
+process.
=head1 SEE ALSO
diff --git a/doc/man7/ossl-guide-tls-introduction.pod b/doc/man7/ossl-guide-tls-introduction.pod
index 19aabfbbb7a3..5789524324d1 100644
--- a/doc/man7/ossl-guide-tls-introduction.pod
+++ b/doc/man7/ossl-guide-tls-introduction.pod
@@ -74,7 +74,7 @@ TLSv1.2 is chosen.
=head1 CERTIFICATES
In order for a client to establish a connection to a server it must authenticate
-the identify of that server, i.e. it needs to confirm that the server is really
+the identity of that server, i.e. it needs to confirm that the server is really
the server that it claims to be and not some imposter. In order to do this the
server will send to the client a digital certificate (also commonly referred to
as an X.509 certificate). The certificate contains various information about the
@@ -311,7 +311,7 @@ L<ossl-guide-tls-server-block(7)>, L<ossl-guide-quic-introduction(7)>
=head1 COPYRIGHT
-Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2023-2025 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
diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod
index 0302900a7314..511195770581 100644
--- a/doc/man7/provider-base.pod
+++ b/doc/man7/provider-base.pod
@@ -154,6 +154,10 @@ provider):
core_new_error OSSL_FUNC_CORE_NEW_ERROR
core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG
core_vset_error OSSL_FUNC_CORE_VSET_ERROR
+ core_set_error_mark OSSL_FUNC_CORE_SET_ERROR_MARK
+ core_clear_last_error_mark OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK
+ core_pop_error_to_mark OSSL_FUNC_CORE_POP_ERROR_TO_MARK
+ core_count_to_mark OSSL_FUNC_CORE_COUNT_TO_MARK
core_obj_add_sigid OSSL_FUNC_CORE_OBJ_ADD_SIGID
core_obj_create OSSL_FUNC_CORE_OBJ_CREATE
CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC
@@ -270,6 +274,33 @@ error occurred or was reported.
This corresponds to the OpenSSL function L<ERR_vset_error(3)>.
+=item core_set_error_mark()
+
+sets a mark on the current topmost error record if there is one.
+
+This corresponds to the OpenSSL function L<ERR_set_mark(3)>.
+
+=item core_clear_last_error_mark()
+
+removes the last mark added if there is one.
+
+This corresponds to the OpenSSL function L<ERR_clear_last_mark(3)>.
+
+=item core_pop_error_to_mark()
+
+pops the top of the error stack until a mark is found. The mark is then removed.
+If there is no mark, the whole stack is removed.
+
+This corresponds to the OpenSSL function L<ERR_pop_to_mark(3)>.
+
+=item core_count_to_mark()
+
+returns the number of entries on the error stack above the most recently
+marked entry, not including that entry. If there is no mark in the error stack,
+the number of entries in the error stack is returned.
+
+This corresponds to the OpenSSL function L<ERR_count_to_mark(3)>.
+
=back
The core_obj_create() function registers a new OID and associated short name
diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod
index 93fdcfb1c0fa..679c35e0f9ba 100644
--- a/doc/man7/provider-cipher.pod
+++ b/doc/man7/provider-cipher.pod
@@ -134,8 +134,8 @@ In order to be a consistent set of functions there must at least be a complete
set of "encrypt" functions, or a complete set of "decrypt" functions, or a
single "cipher" function. Similarly, there can be a complete set of pipeline
"encrypt" functions, and/or a complete set of pipeline "decrypt" functions.
-In all cases both the OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx functions must be
-present.
+In all cases the OSSL_FUNC_cipher_get_params and both OSSL_FUNC_cipher_newctx
+and OSSL_FUNC_cipher_freectx functions must be present.
All other functions are optional.
=head2 Context Management Functions
diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod
index f8235ac8a0af..420b7cdbfcda 100644
--- a/doc/man7/provider-keymgmt.pod
+++ b/doc/man7/provider-keymgmt.pod
@@ -32,7 +32,7 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
void OSSL_FUNC_keymgmt_gen_cleanup(void *genctx);
/* Key loading by object reference, also a constructor */
- void *OSSL_FUNC_keymgmt_load(const void *reference, size_t *reference_sz);
+ void *OSSL_FUNC_keymgmt_load(const void *reference, size_t reference_sz);
/* Key object information */
int OSSL_FUNC_keymgmt_get_params(void *keydata, OSSL_PARAM params[]);
diff --git a/doc/man7/provider-signature.pod b/doc/man7/provider-signature.pod
index 203223cd6bde..61202b523640 100644
--- a/doc/man7/provider-signature.pod
+++ b/doc/man7/provider-signature.pod
@@ -107,8 +107,7 @@ for further information.
The signature (OSSL_OP_SIGNATURE) operation enables providers to implement
signature algorithms and make them available to applications via the API
functions L<EVP_PKEY_sign(3)>, L<EVP_PKEY_verify(3)>,
-and L<EVP_PKEY_verify_recover(3)> (as well
-as other related functions).
+and L<EVP_PKEY_verify_recover(3)> (as well as other related functions).
All "functions" mentioned here are passed as function pointers between
F<libcrypto> and the provider in L<OSSL_DISPATCH(3)> arrays via
@@ -201,10 +200,22 @@ set of "signature" functions, i.e. at least one of:
=back
-OSSL_FUNC_signature_set_ctx_params and OSSL_FUNC_signature_settable_ctx_params are optional,
-but if one of them is present then the other one must also be present. The same
-applies to OSSL_FUNC_signature_get_ctx_params and OSSL_FUNC_signature_gettable_ctx_params, as
-well as the "md_params" functions. The OSSL_FUNC_signature_dupctx function is optional.
+The OSSL_FUNC_signature_set_ctx_params() and
+OSSL_FUNC_signature_settable_ctx_params() functions are optional,
+but if one of them is provided then the other one must also be provided.
+The same applies to the OSSL_FUNC_signature_get_ctx_params() and
+OSSL_FUNC_signature_gettable_ctx_params() functions,
+as well as the "md_params" functions.
+
+The OSSL_FUNC_signature_dupctx() function is optional.
+It is not yet used by OpenSSL.
+
+The OSSL_FUNC_signature_query_key_types() function is optional.
+When present, it should return a NULL-terminated array of strings
+indicating the key types supported by the provider for signature operations.
+Otherwise the signature algorithm name must match the given key
+or match the default signature algorithm name of the key,
+both checked using L<EVP_SIGNATURE_is_a(3)>.
A signature algorithm must also implement some mechanism for generating,
loading or importing keys via the key management (OSSL_OP_KEYMGMT) operation.
@@ -378,7 +389,7 @@ should be written to I<*siglen>. If I<sig> is NULL then the maximum length of
the signature should be written to I<*siglen>.
OSSL_FUNC_signature_digest_sign() implements a "one shot" digest sign operation
-previously started through OSSL_FUNC_signature_digeset_sign_init(). A previously
+previously started through OSSL_FUNC_signature_digest_sign_init(). A previously
initialised signature context is passed in the I<ctx> parameter. The data to be
signed is in I<tbs> which should be I<tbslen> bytes long. Unless I<sig> is NULL,
the signature should be written to the location pointed to by the I<sig>
@@ -388,7 +399,7 @@ length of the signature should be written to I<*siglen>.
=head2 Digest Verify Functions
-OSSL_FUNC_signature_digeset_verify_init() initialises a context for verifying given a
+OSSL_FUNC_signature_digest_verify_init() initialises a context for verifying given a
provider side verification context in the I<ctx> parameter, and a pointer to a
provider key object in the I<provkey> parameter.
The I<params>, if not NULL, should be set on the context in a manner similar to
@@ -412,7 +423,7 @@ verification context is passed in the I<ctx> parameter. The signature to be
verified is in I<sig> which is I<siglen> bytes long.
OSSL_FUNC_signature_digest_verify() implements a "one shot" digest verify operation
-previously started through OSSL_FUNC_signature_digeset_verify_init(). A previously
+previously started through OSSL_FUNC_signature_digest_verify_init(). A previously
initialised verification context is passed in the I<ctx> parameter. The data to be
verified is in I<tbs> which should be I<tbslen> bytes long. The signature to be
verified is in I<sig> which is I<siglen> bytes long.
@@ -470,8 +481,13 @@ The length of the "digest-size" parameter should not exceed that of a B<size_t>.
=item "algorithm-id" (B<OSSL_SIGNATURE_PARAM_ALGORITHM_ID>) <octet string>
-Gets the DER encoded AlgorithmIdentifier that corresponds to the combination of
-signature algorithm and digest algorithm for the signature operation.
+Gets the DER-encoded AlgorithmIdentifier for the signature operation.
+This typically corresponds to the combination of a digest algorithm
+with a purely asymmetric signature algorithm, such as SHA256WithECDSA.
+
+The L<ASN1_item_sign_ctx(3)> function relies on this operation and is used by
+many other functions that sign ASN.1 structures such as X.509 certificates,
+certificate requests, and CRLs, as well as OCSP, CMP, and CMS messages.
=item "nonce-type" (B<OSSL_SIGNATURE_PARAM_NONCE_TYPE>) <unsigned integer>
@@ -599,11 +615,20 @@ OSSL_FUNC_signature_gettable_ctx_params(), OSSL_FUNC_signature_settable_ctx_para
OSSL_FUNC_signature_gettable_md_ctx_params() and OSSL_FUNC_signature_settable_md_ctx_params(),
return the gettable or settable parameters in a constant L<OSSL_PARAM(3)> array.
-All other functions should return 1 for success or 0 on error.
+OSSL_FUNC_signature_query_key_types() should return a NULL-terminated array of strings.
+
+All verification functions should return 1 for success,
+0 for a non-matching signature, and a negative value for operation failure.
+
+All other functions should return 1 for success
+and 0 or a negative value for failure.
=head1 SEE ALSO
-L<provider(7)>
+L<provider(7)>, L<provider-base(7)/Provider Functions>,
+L<OSSL_PARAM(3)>, L<OSSL_DISPATCH(3)>, L<OSSL_ALGORITHM(3)>,
+L<EVP_PKEY_sign(3)>, L<EVP_PKEY_verify(3)>, L<EVP_PKEY_verify_recover(3)>,
+L<EVP_SIGNATURE_is_a(3)>, L<ASN1_item_sign_ctx(3)>
=head1 HISTORY
diff --git a/fuzz/dtlsserver.c b/fuzz/dtlsserver.c
index 68ddb1e6e683..7ea57ea05336 100644
--- a/fuzz/dtlsserver.c
+++ b/fuzz/dtlsserver.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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.
@@ -590,10 +590,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
SSL *server;
BIO *in;
BIO *out;
-#if !defined(OPENSSL_NO_EC) \
- || (!defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0))
BIO *bio_buf;
-#endif
SSL_CTX *ctx;
int ret;
#ifndef OPENSSL_NO_DEPRECATED_3_0
diff --git a/include/crypto/dh.h b/include/crypto/dh.h
index 51232d18c244..b4a4a3c1fae8 100644
--- a/include/crypto/dh.h
+++ b/include/crypto/dh.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -42,7 +42,7 @@ int ossl_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
int ossl_dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret);
int ossl_dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret);
-int ossl_dh_check_pairwise(const DH *dh);
+int ossl_dh_check_pairwise(const DH *dh, int return_on_null_numbers);
const DH_METHOD *ossl_dh_get_method(const DH *dh);
diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h
index dcb465cbcae0..ffbc95a77888 100644
--- a/include/crypto/rsa.h
+++ b/include/crypto/rsa.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -124,6 +124,10 @@ ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx);
int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
const X509_ALGOR *sigalg, EVP_PKEY *pkey);
+# ifdef FIPS_MODULE
+int ossl_rsa_key_pairwise_test(RSA *rsa);
+# endif /* FIPS_MODULE */
+
# if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]);
void ossl_rsa_acvp_test_gen_params_free(OSSL_PARAM *dst);
diff --git a/include/internal/common.h b/include/internal/common.h
index 0c0415b777bd..894dac9a4e2b 100644
--- a/include/internal/common.h
+++ b/include/internal/common.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -22,8 +22,8 @@
# define ossl_likely(x) __builtin_expect(!!(x), 1)
# define ossl_unlikely(x) __builtin_expect(!!(x), 0)
# else
-# define ossl_likely(x) x
-# define ossl_unlikely(x) x
+# define ossl_likely(x) (x)
+# define ossl_unlikely(x) (x)
# endif
# if defined(__GNUC__) || defined(__clang__)
diff --git a/include/internal/constant_time.h b/include/internal/constant_time.h
index 4a2df34da9f2..73219759e0ce 100644
--- a/include/internal/constant_time.h
+++ b/include/internal/constant_time.h
@@ -322,6 +322,18 @@ static ossl_inline size_t value_barrier_s(size_t a)
return r;
}
+/* Convenience method for unsigned char. */
+static ossl_inline unsigned char value_barrier_8(unsigned char a)
+{
+#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
+ unsigned char r;
+ __asm__("" : "=r"(r) : "0"(a));
+#else
+ volatile unsigned char r = a;
+#endif
+ return r;
+}
+
static ossl_inline unsigned int constant_time_select(unsigned int mask,
unsigned int a,
unsigned int b)
@@ -382,7 +394,7 @@ static ossl_inline void constant_time_cond_swap_32(uint32_t mask, uint32_t *a,
{
uint32_t xor = *a ^ *b;
- xor &= mask;
+ xor &= value_barrier_32(mask);
*a ^= xor;
*b ^= xor;
}
@@ -402,7 +414,7 @@ static ossl_inline void constant_time_cond_swap_64(uint64_t mask, uint64_t *a,
{
uint64_t xor = *a ^ *b;
- xor &= mask;
+ xor &= value_barrier_64(mask);
*a ^= xor;
*b ^= xor;
}
@@ -429,7 +441,7 @@ static ossl_inline void constant_time_cond_swap_buff(unsigned char mask,
for (i = 0; i < len; i++) {
tmp = a[i] ^ b[i];
- tmp &= mask;
+ tmp &= value_barrier_8(mask);
a[i] ^= tmp;
b[i] ^= tmp;
}
diff --git a/include/internal/e_os.h b/include/internal/e_os.h
index 0c546c1d9460..8419f7143669 100644
--- a/include/internal/e_os.h
+++ b/include/internal/e_os.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -106,17 +106,6 @@
# define EACCES 13
# endif
# include <string.h>
-# ifdef _WIN64
-# define strlen(s) _strlen31(s)
-/* cut strings to 2GB */
-static __inline unsigned int _strlen31(const char *str)
-{
- unsigned int len = 0;
- while (*str && len < 0x80000000U)
- str++, len++;
- return len & 0x7FFFFFFF;
-}
-# endif /* def(_WIN64) */
# include <malloc.h>
# if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin)
# if _MSC_VER>=1300 && _MSC_VER<1600
diff --git a/include/internal/hashfunc.h b/include/internal/hashfunc.h
index cabc7beed4a7..fae8a275fa2e 100644
--- a/include/internal/hashfunc.h
+++ b/include/internal/hashfunc.h
@@ -11,6 +11,7 @@
# define OPENSSL_HASHFUNC_H
# include <openssl/e_os2.h>
+# include <stddef.h>
/**
* Generalized fnv1a 64 bit hash function
*/
diff --git a/include/internal/json_enc.h b/include/internal/json_enc.h
index e7d9a6d922e7..d736a1d645f9 100644
--- a/include/internal/json_enc.h
+++ b/include/internal/json_enc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2025 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
@@ -202,9 +202,6 @@ void ossl_json_u64(OSSL_JSON_ENC *json, uint64_t value);
/* Encode a JSON integer from an int64_t. */
void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value);
-/* Encode a JSON number from a 64-bit floating point value. */
-void ossl_json_f64(OSSL_JSON_ENC *json, double value);
-
/*
* Encode a JSON UTF-8 string from a zero-terminated string. The string passed
* can be freed immediately following the call to this function.
diff --git a/include/internal/provider.h b/include/internal/provider.h
index 6909a1919c3d..7d94346155cc 100644
--- a/include/internal/provider.h
+++ b/include/internal/provider.h
@@ -61,6 +61,9 @@ int ossl_provider_add_to_store(OSSL_PROVIDER *prov, OSSL_PROVIDER **actualprov,
/* Return pointer to the provider's context */
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
+/* Force loading of fallback providers if necessary */
+int ossl_provider_activate_fallbacks(OSSL_LIB_CTX *ctx);
+
/* Iterate over all loaded providers */
int ossl_provider_doall_activated(OSSL_LIB_CTX *,
int (*cb)(OSSL_PROVIDER *provider,
diff --git a/include/internal/quic_ackm.h b/include/internal/quic_ackm.h
index c271dfca2e1d..949d91903bb1 100644
--- a/include/internal/quic_ackm.h
+++ b/include/internal/quic_ackm.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -23,7 +23,7 @@ OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),
void *now_arg,
OSSL_STATM *statm,
const OSSL_CC_METHOD *cc_method,
- OSSL_CC_DATA *cc_data);
+ OSSL_CC_DATA *cc_data, int is_server);
void ossl_ackm_free(OSSL_ACKM *ackm);
void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm,
diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h
index acfeb0d51505..e7fd260ab600 100644
--- a/include/internal/quic_ssl.h
+++ b/include/internal/quic_ssl.h
@@ -72,8 +72,8 @@ __owur const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u);
int ossl_quic_renegotiate_check(SSL *ssl, int initok);
int ossl_quic_do_handshake(SSL *s);
-void ossl_quic_set_connect_state(SSL *s);
-void ossl_quic_set_accept_state(SSL *s);
+int ossl_quic_set_connect_state(SSL *s, int raiseerrs);
+int ossl_quic_set_accept_state(SSL *s, int raiseerrs);
__owur int ossl_quic_has_pending(const SSL *s);
__owur int ossl_quic_handle_events(SSL *s);
diff --git a/include/internal/quic_tls.h b/include/internal/quic_tls.h
index eb385bb7ff97..ec0d07da0b39 100644
--- a/include/internal/quic_tls.h
+++ b/include/internal/quic_tls.h
@@ -96,6 +96,8 @@ int ossl_quic_tls_configure(QUIC_TLS *qtls);
/* Advance the state machine */
int ossl_quic_tls_tick(QUIC_TLS *qtls);
+void ossl_quic_tls_clear(QUIC_TLS *qtls);
+
int ossl_quic_tls_set_transport_params(QUIC_TLS *qtls,
const unsigned char *transport_params,
size_t transport_params_len);
diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h
index 690a38206a35..13de04e2622c 100644
--- a/include/openssl/core_dispatch.h
+++ b/include/openssl/core_dispatch.h
@@ -253,6 +253,10 @@ OSSL_CORE_MAKE_FUNC(int, provider_up_ref,
OSSL_CORE_MAKE_FUNC(int, provider_free,
(const OSSL_CORE_HANDLE *prov, int deactivate))
+/* Additional error functions provided by the core */
+# define OSSL_FUNC_CORE_COUNT_TO_MARK 120
+OSSL_CORE_MAKE_FUNC(int, core_count_to_mark, (const OSSL_CORE_HANDLE *prov))
+
/* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
# define OSSL_FUNC_PROVIDER_TEARDOWN 1024
OSSL_CORE_MAKE_FUNC(void, provider_teardown, (void *provctx))
diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h
index c51e07cad98f..6dc846a28445 100644
--- a/include/openssl/evperr.h
+++ b/include/openssl/evperr.h
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -104,6 +104,12 @@
# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179
# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
+# define EVP_R_PROVIDER_ASYM_CIPHER_FAILURE 232
+# define EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED 235
+# define EVP_R_PROVIDER_KEYMGMT_FAILURE 233
+# define EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED 236
+# define EVP_R_PROVIDER_SIGNATURE_FAILURE 234
+# define EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED 237
# define EVP_R_PUBLIC_KEY_NOT_RSA 106
# define EVP_R_SETTING_XOF_FAILED 227
# define EVP_R_SET_DEFAULT_PROPERTY_FAILURE 209
diff --git a/include/openssl/pem.h b/include/openssl/pem.h
index 94424e6c209e..de1b6581f28f 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/pem.h
@@ -57,6 +57,7 @@ extern "C" {
# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
# define PEM_STRING_PARAMETERS "PARAMETERS"
# define PEM_STRING_CMS "CMS"
+# define PEM_STRING_SM2PRIVATEKEY "SM2 PRIVATE KEY"
# define PEM_STRING_SM2PARAMETERS "SM2 PARAMETERS"
# define PEM_STRING_ACERT "ATTRIBUTE CERTIFICATE"
diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h
index 2d39e096eeab..c4439cb28715 100644
--- a/include/openssl/self_test.h
+++ b/include/openssl/self_test.h
@@ -50,6 +50,7 @@ extern "C" {
# define OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1 "RSA"
# define OSSL_SELF_TEST_DESC_PCT_ECDSA "ECDSA"
# define OSSL_SELF_TEST_DESC_PCT_EDDSA "EDDSA"
+# define OSSL_SELF_TEST_DESC_PCT_DH "DH"
# define OSSL_SELF_TEST_DESC_PCT_DSA "DSA"
# define OSSL_SELF_TEST_DESC_PCT_ML_DSA "ML-DSA"
# define OSSL_SELF_TEST_DESC_PCT_ML_KEM "ML-KEM"
diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
index b3420799683b..383c5bc411f1 100644
--- a/include/openssl/ssl.h.in
+++ b/include/openssl/ssl.h.in
@@ -1831,8 +1831,8 @@ __owur int SSL_set_purpose(SSL *ssl, int purpose);
__owur int SSL_CTX_set_trust(SSL_CTX *ctx, int trust);
__owur int SSL_set_trust(SSL *ssl, int trust);
-__owur int SSL_set1_host(SSL *s, const char *hostname);
-__owur int SSL_add1_host(SSL *s, const char *hostname);
+__owur int SSL_set1_host(SSL *s, const char *host);
+__owur int SSL_add1_host(SSL *s, const char *host);
__owur const char *SSL_get0_peername(SSL *s);
void SSL_set_hostflags(SSL *s, unsigned int flags);
diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums
index 804a4fa8c08e..04b820f1f1ec 100644
--- a/providers/fips-sources.checksums
+++ b/providers/fips-sources.checksums
@@ -28,7 +28,7 @@ f525e1bca51d39adcd411cbf8f874fe1441b23a6f614644da78dfd8544d13b23 crypto/aes/asm
5d03d59af5d77979bed0662a2e971951899d407d11dcf6a8e174453aaebecea2 crypto/aes/asm/aesni-xts-avx512.pl
0489a10fbb1a8ca3652848d5c1e14e519501e189bad3e5827a573c26df359691 crypto/aes/asm/aesp8-ppc.pl
e397a5781893e97dd90a5a52049633be12a43f379ec5751bca2a6350c39444c8 crypto/aes/asm/aest4-sparcv9.pl
-901a977a566f51788186ed566438db09d2331894f9de9ace1aa7e267dae3fe74 crypto/aes/asm/aesv8-armx.pl
+578142d03bc47353952fca2027eb63ec97ce9a1379c0f3c7ac0fdf110eb3378b crypto/aes/asm/aesv8-armx.pl
5e8005fdb6641df465bdda20c3476f7176e6bcd63d5073044a0c02a327c7f172 crypto/aes/asm/bsaes-armv7.pl
12cd3c8a9ce7153c577ff6238d81ec1947dfc43ee80cb15ee886cdf811969417 crypto/aes/asm/bsaes-armv8.pl
c72f6cbf3b9900d956e05003ec8df758b29b43519c7801d677c3f992bc589d4e crypto/aes/asm/bsaes-x86_64.pl
@@ -59,11 +59,11 @@ b27ec5181e387e812925bb26823b830f49d7a6e4971b6d11ea583f5632a1504b crypto/bn/asm/
0b3350f56d423a4df918a08e90c7c66227c4449a9f9c44096eacc254ebc65f9f crypto/bn/asm/ppc64-mont-fixed.pl
a25be64867ab837d93855af232e2bfa71b85b2c6f00e35e620fdc5618187fb6f crypto/bn/asm/ppc64-mont.pl
a6982e91f35fbcefe897106b3f5c8957359fb58b74beac12bdcb8d3b7daa15f5 crypto/bn/asm/rsaz-2k-avx512.pl
-9ff806a5dc4320c73cdf717161185b3515bb56e893f098e617ebb16b25ed9006 crypto/bn/asm/rsaz-2k-avxifma.pl
+1b059fa9056c6b476f036ffa5dc74092d9366ee94a98f8f3e57e9b452a695232 crypto/bn/asm/rsaz-2k-avxifma.pl
df7268cd5461269db0d8d1ef62c2d9ff6608eb0c071e798b06ad9ddfcbef1a31 crypto/bn/asm/rsaz-3k-avx512.pl
-a36293b89332a4fb8ef4f3013c26bc5bb42290ec255a699b15b4e72285f49886 crypto/bn/asm/rsaz-3k-avxifma.pl
+b8424d830f41a038f3c98d8664c6cf7d2d3e1748cdce260db41fa3c74f1d88d9 crypto/bn/asm/rsaz-3k-avxifma.pl
9ae9cf7a926eea6543237eb4c537860a36e6373e9091e2c581868871ba84fd74 crypto/bn/asm/rsaz-4k-avx512.pl
-2cd3ac19df2f322e518aba881dc98423c3aafcef8cec6c8611f870fdf6d54d7d crypto/bn/asm/rsaz-4k-avxifma.pl
+afcf51a732c80eadae1650e22e4af34904112a8b95467087a16d9d2394934730 crypto/bn/asm/rsaz-4k-avxifma.pl
6e47bf041e51d8086c4933c2a5da3ce6d1b136592984754461d59aa81e4995a6 crypto/bn/asm/rsaz-avx2.pl
149842bf63d1ef1895a251a83d9941fc3ed744dab359b42d635d04cc8d2f2864 crypto/bn/asm/rsaz-x86_64.pl
30fedf48dfc5fec1c2044b6c226dd9fc42a92522cc589797a23a79d452bdd2cf crypto/bn/asm/s390x-gf2m.pl
@@ -123,7 +123,7 @@ ad80d38930e576afdf55dfd88c3c7ddfa390cb474b9b1b72d8a37fa0dde177db crypto/bn/rsaz
1d2760fae983b7fdba8fbb63b0f357dc161f6d0f0695f6b73e8d92ed19899185 crypto/context.c
67c2367871b9350a7f7af5be903d6bcca9ebdbff0e9a9bd9f61b56bef5b76696 crypto/core_algorithm.c
ab29529cca1308302d852999f2790c404a4dc0ef8cd6653260739f70b2f22758 crypto/core_fetch.c
-61111a5f2eba07860b1ae2b6512c9cfb30cb7f580db5606fe1c22f1fa7599f2f crypto/core_namemap.c
+79522ab7376ba85aca2cfce84a77613e3721470307f2acb28fd318a51182be0d crypto/core_namemap.c
819f75bcb1cbd6633381ec9ad043152ae2ec1f71471650864f2cb8c88612cab5 crypto/cpuid.c
a6732e22ccb49cf51fc9dbf23f6059774b70ecc3d7e848c5df112a2d3c179027 crypto/cryptlib.c
66dbfc58916709d5a6913777346083247942a8d9458ee9b2bf443f0ea4988d64 crypto/ctype.c
@@ -136,7 +136,7 @@ eeef5722ad56bf1af2ff71681bcc8b8525bc7077e973c98cee920ce9bcc66c81 crypto/des/ecb
9549901d6f0f96cd17bd76c2b6cb33fb25641707bfdb8ed34aab250c34f7f4f6 crypto/des/set_key.c
8344811b14d151f6cd40a7bc45c8f4a1106252b119c1d5e6a589a023f39b107d crypto/des/spr.h
a54b1b60cf48ca89dfb3f71d299794dd6c2e462c576b0fe583d1448f819c80ea crypto/dh/dh_backend.c
-24cf9462da6632c52b726041271f8a43dfb3f74414abe460d9cc9c7fd2fd2d7d crypto/dh/dh_check.c
+9db32c052fb3cf7c36ab8e642f4852c2fa68a7b6bae0e3b1746522f826827068 crypto/dh/dh_check.c
c117ac4fd24369c7813ac9dc9685640700a82bb32b0f7e038e85afd6c8db75c7 crypto/dh/dh_gen.c
6b17861887b2535159b9e6ca4f927767dad3e71b6e8be50055bc784f78e92d64 crypto/dh/dh_group_params.c
a539a8930035fee3b723d74a1d13e931ff69a2b523c83d4a2d0d9db6c78ba902 crypto/dh/dh_kdf.c
@@ -204,7 +204,7 @@ a47d8541bb2cc180f4c7d3ac0f888657e17621b318ea8a2eacdefb1926efb500 crypto/ec/ecp_
43f81968983e9a466b7dc9cffe64302418703f7a66adcbac4b7c4d8cb19c9af5 crypto/ec/ecx_backend.c
5ee19c357c318b2948ff5d9118a626a6207af2b2eade7d8536051d4a522668d3 crypto/ec/ecx_backend.h
2be4ca60082891bdc99f8c6ebc5392c1f0a7a53f0bcf18dcf5497a7aee0b9c84 crypto/ec/ecx_key.c
-62136e558017c5c3b2c60ac22f1bfed252519c6a8595f9725356bca1a0c70ea8 crypto/evp/asymcipher.c
+c1f04d877f96f2d0852290e34b1994dd48222650ac1121903cee9c259fe3ebf2 crypto/evp/asymcipher.c
80da494704c8fc54fea36e5de7100a6c2fdcc5f8c50f43ac477df5f56fa57e58 crypto/evp/dh_support.c
bc9f3b827e3d29ac485fff9fb1c8f71d7e2bcd883ccc44c776de2f620081df58 crypto/evp/digest.c
838277f228cd3025cf95a9cd435e5606ad1fb5d207bbb057aa29892e6a657c55 crypto/evp/ec_support.c
@@ -212,14 +212,14 @@ bc9f3b827e3d29ac485fff9fb1c8f71d7e2bcd883ccc44c776de2f620081df58 crypto/evp/dig
baccbd623a94ba350c07e0811033ad66a2c892ef51ccb051b4a65bf2ba625a85 crypto/evp/evp_fetch.c
52b4aba9e2beb9d382ebd09daf44009e5ddaeae8d3434546e2884ab8ea481d7a crypto/evp/evp_lib.c
32949d15dfc1a3049eb3000ddc10db077eb442e1fa224b2541aa1fcc6137d80e crypto/evp/evp_local.h
-eaaf795148c5dd99c4194d076c029c843f3aee0c37afeb0dac43a86fd931ac68 crypto/evp/evp_rand.c
+603c97974acd94e66f9718d3d68ab5cd6e0093499feabb1f1417778d768b5d6e crypto/evp/evp_rand.c
2a128617ec0178e9eeacbe41d75a5530755f41ea524cd124607543cf73456a0c crypto/evp/evp_utils.c
3d04aa938f45a04550ce4d53306d60da4ca6a54e1a4e9f19b75ca22277ce7bdb crypto/evp/exchange.c
294284ad040fe4b74845f91b1903c961c757e1ef3fcc2ffa35f43f37f1655e64 crypto/evp/kdf_lib.c
90742590db894920ffdb737a450ee591488aa455802e777400b1bf887618fd7a crypto/evp/kdf_meth.c
948f7904e81008588288a1ba7969b9de83546c687230ffe2a3fd0be1651bce8f crypto/evp/kem.c
55d141a74405415ad21789abcace9557f1d1ef54cf207e99993bf0a801f4b81e crypto/evp/keymgmt_lib.c
-ac5194aedcd6790903817faf4aec199a2100e27cf2d778caae3d8d79cc28f596 crypto/evp/keymgmt_meth.c
+d57908a9473d2af324f32549649016f7a3c196b5ac8b54d6ca3c82f84cab5d48 crypto/evp/keymgmt_meth.c
9e44d1ffb52fee194b12c50962907c8637e7d92f08339345ec9fd3bd4a248e69 crypto/evp/mac_lib.c
cd611921dc773b47207c036b9108ec820ab39d67780ba4adc9ccb9dc8da58627 crypto/evp/mac_meth.c
4f0a9a7baa72c6984edb53c46101b6ff774543603bec1e1d3a6123adf27e41db crypto/evp/p_lib.c
@@ -227,7 +227,7 @@ cd611921dc773b47207c036b9108ec820ab39d67780ba4adc9ccb9dc8da58627 crypto/evp/mac
759573aea2a4cc7b6f763b440e6868bfcfcb7ca94d812fa61ab24a194be2cb36 crypto/evp/pmeth_gn.c
c2c8f6d17dc3d85ffcced051047c0b00ce99d119635f4626c5c6db3d59d86fbb crypto/evp/pmeth_lib.c
ba4ff38738cbcfd3841d53a2fab92227638ceca176d3ffe50e486c9dcbabb5dd crypto/evp/s_lib.c
-0eaabfe314cb94a942584f74de69f8dec1287a4afe383050e37ee44a41aea447 crypto/evp/signature.c
+3c003fa01341a69c461b75cffd93cf31a1899373d7e95a1ef3754ea1bfbb77fe crypto/evp/signature.c
a3ba57f8181cfbbf017fe1d4fa8d80f4999eea6d2834b0bcda22b60e6a5e31e3 crypto/evp/skeymgmt_meth.c
64f7e366e681930ba10267272b87dba223b9744a01c27ba0504a4941802a580d crypto/ex_data.c
d986ec74995b05ff65a68df320ab45894ba35d7be4906f8d78ca5fca294a4e6c crypto/ffc/ffc_backend.c
@@ -263,7 +263,7 @@ ff65c82c56e341f47df03d0c74de7fb537de0e68a4fa23fa07a9fdb51c511f1c crypto/ml_dsa/
1d7f57a41034988a4e7d4c9a998760d2ef802c5e90275d09a3ca31c5f3403d94 crypto/ml_dsa/ml_dsa_sign.c
5217ef237e21872205703b95577290c34898423466a465c7bd609b2eb4627964 crypto/ml_dsa/ml_dsa_sign.h
abd934284bcd8061027a69f437fa4410c6b72cd950be1ebe048244d036371208 crypto/ml_dsa/ml_dsa_vector.h
-e100125310394a6b8796a29c4536c248aeeab6a344f8ce53573ca4daed8259a8 crypto/ml_kem/ml_kem.c
+defc2e4e81ff1b78056c795bc0565f4241a259c2957abe84a51bcbc1e4ace3f1 crypto/ml_kem/ml_kem.c
36e24eae5d38cc9666ae40e4e8a2dc12328e1159fea68447cb19dab174d25adf crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl
33357356cd739d4ae89d52f0804b6900e4b94d8829323819c6f64c8908e978df crypto/modes/asm/aes-gcm-armv8_64.pl
bcc09bdb474f045d04c983fa09c31a010c5a25513f53a5d3653ade91304f0f96 crypto/modes/asm/aes-gcm-avx512.pl
@@ -298,21 +298,21 @@ b0decda3aae1d3e07cf3cbe9153cdde9deafe65fae346cd208951b4d7dec512e crypto/packet.
05563d44cb345e7859093296f95a3ea5139fcc316e98fcb86c6748ee49363a84 crypto/param_build.c
cae7bd4973d36edbdc3bdd8d2c8d157f2c4fcfae00fdf821b67aebb789bc8aa6 crypto/param_build_set.c
7b32b19c1cf7152ef7e55e8ae7a045be4882da84ecd82ddf24df961656ec581b crypto/params.c
-bb7b79b5a070050f5e7dfc66b5635f0891bc278e3e24eec3583b769b33bef657 crypto/params_dup.c
-17df6718f11307a0d0c4d8de5a8bbb35408f5546c465c1dd3b631c924adb2e58 crypto/params_from_text.c
+c0e0ba07ca5d4acfe450e4ae53a10ed254097ed2f537f01a4a43a9f5b5cab501 crypto/params_dup.c
+fc2432f5a76784d4ca47db1803c8b19acbaea26987f8e33dd8cc5571f8101b40 crypto/params_from_text.c
f50450f7e5f6896fb8e3cde2fdc11cc543124c854ef9d88252a166606ca80081 crypto/params_idx.c
9620a96eb5e411f5c96c210fb7975afe6b24635e4c5565be34fb8d10589890e7 crypto/ppccap.c
46fa4994a6234a98a2845d9337475913f6bc229f1928abc82224de7edf2784b8 crypto/ppccpuid.pl
467c416422ecf61e3b713c5eb259fdbcb4aa73ae8dee61804d0b85cfd3fff4f7 crypto/property/defn_cache.c
-ced9474eca99c4920ee9dc3a810ee77af31aa344d54ea2aca702305abfc6aa1f crypto/property/property.c
+91c1f1f8eb5588ed9da17386c244ae68a6a81717b1c7ab6c9f1a6a57973a039f crypto/property/property.c
66da4f28d408133fb544b14aeb9ad4913e7c5c67e2826e53f0dc5bf4d8fada26 crypto/property/property_local.h
d32105cb087d708d0504a787f74bc163cc398c299faf2e98d6bb5ae02f5ce9b7 crypto/property/property_parse.c
a7cefda6a117550e2c76e0f307565ce1e11640b11ba10c80e469a837fd1212a3 crypto/property/property_query.c
20e69b9d594dfc443075eddbb0e6bcc0ed36ca51993cd50cc5a4f86eb31127f8 crypto/property/property_string.c
-8dffed281002fcbc3e54dd4be74f5739c3e6a244ce579f6a86ad8d5dfb0d3374 crypto/provider_core.c
+faa002fd33a147494ea93dbd1cef07138c6f61432d6465ceb4a34118e31e0a72 crypto/provider_core.c
d0af10d4091b2032aac1b7db80f8c2e14fa7176592716b25b9437ab6b53c0a89 crypto/provider_local.h
5ba2e1c74ddcd0453d02e32612299d1eef18eff8493a7606c15d0dc3738ad1d9 crypto/provider_predefined.c
-eeb769fb3f552c7fbb1de4d3725e03376919bc062e8d4fc5ee47f3571206047e crypto/rand/rand_lib.c
+e13cf63765dd538a75eb9d2cb8fcb0243e6bd2988dd420c83806a69984dad558 crypto/rand/rand_lib.c
fd03b9bb2c23470fa40880ed3bf9847bb17d50592101a78c0ad7a0f121209788 crypto/rand/rand_local.h
426ba915ca65a770f8264129f8ac47db7aaf06c6ae51517c5d775eacdf91b9f6 crypto/rcu_internal.h
48f6a98e3d7e9ae79f2d2b8ea9965d0c4ec3b1a4473adbceb47fe1e7930dc3c1 crypto/riscv32cpuid.pl
@@ -322,7 +322,7 @@ f0c8792a99132e0b9c027cfa7370f45594a115934cdc9e8f23bdd64abecaf7fd crypto/rsa/rsa
1b828f428f0e78b591378f7b780164c4574620c68f9097de041cbd576f811bf6 crypto/rsa/rsa_backend.c
38a102cd1da1f6ca5a46e6a22f018237964336274385f5c70cbedcaa6997647e crypto/rsa/rsa_chk.c
e762c599b17d5c89f4b1c9eb7d0ca1f04a95d815c86a3e72c30b231ce57fb199 crypto/rsa/rsa_crpt.c
-a3d20f27ae3cb41af5b62febd0bb19025e59d401b136306d570cdba103b15542 crypto/rsa/rsa_gen.c
+026645569b11cf7c1247e4537cc004eea4469ed661391aef4fbc13e96c4952ca crypto/rsa/rsa_gen.c
f22bc4e2c3acab83e67820c906c1caf048ec1f0d4fcb7472c1bec753c75f8e93 crypto/rsa/rsa_lib.c
5ae8edaf654645996385fbd420ef73030762fc146bf41deb5294d6d83e257a16 crypto/rsa/rsa_local.h
cf0b75cd54b61b9b9a290ef18d0ddce9fb26a029a54eb3f720d9b25188440f00 crypto/rsa/rsa_mp_names.c
@@ -397,7 +397,7 @@ c26498960895d435af4ef5f592d98a0c011c00609bbba8bbd0078d4a4f081609 crypto/slh_dsa
4c7981f7db69025f52495c549fb3b3a76be62b9e13072c3f3b7f1dedeaf8cc91 crypto/slh_dsa/slh_dsa_key.h
5dcb631891eb6afcd27a6b19d2de4d493c71dab159e53620d86d9b96642e97e8 crypto/slh_dsa/slh_dsa_local.h
adb3f4dea52396935b8442df7b36ed99324d3f3e8ce3fdf714d6dfd683e1f9f0 crypto/slh_dsa/slh_fors.c
-ff320d5fc65580eb85e4e0530f332af515124a5ec8915b5a7ec04acad524c11d crypto/slh_dsa/slh_hash.c
+3891252acdefc4eff77d7a65cc35d77bdca8083c9dd0d44ff91889ceafcccb45 crypto/slh_dsa/slh_hash.c
a146cdf01b4b6e20127f0e48b30ed5e8820bec0fca2d9423c7b63eddf0f19af3 crypto/slh_dsa/slh_hash.h
6402664fbb259808a6f7b5a5d6be2b4a3cc8a905399d97b160cdb3e4a97c02c4 crypto/slh_dsa/slh_hypertree.c
98ba100862bb45d13bcddff79bc55e44eadd95f528dd49accb4da3ca85fcc52d crypto/slh_dsa/slh_params.c
@@ -415,8 +415,8 @@ e298c753be277ad9a2ac0132d9897cb4c85607dbb2d11cfefd0c98e0f6a723d9 crypto/thread/
a00e16963e1e2a0126c6a8e62da8a14f98de9736027654c925925dadd0ca3cc1 crypto/thread/arch/thread_win.c
27ec0090f4243c96e4fbe1babfd4320c2a16615ffa368275433217d50a1ef76c crypto/thread/internal.c
67ba8d87fbbb7c9a9e438018e7ecfd1cedd4d00224be05755580d044f5f1317a crypto/threads_lib.c
-30c223a6099b9d8aa7bf1a0a258f2ecad2129da2486eb8718f06c846752e234b crypto/threads_none.c
-40952905fcf107fa1ff6b51036d55b374dd7e4b8d71e541769675354e81b076f crypto/threads_pthread.c
+b1a828491d9ce305802662561788facac92dff70cca9ead807f3e28741ff21e0 crypto/threads_none.c
+c659f7ce5c4b59d2a1cff78485fa8e89c8d20d5798df4afc1b94ff635ffc0262 crypto/threads_pthread.c
9c3bf7b4baa302a4017150fbcaa114ee9df935b18d5a3a8c8015003780d4e7de crypto/threads_win.c
7edd638df588b14711a50c98d458c4fc83f223ed03bc6c39c7c8edf7915b7cfa crypto/time.c
88c5f9f4d2611223d283ebd2ae10ae5ecbb9972d00f747d93fcb74b62641e3f9 crypto/x86_64cpuid.pl
@@ -433,7 +433,7 @@ e69b2b20fb415e24b970941c84a62b752b5d0175bc68126e467f7cc970495504 include/crypto
6c72cfa9e59d276c1debcfd36a0aff277539b43d2272267147fad4165d72747c include/crypto/ctype.h
f69643f16687c5a290b2ce6b846c6d1dddabfaf7e4d26fde8b1181955de32833 include/crypto/decoder.h
89693e0a7528a9574e1d2f80644b29e3b895d3684111dd07c18cc5bed28b45b7 include/crypto/des_platform.h
-daf508bb7ed5783f1c8c622f0c230e179244dd3f584e1223a19ab95930fbcb4f include/crypto/dh.h
+48d133a1eb8c3b3198cfe1cafda47f9abe8050d53004f3874f258a78f29b9e48 include/crypto/dh.h
679f6e52d9becdf51fde1649478083d18fa4f5a6ece21eeb1decf70f739f49d5 include/crypto/dsa.h
c7aafee54cc3ace0c563f15aa5af2cdce13e2cfc4f9a9a133952825fb7c8faf5 include/crypto/ec.h
adf369f3c9392e9f2dec5a87f61ac9e48160f4a763dae51d4ad5306c4ca4e226 include/crypto/ecx.h
@@ -445,15 +445,15 @@ bbe5e52d84e65449a13e42cd2d6adce59b8ed6e73d6950917aa77dc1f3f5dff6 include/crypto
6e7762e7fb63f56d25b24f70209f4dc834c59a87f74467531ec81646f565dbe3 include/crypto/modes.h
920bc48a4dad3712bdcef188c0ce8e8a8304e0ce332b54843bab366fc5eab472 include/crypto/rand.h
71f23915ea74e93971fb0205901031be3abea7ffef2c52e4cc4848515079f68d include/crypto/rand_pool.h
-6f16685ffbc97dc2ac1240bfddf4bbac2dd1ad83fff6da91aee6f3f64c6ee8ff include/crypto/rsa.h
+b1df067691f9741ef9c42b2e5f12461bcd87b745514fc5701b9c9402fb10b224 include/crypto/rsa.h
32f0149ab1d82fddbdfbbc44e3078b4a4cc6936d35187e0f8d02cc0bc19f2401 include/crypto/security_bits.h
80338f3865b7c74aab343879432a6399507b834e2f55dd0e9ee7a5eeba11242a include/crypto/sha.h
0814571bff328719cc1e5a73a4daf6f5810b17f9e50fe63287f91f445f053213 include/crypto/slh_dsa.h
7676b02824b2d68df6bddeb251e9b8a8fa2e35a95dad9a7ebeca53f9ab8d2dad include/crypto/sparse_array.h
d6d1cd1ec7581046f5a84359a32ed41caad9e7c1b4d1eb9665ea4763de10e6b3 include/crypto/types.h
27d13538d9303b1c2f0b2ce9b6d376097ce7661354fbefbde24b7ef07206ea45 include/internal/bio.h
-a8cb407a10e50b1168412bd6ed6af9552cac1326d28c35f91152c48edc42dc3f include/internal/common.h
-6aaccec4ca8f14a9d6c6b1e6428c1f72147a9c63c45b01107b2a0f29c1065adf include/internal/constant_time.h
+7c8bdf83fc61de37027111c24c41049debb2c9f856fa97bf6ac93319cfef1f35 include/internal/common.h
+77616e7546ed1bae9df366327663261282b16664a616725436715df9ff99b598 include/internal/constant_time.h
c5bb97f654984130c8b44c09a52395bce0b22985d5dbc9c4d9377d86283f11f8 include/internal/core.h
bbba72ba1d0e2985cb316dd9f3bf63893dd58d5624ad7caa10aad81d8b6df0fc include/internal/cryptlib.h
9571cfd3d5666749084b354a6d65adee443deeb5713a58c098c7b03bc69dbc63 include/internal/deprecated.h
@@ -461,13 +461,13 @@ dc5afb955d810feb5af9f8d25cd8a92118abef320fee95c07b04f301c4e0d96c include/intern
8059e715f981fbe02b5731610ed24bb6ae617a55e90b03f4260cbb6ccd71e8de include/internal/deterministic_nonce.h
fd1722d6b79520ee4ac477280d5131eb1b744c3b422fd15f5e737ef966a97c3b include/internal/dso.h
f144daebef828a5bd4416466257a50f06b894e0ce0adf1601aa381f34f25a9e7 include/internal/dsoerr.h
-9bc1bb8edd4874773358832ea0aeab820e08a3b30bc955147208c44d5fd04090 include/internal/e_os.h
+924fddff69e5ee237e38d48dd55d4c5f6d6ef8b6443bbe217c760009bbcc87c4 include/internal/e_os.h
6e33d1c6f82a4483a0e52ee3c9713e123efc5aba0601e7f13078aa45910cd70a include/internal/e_winsock.h
c9cb7a25ba2c1a451ba7cca7e165606f891ee8d3e927c06a2e4f84db7f7622eb include/internal/encoder.h
70d3e0d5a1bd8db58dcc57bea4d1c3ed816c735fe0e6b2f4b07073712d2dc5ef include/internal/endian.h
4838a68ff626825c261df6a1fd21e156e25d8365af45552f29054d7038a7db3d include/internal/ffc.h
4c9c4b7fc19615fb480fe18c86521d57313d24a8de556681741054abc2e3a690 include/internal/fips.h
-987958a28eac3411c4b4bf0a5d351c2274caa2a30b6376c21e5777e7c33d962f include/internal/hashfunc.h
+45e1f3a274ddce17d62681f3150eeb522ef9716b0b41bfdc33327cf72c4356d2 include/internal/hashfunc.h
d9c95e7fe7ae09b2c4aff57eaefbec962cbbeb202ee3cf15950716760c83460f include/internal/hashtable.h
f6f30785e3eced1ccdd4b149286ff2b8bbb860eb7e070cbe54c997aa022854da include/internal/namemap.h
b02701592960eb4608bb83b297eed90184004828c7fc03ea81568062f347623d include/internal/nelem.h
@@ -478,7 +478,7 @@ f42d4a6108a18ade3eb99682c072adf83889b6ba3fc80ee3e20929ed8d0f7137 include/intern
46d7980258a8d11353af3e3dab87c368eec054e46ac8a0facec68b23ba94d91b include/internal/params.h
d4ac19b28ea61f03383364cfad1e941cac44fc36787d80882c5b76ecc9d34e29 include/internal/property.h
727326afb3d33fdffdf26471e313f27892708318c0934089369e4b28267e2635 include/internal/propertyerr.h
-3f1eeabbcfd18c23d365a3586abb59091b654a741b4970162c88374711d7c975 include/internal/provider.h
+f3ac89b2eaaa7f83d7d2606be65aff28136aec5b961884c45f79bf8540ad6f34 include/internal/provider.h
95d21e761402fcbf1d3bdb261e425316b07d2790dd190e4eeaa1e21e40ff9a59 include/internal/rcu.h
baf5df9b8b91cb5b821ee27348a47364c9dfc86144c9573403e9d54fa970f81f include/internal/refcount.h
a01805714966e6de536ee182d5476cb1708d019631f016f331a034cf3b2b3158 include/internal/safe_math.h
@@ -511,7 +511,7 @@ bb45de4eafdd89c14096e9af9b0aee12b09adcee43b9313a3a373294dec99142 include/openss
69d98c5230b1c2a1b70c3e6b244fcfd8460a80ebf548542ea43bb1a57fe6cf57 include/openssl/configuration.h.in
6b3810dac6c9d6f5ee36a10ad6d895a5e4553afdfb9641ce9b7dc5db7eef30b7 include/openssl/conftypes.h
28c6f0ede39c821dcf4abeeb4e41972038ebb3e3c9d0a43ffdf28edb559470e1 include/openssl/core.h
-940f6276e5bab8a7c59eedba56150902e619823c10dc5e50cf63575be6be9ba0 include/openssl/core_dispatch.h
+b59255ddb1ead5531c3f0acf72fa6627d5c7192f3d23e9536eed00f32258c43b include/openssl/core_dispatch.h
d37532e62315d733862d0bff8d8de9fe40292a75deacae606f4776e544844316 include/openssl/core_names.h.in
57898905771752f6303e2b1cca1c9a41ea5e9c7bf08ee06531213a65e960e424 include/openssl/crypto.h.in
628e2a9e67412e2903ecb75efb27b262db1f266b805c07ece6b85bf7ffa19dac include/openssl/cryptoerr.h
@@ -531,7 +531,7 @@ bc9ec2be442a4f49980ba2c63c8f0da701de1f6e23d7db35d781658f833dd7b9 include/openss
69dd983f45b8ccd551f084796519446552963a18c52b70470d978b597c81b2dc include/openssl/encodererr.h
aa02455482d744418123266f581b9b4310ba678c7d28c10fffc5eec74ce3c8ef include/openssl/err.h.in
29ea398f6a2dfa3d42516030f4b5e6b1de06bbff4326ae42a7e63e2380abe33a include/openssl/evp.h
-04f901922c5b607b6f1fbcd8e9510e9475e3060d6901517b52ae8a5ed0f0065b include/openssl/evperr.h
+b2a8058dd51abe6c1ac4a0f32175f550a308efd31607a9cf1620aa032b1f7e55 include/openssl/evperr.h
f37c13a7cc0b05a734efcafb7da321dcc366090c255da8ee532e5f2be2eaa152 include/openssl/fips_names.h
fef2b79b4de2cd74b02f12f1c0515cb2eaca742b8ded67fce722fb417e818e25 include/openssl/fipskey.h.in
47a088c98ad536ea99f2c6a9333e372507cb61b9bdffb930c586ed52f8f261eb include/openssl/hmac.h
@@ -559,7 +559,7 @@ ed785c451189aa5f7299f9f32a841e7f25b67c4ee937c8de8491a39240f5bd9d include/openss
2f4f0106e9b2db6636491dbe3ef81b80dbf01aefe6f73d19663423b7fcd54466 include/openssl/rsa.h
2f339ba2f22b8faa406692289a6e51fdbbb04b03f85cf3ca849835e58211ad23 include/openssl/rsaerr.h
6586f2187991731835353de0ffad0b6b57609b495e53d0f32644491ece629eb2 include/openssl/safestack.h.in
-b0c9ed3ce37034524623c579e8a2ea0feb6aab39e7489ce66e2b6bf28ec81840 include/openssl/self_test.h
+cad320f140eade8a90b4d068e03d2fc0448204656f8c1270f69be82bc3272806 include/openssl/self_test.h
a435cb5d87a37c05921afb2d68f581018ec9f62fd9b3194ab651139b24f616d2 include/openssl/sha.h
c169a015d7be52b7b99dd41c418a48d97e52ad21687c39c512a83a7c3f3ddb70 include/openssl/stack.h
22d7584ad609e30e818b54dca1dfae8dea38913fffedd25cd540c550372fb9a6 include/openssl/symhacks.h
@@ -611,14 +611,14 @@ bde6107744cf6840a4c350a48265ed000c49b0524fa60b0d68d6d7b33df5fce6 providers/comm
8ea192553b423e881d85118c70bcb26a40fbdee4e110f230c966939c76f4aa7e providers/common/securitycheck_fips.c
abd5997bc33b681a4ab275978b92aebca0806a4a3f0c2f41dacf11b3b6f4e101 providers/fips/fips_entry.c
d8cb05784ae8533a7d9569d4fbaaea4175b63a7c9f4fb0f254215224069dea6b providers/fips/fipsindicator.c
-6d9c45b756b3e64fb31b3fdf75a4d93f8a71b7dc6c5d2cd842ef9d3a8ec445e4 providers/fips/fipsprov.c
+485441c31b5ff7916a12d0b8438d131a58cbc1ff6267cd266ae2dd6128c825cc providers/fips/fipsprov.c
7be8349d3b557b6d9d5f87d318253a73d21123628a08f50726502abf0e3d8a44 providers/fips/include/fips/fipsindicator.h
ef204adc49776214dbb299265bc4f2c40b48848cbea4c25b8029f2b46a5c9797 providers/fips/include/fips_indicator_params.inc
f2581d7b4e105f2bb6d30908f3c2d9959313be08cec6dbeb49030c125a7676d3 providers/fips/include/fips_selftest_params.inc
669f76f742bcaaf28846b057bfab97da7c162d69da244de71b7c743bf16e430f providers/fips/include/fipscommon.h
1af975061d9ea273fd337c74ccaab7b9331ab781d887c4e7164c5ac35e2c2e94 providers/fips/self_test.c
5c2c6c2f69e2eb01b88fa35630f27948e00dd2c2fd351735c74f34ccb2005cbe providers/fips/self_test.h
-9c5c8131ee9a5b2d1056b5548db3269c00445294134cb30b631707f69f8904f1 providers/fips/self_test_data.inc
+826d559ea7019c5db557679c3fe1ff5022be0132789c847d61da3c293fc02227 providers/fips/self_test_data.inc
2e568e2b161131240e97bd77a730c2299f961c2f1409ea8466422fc07f9be23f providers/fips/self_test_kats.c
7a368f6c6a5636593018bf10faecc3be1005e7cb3f0647f25c62b6f0fb7ac974 providers/implementations/asymciphers/rsa_enc.c
c2f1b12c64fc369dfc3b9bc9e76a76de7280e6429adaee55d332eb1971ad1879 providers/implementations/ciphers/cipher_aes.c
@@ -663,7 +663,7 @@ bb67eaa7a98494ca938726f9218213870fc97dd87b56bda950626cc794baf20b providers/impl
c4b1cb143de15acc396ce2e03fdd165defd25ebc831de9cdfacf408ea883c666 providers/implementations/ciphers/ciphercommon_local.h
39b47b6ef9d71852964c26e07ef0e9b23f04c7493b1b16ba7c3dba7074b6b70d providers/implementations/digests/digestcommon.c
6b1b0223a8ed6cd9210bcef2e148266bd5131d0f5fc6cd459f4bc0db808c6008 providers/implementations/digests/sha2_prov.c
-47a1b107e0e37607370e3f91c23eb8b6403892867239d5e1c17f8c94cfa83c56 providers/implementations/digests/sha3_prov.c
+efb4d6e3b1d870ba680c73beb509398e6cce633937c58e6cc5fbbfcf7888711f providers/implementations/digests/sha3_prov.c
9b37f34d48b3346c6ca3de430e190d7bfbd4e327d728870a64c7bd806ab700b6 providers/implementations/exchange/dh_exch.c
ad943431c43913443461c709a179c577f7278aa061fab6e1ecbb4d0f211db63d providers/implementations/exchange/ecdh_exch.c
d44c5a6d3156392757415f34afc1ab164fb0e9cd1e97977386d7cd13f3555df5 providers/implementations/exchange/ecx_exch.c
@@ -683,7 +683,7 @@ b41c9a4e90d951a2d0e796b1cbbdbe8cb6fc18306d9b70be7a489249c11c294a providers/impl
190f66af533067b80f18d7a12ba5440927e3e93b218f67473b4dea7dd9db88a6 providers/implementations/include/prov/mlx_kem.h
af1adbeaa97de9b550f987e4badfa3809ba8c734bf7b90b830882cd95175d667 providers/implementations/include/prov/names.h
b9f8781167f274ccd8b643b3bb6c4e1108fb27b2aae588518261af9415228dae providers/implementations/include/prov/seeding.h
-c67ea899ea2f37e4fc44f25bdbb965f91cc4d29c833c1e3a19603f97efd6288a providers/implementations/kdfs/hkdf.c
+f63b54479dcc4923db9d0baa87b38a8da6f8186b8838a906e6b9ef52522bf489 providers/implementations/kdfs/hkdf.c
8a294c68ed3369ba4f3f7ee87b322702ddb59b63bf5ec2c72719ef121618c3ca providers/implementations/kdfs/kbkdf.c
c0acc0869b8adbd399fbd024f7f7e664c462f4be51b72b41b7aebf1e3233a897 providers/implementations/kdfs/pbkdf2.c
c0778565abff112c0c5257329a7750ec4605e62f26cc36851fa1fbee6e03c70c providers/implementations/kdfs/pbkdf2.h
@@ -692,32 +692,32 @@ abe2b0f3711eaa34846e155cffc9242e4051c45de896f747afd5ac9d87f637dc providers/impl
e18ef50cd62647a2cc784c45169d75054dccd58fc106bf623d921de995bb3c34 providers/implementations/kdfs/sskdf.c
6d9767a99a5b46d44ac9e0898ee18d219c04dfb34fda42e71d54adccbed7d57c providers/implementations/kdfs/tls1_prf.c
88d04ff4c93648a4fbfd9ce137cfc64f2c85e1850593c1ab35334b8b3de8ad99 providers/implementations/kdfs/x942kdf.c
-3e199221ff78d80a3678e917dbbd232c5cd15f35b7c41bac92b60f766f656af7 providers/implementations/kem/ml_kem_kem.c
+b04249bcc64d6f7ec16f494afef252356b2f56424a034ab53def90463de0cb6f providers/implementations/kem/ml_kem_kem.c
a2e2b44064ef44b880b89ab6adc83686936acaa906313a37e5ec69d632912034 providers/implementations/kem/mlx_kem.c
c764555b9dc9b273c280514a5d2d44156f82f3e99155a77c627f2c773209bcd7 providers/implementations/kem/rsa_kem.c
-b9f7fc5c19f637cee55b0a435b838f5de3a5573ca376ba602e90f70855a78852 providers/implementations/keymgmt/dh_kmgmt.c
+a780a73b02f97d42a621fe096adf57a362b458cd5e5cfe1e3e619e88a407c7d7 providers/implementations/keymgmt/dh_kmgmt.c
24cc3cc8e8681c77b7f96c83293bd66045fd8ad69f756e673ca7f8ca9e82b0af providers/implementations/keymgmt/dsa_kmgmt.c
-e10086c31aafae0562054e3b07f12409e39b87b5e96ee7668c231c37861aa447 providers/implementations/keymgmt/ec_kmgmt.c
+967ab174fa4fadb4d4b1d226a1870028a3945d6e85c04d08f215686fe8fd2a07 providers/implementations/keymgmt/ec_kmgmt.c
258ae17bb2dd87ed1511a8eb3fe99eed9b77f5c2f757215ff6b3d0e8791fc251 providers/implementations/keymgmt/ec_kmgmt_imexport.inc
-b9646607ca2027919b591048bce0364349049a668468ccdda76b8a8082d7749c providers/implementations/keymgmt/ecx_kmgmt.c
+b335f1aca68f0b0b3f31e73473de264c812a932517d5a2c2339754d3e3f72a8a providers/implementations/keymgmt/ecx_kmgmt.c
daf35a7ab961ef70aefca981d80407935904c5da39dca6692432d6e6bc98759d providers/implementations/keymgmt/kdf_legacy_kmgmt.c
-17d6bc9f386f147765d9653639056dcb40e258239a5a9fdc4876a4f0a1d47c21 providers/implementations/keymgmt/mac_legacy_kmgmt.c
-d3d5c6d673ed16b4d179e7049f5eb3e6fc6cfbddb362ec8553ee32bd41864c72 providers/implementations/keymgmt/ml_dsa_kmgmt.c
-b05ed431602f27241993b9f50f11ced172b9278366c35ca9596890f6c763fb6b providers/implementations/keymgmt/ml_kem_kmgmt.c
+d97d7c8d3410b3e560ef2becaea2a47948e22205be5162f964c5e51a7eef08cb providers/implementations/keymgmt/mac_legacy_kmgmt.c
+24384616fcba4eb5594ccb2ebc199bcee8494ce1b3f4ac7824f17743e39c0279 providers/implementations/keymgmt/ml_dsa_kmgmt.c
+830c339dfc7f301ce5267ef9b0dc173b84d9597509c1a61ae038f3c01af78f45 providers/implementations/keymgmt/ml_kem_kmgmt.c
e15b780a1489bbe4c7d40d6aaa3bccfbf973e3946578f460eeb8373c657eee91 providers/implementations/keymgmt/mlx_kmgmt.c
-9376a19735fcc79893cb3c6b0cff17a2cae61db9e9165d9a30f8def7f8e8e7c7 providers/implementations/keymgmt/rsa_kmgmt.c
-093f6c2b9f39a97d4061800f59177c88f5ca2c1034e4d795a5a1d7a599916a06 providers/implementations/keymgmt/slh_dsa_kmgmt.c
+d63d47e8705772c4269dbdb110400ec9a6dc49ea2217f3d2aecc8ce733d9e47f providers/implementations/keymgmt/rsa_kmgmt.c
+6f0a786170ba9af860e36411d158ac0bd74bcb4d75c818a0cebadbc764759283 providers/implementations/keymgmt/slh_dsa_kmgmt.c
9d02d481b9c7c0c9e0932267d1a3e1fef00830aaa03093f000b88aa042972b9f providers/implementations/macs/cmac_prov.c
3c558b57fff3588b6832475e0b1c5be590229ad50d95a6ebb089b62bf5fe382d providers/implementations/macs/gmac_prov.c
3b5e591e8f6c6ba721a20d978452c9aae9a8259b3595b158303a49b35f286e53 providers/implementations/macs/hmac_prov.c
6f9100c9cdd39f94601d04a6564772686571711ff198cf8469e86444d1ba25f3 providers/implementations/macs/kmac_prov.c
4115f822e2477cd2c92a1c956cca1e4dbc5d86366e2a44a37526756153c0e432 providers/implementations/rands/drbg.c
-a417b4596695f6f3b456fa380df9014259a4af6278deb325c885203d5799f569 providers/implementations/rands/drbg_ctr.c
+b7e24bb9265501e37253e801028f3fd0af5111a100c0b2005c53d43f02c03389 providers/implementations/rands/drbg_ctr.c
857043f63023b1b74936600aca189f39910d1b109720903cbe7f0d5752f381e9 providers/implementations/rands/drbg_hash.c
8bdd3fef08e6395de772b04648bf819268907bcf1f0f1b150880dc2056d9cb10 providers/implementations/rands/drbg_hmac.c
-b6dba662e23d8c762cc31d5ead7f42bbad682fb64a8b064bdc415b7b5d89fc13 providers/implementations/rands/drbg_local.h
+2c63defffcc681ada17a6cc3eb895634fd8bf86110796a6381cc3dedd26fd47d providers/implementations/rands/drbg_local.h
ddae75f1e08416c92802faafba9d524e3bf58c13e9fcb51735733e161006f89e providers/implementations/rands/fips_crng_test.c
-068bec8b3cab01b0ab6d5d5046eab4d993058234a7687347e0bff637c70e479e providers/implementations/rands/test_rng.c
+04e726d547a00d0254362b0ebd3ddf87f58a53b78d3a070a1620f5fa714330bb providers/implementations/rands/test_rng.c
bd3c3d166be0e171e08e1cd03a943a643b4c181f11d8dde5e508d50163ac0cb8 providers/implementations/signature/dsa_sig.c
848ecf7587757410f98661a22fdf6eece53cc317224a22826d838131a47de8b0 providers/implementations/signature/ecdsa_sig.c
bd48b0fe43f0d0d91eb34bdfd48fbcfd69bceabf0ddc678702fe9ef968064bb6 providers/implementations/signature/eddsa_sig.c
diff --git a/providers/fips.checksum b/providers/fips.checksum
index c0525187cfad..0f8f0c2ec6ca 100644
--- a/providers/fips.checksum
+++ b/providers/fips.checksum
@@ -1 +1 @@
-e52ef0424b1c707a55e63763491f5ffc6462cab120929199bae37bd876094761 providers/fips-sources.checksums
+ef8128a08964171aaf5852362d97486b641fe521ad648e0c1108fd6d7f5a78ba providers/fips-sources.checksums
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 373cd1c2e4c5..e260b5b6652e 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -17,6 +17,7 @@
#include <openssl/proverr.h>
#include <openssl/indicator.h>
#include "internal/cryptlib.h"
+#include "internal/provider.h"
#include "prov/implementations.h"
#include "prov/names.h"
#include "prov/provider_ctx.h"
@@ -64,6 +65,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
+static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
static OSSL_FUNC_CRYPTO_malloc_fn *c_CRYPTO_malloc;
static OSSL_FUNC_CRYPTO_zalloc_fn *c_CRYPTO_zalloc;
static OSSL_FUNC_CRYPTO_free_fn *c_CRYPTO_free;
@@ -796,6 +798,9 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(in));
break;
+ case OSSL_FUNC_CORE_COUNT_TO_MARK:
+ set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
+ break;
case OSSL_FUNC_CRYPTO_MALLOC:
set_func(c_CRYPTO_malloc, OSSL_FUNC_CRYPTO_malloc(in));
break;
@@ -887,6 +892,15 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
goto err;
/*
+ * Ensure our internal provider is loaded. We use this whenever the FIPS
+ * provider internally uses the EVP API. We proactively load this now
+ * rather than waiting for lazy loading to ensure it is always present when
+ * we need it.
+ */
+ if (!ossl_provider_activate_fallbacks(libctx))
+ goto err;
+
+ /*
* We did initial set up of selftest_params in a local copy, because we
* could not create fgbl until c_CRYPTO_zalloc was defined in the loop
* above.
@@ -1025,6 +1039,11 @@ int ERR_pop_to_mark(void)
return c_pop_error_to_mark(NULL);
}
+int ERR_count_to_mark(void)
+{
+ return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
+}
+
/*
* This must take a library context, since it's called from the depths
* of crypto/initthread.c code, where it's (correctly) assumed that the
diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc
index 5cbb5352a596..a8d0469900c1 100644
--- a/providers/fips/self_test_data.inc
+++ b/providers/fips/self_test_data.inc
@@ -208,28 +208,6 @@ static const ST_KAT_DIGEST st_kat_digest_tests[] =
/*- CIPHER TEST DATA */
-/* DES3 test data */
-static const unsigned char des_ede3_cbc_pt[] = {
- 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
- 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
- 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
- 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51
-};
-static const unsigned char des_ede3_cbc_key[] = {
- 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
- 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
- 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
-};
-static const unsigned char des_ede3_cbc_iv[] = {
- 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17
-};
-static const unsigned char des_ede3_cbc_ct[] = {
- 0x20, 0x79, 0xC3, 0xD5, 0x3A, 0xA7, 0x63, 0xE1,
- 0x93, 0xB7, 0x9E, 0x25, 0x69, 0xAB, 0x52, 0x62,
- 0x51, 0x65, 0x70, 0x48, 0x1F, 0x25, 0xB5, 0x0F,
- 0x73, 0xC0, 0xBD, 0xA8, 0x5C, 0x8E, 0x0D, 0xA7
-};
-
/* AES-256 GCM test data */
static const unsigned char aes_256_gcm_key[] = {
0x92, 0xe1, 0x1d, 0xcd, 0xaa, 0x86, 0x6f, 0x5c,
@@ -907,38 +885,39 @@ static const unsigned char dh_priv[] = {
0x40, 0xb8, 0xfc, 0xe6
};
static const unsigned char dh_pub[] = {
- 0x95, 0xdd, 0x33, 0x8d, 0x29, 0xe5, 0x71, 0x04,
- 0x92, 0xb9, 0x18, 0x31, 0x7b, 0x72, 0xa3, 0x69,
- 0x36, 0xe1, 0x95, 0x1a, 0x2e, 0xe5, 0xa5, 0x59,
- 0x16, 0x99, 0xc0, 0x48, 0x6d, 0x0d, 0x4f, 0x9b,
- 0xdd, 0x6d, 0x5a, 0x3f, 0x6b, 0x98, 0x89, 0x0c,
- 0x62, 0xb3, 0x76, 0x52, 0xd3, 0x6e, 0x71, 0x21,
- 0x11, 0xe6, 0x8a, 0x73, 0x55, 0x37, 0x25, 0x06,
- 0x99, 0xef, 0xe3, 0x30, 0x53, 0x73, 0x91, 0xfb,
- 0xc2, 0xc5, 0x48, 0xbc, 0x5a, 0xc3, 0xe5, 0xb2,
- 0x33, 0x86, 0xc3, 0xee, 0xf5, 0xeb, 0x43, 0xc0,
- 0x99, 0xd7, 0x0a, 0x52, 0x02, 0x68, 0x7e, 0x83,
- 0x96, 0x42, 0x48, 0xfc, 0xa9, 0x1f, 0x40, 0x90,
- 0x8e, 0x8f, 0xb3, 0x31, 0x93, 0x15, 0xf6, 0xd2,
- 0x60, 0x6d, 0x7f, 0x7c, 0xd5, 0x2c, 0xc6, 0xe7,
- 0xc5, 0x84, 0x3a, 0xfb, 0x22, 0x51, 0x9c, 0xf0,
- 0xf0, 0xf9, 0xd3, 0xa0, 0xa4, 0xe8, 0xc8, 0x88,
- 0x99, 0xef, 0xed, 0xe7, 0x36, 0x43, 0x51, 0xfb,
- 0x6a, 0x36, 0x3e, 0xe7, 0x17, 0xe5, 0x44, 0x5a,
- 0xda, 0xb4, 0xc9, 0x31, 0xa6, 0x48, 0x39, 0x97,
- 0xb8, 0x7d, 0xad, 0x83, 0x67, 0x7e, 0x4d, 0x1d,
- 0x3a, 0x77, 0x75, 0xe0, 0xf6, 0xd0, 0x0f, 0xdf,
- 0x73, 0xc7, 0xad, 0x80, 0x1e, 0x66, 0x5a, 0x0e,
- 0x5a, 0x79, 0x6d, 0x0a, 0x03, 0x80, 0xa1, 0x9f,
- 0xa1, 0x82, 0xef, 0xc8, 0xa0, 0x4f, 0x5e, 0x4d,
- 0xb9, 0x0d, 0x1a, 0x86, 0x37, 0xf9, 0x5d, 0xb1,
- 0x64, 0x36, 0xbd, 0xc8, 0xf3, 0xfc, 0x09, 0x6c,
- 0x4f, 0xf7, 0xf2, 0x34, 0xbe, 0x8f, 0xef, 0x47,
- 0x9a, 0xc4, 0xb0, 0xdc, 0x4b, 0x77, 0x26, 0x3e,
- 0x07, 0xd9, 0x95, 0x9d, 0xe0, 0xf1, 0xbf, 0x3f,
- 0x0a, 0xe3, 0xd9, 0xd5, 0x0e, 0x4b, 0x89, 0xc9,
- 0x9e, 0x3e, 0xa1, 0x21, 0x73, 0x43, 0xdd, 0x8c,
- 0x65, 0x81, 0xac, 0xc4, 0x95, 0x9c, 0x91, 0xd3
+ 0x00, 0x8f, 0x81, 0x67, 0x68, 0xce, 0x97, 0x99,
+ 0x7e, 0x11, 0x5c, 0xad, 0x5b, 0xe1, 0x0c, 0xd4,
+ 0x15, 0x44, 0xdf, 0xc2, 0x47, 0xe7, 0x06, 0x27,
+ 0x5e, 0xf3, 0x9d, 0x5c, 0x4b, 0x2e, 0x35, 0x05,
+ 0xfd, 0x3c, 0x8f, 0x35, 0x85, 0x1b, 0x82, 0xdd,
+ 0x49, 0xc9, 0xa8, 0x7e, 0x3a, 0x5f, 0x33, 0xdc,
+ 0x8f, 0x5e, 0x32, 0x76, 0xe1, 0x52, 0x1b, 0x88,
+ 0x85, 0xda, 0xa9, 0x1d, 0x5f, 0x1c, 0x05, 0x3a,
+ 0xd4, 0x8d, 0xbb, 0xe7, 0x46, 0x46, 0x1e, 0x29,
+ 0x4b, 0x5a, 0x02, 0x88, 0x46, 0x94, 0xd0, 0x68,
+ 0x7d, 0xb2, 0x9f, 0x3a, 0x3d, 0x82, 0x05, 0xe5,
+ 0xa7, 0xbe, 0x6c, 0x7e, 0x24, 0x35, 0x25, 0x14,
+ 0xf3, 0x45, 0x08, 0x90, 0xfc, 0x55, 0x2e, 0xa8,
+ 0xb8, 0xb1, 0x89, 0x15, 0x94, 0x51, 0x44, 0xa9,
+ 0x9f, 0x68, 0xcb, 0x90, 0xbc, 0xd3, 0xae, 0x02,
+ 0x37, 0x26, 0xe4, 0xe9, 0x1a, 0x90, 0x95, 0x7e,
+ 0x1d, 0xac, 0x0c, 0x91, 0x97, 0x83, 0x24, 0x83,
+ 0xb9, 0xa1, 0x40, 0x72, 0xac, 0xf0, 0x55, 0x32,
+ 0x18, 0xab, 0xb8, 0x90, 0xda, 0x13, 0x4a, 0xc8,
+ 0x4b, 0x7c, 0x18, 0xbc, 0x33, 0xbf, 0x99, 0x85,
+ 0x39, 0x3e, 0xc6, 0x95, 0x9b, 0x48, 0x8e, 0xbe,
+ 0x46, 0x59, 0x48, 0x41, 0x0d, 0x37, 0x25, 0x94,
+ 0xbe, 0x8d, 0xf5, 0x81, 0x52, 0xf6, 0xdc, 0xeb,
+ 0x98, 0xd7, 0x3b, 0x44, 0x61, 0x6f, 0xa3, 0xef,
+ 0x7b, 0xfe, 0xbb, 0xc2, 0x8e, 0x46, 0x63, 0xbc,
+ 0x52, 0x65, 0xf9, 0xf8, 0x85, 0x41, 0xdf, 0x82,
+ 0x4a, 0x10, 0x2a, 0xe3, 0x0c, 0xb7, 0xad, 0x84,
+ 0xa6, 0x6f, 0x4e, 0x8e, 0x96, 0x1e, 0x04, 0xf7,
+ 0x57, 0x39, 0xca, 0x58, 0xd4, 0xef, 0x5a, 0xf1,
+ 0xf5, 0x69, 0xc2, 0xb1, 0x5c, 0x0a, 0xce, 0xbe,
+ 0x38, 0x01, 0xb5, 0x3f, 0x07, 0x8a, 0x72, 0x90,
+ 0x10, 0xac, 0x51, 0x3a, 0x96, 0x43, 0xdf, 0x6f,
+ 0xea
};
static const unsigned char dh_peer_pub[] = {
0x1f, 0xc1, 0xda, 0x34, 0x1d, 0x1a, 0x84, 0x6a,
diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c
index e0f5b7d91587..3724da23bcd3 100644
--- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c
+++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -32,7 +32,7 @@ static OSSL_FUNC_cipher_set_ctx_params_fn chacha20_poly1305_set_ctx_params;
static OSSL_FUNC_cipher_cipher_fn chacha20_poly1305_cipher;
static OSSL_FUNC_cipher_final_fn chacha20_poly1305_final;
static OSSL_FUNC_cipher_gettable_ctx_params_fn chacha20_poly1305_gettable_ctx_params;
-#define chacha20_poly1305_settable_ctx_params ossl_cipher_aead_settable_ctx_params
+static OSSL_FUNC_cipher_settable_ctx_params_fn chacha20_poly1305_settable_ctx_params;
#define chacha20_poly1305_gettable_params ossl_cipher_generic_gettable_params
#define chacha20_poly1305_update chacha20_poly1305_cipher
@@ -158,6 +158,21 @@ static const OSSL_PARAM *chacha20_poly1305_gettable_ctx_params
return chacha20_poly1305_known_gettable_ctx_params;
}
+static const OSSL_PARAM chacha20_poly1305_known_settable_ctx_params[] = {
+ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
+ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
+ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
+ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
+ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
+ OSSL_PARAM_END
+};
+static const OSSL_PARAM *chacha20_poly1305_settable_ctx_params(
+ ossl_unused void *cctx, ossl_unused void *provctx
+ )
+{
+ return chacha20_poly1305_known_settable_ctx_params;
+}
+
static int chacha20_poly1305_set_ctx_params(void *vctx,
const OSSL_PARAM params[])
{
@@ -238,7 +253,6 @@ static int chacha20_poly1305_set_ctx_params(void *vctx,
return 0;
}
}
- /* ignore OSSL_CIPHER_PARAM_AEAD_MAC_KEY */
return 1;
}
diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c
index d4f6d9797cd3..a3d209e0eac3 100644
--- a/providers/implementations/digests/sha3_prov.c
+++ b/providers/implementations/digests/sha3_prov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -20,7 +20,7 @@
#include "prov/implementations.h"
#define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
-#define SHAKE_FLAGS PROV_DIGEST_FLAG_XOF
+#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)
#define KMAC_FLAGS PROV_DIGEST_FLAG_XOF
/*
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c
index abea679fe19a..a38c71883dd1 100644
--- a/providers/implementations/encode_decode/decode_pem2der.c
+++ b/providers/implementations/encode_decode/decode_pem2der.c
@@ -151,6 +151,7 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
{ PEM_STRING_DSAPARAMS, OSSL_OBJECT_PKEY, "DSA", "type-specific" },
{ PEM_STRING_ECPRIVATEKEY, OSSL_OBJECT_PKEY, "EC", "type-specific" },
{ PEM_STRING_ECPARAMETERS, OSSL_OBJECT_PKEY, "EC", "type-specific" },
+ { PEM_STRING_SM2PRIVATEKEY, OSSL_OBJECT_PKEY, "SM2", "type-specific" },
{ PEM_STRING_SM2PARAMETERS, OSSL_OBJECT_PKEY, "SM2", "type-specific" },
{ PEM_STRING_RSA, OSSL_OBJECT_PKEY, "RSA", "type-specific" },
{ PEM_STRING_RSA_PUBLIC, OSSL_OBJECT_PKEY, "RSA", "type-specific" },
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
index 264bc5d4c162..6e3e8b5c0f66 100644
--- a/providers/implementations/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -307,13 +307,11 @@ static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[])
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
- if (p->data_size != 0 && p->data != NULL) {
- OPENSSL_free(ctx->salt);
- ctx->salt = NULL;
- if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
- &ctx->salt_len))
- return 0;
- }
+ OPENSSL_free(ctx->salt);
+ ctx->salt = NULL;
+ if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0,
+ &ctx->salt_len))
+ return 0;
}
return 1;
diff --git a/providers/implementations/kem/ml_kem_kem.c b/providers/implementations/kem/ml_kem_kem.c
index ac798cb4b6ba..27aa3b819836 100644
--- a/providers/implementations/kem/ml_kem_kem.c
+++ b/providers/implementations/kem/ml_kem_kem.c
@@ -171,7 +171,7 @@ static int ml_kem_encapsulate(void *vctx, unsigned char *ctext, size_t *clen,
return 1;
}
if (shsec == NULL) {
- ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL,
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_NULL_OUTPUT_BUFFER,
"NULL shared-secret buffer");
goto end;
}
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
index c2ee8593557a..98a8a45cf15a 100644
--- a/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -19,10 +19,12 @@
#include <openssl/core_names.h>
#include <openssl/bn.h>
#include <openssl/err.h>
+#include <openssl/self_test.h>
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "crypto/dh.h"
+#include "internal/fips.h"
#include "internal/sizes.h"
static OSSL_FUNC_keymgmt_new_fn dh_newdata;
@@ -207,6 +209,18 @@ static int dh_import(void *keydata, int selection, const OSSL_PARAM params[])
selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
ok = ok && ossl_dh_key_fromdata(dh, params, include_private);
+#ifdef FIPS_MODULE
+ /*
+ * FIPS 140-3 IG 10.3.A additional comment 1 mandates that a pairwise
+ * consistency check be undertaken on key import. The required test
+ * is described in SP 800-56Ar3 5.6.2.1.4.
+ */
+ if (ok > 0 && !ossl_fips_self_testing()) {
+ ok = ossl_dh_check_pairwise(dh, 1);
+ if (ok <= 0)
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
+ }
+#endif /* FIPS_MODULE */
}
return ok;
@@ -440,7 +454,7 @@ static int dh_validate(const void *keydata, int selection, int checktype)
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR)
== OSSL_KEYMGMT_SELECT_KEYPAIR)
- ok = ok && ossl_dh_check_pairwise(dh);
+ ok = ok && ossl_dh_check_pairwise(dh, 0);
return ok;
}
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index 9421aabb1455..7d3c22316975 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -20,12 +20,14 @@
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/proverr.h>
+#include <openssl/self_test.h>
#include "crypto/bn.h"
#include "crypto/ec.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "prov/securitycheck.h"
+#include "internal/fips.h"
#include "internal/param_build_set.h"
#ifndef FIPS_MODULE
@@ -429,6 +431,21 @@ int common_import(void *keydata, int selection, const OSSL_PARAM params[],
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
ok = ok && ossl_ec_key_otherparams_fromdata(ec, params);
+#ifdef FIPS_MODULE
+ if (ok > 0
+ && !ossl_fips_self_testing()
+ && EC_KEY_get0_public_key(ec) != NULL
+ && EC_KEY_get0_private_key(ec) != NULL
+ && EC_KEY_get0_group(ec) != NULL) {
+ BN_CTX *bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
+
+ ok = bnctx != NULL && ossl_ec_key_pairwise_check(ec, bnctx);
+ BN_CTX_free(bnctx);
+ if (ok <= 0)
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
+ }
+#endif /* FIPS_MODULE */
+
return ok;
}
diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c
index 230a75cc5795..faf25606e33a 100644
--- a/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -17,6 +17,7 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/self_test.h>
+#include "internal/fips.h"
#include "internal/param_build_set.h"
#include <openssl/param_build.h>
#include "crypto/ecx.h"
@@ -92,6 +93,15 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
#endif
+#ifdef FIPS_MODULE
+static int ecd_fips140_pairwise_test(const ECX_KEY *ecx, int type, int self_test);
+#endif /* FIPS_MODULE */
+
+static ossl_inline int ecx_key_type_is_ed(ECX_KEY_TYPE type)
+{
+ return type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448;
+}
+
static void *x25519_new_key(void *provctx)
{
if (!ossl_prov_is_running())
@@ -208,6 +218,14 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
ok = ok && ossl_ecx_key_fromdata(key, params, include_private);
+#ifdef FIPS_MODULE
+ if (ok > 0 && ecx_key_type_is_ed(key->type) && !ossl_fips_self_testing())
+ if (key->haspubkey && key->privkey != NULL) {
+ ok = ecd_fips140_pairwise_test(key, key->type, 1);
+ if (ok <= 0)
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
+ }
+#endif /* FIPS_MODULE */
return ok;
}
@@ -505,9 +523,11 @@ static void *ecx_gen_init(void *provctx, int selection,
if (algdesc != NULL
&& !ossl_FIPS_IND_callback(libctx, algdesc, "KeyGen Init")) {
OPENSSL_free(gctx);
- return 0;
+ return NULL;
}
#endif
+ } else {
+ return NULL;
}
if (!ecx_gen_set_params(gctx, params)) {
ecx_gen_cleanup(gctx);
@@ -701,8 +721,7 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx)
}
#ifndef FIPS_MODULE
if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
- if (gctx->type == ECX_KEY_TYPE_ED25519
- || gctx->type == ECX_KEY_TYPE_ED448)
+ if (ecx_key_type_is_ed(gctx->type))
goto err;
if (!ossl_ecx_dhkem_derive_private(key, privkey,
gctx->dhkem_ikm, gctx->dhkem_ikmlen))
@@ -843,6 +862,9 @@ static void ecx_gen_cleanup(void *genctx)
{
struct ecx_gen_ctx *gctx = genctx;
+ if (gctx == NULL)
+ return;
+
OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
OPENSSL_free(gctx->propq);
OPENSSL_free(gctx);
@@ -963,7 +985,7 @@ static int ecx_validate(const void *keydata, int selection, int type,
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
return ok;
- if (type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448)
+ if (ecx_key_type_is_ed(type))
ok = ok && ecd_key_pairwise_check(ecx, type);
else
ok = ok && ecx_key_pairwise_check(ecx, type);
diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c
index 161a433caf5a..a83017e3aebf 100644
--- a/providers/implementations/keymgmt/mac_legacy_kmgmt.c
+++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c
@@ -519,6 +519,9 @@ static void mac_gen_cleanup(void *genctx)
{
struct mac_gen_ctx *gctx = genctx;
+ if (gctx == NULL)
+ return;
+
OPENSSL_secure_clear_free(gctx->priv_key, gctx->priv_key_len);
ossl_prov_cipher_reset(&gctx->cipher);
OPENSSL_free(gctx);
diff --git a/providers/implementations/keymgmt/ml_dsa_kmgmt.c b/providers/implementations/keymgmt/ml_dsa_kmgmt.c
index 9105847e6dc7..53feeba4ac3d 100644
--- a/providers/implementations/keymgmt/ml_dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/ml_dsa_kmgmt.c
@@ -84,6 +84,8 @@ static int ml_dsa_pairwise_test(const ML_DSA_KEY *key)
sig, &sig_len, sizeof(sig)) <= 0)
goto err;
+ OSSL_SELF_TEST_oncorrupt_byte(st, sig);
+
if (ossl_ml_dsa_verify(key, 0, msg, sizeof(msg), NULL, 0, 0,
sig, sig_len) <= 0)
goto err;
@@ -355,7 +357,7 @@ static int ml_dsa_export(void *keydata, int selection,
OSSL_CALLBACK *param_cb, void *cbarg)
{
ML_DSA_KEY *key = keydata;
- OSSL_PARAM params[3];
+ OSSL_PARAM params[4];
const uint8_t *buf;
int include_private, pnum = 0;
@@ -368,9 +370,8 @@ static int ml_dsa_export(void *keydata, int selection,
include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
/*
- * Note that the public key can be recovered from the private key, so we
- * just export one or the other. If the seed is present, both the seed and
- * the private key are exported. The recipient will have a choice.
+ * Note that if the seed is present, both the seed and the private key are
+ * exported. The recipient will have a choice.
*/
if (include_private) {
if ((buf = ossl_ml_dsa_key_get_seed(key)) != NULL) {
@@ -383,7 +384,8 @@ static int ml_dsa_export(void *keydata, int selection,
ossl_ml_dsa_key_get_priv_len(key));
}
}
- if (pnum == 0 && (buf = ossl_ml_dsa_key_get_pub(key)) != NULL) {
+ if (((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+ && ((buf = ossl_ml_dsa_key_get_pub(key)) != NULL)) {
params[pnum++] = OSSL_PARAM_construct_octet_string
(OSSL_PKEY_PARAM_PUB_KEY, (void *)buf,
ossl_ml_dsa_key_get_pub_len(key));
@@ -472,8 +474,10 @@ static void *ml_dsa_gen(void *genctx, int evp_type)
goto err;
}
#ifdef FIPS_MODULE
- if (!ml_dsa_pairwise_test(key))
+ if (!ml_dsa_pairwise_test(key)) {
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
goto err;
+ }
#endif
return key;
err:
@@ -525,6 +529,9 @@ static void ml_dsa_gen_cleanup(void *genctx)
{
struct ml_dsa_gen_ctx *gctx = genctx;
+ if (gctx == NULL)
+ return;
+
OPENSSL_cleanse(gctx->entropy, gctx->entropy_len);
OPENSSL_free(gctx->propq);
OPENSSL_free(gctx);
diff --git a/providers/implementations/keymgmt/ml_kem_kmgmt.c b/providers/implementations/keymgmt/ml_kem_kmgmt.c
index ba854c663784..3936b6c3cd40 100644
--- a/providers/implementations/keymgmt/ml_kem_kmgmt.c
+++ b/providers/implementations/keymgmt/ml_kem_kmgmt.c
@@ -794,6 +794,9 @@ static void ml_kem_gen_cleanup(void *vgctx)
{
PROV_ML_KEM_GEN_CTX *gctx = vgctx;
+ if (gctx == NULL)
+ return;
+
if (gctx->seed != NULL)
OPENSSL_cleanse(gctx->seed, ML_KEM_RANDOM_BYTES);
OPENSSL_free(gctx->propq);
diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c
index 77d095009421..380c1c087b4c 100644
--- a/providers/implementations/keymgmt/rsa_kmgmt.c
+++ b/providers/implementations/keymgmt/rsa_kmgmt.c
@@ -25,6 +25,7 @@
#include "prov/provider_ctx.h"
#include "crypto/rsa.h"
#include "crypto/cryptlib.h"
+#include "internal/fips.h"
#include "internal/param_build_set.h"
static OSSL_FUNC_keymgmt_new_fn rsa_newdata;
@@ -196,6 +197,23 @@ static int rsa_import(void *keydata, int selection, const OSSL_PARAM params[])
ok = ok && ossl_rsa_fromdata(rsa, params, include_private);
}
+#ifdef FIPS_MODULE
+ if (ok > 0 && !ossl_fips_self_testing()) {
+ const BIGNUM *n, *e, *d, *dp, *dq, *iq, *p, *q;
+
+ RSA_get0_key(rsa, &n, &e, &d);
+ RSA_get0_crt_params(rsa, &dp, &dq, &iq);
+ p = RSA_get0_p(rsa);
+ q = RSA_get0_q(rsa);
+
+ /* Check for the public key */
+ if (n != NULL && e != NULL)
+ /* Check for private key in straightforward or CRT form */
+ if (d != NULL || (p != NULL && q != NULL && dp != NULL
+ && dq != NULL && iq != NULL))
+ ok = ossl_rsa_key_pairwise_test(rsa);
+ }
+#endif /* FIPS_MODULE */
return ok;
}
diff --git a/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/providers/implementations/keymgmt/slh_dsa_kmgmt.c
index b67367b449cd..cd2ebea72abb 100644
--- a/providers/implementations/keymgmt/slh_dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/slh_dsa_kmgmt.c
@@ -145,21 +145,23 @@ static const OSSL_PARAM *slh_dsa_gettable_params(void *provctx)
}
static int key_to_params(SLH_DSA_KEY *key, OSSL_PARAM_BLD *tmpl,
- int include_private)
+ int selection)
{
/* Error if there is no key or public key */
if (key == NULL || ossl_slh_dsa_key_get_pub(key) == NULL)
return 0;
- /*
- * Note that the private key always contains the public key elements so we
- * just save the one blob and return.
- */
- if (include_private && ossl_slh_dsa_key_get_priv(key) != NULL)
- return ossl_param_build_set_octet_string(tmpl, NULL,
- OSSL_PKEY_PARAM_PRIV_KEY,
- ossl_slh_dsa_key_get_priv(key),
- ossl_slh_dsa_key_get_priv_len(key));
- /* Otherwise write out the public key element */
+
+ if (((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+ && ossl_slh_dsa_key_get_priv(key) != NULL)
+ if (ossl_param_build_set_octet_string(tmpl, NULL,
+ OSSL_PKEY_PARAM_PRIV_KEY,
+ ossl_slh_dsa_key_get_priv(key),
+ ossl_slh_dsa_key_get_priv_len(key)) != 1)
+ return 0;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
+ return 1;
+
return ossl_param_build_set_octet_string(tmpl, NULL,
OSSL_PKEY_PARAM_PUB_KEY,
ossl_slh_dsa_key_get_pub(key),
@@ -215,7 +217,7 @@ static int slh_dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
SLH_DSA_KEY *key = keydata;
OSSL_PARAM_BLD *tmpl;
OSSL_PARAM *params = NULL;
- int ret = 0, include_private;
+ int ret = 0;
if (!ossl_prov_is_running() || key == NULL)
return 0;
@@ -227,8 +229,7 @@ static int slh_dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
if (tmpl == NULL)
return 0;
- include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
- if (!key_to_params(key, tmpl, include_private))
+ if (!key_to_params(key, tmpl, selection))
goto err;
params = OSSL_PARAM_BLD_to_param(tmpl);
@@ -346,8 +347,10 @@ static void *slh_dsa_gen(void *genctx, const char *alg)
gctx->entropy, gctx->entropy_len))
goto err;
#ifdef FIPS_MODULE
- if (!slh_dsa_fips140_pairwise_test(ctx, key, gctx->libctx))
+ if (!slh_dsa_fips140_pairwise_test(ctx, key, gctx->libctx)) {
+ ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
goto err;
+ }
#endif /* FIPS_MODULE */
ossl_slh_dsa_hash_ctx_free(ctx);
return key;
@@ -403,6 +406,9 @@ static void slh_dsa_gen_cleanup(void *genctx)
{
struct slh_dsa_gen_ctx *gctx = genctx;
+ if (gctx == NULL)
+ return;
+
OPENSSL_cleanse(gctx->entropy, gctx->entropy_len);
OPENSSL_free(gctx->propq);
OPENSSL_free(gctx);
diff --git a/providers/implementations/keymgmt/template_kmgmt.c b/providers/implementations/keymgmt/template_kmgmt.c
index b8e377a7f912..0d62f556ecd5 100644
--- a/providers/implementations/keymgmt/template_kmgmt.c
+++ b/providers/implementations/keymgmt/template_kmgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2025 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
@@ -387,6 +387,9 @@ static void template_gen_cleanup(void *genctx)
{
struct template_gen_ctx *gctx = genctx;
+ if (gctx == NULL)
+ return;
+
debug_print("gen cleanup for %p\n", gctx);
OPENSSL_free(gctx);
}
diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c
index b906da099184..a5c929a2cadc 100644
--- a/providers/implementations/rands/drbg_ctr.c
+++ b/providers/implementations/rands/drbg_ctr.c
@@ -23,6 +23,7 @@
#include "crypto/evp.h"
#include "crypto/evp/evp_local.h"
#include "internal/provider.h"
+#include "internal/common.h"
static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;
static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
@@ -85,6 +86,8 @@ static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
* are XORing. So just process however much input we have.
*/
n = inlen < ctr->keylen ? inlen : ctr->keylen;
+ if (!ossl_assert(n <= sizeof(ctr->K)))
+ return;
for (i = 0; i < n; i++)
ctr->K[i] ^= in[i];
if (inlen <= ctr->keylen)
diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h
index e591e0b3d18e..6cfd43db2d1d 100644
--- a/providers/implementations/rands/drbg_local.h
+++ b/providers/implementations/rands/drbg_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -32,16 +32,6 @@
# define TIME_INTERVAL (60*60) /* 1 hour */
/*
- * The number of bytes that constitutes an atomic lump of entropy with respect
- * to the FIPS 140-2 section 4.9.2 Conditional Tests. The size is somewhat
- * arbitrary, the smaller the value, the less entropy is consumed on first
- * read but the higher the probability of the test failing by accident.
- *
- * The value is in bytes.
- */
-#define CRNGT_BUFSIZ 16
-
-/*
* Maximum input size for the DRBG (entropy, nonce, personalization string)
*
* NIST SP800 90Ar1 allows a maximum of (1 << 35) bits i.e., (1 << 32) bytes.
@@ -247,14 +237,6 @@ int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]);
OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL), \
OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL)
-/* Continuous test "entropy" calls */
-size_t ossl_crngt_get_entropy(PROV_DRBG *drbg,
- unsigned char **pout,
- int entropy, size_t min_len, size_t max_len,
- int prediction_resistance);
-void ossl_crngt_cleanup_entropy(PROV_DRBG *drbg,
- unsigned char *out, size_t outlen);
-
/* Confirm digest is allowed to be used with a DRBG */
int ossl_drbg_verify_digest(PROV_DRBG *drbg, OSSL_LIB_CTX *libctx, const EVP_MD *md);
diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c
index dc5339166567..e81c82d23fa8 100644
--- a/providers/implementations/rands/test_rng.c
+++ b/providers/implementations/rands/test_rng.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -158,7 +158,7 @@ static int test_rng_reseed(ossl_unused void *vtest,
static size_t test_rng_nonce(void *vtest, unsigned char *out,
unsigned int strength, size_t min_noncelen,
- ossl_unused size_t max_noncelen)
+ size_t max_noncelen)
{
PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
size_t i;
@@ -174,9 +174,10 @@ static size_t test_rng_nonce(void *vtest, unsigned char *out,
if (t->nonce == NULL)
return 0;
+ i = t->nonce_len > max_noncelen ? max_noncelen : t->nonce_len;
if (out != NULL)
- memcpy(out, t->nonce, t->nonce_len);
- return t->nonce_len;
+ memcpy(out, t->nonce, i);
+ return i;
}
static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[])
diff --git a/providers/implementations/storemgmt/winstore_store.c b/providers/implementations/storemgmt/winstore_store.c
index 55dcc2aff202..59a86a105e9f 100644
--- a/providers/implementations/storemgmt/winstore_store.c
+++ b/providers/implementations/storemgmt/winstore_store.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -183,6 +183,7 @@ static int setup_decoder(struct winstore_ctx_st *ctx)
{
OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx);
const OSSL_ALGORITHM *to_algo = NULL;
+ const char *input_structure = NULL;
if (ctx->dctx != NULL)
return 1;
@@ -198,7 +199,8 @@ static int setup_decoder(struct winstore_ctx_st *ctx)
goto err;
}
- if (!OSSL_DECODER_CTX_set_input_structure(ctx->dctx, "Certificate")) {
+ input_structure = "Certificate";
+ if (!OSSL_DECODER_CTX_set_input_structure(ctx->dctx, input_structure)) {
ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
goto err;
}
@@ -208,6 +210,7 @@ static int setup_decoder(struct winstore_ctx_st *ctx)
to_algo++) {
OSSL_DECODER *to_obj = NULL;
OSSL_DECODER_INSTANCE *to_obj_inst = NULL;
+ const char *input_type;
/*
* Create the internal last resort decoder implementation
@@ -217,12 +220,22 @@ static int setup_decoder(struct winstore_ctx_st *ctx)
*/
to_obj = ossl_decoder_from_algorithm(0, to_algo, NULL);
if (to_obj != NULL)
- to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx);
+ to_obj_inst = ossl_decoder_instance_new_forprov(to_obj, ctx->provctx,
+ input_structure);
OSSL_DECODER_free(to_obj);
if (to_obj_inst == NULL)
goto err;
+ /*
+ * The input type has to be DER
+ */
+ input_type = OSSL_DECODER_INSTANCE_get_input_type(to_obj_inst);
+ if (OPENSSL_strcasecmp(input_type, "DER") != 0) {
+ ossl_decoder_instance_free(to_obj_inst);
+ continue;
+ }
+
if (!ossl_decoder_ctx_add_decoder_inst(ctx->dctx,
to_obj_inst)) {
ossl_decoder_instance_free(to_obj_inst);
diff --git a/providers/legacyprov.c b/providers/legacyprov.c
index 16e3639e76f1..6dbe3a8505d0 100644
--- a/providers/legacyprov.c
+++ b/providers/legacyprov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -48,6 +48,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
+static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
#endif
/* Parameters we provide to the core */
@@ -234,6 +235,9 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(tmp));
break;
+ case OSSL_FUNC_CORE_COUNT_TO_MARK:
+ set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
+ break;
}
}
#endif
@@ -301,4 +305,9 @@ int ERR_pop_to_mark(void)
{
return c_pop_error_to_mark(NULL);
}
+
+int ERR_count_to_mark(void)
+{
+ return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
+}
#endif
diff --git a/ssl/quic/json_enc.c b/ssl/quic/json_enc.c
index 3e9f715dfaca..527230137ec2 100644
--- a/ssl/quic/json_enc.c
+++ b/ssl/quic/json_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2025 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
@@ -11,7 +11,6 @@
#include "internal/nelem.h"
#include "internal/numbers.h"
#include <string.h>
-#include <math.h>
/*
* wbuf
@@ -595,33 +594,6 @@ void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value)
json_write_char(json, '"');
}
-/* Encode a JSON number from a 64-bit floating point value. */
-void ossl_json_f64(OSSL_JSON_ENC *json, double value)
-{
- char buf[32];
-
- if (!json_pre_item(json))
- return;
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
- {
- int checks = isnan(value);
-# if !defined(OPENSSL_SYS_VMS)
- checks |= isinf(value);
-# endif
-
- if (checks) {
- json_raise_error(json);
- return;
- }
- }
-#endif
-
- BIO_snprintf(buf, sizeof(buf), "%1.17g", value);
- json_write_str(json, buf);
- json_post_item(json);
-}
-
/*
* Encode a JSON UTF-8 string from a zero-terminated string. The string passed
* can be freed immediately following the call to this function.
diff --git a/ssl/quic/quic_ackm.c b/ssl/quic/quic_ackm.c
index 75a1e5741a03..93c83a36d8fe 100644
--- a/ssl/quic/quic_ackm.c
+++ b/ssl/quic/quic_ackm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -536,6 +536,9 @@ struct ossl_ackm_st {
/* Set to 1 when the handshake is confirmed. */
char handshake_confirmed;
+ /* Set to 1 when attached to server channel */
+ char is_server;
+
/* Set to 1 when the peer has completed address validation. */
char peer_completed_addr_validation;
@@ -855,7 +858,13 @@ static OSSL_TIME ackm_get_pto_time_and_space(OSSL_ACKM *ackm, int *space)
}
for (i = QUIC_PN_SPACE_INITIAL; i < QUIC_PN_SPACE_NUM; ++i) {
- if (ackm->ack_eliciting_bytes_in_flight[i] == 0)
+ /*
+ * RFC 9002 section 6.2.2.1 keep probe timeout armed until
+ * handshake is confirmed (client sees HANDSHAKE_DONE message
+ * from server).
+ */
+ if (ackm->ack_eliciting_bytes_in_flight[i] == 0 &&
+ (ackm->handshake_confirmed == 1 || ackm->is_server == 1))
continue;
if (i == QUIC_PN_SPACE_APP) {
@@ -875,10 +884,18 @@ static OSSL_TIME ackm_get_pto_time_and_space(OSSL_ACKM *ackm, int *space)
}
}
- t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration);
- if (ossl_time_compare(t, pto_timeout) < 0) {
- pto_timeout = t;
- pto_space = i;
+ /*
+ * Only re-arm timer if stack has sent at least one ACK eliciting frame.
+ * If stack has sent no ACK eliciting frame at given encryption level then
+ * particular timer is zero and we must not attempt to set it. Timer keeps
+ * time since epoch (Jan 1 1970) and we must not set timer to past.
+ */
+ if (!ossl_time_is_zero(ackm->time_of_last_ack_eliciting_pkt[i])) {
+ t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration);
+ if (ossl_time_compare(t, pto_timeout) < 0) {
+ pto_timeout = t;
+ pto_space = i;
+ }
}
}
@@ -1021,7 +1038,8 @@ OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),
void *now_arg,
OSSL_STATM *statm,
const OSSL_CC_METHOD *cc_method,
- OSSL_CC_DATA *cc_data)
+ OSSL_CC_DATA *cc_data,
+ int is_server)
{
OSSL_ACKM *ackm;
int i;
@@ -1045,6 +1063,7 @@ OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),
ackm->statm = statm;
ackm->cc_method = cc_method;
ackm->cc_data = cc_data;
+ ackm->is_server = (char)is_server;
ackm->rx_max_ack_delay = ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY);
ackm->tx_max_ack_delay = DEFAULT_TX_MAX_ACK_DELAY;
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index 8fb651d9ceb6..f8e4252ba48f 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -242,7 +242,8 @@ static int ch_init(QUIC_CHANNEL *ch)
goto err;
if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm,
- ch->cc_method, ch->cc_data)) == NULL)
+ ch->cc_method, ch->cc_data,
+ ch->is_server)) == NULL)
goto err;
if (!ossl_quic_stream_map_init(&ch->qsm, get_stream_limit, ch,
diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h
index cdd0969586df..816ccf694b8f 100644
--- a/ssl/quic/quic_channel_local.h
+++ b/ssl/quic/quic_channel_local.h
@@ -41,7 +41,10 @@ struct quic_channel_st {
/*
* The associated TLS 1.3 connection data. Used to provide the handshake
* layer; its 'network' side is plugged into the crypto stream for each EL
- * (other than the 0-RTT EL).
+ * (other than the 0-RTT EL). Note that the `tls` SSL object is not "owned"
+ * by this channel. It is created and managed elsewhere and is guaranteed
+ * to be valid for the lifetime of the channel. Therefore we do not free it
+ * when we free the channel.
*/
QUIC_TLS *qtls;
SSL *tls;
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index 6e3de7d50501..5ad5a79157f4 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -186,6 +186,10 @@ static int quic_raise_non_normal_error(QCTX *ctx,
* This determines whether SSL_get_error() is updated; the value it returns
* is modified only by an I/O call.
*
+ * QCTX_NO_ERROR
+ * Don't raise an error if the object type is wrong. Should not be used in
+ * conjunction with any flags that may raise errors not related to a wrong
+ * object type.
*/
#define QCTX_C (1U << 0)
#define QCTX_S (1U << 1)
@@ -195,6 +199,7 @@ static int quic_raise_non_normal_error(QCTX *ctx,
#define QCTX_LOCK (1U << 5)
#define QCTX_IO (1U << 6)
#define QCTX_D (1U << 7)
+#define QCTX_NO_ERROR (1U << 8)
/*
* Called when expect_quic failed. Used to diagnose why such a call failed and
@@ -205,7 +210,9 @@ static int wrong_type(const SSL *s, uint32_t flags)
const uint32_t mask = QCTX_C | QCTX_S | QCTX_L | QCTX_D;
int code = ERR_R_UNSUPPORTED;
- if ((flags & mask) == QCTX_D)
+ if ((flags & QCTX_NO_ERROR) != 0)
+ return 1;
+ else if ((flags & mask) == QCTX_D)
code = SSL_R_DOMAIN_USE_ONLY;
else if ((flags & mask) == QCTX_L)
code = SSL_R_LISTENER_USE_ONLY;
@@ -225,7 +232,8 @@ static int wrong_type(const SSL *s, uint32_t flags)
*
* After this returns 1, all fields of the passed QCTX are initialised.
* Returns 0 on failure. This function is intended to be used to provide API
- * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure.
+ * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure
+ * unless the QCTX_NO_ERROR flag is set.
*
* The flags argument controls the preconditions and postconditions of this
* function. See above for the different flags.
@@ -378,6 +386,25 @@ err:
return ok;
}
+static int is_quic_c(const SSL *s, QCTX *ctx, int raiseerrs)
+{
+ uint32_t flags = QCTX_C;
+
+ if (!raiseerrs)
+ flags |= QCTX_NO_ERROR;
+ return expect_quic_as(s, ctx, flags);
+}
+
+/* Same as expect_quic_cs except that errors are not raised if raiseerrs == 0 */
+static int is_quic_cs(const SSL *s, QCTX *ctx, int raiseerrs)
+{
+ uint32_t flags = QCTX_C | QCTX_S;
+
+ if (!raiseerrs)
+ flags |= QCTX_NO_ERROR;
+ return expect_quic_as(s, ctx, flags);
+}
+
static int expect_quic_cs(const SSL *s, QCTX *ctx)
{
return expect_quic_as(s, ctx, QCTX_C | QCTX_S);
@@ -1672,33 +1699,47 @@ long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg)
}
/* SSL_set_connect_state */
-void ossl_quic_set_connect_state(SSL *s)
+int ossl_quic_set_connect_state(SSL *s, int raiseerrs)
{
QCTX ctx;
- if (!expect_quic_cs(s, &ctx))
- return;
+ if (!is_quic_c(s, &ctx, raiseerrs))
+ return 0;
+
+ if (ctx.qc->as_server_state == 0)
+ return 1;
/* Cannot be changed after handshake started */
- if (ctx.qc->started || ctx.is_stream)
- return;
+ if (ctx.qc->started) {
+ if (raiseerrs)
+ QUIC_RAISE_NON_NORMAL_ERROR(NULL, SSL_R_INVALID_COMMAND, NULL);
+ return 0;
+ }
ctx.qc->as_server_state = 0;
+ return 1;
}
/* SSL_set_accept_state */
-void ossl_quic_set_accept_state(SSL *s)
+int ossl_quic_set_accept_state(SSL *s, int raiseerrs)
{
QCTX ctx;
- if (!expect_quic_cs(s, &ctx))
- return;
+ if (!is_quic_c(s, &ctx, raiseerrs))
+ return 0;
+
+ if (ctx.qc->as_server_state == 1)
+ return 1;
/* Cannot be changed after handshake started */
- if (ctx.qc->started || ctx.is_stream)
- return;
+ if (ctx.qc->started) {
+ if (raiseerrs)
+ QUIC_RAISE_NON_NORMAL_ERROR(NULL, SSL_R_INVALID_COMMAND, NULL);
+ return 0;
+ }
ctx.qc->as_server_state = 1;
+ return 1;
}
/* SSL_do_handshake */
@@ -1983,7 +2024,8 @@ int ossl_quic_do_handshake(SSL *s)
int ossl_quic_connect(SSL *s)
{
/* Ensure we are in connect state (no-op if non-idle). */
- ossl_quic_set_connect_state(s);
+ if (!ossl_quic_set_connect_state(s, 1))
+ return -1;
/* Begin or continue the handshake */
return ossl_quic_do_handshake(s);
@@ -1993,7 +2035,8 @@ int ossl_quic_connect(SSL *s)
int ossl_quic_accept(SSL *s)
{
/* Ensure we are in accept state (no-op if non-idle). */
- ossl_quic_set_accept_state(s);
+ if (!ossl_quic_set_accept_state(s, 1))
+ return -1;
/* Begin or continue the handshake */
return ossl_quic_do_handshake(s);
@@ -2325,8 +2368,9 @@ int ossl_quic_get_error(const SSL *s, int i)
QCTX ctx;
int net_error, last_error;
- if (!expect_quic_cs(s, &ctx))
- return 0;
+ /* SSL_get_errors() should not raise new errors */
+ if (!is_quic_cs(s, &ctx, 0 /* suppress errors */))
+ return SSL_ERROR_SSL;
qctx_lock(&ctx);
net_error = ossl_quic_channel_net_error(ctx.qc->ch);
@@ -4849,6 +4893,9 @@ int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,
return 0;
key = ossl_quic_build_new_token(peer, NULL, 0);
+ if (key == NULL)
+ return 0;
+
ossl_crypto_mutex_lock(c->mutex);
tok = lh_QUIC_TOKEN_retrieve(c->cache, key);
if (tok != NULL) {
@@ -5106,6 +5153,8 @@ static int test_poll_event_w(QUIC_XSO *xso)
&& ossl_quic_stream_has_send_buffer(xso->stream)
&& ossl_quic_sstream_get_buffer_avail(xso->stream->sstream)
&& !ossl_quic_sstream_get_final_size(xso->stream->sstream, NULL)
+ && ossl_quic_txfc_get_cwm(&xso->stream->txfc)
+ > ossl_quic_sstream_get_cur_size(xso->stream->sstream)
&& quic_mutation_allowed(xso->conn, /*req_active=*/1);
}
diff --git a/ssl/quic/quic_method.c b/ssl/quic/quic_method.c
index 0de2bca47e6b..8092855efc61 100644
--- a/ssl/quic/quic_method.c
+++ b/ssl/quic/quic_method.c
@@ -23,5 +23,5 @@ IMPLEMENT_quic_meth_func(OSSL_QUIC_ANY_VERSION,
IMPLEMENT_quic_meth_func(OSSL_QUIC_ANY_VERSION,
OSSL_QUIC_server_method,
- ssl_undefined_function,
- ossl_quic_connect, ssl3_undef_enc_method)
+ ossl_quic_accept,
+ ssl_undefined_function, ssl3_undef_enc_method)
diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c
index 9097f56aa1c3..684c088c08c0 100644
--- a/ssl/quic/quic_port.c
+++ b/ssl/quic/quic_port.c
@@ -458,34 +458,38 @@ static SSL *port_new_handshake_layer(QUIC_PORT *port, QUIC_CHANNEL *ch)
QUIC_CONNECTION *qc = NULL;
QUIC_LISTENER *ql = NULL;
- if (port->get_conn_user_ssl != NULL) {
- user_ssl = port->get_conn_user_ssl(ch, port->user_ssl_arg);
- if (user_ssl == NULL)
- return NULL;
- qc = (QUIC_CONNECTION *)user_ssl;
- ql = (QUIC_LISTENER *)port->user_ssl_arg;
+ /*
+ * It only makes sense to call this function if we know how to associate
+ * the handshake layer we are about to create with some user_ssl object.
+ */
+ if (!ossl_assert(port->get_conn_user_ssl != NULL))
+ return NULL;
+ user_ssl = port->get_conn_user_ssl(ch, port->user_ssl_arg);
+ if (user_ssl == NULL)
+ return NULL;
+ qc = (QUIC_CONNECTION *)user_ssl;
+ ql = (QUIC_LISTENER *)port->user_ssl_arg;
+
+ /*
+ * We expect the user_ssl to be newly created so it must not have an
+ * existing qc->tls
+ */
+ if (!ossl_assert(qc->tls == NULL)) {
+ SSL_free(user_ssl);
+ return NULL;
}
tls = ossl_ssl_connection_new_int(port->channel_ctx, user_ssl, TLS_method());
+ qc->tls = tls;
if (tls == NULL || (tls_conn = SSL_CONNECTION_FROM_SSL(tls)) == NULL) {
SSL_free(user_ssl);
return NULL;
}
- /*
- * If we got a user ssl, which will be embedded in a quic connection
- * we need to fix up the connections tls pointer here
- */
- if (qc != NULL)
- qc->tls = tls;
-
if (ql != NULL && ql->obj.ssl.ctx->new_pending_conn_cb != NULL)
if (!ql->obj.ssl.ctx->new_pending_conn_cb(ql->obj.ssl.ctx, user_ssl,
ql->obj.ssl.ctx->new_pending_conn_arg)) {
- SSL_free(tls);
SSL_free(user_ssl);
- if (qc != NULL)
- qc->tls = NULL;
return NULL;
}
@@ -531,6 +535,11 @@ static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx,
*/
ch->tls = (tls != NULL) ? tls : port_new_handshake_layer(port, ch);
+ if (ch->tls == NULL) {
+ OPENSSL_free(ch);
+ return NULL;
+ }
+
#ifndef OPENSSL_NO_QLOG
/*
* If we're using qlog, make sure the tls get further configured properly
@@ -548,7 +557,6 @@ static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx,
* And finally init the channel struct
*/
if (!ossl_quic_channel_init(ch)) {
- SSL_free(ch->tls);
OPENSSL_free(ch);
return NULL;
}
diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c
index a36b02d5dcb4..f800d8984193 100644
--- a/ssl/quic/quic_rx_depack.c
+++ b/ssl/quic/quic_rx_depack.c
@@ -1429,16 +1429,8 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket)
uint32_t enc_level;
size_t dgram_len = qpacket->datagram_len;
- /*
- * ok has three states:
- * -1 error with ackm_data uninitialized
- * 0 error with ackm_data initialized
- * 1 success (ackm_data initialized)
- */
- int ok = -1; /* Assume the worst */
-
if (ch == NULL)
- goto end;
+ return 0;
ch->did_crypto_frame = 0;
@@ -1456,9 +1448,8 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket)
* Retry and Version Negotiation packets should not be passed to this
* function.
*/
- goto end;
+ return 0;
- ok = 0; /* Still assume the worst */
ackm_data.pkt_space = ossl_quic_enc_level_to_pn_space(enc_level);
/*
@@ -1480,18 +1471,9 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket)
enc_level,
qpacket->time,
&ackm_data))
- goto end;
+ return 0;
- ok = 1;
- end:
- /*
- * ASSUMPTION: If this function is called at all, |qpacket| is
- * a legitimate packet, even if its contents aren't.
- * Therefore, we call ossl_ackm_on_rx_packet() unconditionally, as long as
- * |ackm_data| has at least been initialized.
- */
- if (ok >= 0)
- ossl_ackm_on_rx_packet(ch->ackm, &ackm_data);
+ ossl_ackm_on_rx_packet(ch->ackm, &ackm_data);
- return ok > 0;
+ return 1;
}
diff --git a/ssl/quic/quic_tls.c b/ssl/quic/quic_tls.c
index d31c93dcf9b5..ccc053203d4f 100644
--- a/ssl/quic/quic_tls.c
+++ b/ssl/quic/quic_tls.c
@@ -177,6 +177,8 @@ quic_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
if (!ossl_assert("Should not happen" == NULL))
goto err;
#endif
+ } else {
+ kdfdigest = NULL;
}
if (!rl->qtls->args.yield_secret_cb(level, qdir, suite_id,
@@ -856,6 +858,13 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls)
}
#endif
+void ossl_quic_tls_clear(QUIC_TLS *qtls)
+{
+ if (qtls == NULL)
+ return;
+ qtls->local_transport_params_consumed = 0;
+}
+
int ossl_quic_tls_set_transport_params(QUIC_TLS *qtls,
const unsigned char *transport_params,
size_t transport_params_len)
diff --git a/ssl/record/methods/dtls_meth.c b/ssl/record/methods/dtls_meth.c
index a69629b07b53..99cb532d03c3 100644
--- a/ssl/record/methods/dtls_meth.c
+++ b/ssl/record/methods/dtls_meth.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2025 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
@@ -571,6 +571,12 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
return OSSL_RECORD_RETURN_FATAL;
}
+ if (rr->length == 0) {
+ /* No payload data in this record. Dump it */
+ rl->packet_length = 0;
+ goto again;
+ }
+
rl->num_recs = 1;
return OSSL_RECORD_RETURN_SUCCESS;
}
diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c
index deebbdc31514..111fbaf7d3a4 100644
--- a/ssl/record/rec_layer_d1.c
+++ b/ssl/record/rec_layer_d1.c
@@ -436,6 +436,17 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type,
#endif
sc->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
+ } else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
+ /*
+ * This is a warning but we receive it if we requested
+ * renegotiation and the peer denied it. Terminate with a fatal
+ * alert because if the application tried to renegotiate it
+ * presumably had a good reason and expects it to succeed. In
+ * the future we might have a renegotiation where we don't care
+ * if the peer refused it where we carry on.
+ */
+ SSLfatal(sc, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION);
+ return -1;
}
} else if (alert_level == SSL3_AL_FATAL) {
sc->rwstate = SSL_NOTHING;
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index 0930222edb15..889b12dd66d0 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -551,6 +551,10 @@ int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int writing, int ret,
return ret;
}
+/*
+ * Release data from a record.
+ * If length == 0 then we will release the entire record.
+ */
int ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr, size_t length)
{
assert(rr->length >= length);
@@ -572,6 +576,7 @@ int ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr, size_t length)
/* We allocated the buffers for this record (only happens with DTLS) */
OPENSSL_free(rr->allocdata);
rr->allocdata = NULL;
+ s->rlayer.curr_rec++;
}
rr->length -= length;
if (rr->length > 0)
@@ -920,10 +925,10 @@ int ssl3_read_bytes(SSL *ssl, uint8_t type, uint8_t *recvd_type,
/*
* This is a warning but we receive it if we requested
* renegotiation and the peer denied it. Terminate with a fatal
- * alert because if application tried to renegotiate it
+ * alert because if the application tried to renegotiate it
* presumably had a good reason and expects it to succeed. In
- * future we might have a renegotiation where we don't care if
- * the peer refused it where we carry on.
+ * the future we might have a renegotiation where we don't care
+ * if the peer refused it where we carry on.
*/
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION);
return -1;
diff --git a/ssl/rio/poll_builder.c b/ssl/rio/poll_builder.c
index 007e360d8716..bd9317a8b8bb 100644
--- a/ssl/rio/poll_builder.c
+++ b/ssl/rio/poll_builder.c
@@ -16,7 +16,9 @@ OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)
int ossl_rio_poll_builder_init(RIO_POLL_BUILDER *rpb)
{
-#if RIO_POLL_METHOD == RIO_POLL_METHOD_SELECT
+#if RIO_POLL_METHOD == RIO_POLL_METHOD_NONE
+ return 0;
+#elif RIO_POLL_METHOD == RIO_POLL_METHOD_SELECT
FD_ZERO(&rpb->rfd);
FD_ZERO(&rpb->wfd);
FD_ZERO(&rpb->efd);
@@ -113,8 +115,11 @@ int ossl_rio_poll_builder_add_fd(RIO_POLL_BUILDER *rpb, int fd,
if (i >= rpb->pfd_alloc) {
if (!rpb_ensure_alloc(rpb, rpb->pfd_alloc * 2))
return 0;
+ pfds = rpb->pfd_heap;
}
+ assert((rpb->pfd_heap != NULL && rpb->pfd_heap == pfds) ||
+ (rpb->pfd_heap == NULL && rpb->pfds == pfds));
assert(i <= rpb->pfd_num && rpb->pfd_num <= rpb->pfd_alloc);
pfds[i].fd = fd;
pfds[i].events = 0;
diff --git a/ssl/rio/poll_builder.h b/ssl/rio/poll_builder.h
index ffc9bbf9fca7..0a03f89df74d 100644
--- a/ssl/rio/poll_builder.h
+++ b/ssl/rio/poll_builder.h
@@ -23,7 +23,9 @@
* FDs.
*/
typedef struct rio_poll_builder_st {
-# if RIO_POLL_METHOD == RIO_POLL_METHOD_SELECT
+# if RIO_POLL_METHOD == RIO_POLL_METHOD_NONE
+ int unused_dummy; /* make microsoft compiler happy */
+# elif RIO_POLL_METHOD == RIO_POLL_METHOD_SELECT
fd_set rfd, wfd, efd;
int hwm_fd;
# elif RIO_POLL_METHOD == RIO_POLL_METHOD_POLL
diff --git a/ssl/rio/poll_method.h b/ssl/rio/poll_method.h
index 9a6de8927089..d5af8663c23d 100644
--- a/ssl/rio/poll_method.h
+++ b/ssl/rio/poll_method.h
@@ -14,9 +14,12 @@
# define RIO_POLL_METHOD_SELECT 1
# define RIO_POLL_METHOD_POLL 2
+# define RIO_POLL_METHOD_NONE 3
# ifndef RIO_POLL_METHOD
-# if !defined(OPENSSL_SYS_WINDOWS) && defined(POLLIN)
+# if defined(OPENSSL_SYS_UEFI)
+# define RIO_POLL_METHOD RIO_POLL_METHOD_NONE
+# elif !defined(OPENSSL_SYS_WINDOWS) && defined(POLLIN)
# define RIO_POLL_METHOD RIO_POLL_METHOD_POLL
# else
# define RIO_POLL_METHOD RIO_POLL_METHOD_SELECT
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 22095fbf2329..14373cdfa029 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -5036,7 +5036,10 @@ int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gense
}
if (EVP_PKEY_derive(pctx, pms, &pmslen) <= 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ /*
+ * the public key was probably a weak key
+ */
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE);
goto err;
}
@@ -5141,7 +5144,7 @@ int ssl_encapsulate(SSL_CONNECTION *s, EVP_PKEY *pubkey,
}
if (EVP_PKEY_encapsulate(pctx, ct, &ctlen, pms, &pmslen) <= 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE);
goto err;
}
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index ae0f98044929..1be6cd7dbc99 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -478,9 +478,9 @@ static int ssl_verify_internal(SSL_CONNECTION *s, STACK_OF(X509) *sk, EVP_PKEY *
/* Set suite B flags if needed */
X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s));
if (!X509_STORE_CTX_set_ex_data(ctx,
- SSL_get_ex_data_X509_STORE_CTX_idx(), s)) {
+ SSL_get_ex_data_X509_STORE_CTX_idx(),
+ SSL_CONNECTION_GET_USER_SSL(s)))
goto end;
- }
/* Verify via DANE if enabled */
if (DANETLS_ENABLED(&s->dane))
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 4c7b62e14232..9696a4c55fab 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -33,6 +33,11 @@
#include "internal/ssl_unwrap.h"
#include "quic/quic_local.h"
+#ifndef OPENSSL_NO_SSLKEYLOG
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
static int ssl_undefined_function_3(SSL_CONNECTION *sc, unsigned char *r,
unsigned char *s, size_t t, size_t *u)
{
@@ -652,6 +657,8 @@ int ossl_ssl_connection_reset(SSL *s)
return 0;
}
+ ossl_quic_tls_clear(sc->qtls);
+
if (!RECORD_LAYER_reset(&sc->rlayer))
return 0;
@@ -1135,52 +1142,55 @@ int SSL_set_trust(SSL *s, int trust)
return X509_VERIFY_PARAM_set_trust(sc->param, trust);
}
-int SSL_set1_host(SSL *s, const char *hostname)
+int SSL_set1_host(SSL *s, const char *host)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return 0;
- /* If a hostname is provided and parses as an IP address,
- * treat it as such. */
- if (hostname != NULL
- && X509_VERIFY_PARAM_set1_ip_asc(sc->param, hostname) == 1)
+ /* clear hostname(s) and IP address in any case, also if host parses as an IP address */
+ (void)X509_VERIFY_PARAM_set1_host(sc->param, NULL, 0);
+ (void)X509_VERIFY_PARAM_set1_ip(sc->param, NULL, 0);
+ if (host == NULL)
return 1;
- return X509_VERIFY_PARAM_set1_host(sc->param, hostname, 0);
+ /* If a host is provided and parses as an IP address, treat it as such. */
+ return X509_VERIFY_PARAM_set1_ip_asc(sc->param, host)
+ || X509_VERIFY_PARAM_set1_host(sc->param, host, 0);
}
-int SSL_add1_host(SSL *s, const char *hostname)
+int SSL_add1_host(SSL *s, const char *host)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return 0;
- /* If a hostname is provided and parses as an IP address,
- * treat it as such. */
- if (hostname) {
+ /* If a host is provided and parses as an IP address, treat it as such. */
+ if (host != NULL) {
ASN1_OCTET_STRING *ip;
char *old_ip;
- ip = a2i_IPADDRESS(hostname);
- if (ip) {
+ ip = a2i_IPADDRESS(host);
+ if (ip != NULL) {
/* We didn't want it; only to check if it *is* an IP address */
ASN1_OCTET_STRING_free(ip);
old_ip = X509_VERIFY_PARAM_get1_ip_asc(sc->param);
- if (old_ip) {
+ if (old_ip != NULL) {
OPENSSL_free(old_ip);
/* There can be only one IP address */
+ ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
+ "IP address was already set");
return 0;
}
- return X509_VERIFY_PARAM_set1_ip_asc(sc->param, hostname);
+ return X509_VERIFY_PARAM_set1_ip_asc(sc->param, host);
}
}
- return X509_VERIFY_PARAM_add1_host(sc->param, hostname, 0);
+ return X509_VERIFY_PARAM_add1_host(sc->param, host, 0);
}
void SSL_set_hostflags(SSL *s, unsigned int flags)
@@ -3978,6 +3988,33 @@ static void do_sslkeylogfile(const SSL *ssl, const char *line)
* via ssl.h.
*/
+#ifndef OPENSSL_NO_SSLKEYLOG
+static BIO *get_sslkeylog_bio(const char *keylogfile)
+{
+# ifdef _POSIX_C_SOURCE
+ BIO *b;
+ int fdno = -1;
+ FILE *fp = NULL;
+
+ fdno = open(keylogfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
+ if (fdno < 0)
+ return NULL;
+
+ fp = fdopen(fdno, "a");
+ if (fp == NULL) {
+ close(fdno);
+ return NULL;
+ }
+
+ if ((b = BIO_new_fp(fp, BIO_CLOSE)) == NULL)
+ fclose(fp);
+ return b;
+# else
+ return BIO_new_file(keylogfile, "a");
+# endif
+}
+#endif
+
SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
const SSL_METHOD *meth)
{
@@ -4290,7 +4327,7 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq,
* if its already there.
*/
if (keylog_bio == NULL) {
- keylog_bio = BIO_new_file(keylogfile, "a");
+ keylog_bio = get_sslkeylog_bio(keylogfile);
if (keylog_bio == NULL) {
OSSL_TRACE(TLS, "Unable to create keylog bio\n");
goto out;
@@ -4945,6 +4982,9 @@ int SSL_do_handshake(SSL *s)
return ossl_quic_do_handshake(s);
#endif
+ if (sc == NULL)
+ return -1;
+
if (sc->handshake_func == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
return -1;
@@ -4977,7 +5017,8 @@ void SSL_set_accept_state(SSL *s)
#ifndef OPENSSL_NO_QUIC
if (IS_QUIC(s)) {
- ossl_quic_set_accept_state(s);
+ /* We suppress errors because this is a void function */
+ (void)ossl_quic_set_accept_state(s, 0 /* suppress errors */);
return;
}
#endif
@@ -4996,7 +5037,8 @@ void SSL_set_connect_state(SSL *s)
#ifndef OPENSSL_NO_QUIC
if (IS_QUIC(s)) {
- ossl_quic_set_connect_state(s);
+ /* We suppress errors because this is a void function */
+ (void)ossl_quic_set_connect_state(s, 0 /* suppress errors */);
return;
}
#endif
@@ -5466,6 +5508,8 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
new_cert = ssl_cert_dup(ctx->cert);
if (new_cert == NULL)
goto err;
+ if (!custom_exts_copy_conn(&new_cert->custext, &sc->cert->custext))
+ goto err;
if (!custom_exts_copy_flags(&new_cert->custext, &sc->cert->custext))
goto err;
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 960f0c0f84b3..c53ebc36ae9d 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -2067,6 +2067,11 @@ typedef struct {
* corresponding ServerHello extension.
*/
# define SSL_EXT_FLAG_SENT 0x2
+/*
+ * Indicates an extension that was set on SSL object and needs to be
+ * preserved when switching SSL contexts.
+ */
+# define SSL_EXT_FLAG_CONN 0x4
typedef struct {
custom_ext_method *meths;
@@ -2772,6 +2777,8 @@ __owur int tls1_generate_master_secret(SSL_CONNECTION *s, unsigned char *out,
__owur int tls13_setup_key_block(SSL_CONNECTION *s);
__owur size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen,
unsigned char *p);
+__owur int tls13_store_handshake_traffic_hash(SSL_CONNECTION *s);
+__owur int tls13_store_server_finished_hash(SSL_CONNECTION *s);
__owur int tls13_change_cipher_state(SSL_CONNECTION *s, int which);
__owur int tls13_update_key(SSL_CONNECTION *s, int send);
__owur int tls13_hkdf_expand(SSL_CONNECTION *s,
@@ -2996,6 +3003,8 @@ __owur int custom_ext_add(SSL_CONNECTION *s, int context, WPACKET *pkt, X509 *x,
__owur int custom_exts_copy(custom_ext_methods *dst,
const custom_ext_methods *src);
+__owur int custom_exts_copy_conn(custom_ext_methods *dst,
+ const custom_ext_methods *src);
__owur int custom_exts_copy_flags(custom_ext_methods *dst,
const custom_ext_methods *src);
void custom_exts_free(custom_ext_methods *exts);
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 8e9aa64de5a7..a50f7ce96b64 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -595,6 +595,8 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello)
SSL_TICKET_STATUS r;
if (SSL_CONNECTION_IS_TLS13(s)) {
+ SSL_SESSION_free(s->session);
+ s->session = NULL;
/*
* By default we will send a new ticket. This can be overridden in the
* ticket processing.
@@ -607,6 +609,7 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello)
hello->pre_proc_exts, NULL, 0))
return -1;
+ /* If we resumed, s->session will now be set */
ret = s->session;
} else {
/* sets s->ext.ticket_expected */
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 1e0dc7b05592..9811e5c94b93 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -1736,11 +1736,14 @@ static int final_early_data(SSL_CONNECTION *s, unsigned int context, int sent)
static int final_maxfragmentlen(SSL_CONNECTION *s, unsigned int context,
int sent)
{
+ if (s->session == NULL)
+ return 1;
+
/* MaxFragmentLength defaults to disabled */
if (s->session->ext.max_fragment_len_mode == TLSEXT_max_fragment_length_UNSPECIFIED)
s->session->ext.max_fragment_len_mode = TLSEXT_max_fragment_length_DISABLED;
- if (s->session && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)) {
+ if (USE_MAX_FRAGMENT_LENGTH_EXT(s->session)) {
s->rlayer.rrlmethod->set_max_frag_len(s->rlayer.rrl,
GET_MAX_FRAGMENT_LENGTH(s->session));
s->rlayer.wrlmethod->set_max_frag_len(s->rlayer.wrl,
@@ -1897,6 +1900,10 @@ int tls_parse_compress_certificate(SSL_CONNECTION *sc, PACKET *pkt, unsigned int
already_set[comp] = 1;
}
}
+ if (PACKET_remaining(&supported_comp_algs) != 0) {
+ SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
+ return 0;
+ }
#endif
return 1;
}
diff --git a/ssl/statem/extensions_cust.c b/ssl/statem/extensions_cust.c
index b9d08da33f90..aa352529c4cc 100644
--- a/ssl/statem/extensions_cust.c
+++ b/ssl/statem/extensions_cust.c
@@ -107,7 +107,7 @@ void custom_ext_init(custom_ext_methods *exts)
custom_ext_method *meth = exts->meths;
for (i = 0; i < exts->meths_count; i++, meth++)
- meth->ext_flags = 0;
+ meth->ext_flags &= ~(SSL_EXT_FLAG_SENT | SSL_EXT_FLAG_RECEIVED);
}
/* Pass received custom extension data to the application for parsing. */
@@ -279,6 +279,31 @@ int custom_exts_copy_flags(custom_ext_methods *dst,
return 1;
}
+/* Copy old style API wrapper arguments */
+static void custom_ext_copy_old_cb(custom_ext_method *methdst,
+ const custom_ext_method *methsrc,
+ int *err)
+{
+ if (methsrc->add_cb != custom_ext_add_old_cb_wrap)
+ return;
+
+ if (*err) {
+ methdst->add_arg = NULL;
+ methdst->parse_arg = NULL;
+ return;
+ }
+
+ methdst->add_arg = OPENSSL_memdup(methsrc->add_arg,
+ sizeof(custom_ext_add_cb_wrap));
+ methdst->parse_arg = OPENSSL_memdup(methsrc->parse_arg,
+ sizeof(custom_ext_parse_cb_wrap));
+
+ if (methdst->add_arg == NULL || methdst->parse_arg == NULL)
+ *err = 1;
+
+ return;
+}
+
/* Copy table of custom extensions */
int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
{
@@ -293,31 +318,59 @@ int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
return 0;
dst->meths_count = src->meths_count;
- for (i = 0; i < src->meths_count; i++) {
- custom_ext_method *methsrc = src->meths + i;
- custom_ext_method *methdst = dst->meths + i;
+ for (i = 0; i < src->meths_count; i++)
+ custom_ext_copy_old_cb(&dst->meths[i], &src->meths[i], &err);
+ }
- if (methsrc->add_cb != custom_ext_add_old_cb_wrap)
- continue;
+ if (err) {
+ custom_exts_free(dst);
+ return 0;
+ }
- /*
- * We have found an old style API wrapper. We need to copy the
- * arguments too.
- */
+ return 1;
+}
- if (err) {
- methdst->add_arg = NULL;
- methdst->parse_arg = NULL;
- continue;
- }
+/* Copy custom extensions that were set on connection */
+int custom_exts_copy_conn(custom_ext_methods *dst,
+ const custom_ext_methods *src)
+{
+ size_t i;
+ int err = 0;
+
+ if (src->meths_count > 0) {
+ size_t meths_count = 0;
- methdst->add_arg = OPENSSL_memdup(methsrc->add_arg,
- sizeof(custom_ext_add_cb_wrap));
- methdst->parse_arg = OPENSSL_memdup(methsrc->parse_arg,
- sizeof(custom_ext_parse_cb_wrap));
+ for (i = 0; i < src->meths_count; i++)
+ if ((src->meths[i].ext_flags & SSL_EXT_FLAG_CONN) != 0)
+ meths_count++;
+
+ if (meths_count > 0) {
+ custom_ext_method *methdst =
+ OPENSSL_realloc(dst->meths,
+ (dst->meths_count + meths_count) *
+ sizeof(custom_ext_method));
+
+ if (methdst == NULL)
+ return 0;
+
+ for (i = 0; i < dst->meths_count; i++)
+ custom_ext_copy_old_cb(&methdst[i], &dst->meths[i], &err);
+
+ dst->meths = methdst;
+ methdst += dst->meths_count;
+
+ for (i = 0; i < src->meths_count; i++) {
+ custom_ext_method *methsrc = &src->meths[i];
+
+ if ((methsrc->ext_flags & SSL_EXT_FLAG_CONN) == 0)
+ continue;
+
+ memcpy(methdst, methsrc, sizeof(custom_ext_method));
+ custom_ext_copy_old_cb(methdst, methsrc, &err);
+ methdst++;
+ }
- if (methdst->add_arg == NULL || methdst->parse_arg == NULL)
- err = 1;
+ dst->meths_count += meths_count;
}
}
@@ -416,6 +469,7 @@ int ossl_tls_add_custom_ext_intern(SSL_CTX *ctx, custom_ext_methods *exts,
meth->add_cb = add_cb;
meth->free_cb = free_cb;
meth->ext_type = ext_type;
+ meth->ext_flags = (ctx == NULL) ? SSL_EXT_FLAG_CONN : 0;
meth->add_arg = add_arg;
meth->parse_arg = parse_arg;
exts->meths_count++;
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 3990a2b0c219..ba4500dd6597 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -911,6 +911,17 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst)
/* SSLfatal() already called */
return WORK_ERROR;
}
+ /*
+ * For QUIC we deferred setting up these keys until now so
+ * that we can ensure write keys are always set up before read
+ * keys.
+ */
+ if (SSL_IS_QUIC_HANDSHAKE(s)
+ && !ssl->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
+ /* SSLfatal() already called */
+ return WORK_ERROR;
+ }
}
}
break;
@@ -1788,8 +1799,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
*/
if (SSL_CONNECTION_IS_TLS13(s)) {
if (!ssl->method->ssl3_enc->setup_key_block(s)
- || !ssl->method->ssl3_enc->change_cipher_state(s,
- SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
+ || !tls13_store_handshake_traffic_hash(s)) {
/* SSLfatal() already called */
goto err;
}
@@ -1802,10 +1812,17 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt)
* are changed. Since QUIC doesn't do TLS early data or need middlebox
* compat this doesn't cause a problem.
*/
- if (s->early_data_state == SSL_EARLY_DATA_NONE
- && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0
- && !ssl->method->ssl3_enc->change_cipher_state(s,
+ if (SSL_IS_QUIC_HANDSHAKE(s)
+ || (s->early_data_state == SSL_EARLY_DATA_NONE
+ && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0)) {
+ if (!ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+ }
+ if (!ssl->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
/* SSLfatal() already called */
goto err;
}
@@ -3816,6 +3833,7 @@ CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s,
* moment. We need to do it now.
*/
if (SSL_CONNECTION_IS_TLS13(s)
+ && !SSL_IS_QUIC_HANDSHAKE(s)
&& SSL_IS_FIRST_HANDSHAKE(s)
&& (s->early_data_state != SSL_EARLY_DATA_NONE
|| (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
@@ -3906,6 +3924,7 @@ CON_FUNC_RETURN tls_construct_client_compressed_certificate(SSL_CONNECTION *sc,
* moment. We need to do it now.
*/
if (SSL_IS_FIRST_HANDSHAKE(sc)
+ && !SSL_IS_QUIC_HANDSHAKE(sc)
&& (sc->early_data_state != SSL_EARLY_DATA_NONE
|| (sc->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
&& (!ssl->method->ssl3_enc->change_cipher_state(sc,
diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c
index b8d976b235d7..78baeed90319 100644
--- a/ssl/statem/statem_dtls.c
+++ b/ssl/statem/statem_dtls.c
@@ -16,9 +16,6 @@
#include "internal/cryptlib.h"
#include "internal/ssl_unwrap.h"
#include <openssl/buffer.h>
-#include <openssl/objects.h>
-#include <openssl/evp.h>
-#include <openssl/x509.h>
#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
@@ -116,6 +113,7 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type)
size_t len, frag_off, overhead, used_len;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s);
+ uint8_t saved_payload[DTLS1_HM_HEADER_LENGTH];
if (!dtls1_query_mtu(s))
return -1;
@@ -218,6 +216,15 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type)
}
dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);
+ /*
+ * Save the data that will be overwritten by
+ * dtls1_write_messsage_header so no corruption occurs when using
+ * a msg callback.
+ */
+ if (s->msg_callback && s->init_off != 0)
+ memcpy(saved_payload, &s->init_buf->data[s->init_off],
+ sizeof(saved_payload));
+
dtls1_write_message_header(s,
(unsigned char *)&s->init_buf->
data[s->init_off]);
@@ -225,6 +232,11 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type)
ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len,
&written);
+
+ if (type == SSL3_RT_HANDSHAKE && s->msg_callback && s->init_off != 0)
+ memcpy(&s->init_buf->data[s->init_off], saved_payload,
+ sizeof(saved_payload));
+
if (ret <= 0) {
/*
* might need to update MTU here, but we don't know which
@@ -297,7 +309,7 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type)
if (written == s->init_num) {
if (s->msg_callback)
s->msg_callback(1, s->version, type, s->init_buf->data,
- (size_t)(s->init_off + s->init_num), ussl,
+ s->init_off + s->init_num, ussl,
s->msg_callback_arg);
s->init_off = 0; /* done writing this message */
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index a23d83eacec2..1e11d077f9e0 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -626,6 +626,7 @@ CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt)
*/
if (SSL_CONNECTION_IS_TLS13(s)
&& !s->server
+ && !SSL_IS_QUIC_HANDSHAKE(s)
&& (s->early_data_state != SSL_EARLY_DATA_NONE
|| (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
&& s->s3.tmp.cert_req == 0
@@ -933,8 +934,22 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
- if (!ssl->method->ssl3_enc->change_cipher_state(s,
- SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
+ if (!tls13_store_server_finished_hash(s)) {
+ /* SSLfatal() already called */
+ return MSG_PROCESS_ERROR;
+ }
+
+ /*
+ * For non-QUIC we set up the client's app data read keys now, so
+ * that we can go straight into reading 0.5RTT data from the server.
+ * For QUIC we don't do that, and instead defer setting up the keys
+ * until after we have set up the write keys in order to ensure that
+ * write keys are always set up before read keys (so that if we read
+ * a message we have the correct keys in place to ack it)
+ */
+ if (!SSL_IS_QUIC_HANDSHAKE(s)
+ && !ssl->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_CLIENT_READ)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
}
@@ -2365,23 +2380,24 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version,
real_max = ver_max;
/* Check for downgrades */
- if (s->version == TLS1_2_VERSION && real_max > s->version) {
- if (memcmp(tls12downgrade,
+ /* TODO(DTLSv1.3): Update this code for DTLSv1.3 */
+ if (!SSL_CONNECTION_IS_DTLS(s) && real_max > s->version) {
+ /* Signal applies to all versions */
+ if (memcmp(tls11downgrade,
s->s3.server_random + SSL3_RANDOM_SIZE
- - sizeof(tls12downgrade),
- sizeof(tls12downgrade)) == 0) {
+ - sizeof(tls11downgrade),
+ sizeof(tls11downgrade)) == 0) {
s->version = origv;
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_INAPPROPRIATE_FALLBACK);
return 0;
}
- } else if (!SSL_CONNECTION_IS_DTLS(s)
- && s->version < TLS1_2_VERSION
- && real_max > s->version) {
- if (memcmp(tls11downgrade,
- s->s3.server_random + SSL3_RANDOM_SIZE
- - sizeof(tls11downgrade),
- sizeof(tls11downgrade)) == 0) {
+ /* Only when accepting TLS1.3 */
+ if (real_max == TLS1_3_VERSION
+ && memcmp(tls12downgrade,
+ s->s3.server_random + SSL3_RANDOM_SIZE
+ - sizeof(tls12downgrade),
+ sizeof(tls12downgrade)) == 0) {
s->version = origv;
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_R_INAPPROPRIATE_FALLBACK);
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index b93a97999de2..43986121efd3 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -977,6 +977,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
if (SSL_CONNECTION_IS_TLS13(s)) {
if (!ssl->method->ssl3_enc->setup_key_block(s)
+ || !tls13_store_handshake_traffic_hash(s)
|| !ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
/* SSLfatal() already called */
@@ -1040,6 +1041,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst)
if (!ssl->method->ssl3_enc->generate_master_secret(s,
s->master_secret, s->handshake_secret, 0,
&dummy)
+ || !tls13_store_server_finished_hash(s)
|| !ssl->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_WRITE))
/* SSLfatal() already called */
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 8d0c2647b79c..2f71f954382d 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -972,8 +972,10 @@ int tls1_get0_implemented_groups(int min_proto_version, int max_proto_version,
goto end;
gix->grp = grps;
gix->ix = ix;
- if (sk_TLS_GROUP_IX_push(collect, gix) <= 0)
+ if (sk_TLS_GROUP_IX_push(collect, gix) <= 0) {
+ OPENSSL_free(gix);
goto end;
+ }
}
sk_TLS_GROUP_IX_sort(collect);
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index 6bddc9b51c4a..0aa97648c4ed 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -446,6 +446,31 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md,
return 1;
}
+static int tls13_store_hash(SSL_CONNECTION *s, unsigned char *hash, size_t len)
+{
+ size_t hashlen;
+
+ if (!ssl3_digest_cached_records(s, 1)
+ || !ssl_handshake_hash(s, hash, len, &hashlen)) {
+ /* SSLfatal() already called */;
+ return 0;
+ }
+
+ return 1;
+}
+
+int tls13_store_handshake_traffic_hash(SSL_CONNECTION *s)
+{
+ return tls13_store_hash(s, s->handshake_traffic_hash,
+ sizeof(s->handshake_traffic_hash));
+}
+
+int tls13_store_server_finished_hash(SSL_CONNECTION *s)
+{
+ return tls13_store_hash(s, s->server_finished_hash,
+ sizeof(s->server_finished_hash));
+}
+
int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
{
/* ASCII: "c e traffic", in hex for EBCDIC compatibility */
@@ -633,6 +658,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
label = server_application_traffic;
labellen = sizeof(server_application_traffic) - 1;
log_label = SERVER_APPLICATION_LABEL;
+ hash = s->server_finished_hash;
}
}
@@ -648,16 +674,6 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
}
}
- /*
- * Save the hash of handshakes up to now for use when we calculate the
- * client application traffic secret
- */
- if (label == server_application_traffic)
- memcpy(s->server_finished_hash, hashval, hashlen);
-
- if (label == server_handshake_traffic)
- memcpy(s->handshake_traffic_hash, hashval, hashlen);
-
if (label == client_application_traffic) {
/*
* We also create the resumption master secret, but this time use the
diff --git a/test/bio_comp_test.c b/test/bio_comp_test.c
index 75ae46adb6fb..515643288407 100644
--- a/test/bio_comp_test.c
+++ b/test/bio_comp_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -83,8 +83,10 @@ static int do_bio_comp(const BIO_METHOD *meth, int n)
int size = sizes[n % 4];
int type = n / 4;
- if (!TEST_ptr(original = OPENSSL_malloc(BUFFER_SIZE))
- || !TEST_ptr(result = OPENSSL_malloc(BUFFER_SIZE)))
+ original = OPENSSL_malloc(BUFFER_SIZE);
+ result = OPENSSL_malloc(BUFFER_SIZE);
+
+ if (!TEST_ptr(original) || !TEST_ptr(result))
goto err;
switch (type) {
diff --git a/test/bio_enc_test.c b/test/bio_enc_test.c
index b12cf9c38bf7..1e4d43105899 100644
--- a/test/bio_enc_test.c
+++ b/test/bio_enc_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -139,7 +139,17 @@ static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,
if (!TEST_ptr(mem))
goto err;
BIO_push(b, mem);
+#if 0
+ /*
+ * This is wrong to do, it always fails, and incorrectly ends up
+ * calling `EVP_CipherFinal()` and setting ctx->finished = 1, ...
+ * all of which are unwanted. But just deleting this is less
+ * instructive to future readers of the code. Don't call BIO_flush
+ * until you're done either reading or writing and want to finalise
+ * the state.
+ */
(void)BIO_flush(b);
+#endif
memset(out, 0, sizeof(out));
len = BIO_read(b, out, sizeof(out));
BIO_free_all(b);
@@ -256,6 +266,66 @@ static int test_bio_enc_chacha20_poly1305(int idx)
# endif
# endif
+static int test_bio_enc_eof_read_flush(void)
+{
+ /* Length chosen to ensure base64 encoding employs padding */
+ const unsigned char pbuf[] = "Attack at dawn";
+ unsigned char cbuf[16]; /* At least as long as pbuf */
+ const EVP_CIPHER *cipher = EVP_aes_256_gcm();
+ EVP_CIPHER_CTX *ctx = NULL;
+ BIO *mem = NULL, *b64 = NULL, *cbio = NULL;
+ unsigned char tag[16];
+ size_t key_size, iv_size;
+ int n, ret = 0;
+
+ memset(tag, 0, sizeof(tag));
+ if (!TEST_ptr(cipher)
+ || !TEST_int_gt((key_size = EVP_CIPHER_key_length(cipher)), 0)
+ || !TEST_int_gt((iv_size = EVP_CIPHER_iv_length(cipher)), 0)
+ || !TEST_ptr(mem = BIO_new(BIO_s_mem()))
+ || !TEST_ptr(b64 = BIO_new(BIO_f_base64()))
+ || !TEST_ptr(cbio = BIO_new(BIO_f_cipher()))
+ || !TEST_ptr(BIO_push(b64, mem))
+ || !TEST_ptr(BIO_push(cbio, b64))
+ || !TEST_int_gt(BIO_get_cipher_ctx(cbio, &ctx), 0)
+ || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, KEY, IV, ENCRYPT))
+ || !TEST_int_gt(BIO_write(cbio, pbuf, sizeof(pbuf) - 1), 0)
+ || !TEST_int_gt(BIO_flush(cbio), 0)
+ || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG,
+ sizeof(tag), tag), 0))
+ goto end;
+ BIO_free(cbio);
+ BIO_free(b64);
+ b64 = cbio = NULL;
+
+ BIO_set_mem_eof_return(mem, 0);
+ BIO_set_flags(mem, BIO_FLAGS_NONCLEAR_RST);
+ if (!TEST_int_gt(BIO_reset(mem), 0)
+ || !TEST_ptr(b64 = BIO_new(BIO_f_base64()))
+ || !TEST_ptr(cbio = BIO_new(BIO_f_cipher()))
+ || !TEST_ptr(BIO_push(b64, mem))
+ || !TEST_ptr(BIO_push(cbio, b64))
+ || !TEST_int_gt(BIO_get_cipher_ctx(cbio, &ctx), 0)
+ || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, KEY, IV, DECRYPT))
+ || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG,
+ sizeof(tag), tag), 0)
+ || !TEST_int_gt((n = BIO_read(cbio, cbuf, sizeof(cbuf))), 0)
+ || !TEST_true(BIO_get_cipher_status(cbio))
+ /* Evaluate both and report whether either or both failed */
+ || (!TEST_int_gt(BIO_flush(cbio), 0) +
+ !TEST_true(BIO_get_cipher_status(cbio)))
+ || !TEST_mem_eq(cbuf, n, pbuf, sizeof(pbuf) - 1))
+ goto end;
+
+ ret = 1;
+
+ end:
+ BIO_free(cbio);
+ BIO_free(b64);
+ BIO_free(mem);
+ return ret;
+}
+
int setup_tests(void)
{
ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2);
@@ -268,5 +338,6 @@ int setup_tests(void)
ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2);
# endif
# endif
+ ADD_TEST(test_bio_enc_eof_read_flush);
return 1;
}
diff --git a/test/bioprinttest.c b/test/bioprinttest.c
index 5ac5025c40e8..937fd0419d02 100644
--- a/test/bioprinttest.c
+++ b/test/bioprinttest.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -19,90 +19,97 @@
static int justprint = 0;
-static char *fpexpected[][10][5] = {
+static char *fpexpected[][11][5] = {
{
- /* 00 */ { "0.0000e+00", "0.0000", "0", "0.0000E+00", "0" },
- /* 01 */ { "6.7000e-01", "0.6700", "0.67", "6.7000E-01", "0.67" },
- /* 02 */ { "6.6667e-01", "0.6667", "0.6667", "6.6667E-01", "0.6667" },
- /* 03 */ { "6.6667e-04", "0.0007", "0.0006667", "6.6667E-04", "0.0006667" },
- /* 04 */ { "6.6667e-05", "0.0001", "6.667e-05", "6.6667E-05", "6.667E-05" },
- /* 05 */ { "6.6667e+00", "6.6667", "6.667", "6.6667E+00", "6.667" },
- /* 06 */ { "6.6667e+01", "66.6667", "66.67", "6.6667E+01", "66.67" },
- /* 07 */ { "6.6667e+02", "666.6667", "666.7", "6.6667E+02", "666.7" },
- /* 08 */ { "6.6667e+03", "6666.6667", "6667", "6.6667E+03", "6667" },
- /* 09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" },
+ /* 0.00 */ { "0.0000e+00", "0.0000", "0", "0.0000E+00", "0" },
+ /* 0.01 */ { "6.7000e-01", "0.6700", "0.67", "6.7000E-01", "0.67" },
+ /* 0.02 */ { "6.6667e-01", "0.6667", "0.6667", "6.6667E-01", "0.6667" },
+ /* 0.03 */ { "6.6667e-04", "0.0007", "0.0006667", "6.6667E-04", "0.0006667" },
+ /* 0.04 */ { "6.6667e-05", "0.0001", "6.667e-05", "6.6667E-05", "6.667E-05" },
+ /* 0.05 */ { "6.6667e+00", "6.6667", "6.667", "6.6667E+00", "6.667" },
+ /* 0.06 */ { "6.6667e+01", "66.6667", "66.67", "6.6667E+01", "66.67" },
+ /* 0.07 */ { "6.6667e+02", "666.6667", "666.7", "6.6667E+02", "666.7" },
+ /* 0.08 */ { "6.6667e+03", "6666.6667", "6667", "6.6667E+03", "6667" },
+ /* 0.09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" },
+ /* 0.10 */ { "-6.6667e+04", "-66666.6667", "-6.667e+04", "-6.6667E+04", "-6.667E+04" },
},
{
- /* 10 */ { "0.00000e+00", "0.00000", "0", "0.00000E+00", "0" },
- /* 11 */ { "6.70000e-01", "0.67000", "0.67", "6.70000E-01", "0.67" },
- /* 12 */ { "6.66667e-01", "0.66667", "0.66667", "6.66667E-01", "0.66667" },
- /* 13 */ { "6.66667e-04", "0.00067", "0.00066667", "6.66667E-04", "0.00066667" },
- /* 14 */ { "6.66667e-05", "0.00007", "6.6667e-05", "6.66667E-05", "6.6667E-05" },
- /* 15 */ { "6.66667e+00", "6.66667", "6.6667", "6.66667E+00", "6.6667" },
- /* 16 */ { "6.66667e+01", "66.66667", "66.667", "6.66667E+01", "66.667" },
- /* 17 */ { "6.66667e+02", "666.66667", "666.67", "6.66667E+02", "666.67" },
- /* 18 */ { "6.66667e+03", "6666.66667", "6666.7", "6.66667E+03", "6666.7" },
- /* 19 */ { "6.66667e+04", "66666.66667", "66667", "6.66667E+04", "66667" },
+ /* 1.00 */ { "0.00000e+00", "0.00000", "0", "0.00000E+00", "0" },
+ /* 1.01 */ { "6.70000e-01", "0.67000", "0.67", "6.70000E-01", "0.67" },
+ /* 1.02 */ { "6.66667e-01", "0.66667", "0.66667", "6.66667E-01", "0.66667" },
+ /* 1.03 */ { "6.66667e-04", "0.00067", "0.00066667", "6.66667E-04", "0.00066667" },
+ /* 1.04 */ { "6.66667e-05", "0.00007", "6.6667e-05", "6.66667E-05", "6.6667E-05" },
+ /* 1.05 */ { "6.66667e+00", "6.66667", "6.6667", "6.66667E+00", "6.6667" },
+ /* 1.06 */ { "6.66667e+01", "66.66667", "66.667", "6.66667E+01", "66.667" },
+ /* 1.07 */ { "6.66667e+02", "666.66667", "666.67", "6.66667E+02", "666.67" },
+ /* 1.08 */ { "6.66667e+03", "6666.66667", "6666.7", "6.66667E+03", "6666.7" },
+ /* 1.09 */ { "6.66667e+04", "66666.66667", "66667", "6.66667E+04", "66667" },
+ /* 1.10 */ { "-6.66667e+04", "-66666.66667", "-66667", "-6.66667E+04", "-66667" },
},
{
- /* 20 */ { " 0.0000e+00", " 0.0000", " 0", " 0.0000E+00", " 0" },
- /* 21 */ { " 6.7000e-01", " 0.6700", " 0.67", " 6.7000E-01", " 0.67" },
- /* 22 */ { " 6.6667e-01", " 0.6667", " 0.6667", " 6.6667E-01", " 0.6667" },
- /* 23 */ { " 6.6667e-04", " 0.0007", " 0.0006667", " 6.6667E-04", " 0.0006667" },
- /* 24 */ { " 6.6667e-05", " 0.0001", " 6.667e-05", " 6.6667E-05", " 6.667E-05" },
- /* 25 */ { " 6.6667e+00", " 6.6667", " 6.667", " 6.6667E+00", " 6.667" },
- /* 26 */ { " 6.6667e+01", " 66.6667", " 66.67", " 6.6667E+01", " 66.67" },
- /* 27 */ { " 6.6667e+02", " 666.6667", " 666.7", " 6.6667E+02", " 666.7" },
- /* 28 */ { " 6.6667e+03", " 6666.6667", " 6667", " 6.6667E+03", " 6667" },
- /* 29 */ { " 6.6667e+04", " 66666.6667", " 6.667e+04", " 6.6667E+04", " 6.667E+04" },
+ /* 2.00 */ { " 0.0000e+00", " 0.0000", " 0", " 0.0000E+00", " 0" },
+ /* 2.01 */ { " 6.7000e-01", " 0.6700", " 0.67", " 6.7000E-01", " 0.67" },
+ /* 2.02 */ { " 6.6667e-01", " 0.6667", " 0.6667", " 6.6667E-01", " 0.6667" },
+ /* 2.03 */ { " 6.6667e-04", " 0.0007", " 0.0006667", " 6.6667E-04", " 0.0006667" },
+ /* 2.04 */ { " 6.6667e-05", " 0.0001", " 6.667e-05", " 6.6667E-05", " 6.667E-05" },
+ /* 2.05 */ { " 6.6667e+00", " 6.6667", " 6.667", " 6.6667E+00", " 6.667" },
+ /* 2.06 */ { " 6.6667e+01", " 66.6667", " 66.67", " 6.6667E+01", " 66.67" },
+ /* 2.07 */ { " 6.6667e+02", " 666.6667", " 666.7", " 6.6667E+02", " 666.7" },
+ /* 2.08 */ { " 6.6667e+03", " 6666.6667", " 6667", " 6.6667E+03", " 6667" },
+ /* 2.09 */ { " 6.6667e+04", " 66666.6667", " 6.667e+04", " 6.6667E+04", " 6.667E+04" },
+ /* 2.10 */ { " -6.6667e+04", " -66666.6667", " -6.667e+04", " -6.6667E+04", " -6.667E+04" },
},
{
- /* 30 */ { " 0.00000e+00", " 0.00000", " 0", " 0.00000E+00", " 0" },
- /* 31 */ { " 6.70000e-01", " 0.67000", " 0.67", " 6.70000E-01", " 0.67" },
- /* 32 */ { " 6.66667e-01", " 0.66667", " 0.66667", " 6.66667E-01", " 0.66667" },
- /* 33 */ { " 6.66667e-04", " 0.00067", " 0.00066667", " 6.66667E-04", " 0.00066667" },
- /* 34 */ { " 6.66667e-05", " 0.00007", " 6.6667e-05", " 6.66667E-05", " 6.6667E-05" },
- /* 35 */ { " 6.66667e+00", " 6.66667", " 6.6667", " 6.66667E+00", " 6.6667" },
- /* 36 */ { " 6.66667e+01", " 66.66667", " 66.667", " 6.66667E+01", " 66.667" },
- /* 37 */ { " 6.66667e+02", " 666.66667", " 666.67", " 6.66667E+02", " 666.67" },
- /* 38 */ { " 6.66667e+03", " 6666.66667", " 6666.7", " 6.66667E+03", " 6666.7" },
- /* 39 */ { " 6.66667e+04", " 66666.66667", " 66667", " 6.66667E+04", " 66667" },
+ /* 3.00 */ { " 0.00000e+00", " 0.00000", " 0", " 0.00000E+00", " 0" },
+ /* 3.01 */ { " 6.70000e-01", " 0.67000", " 0.67", " 6.70000E-01", " 0.67" },
+ /* 3.02 */ { " 6.66667e-01", " 0.66667", " 0.66667", " 6.66667E-01", " 0.66667" },
+ /* 3.03 */ { " 6.66667e-04", " 0.00067", " 0.00066667", " 6.66667E-04", " 0.00066667" },
+ /* 3.04 */ { " 6.66667e-05", " 0.00007", " 6.6667e-05", " 6.66667E-05", " 6.6667E-05" },
+ /* 3.05 */ { " 6.66667e+00", " 6.66667", " 6.6667", " 6.66667E+00", " 6.6667" },
+ /* 3.06 */ { " 6.66667e+01", " 66.66667", " 66.667", " 6.66667E+01", " 66.667" },
+ /* 3.07 */ { " 6.66667e+02", " 666.66667", " 666.67", " 6.66667E+02", " 666.67" },
+ /* 3.08 */ { " 6.66667e+03", " 6666.66667", " 6666.7", " 6.66667E+03", " 6666.7" },
+ /* 3.09 */ { " 6.66667e+04", " 66666.66667", " 66667", " 6.66667E+04", " 66667" },
+ /* 3.10 */ { "-6.66667e+04", "-66666.66667", " -66667", "-6.66667E+04", " -66667" },
},
{
- /* 40 */ { "0e+00", "0", "0", "0E+00", "0" },
- /* 41 */ { "7e-01", "1", "0.7", "7E-01", "0.7" },
- /* 42 */ { "7e-01", "1", "0.7", "7E-01", "0.7" },
- /* 43 */ { "7e-04", "0", "0.0007", "7E-04", "0.0007" },
- /* 44 */ { "7e-05", "0", "7e-05", "7E-05", "7E-05" },
- /* 45 */ { "7e+00", "7", "7", "7E+00", "7" },
- /* 46 */ { "7e+01", "67", "7e+01", "7E+01", "7E+01" },
- /* 47 */ { "7e+02", "667", "7e+02", "7E+02", "7E+02" },
- /* 48 */ { "7e+03", "6667", "7e+03", "7E+03", "7E+03" },
- /* 49 */ { "7e+04", "66667", "7e+04", "7E+04", "7E+04" },
+ /* 4.00 */ { "0e+00", "0", "0", "0E+00", "0" },
+ /* 4.01 */ { "7e-01", "1", "0.7", "7E-01", "0.7" },
+ /* 4.02 */ { "7e-01", "1", "0.7", "7E-01", "0.7" },
+ /* 4.03 */ { "7e-04", "0", "0.0007", "7E-04", "0.0007" },
+ /* 4.04 */ { "7e-05", "0", "7e-05", "7E-05", "7E-05" },
+ /* 4.05 */ { "7e+00", "7", "7", "7E+00", "7" },
+ /* 4.06 */ { "7e+01", "67", "7e+01", "7E+01", "7E+01" },
+ /* 4.07 */ { "7e+02", "667", "7e+02", "7E+02", "7E+02" },
+ /* 4.08 */ { "7e+03", "6667", "7e+03", "7E+03", "7E+03" },
+ /* 4.09 */ { "7e+04", "66667", "7e+04", "7E+04", "7E+04" },
+ /* 4.10 */ { "-7e+04", "-66667", "-7e+04", "-7E+04", "-7E+04" },
},
{
- /* 50 */ { "0.000000e+00", "0.000000", "0", "0.000000E+00", "0" },
- /* 51 */ { "6.700000e-01", "0.670000", "0.67", "6.700000E-01", "0.67" },
- /* 52 */ { "6.666667e-01", "0.666667", "0.666667", "6.666667E-01", "0.666667" },
- /* 53 */ { "6.666667e-04", "0.000667", "0.000666667", "6.666667E-04", "0.000666667" },
- /* 54 */ { "6.666667e-05", "0.000067", "6.66667e-05", "6.666667E-05", "6.66667E-05" },
- /* 55 */ { "6.666667e+00", "6.666667", "6.66667", "6.666667E+00", "6.66667" },
- /* 56 */ { "6.666667e+01", "66.666667", "66.6667", "6.666667E+01", "66.6667" },
- /* 57 */ { "6.666667e+02", "666.666667", "666.667", "6.666667E+02", "666.667" },
- /* 58 */ { "6.666667e+03", "6666.666667", "6666.67", "6.666667E+03", "6666.67" },
- /* 59 */ { "6.666667e+04", "66666.666667", "66666.7", "6.666667E+04", "66666.7" },
+ /* 5.00 */ { "0.000000e+00", "0.000000", "0", "0.000000E+00", "0" },
+ /* 5.01 */ { "6.700000e-01", "0.670000", "0.67", "6.700000E-01", "0.67" },
+ /* 5.02 */ { "6.666667e-01", "0.666667", "0.666667", "6.666667E-01", "0.666667" },
+ /* 5.03 */ { "6.666667e-04", "0.000667", "0.000666667", "6.666667E-04", "0.000666667" },
+ /* 5.04 */ { "6.666667e-05", "0.000067", "6.66667e-05", "6.666667E-05", "6.66667E-05" },
+ /* 5.05 */ { "6.666667e+00", "6.666667", "6.66667", "6.666667E+00", "6.66667" },
+ /* 5.06 */ { "6.666667e+01", "66.666667", "66.6667", "6.666667E+01", "66.6667" },
+ /* 5.07 */ { "6.666667e+02", "666.666667", "666.667", "6.666667E+02", "666.667" },
+ /* 5.08 */ { "6.666667e+03", "6666.666667", "6666.67", "6.666667E+03", "6666.67" },
+ /* 5.09 */ { "6.666667e+04", "66666.666667", "66666.7", "6.666667E+04", "66666.7" },
+ /* 5.10 */ { "-6.666667e+04", "-66666.666667", "-66666.7", "-6.666667E+04", "-66666.7" },
},
{
- /* 60 */ { "0.0000e+00", "000.0000", "00000000", "0.0000E+00", "00000000" },
- /* 61 */ { "6.7000e-01", "000.6700", "00000.67", "6.7000E-01", "00000.67" },
- /* 62 */ { "6.6667e-01", "000.6667", "000.6667", "6.6667E-01", "000.6667" },
- /* 63 */ { "6.6667e-04", "000.0007", "0.0006667", "6.6667E-04", "0.0006667" },
- /* 64 */ { "6.6667e-05", "000.0001", "6.667e-05", "6.6667E-05", "6.667E-05" },
- /* 65 */ { "6.6667e+00", "006.6667", "0006.667", "6.6667E+00", "0006.667" },
- /* 66 */ { "6.6667e+01", "066.6667", "00066.67", "6.6667E+01", "00066.67" },
- /* 67 */ { "6.6667e+02", "666.6667", "000666.7", "6.6667E+02", "000666.7" },
- /* 68 */ { "6.6667e+03", "6666.6667", "00006667", "6.6667E+03", "00006667" },
- /* 69 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" },
+ /* 6.00 */ { "0.0000e+00", "000.0000", "00000000", "0.0000E+00", "00000000" },
+ /* 6.01 */ { "6.7000e-01", "000.6700", "00000.67", "6.7000E-01", "00000.67" },
+ /* 6.02 */ { "6.6667e-01", "000.6667", "000.6667", "6.6667E-01", "000.6667" },
+ /* 6.03 */ { "6.6667e-04", "000.0007", "0.0006667", "6.6667E-04", "0.0006667" },
+ /* 6.04 */ { "6.6667e-05", "000.0001", "6.667e-05", "6.6667E-05", "6.667E-05" },
+ /* 6.05 */ { "6.6667e+00", "006.6667", "0006.667", "6.6667E+00", "0006.667" },
+ /* 6.06 */ { "6.6667e+01", "066.6667", "00066.67", "6.6667E+01", "00066.67" },
+ /* 6.07 */ { "6.6667e+02", "666.6667", "000666.7", "6.6667E+02", "000666.7" },
+ /* 6.08 */ { "6.6667e+03", "6666.6667", "00006667", "6.6667E+03", "00006667" },
+ /* 6.09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" },
+ /* 6.10 */ { "-6.6667e+04", "-66666.6667", "-6.667e+04", "-6.6667E+04", "-6.667E+04" },
},
};
@@ -203,7 +210,7 @@ static int dofptest(int test, int sub, double val, const char *width, int prec)
if (justprint) {
if (i == 0)
- printf(" /* %d%d */ { \"%s\"", test, sub, result);
+ printf(" /* %d.%02d */ { \"%s\"", test, sub, result);
else
printf(", \"%s\"", result);
} else if (!TEST_str_eq(fpexpected[test][sub][i], result)) {
@@ -234,7 +241,8 @@ static int test_fp(int i)
&& TEST_true(dofptest(i, t++, 66.0 + frac, pwp->w, pwp->p))
&& TEST_true(dofptest(i, t++, 666.0 + frac, pwp->w, pwp->p))
&& TEST_true(dofptest(i, t++, 6666.0 + frac, pwp->w, pwp->p))
- && TEST_true(dofptest(i, t++, 66666.0 + frac, pwp->w, pwp->p));
+ && TEST_true(dofptest(i, t++, 66666.0 + frac, pwp->w, pwp->p))
+ && TEST_true(dofptest(i, t++, -66666.0 - frac, pwp->w, pwp->p));
if (justprint)
printf(" },\n");
return r;
diff --git a/test/cmp_client_test.c b/test/cmp_client_test.c
index 4b3b5f4929c9..405249010c0b 100644
--- a/test/cmp_client_test.c
+++ b/test/cmp_client_test.c
@@ -227,7 +227,8 @@ static int test_exec_IR_ses_poll_ok(void)
static int test_exec_IR_ses_poll_no_timeout(void)
{
return test_exec_REQ_ses_poll(OSSL_CMP_PKIBODY_IR, checkAfter,
- 2 /* pollCount */, checkAfter + 4,
+ 2 /* pollCount */,
+ checkAfter + 14, /* usually 4 is sufficient */
OSSL_CMP_PKISTATUS_accepted);
}
diff --git a/test/crltest.c b/test/crltest.c
index c18448122024..9cea5b2f072f 100644
--- a/test/crltest.c
+++ b/test/crltest.c
@@ -9,6 +9,7 @@
#include "internal/nelem.h"
#include <string.h>
+#include <time.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
@@ -17,7 +18,16 @@
#include "testutil.h"
+/*
+ * We cannot use old certificates for new tests because the private key
+ * associated with them is no longer available. Therefore, we add kCRLTestLeaf,
+ * kCRLTestLeaf2 and PARAM_TIME2, as well as pass the verification time to the
+ * verify function as a parameter. Certificates and CRL from
+ * https://github.com/openssl/openssl/issues/27506 are used.
+ */
+
#define PARAM_TIME 1474934400 /* Sep 27th, 2016 */
+#define PARAM_TIME2 1753284700 /* July 23th, 2025 */
static const char *kCRLTestRoot[] = {
"-----BEGIN CERTIFICATE-----\n",
@@ -70,6 +80,61 @@ static const char *kCRLTestLeaf[] = {
NULL
};
+static const char *kCRLTestRoot2[] = {
+ "-----BEGIN CERTIFICATE-----\n",
+ "MIID4zCCAsugAwIBAgIUGTcyNat9hTOo8nnGdzF7MTzL9WAwDQYJKoZIhvcNAQEL\n",
+ "BQAweTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM\n",
+ "DVNhbiBGcmFuY2lzY28xEzARBgNVBAoMCk15IENvbXBhbnkxEzARBgNVBAMMCk15\n",
+ "IFJvb3QgQ0ExEzARBgNVBAsMCk15IFJvb3QgQ0EwHhcNMjUwMzAzMDcxNDA0WhcN\n",
+ "MzUwMzAxMDcxNDA0WjB5MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p\n",
+ "YTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwKTXkgQ29tcGFueTET\n",
+ "MBEGA1UEAwwKTXkgUm9vdCBDQTETMBEGA1UECwwKTXkgUm9vdCBDQTCCASIwDQYJ\n",
+ "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAN6jjwkmV+pse430MQfyaWv+JtAd2r6K\n",
+ "qzEquBcoofzuf/yvdEhQPjK3bcotgfEcFq3QMo1MJ7vqRHEIu0hJ+5ZnEQtIRcrg\n",
+ "Vm7/EoVCBpDc9BDtW40TDp69z9kaKyyKYy6rxmSKgJydGBeGGMwBxgTK/o0xAriC\n",
+ "C3lLXHT8G8YMamKUpToPL5iCRX+GJPnnizB2ODvpQGMWkbp9+1xEc4dD7Db2wfUb\n",
+ "gatDYUoGndQKWD49UhURavQZeLpDxlz93YutRRkZTWc4IB7WebiEb39BDjSP3QYm\n",
+ "2h+rZYyjp3Gxy8pBNTPzE9Dk4yjiqS7o3WGvi/S6zKTLDvWl9t6pMOMCAwEAAaNj\n",
+ "MGEwHQYDVR0OBBYEFNdhiR+Tlot2VBbp5XfcfLdlG4AkMA4GA1UdDwEB/wQEAwIB\n",
+ "hjAfBgNVHSMEGDAWgBTXYYkfk5aLdlQW6eV33Hy3ZRuAJDAPBgNVHRMBAf8EBTAD\n",
+ "AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvwutY0WMcKoqulifnYfhxGLtXSSvD2GET\n",
+ "uNRv+S1KI5JKcAdfvnbNDpUwlujMDIpe3ewmv9i6kcitpHwZXdVAw6KWagJ0kDSt\n",
+ "jbArJxuuuFmSFDS7kj8x7FZok5quAWDSSg+ubV2tCVxmDuTs1WXJXD3l9g+3J9GU\n",
+ "kyeFMKqwRp8w22vm9ilgXrzeesAmmAg/pEb56ljTPeaONQxVe7KJhv2q8J17sML8\n",
+ "BE7TdVx7UFQbO/t9XqdT5O9eF8JUx4Vn4QSr+jdjJ/ns4T3/IC9dJq9k7tjD48iA\n",
+ "TNc+7x+uj8P39VA96HpjujVakj8/qn5SQMPJgDds+MSXrX+6JBWm\n",
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
+static const char *kCRLTestLeaf2[] = {
+ "-----BEGIN CERTIFICATE-----\n",
+ "MIIECjCCAvKgAwIBAgIUPxuMqMtuN1j3XZVRVrNmaTCIP04wDQYJKoZIhvcNAQEL\n",
+ "BQAweTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM\n",
+ "DVNhbiBGcmFuY2lzY28xEzARBgNVBAoMCk15IENvbXBhbnkxEzARBgNVBAMMCk15\n",
+ "IFJvb3QgQ0ExEzARBgNVBAsMCk15IFJvb3QgQ0EwHhcNMjUwNDE3MTAxNjQ5WhcN\n",
+ "MjYwNDE3MTAxNjQ5WjBoMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpamluZzEQ\n",
+ "MA4GA1UEBwwHQmVpamluZzEYMBYGA1UECgwPTXkgT3JnYW5pemF0aW9uMRswGQYD\n",
+ "VQQDDBJNeSBJbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n",
+ "ggEKAoIBAQDIxRxZQokflDaLYoD21HT2U4EshqtKpSf9zPS5unBMCfnQkU4IJjBF\n",
+ "3qQmfgz5ZOpZv3x0w48fDjiysk0eOVCFAo+uixEjMeuln6Wj3taetch2Sk0YNm5J\n",
+ "SJCNF2olHZXn5R8ngEmho2j1wbwNnpcccZyRNzUSjR9oAgObkP3O7fyQKJRxwNU0\n",
+ "sN7mfoyEOczKtUaYbqi2gPx6OOqNLjXlLmfZ8PJagKCN/oYkGU5PoRNXp65Znhu6\n",
+ "s8FuSmvTodu8Qhs9Uizo+SycaBXn5Fbqt32S+9vPfhH9FfELDfQIaBp+iQAxcKPX\n",
+ "tUglXEjiEVrbNf722PuWIWN9EIBolULVAgMBAAGjgZowgZcwEgYDVR0TAQH/BAgw\n",
+ "BgEB/wIBATAxBgNVHR8EKjAoMCagJKAihiBodHRwOi8vbG9jYWxob3N0OjgwMDAv\n",
+ "Y2FfY3JsLmRlcjAdBgNVHQ4EFgQUh40vFgoopz5GUggPEEk2+bKgbwQwHwYDVR0j\n",
+ "BBgwFoAU12GJH5OWi3ZUFunld9x8t2UbgCQwDgYDVR0PAQH/BAQDAgGGMA0GCSqG\n",
+ "SIb3DQEBCwUAA4IBAQDANfJuTgo0vRaMPYqOeW8R4jLHdVazdGLeQQ/85vXr/Gl1\n",
+ "aL40tLp4yZbThxuxTzPzfY1OGkG69YQ/8Vo0gCEi5KjBMYPKmZISKy1MwROQ1Jfp\n",
+ "HkmyZk1TfuzG/4fN/bun2gjpDYcihf4xA4NhSVzQyvqm1N6VkTgK+bEWTOGzqw66\n",
+ "6IYPN6oVDmLbwU1EvV3rggB7HUJCJP4qW9DbAQRAijUurPUGoU2vEbrSyYkfQXCf\n",
+ "p4ouOTMl6O7bJ110SKzxbCfWqom+iAwHlU2tOPVmOp1CLDCClMRNHIFMDGAoBomH\n",
+ "s01wD+IcIi9OkQEbqVb/XDKes8fqzQgTtSM9C9Ot\n",
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
static const char *kBasicCRL[] = {
"-----BEGIN X509 CRL-----\n",
"MIIBpzCBkAIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n",
@@ -124,6 +189,24 @@ static const char *kBadIssuerCRL[] = {
NULL
};
+static const char *kEmptyIdpCRL[] = {
+ "-----BEGIN X509 CRL-----\n",
+ "MIICOTCCASECAQEwDQYJKoZIhvcNAQELBQAweTELMAkGA1UEBhMCVVMxEzARBgNV\n",
+ "BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEzARBgNVBAoM\n",
+ "Ck15IENvbXBhbnkxEzARBgNVBAMMCk15IFJvb3QgQ0ExEzARBgNVBAsMCk15IFJv\n",
+ "b3QgQ0EXDTI1MDEwMTAwMDAwMFoXDTI1MTIwMTAwMDAwMFowJzAlAhQcgAIu+B8k\n",
+ "Be6WphLcth/grHAeXhcNMjUwNDE3MTAxNjUxWqBLMEkwGAYDVR0UBBECDxnP/97a\n",
+ "dO3y9qRGDM7hQDAfBgNVHSMEGDAWgBTXYYkfk5aLdlQW6eV33Hy3ZRuAJDAMBgNV\n",
+ "HRwBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAf+mtlDi9IftsYwTcxYYKxE203\n",
+ "+prttFB00om29jjtkGYRxcs3vZQRTvera21YFn3mrS/lxvhBq6GMx0I61AQ48Pr4\n",
+ "63bDvZgf+/P6T2+MLgLds23o3TOfy2SBSdnFEcN0bFUgF5U0bFpQqlQWx+FYhrAf\n",
+ "ZX3RAhURiKKfGKGeVOVKS0u+x666FoDQ7pbhbHM3+jnuzdtv8RQMkj1AZMw0FMl8\n",
+ "m2dFQhZqT9WdJqZAc8ldc6V3a0rUeOV8BUPACf1k4B0CKhn4draIqltZkWgl3cmU\n",
+ "SX2V/a51lS12orfNYSEx+vtJ9gpx4LDxyOnai18vueVyljrXuQSrcYuxS2Cd\n",
+ "-----END X509 CRL-----\n",
+ NULL
+};
+
/*
* This is kBasicCRL but with a critical issuing distribution point
* extension.
@@ -189,6 +272,8 @@ static const char **unknown_critical_crls[] = {
static X509 *test_root = NULL;
static X509 *test_leaf = NULL;
+static X509 *test_root2 = NULL;
+static X509 *test_leaf2 = NULL;
/*
* Glue an array of strings together. Return a BIO and put the string
@@ -251,7 +336,7 @@ static X509 *X509_from_strings(const char **pem)
* Returns a value from X509_V_ERR_xxx or X509_V_OK.
*/
static int verify(X509 *leaf, X509 *root, STACK_OF(X509_CRL) *crls,
- unsigned long flags)
+ unsigned long flags, time_t verification_time)
{
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
X509_STORE *store = X509_STORE_new();
@@ -276,8 +361,8 @@ static int verify(X509 *leaf, X509 *root, STACK_OF(X509_CRL) *crls,
goto err;
X509_STORE_CTX_set0_trusted_stack(ctx, roots);
X509_STORE_CTX_set0_crls(ctx, crls);
- X509_VERIFY_PARAM_set_time(param, PARAM_TIME);
- if (!TEST_long_eq((long)X509_VERIFY_PARAM_get_time(param), PARAM_TIME))
+ X509_VERIFY_PARAM_set_time(param, verification_time);
+ if (!TEST_long_eq((long)X509_VERIFY_PARAM_get_time(param), (long)verification_time))
goto err;
X509_VERIFY_PARAM_set_depth(param, 16);
if (flags)
@@ -341,10 +426,11 @@ static int test_basic_crl(void)
&& TEST_ptr(revoked_crl)
&& TEST_int_eq(verify(test_leaf, test_root,
make_CRL_stack(basic_crl, NULL),
- X509_V_FLAG_CRL_CHECK), X509_V_OK)
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME), X509_V_OK)
&& TEST_int_eq(verify(test_leaf, test_root,
make_CRL_stack(basic_crl, revoked_crl),
- X509_V_FLAG_CRL_CHECK), X509_V_ERR_CERT_REVOKED);
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME),
+ X509_V_ERR_CERT_REVOKED);
X509_CRL_free(basic_crl);
X509_CRL_free(revoked_crl);
return r;
@@ -353,7 +439,7 @@ static int test_basic_crl(void)
static int test_no_crl(void)
{
return TEST_int_eq(verify(test_leaf, test_root, NULL,
- X509_V_FLAG_CRL_CHECK),
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME),
X509_V_ERR_UNABLE_TO_GET_CRL);
}
@@ -365,12 +451,26 @@ static int test_bad_issuer_crl(void)
r = TEST_ptr(bad_issuer_crl)
&& TEST_int_eq(verify(test_leaf, test_root,
make_CRL_stack(bad_issuer_crl, NULL),
- X509_V_FLAG_CRL_CHECK),
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME),
X509_V_ERR_UNABLE_TO_GET_CRL);
X509_CRL_free(bad_issuer_crl);
return r;
}
+static int test_crl_empty_idp(void)
+{
+ X509_CRL *empty_idp_crl = CRL_from_strings(kEmptyIdpCRL);
+ int r;
+
+ r = TEST_ptr(empty_idp_crl)
+ && TEST_int_eq(verify(test_leaf2, test_root2,
+ make_CRL_stack(empty_idp_crl, NULL),
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME2),
+ X509_V_ERR_UNABLE_TO_GET_CRL);
+ X509_CRL_free(empty_idp_crl);
+ return r;
+}
+
static int test_known_critical_crl(void)
{
X509_CRL *known_critical_crl = CRL_from_strings(kKnownCriticalCRL);
@@ -379,7 +479,7 @@ static int test_known_critical_crl(void)
r = TEST_ptr(known_critical_crl)
&& TEST_int_eq(verify(test_leaf, test_root,
make_CRL_stack(known_critical_crl, NULL),
- X509_V_FLAG_CRL_CHECK), X509_V_OK);
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME), X509_V_OK);
X509_CRL_free(known_critical_crl);
return r;
}
@@ -392,7 +492,7 @@ static int test_unknown_critical_crl(int n)
r = TEST_ptr(unknown_critical_crl)
&& TEST_int_eq(verify(test_leaf, test_root,
make_CRL_stack(unknown_critical_crl, NULL),
- X509_V_FLAG_CRL_CHECK),
+ X509_V_FLAG_CRL_CHECK, PARAM_TIME),
X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
X509_CRL_free(unknown_critical_crl);
return r;
@@ -412,7 +512,7 @@ static int test_reuse_crl(int idx)
if (idx & 1) {
if (!TEST_true(X509_CRL_up_ref(reused_crl)))
goto err;
- addref_crl = reused_crl;
+ addref_crl = reused_crl;
}
idx >>= 1;
@@ -455,12 +555,15 @@ static int test_reuse_crl(int idx)
int setup_tests(void)
{
if (!TEST_ptr(test_root = X509_from_strings(kCRLTestRoot))
- || !TEST_ptr(test_leaf = X509_from_strings(kCRLTestLeaf)))
+ || !TEST_ptr(test_leaf = X509_from_strings(kCRLTestLeaf))
+ || !TEST_ptr(test_root2 = X509_from_strings(kCRLTestRoot2))
+ || !TEST_ptr(test_leaf2 = X509_from_strings(kCRLTestLeaf2)))
return 0;
ADD_TEST(test_no_crl);
ADD_TEST(test_basic_crl);
ADD_TEST(test_bad_issuer_crl);
+ ADD_TEST(test_crl_empty_idp);
ADD_TEST(test_known_critical_crl);
ADD_ALL_TESTS(test_unknown_critical_crl, OSSL_NELEM(unknown_critical_crls));
ADD_ALL_TESTS(test_reuse_crl, 6);
@@ -471,4 +574,6 @@ void cleanup_tests(void)
{
X509_free(test_root);
X509_free(test_leaf);
+ X509_free(test_root2);
+ X509_free(test_leaf2);
}
diff --git a/test/dhtest.c b/test/dhtest.c
index bef706909c73..e12aa76fe40e 100644
--- a/test/dhtest.c
+++ b/test/dhtest.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -208,17 +208,17 @@ static int dh_test(void)
alen = DH_size(a);
if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
- || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
+ || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0))
goto err3;
blen = DH_size(b);
if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
- || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
+ || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0))
goto err3;
clen = DH_size(c);
if (!TEST_ptr(cbuf = OPENSSL_malloc(clen))
- || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
+ || !TEST_int_gt((cout = DH_compute_key(cbuf, apub_key, c)), 0))
goto err3;
if (!TEST_true(aout >= 20)
@@ -694,12 +694,12 @@ static int rfc7919_test(void)
alen = DH_size(a);
if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen))
- || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
+ || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0))
goto err;
blen = DH_size(b);
if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen))
- || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
+ || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0))
goto err;
if (!TEST_true(aout >= 20)
diff --git a/test/dtlstest.c b/test/dtlstest.c
index 011d8775c157..ecd15fa0bcd6 100644
--- a/test/dtlstest.c
+++ b/test/dtlstest.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -587,6 +587,105 @@ static int test_swap_records(int idx)
return testresult;
}
+static int test_duplicate_app_data(void)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *sssl = NULL, *cssl = NULL;
+ int testresult = 0;
+ BIO *bio;
+ char msg[] = { 0x00, 0x01, 0x02, 0x03 };
+ char buf[10];
+ int ret;
+
+ if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
+ DTLS_client_method(),
+ DTLS1_VERSION, 0,
+ &sctx, &cctx, cert, privkey)))
+ return 0;
+
+#ifndef OPENSSL_NO_DTLS1_2
+ if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA")))
+ goto end;
+#else
+ /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
+ if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA:@SECLEVEL=0"))
+ || !TEST_true(SSL_CTX_set_cipher_list(cctx,
+ "AES128-SHA:@SECLEVEL=0")))
+ goto end;
+#endif
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl,
+ NULL, NULL)))
+ goto end;
+
+ /* Send flight 1: ClientHello */
+ if (!TEST_int_le(SSL_connect(cssl), 0))
+ goto end;
+
+ /* Recv flight 1, send flight 2: ServerHello, Certificate, ServerHelloDone */
+ if (!TEST_int_le(SSL_accept(sssl), 0))
+ goto end;
+
+ /* Recv flight 2, send flight 3: ClientKeyExchange, CCS, Finished */
+ if (!TEST_int_le(SSL_connect(cssl), 0))
+ goto end;
+
+ /* Recv flight 3, send flight 4: datagram 0(NST, CCS) datagram 1(Finished) */
+ if (!TEST_int_gt(SSL_accept(sssl), 0))
+ goto end;
+
+ bio = SSL_get_wbio(sssl);
+ if (!TEST_ptr(bio))
+ goto end;
+
+ /*
+ * Send flight 4 (cont'd): datagram 2(app data)
+ * + datagram 3 (app data duplicate)
+ */
+ if (!TEST_int_eq(SSL_write(sssl, msg, sizeof(msg)), (int)sizeof(msg)))
+ goto end;
+
+ if (!TEST_true(mempacket_dup_last_packet(bio)))
+ goto end;
+
+ /* App data comes before NST/CCS */
+ if (!TEST_true(mempacket_move_packet(bio, 0, 2)))
+ goto end;
+
+ /*
+ * Recv flight 4 (datagram 2): app data + flight 4 (datagram 0): NST, CCS, +
+ * + flight 4 (datagram 1): Finished
+ */
+ if (!TEST_int_gt(SSL_connect(cssl), 0))
+ goto end;
+
+ /*
+ * Read flight 4 (app data)
+ */
+ if (!TEST_int_eq(SSL_read(cssl, buf, sizeof(buf)), (int)sizeof(msg)))
+ goto end;
+
+ if (!TEST_mem_eq(buf, sizeof(msg), msg, sizeof(msg)))
+ goto end;
+
+ /*
+ * Read flight 4, datagram 3. We expect the duplicated app data to have been
+ * dropped, with no more data available
+ */
+ if (!TEST_int_le(ret = SSL_read(cssl, buf, sizeof(buf)), 0)
+ || !TEST_int_eq(SSL_get_error(cssl, ret), SSL_ERROR_WANT_READ))
+ goto end;
+
+ testresult = 1;
+ end:
+ SSL_free(cssl);
+ SSL_free(sssl);
+ SSL_CTX_free(cctx);
+ SSL_CTX_free(sctx);
+
+ return testresult;
+}
+
/* Confirm that we can create a connections using DTLSv1_listen() */
static int test_listen(void)
{
@@ -658,6 +757,7 @@ int setup_tests(void)
ADD_TEST(test_just_finished);
ADD_ALL_TESTS(test_swap_records, 4);
ADD_TEST(test_listen);
+ ADD_TEST(test_duplicate_app_data);
return 1;
}
diff --git a/test/ectest.c b/test/ectest.c
index 70df89ee2f87..e1cb59d58dbb 100644
--- a/test/ectest.c
+++ b/test/ectest.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -2819,7 +2819,7 @@ static int custom_params_test(int id)
int is_prime = 0;
EC_KEY *eckey1 = NULL, *eckey2 = NULL;
EVP_PKEY *pkey1 = NULL, *pkey2 = NULL;
- EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL;
+ EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL, *dctx = NULL;
size_t sslen, t;
unsigned char *pub1 = NULL , *pub2 = NULL;
OSSL_PARAM_BLD *param_bld = NULL;
@@ -3042,11 +3042,12 @@ static int custom_params_test(int id)
EVP_PKEY_CTX_free(pctx1);
if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
|| !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
- || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
- || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1)
+ || !TEST_ptr(dctx = EVP_PKEY_CTX_dup(pctx1))
+ || !TEST_int_eq(EVP_PKEY_derive_set_peer_ex(dctx, pkey2, 1), 1)
+ || !TEST_int_eq(EVP_PKEY_derive(dctx, NULL, &t), 1)
|| !TEST_int_gt(bsize, t)
|| !TEST_int_le(sslen, t)
- || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1)
+ || !TEST_int_eq(EVP_PKEY_derive(dctx, buf1, &t), 1)
/* compare with previous result */
|| !TEST_mem_eq(buf1, t, buf2, sslen))
goto err;
@@ -3074,6 +3075,7 @@ static int custom_params_test(int id)
EVP_PKEY_free(pkey2);
EVP_PKEY_CTX_free(pctx1);
EVP_PKEY_CTX_free(pctx2);
+ EVP_PKEY_CTX_free(dctx);
return ret;
}
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index d6d973d5b925..2bcc2797aa69 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -3524,6 +3524,7 @@ static int test_empty_salt_info_HKDF(void)
size_t outlen;
int ret = 0;
unsigned char salt[] = "";
+ unsigned char fake[] = "0123456789";
unsigned char key[] = "012345678901234567890123456789";
unsigned char info[] = "";
const unsigned char expected[] = {
@@ -3540,6 +3541,8 @@ static int test_empty_salt_info_HKDF(void)
if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0)
+ || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, fake,
+ sizeof(fake) - 1), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt,
sizeof(salt) - 1), 0)
|| !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_key(pctx, key,
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index a51a4a3c073a..450195f998d8 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 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
@@ -2180,6 +2180,53 @@ err:
return ret;
}
+static const char *name_dup_algs[] = {
+#ifndef OPENSSL_NO_ECX
+ "ED25519",
+#endif
+#ifndef OPENSSL_NO_ML_KEM
+ "ML-KEM-512",
+#endif
+#ifndef OPENSSL_NO_ML_DSA
+ "ML-DSA-44",
+#endif
+ NULL
+};
+
+static int test_name_dup(int idx)
+{
+ const char *alg = name_dup_algs[idx];
+ EVP_PKEY *key = NULL;
+ EVP_PKEY_CTX *factory = NULL, *ctx = NULL;
+ int i, ret = 0;
+
+ if (alg == NULL
+ || (factory = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL)) == NULL)
+ return 1;
+ TEST_info("Testing fresh context dup for: %s", alg);
+
+ /* Run twice to check that *repeated* use works */
+ for (i = 0; i < 2; ++i) {
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(key);
+ key = NULL;
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_dup(factory))
+ || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
+ || !TEST_int_gt(EVP_PKEY_keygen(ctx, &key), 0)) {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+ ret = 1;
+
+ end:
+ EVP_PKEY_CTX_free(factory);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(key);
+
+ return ret;
+}
+
int setup_tests(void)
{
if (!test_skip_common_options()) {
@@ -2191,6 +2238,7 @@ int setup_tests(void)
return 0;
ADD_TEST(test_evp_pkey_ctx_dup_kdf);
+ ADD_ALL_TESTS(test_name_dup, OSSL_NELEM(name_dup_algs));
ADD_TEST(test_evp_pkey_get_bn_param_large);
ADD_TEST(test_fromdata_rsa);
ADD_TEST(test_fromdata_rsa_derive_from_pq_sp800);
diff --git a/test/evp_test.c b/test/evp_test.c
index e34ea1d96e67..9351e143883f 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -677,8 +677,10 @@ static int digest_test_init(EVP_TEST *t, const char *alg)
if ((digest = fetched_digest = EVP_MD_fetch(libctx, alg, propquery)) == NULL
&& (digest = EVP_get_digestbyname(alg)) == NULL)
return 0;
- if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat))))
+ if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat)))) {
+ EVP_MD_free(fetched_digest);
return 0;
+ }
t->data = mdat;
mdat->digest = digest;
mdat->fetched_digest = fetched_digest;
@@ -5359,7 +5361,9 @@ static int run_file_tests(int i)
clear_test(t);
free_key_list(public_keys);
+ public_keys = NULL;
free_key_list(private_keys);
+ private_keys = NULL;
BIO_free(t->s.key);
c = t->s.errors;
OPENSSL_free(t);
diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c
index c1b8e2828614..46fc9104ef95 100644
--- a/test/fake_rsaprov.c
+++ b/test/fake_rsaprov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2021-2025 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.
@@ -9,12 +9,15 @@
*/
#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
#include <openssl/core_names.h>
#include <openssl/core_object.h>
#include <openssl/rand.h>
#include <openssl/provider.h>
#include "testutil.h"
#include "fake_rsaprov.h"
+#include "internal/asn1.h"
static OSSL_FUNC_keymgmt_new_fn fake_rsa_keymgmt_new;
static OSSL_FUNC_keymgmt_free_fn fake_rsa_keymgmt_free;
@@ -32,6 +35,16 @@ static int exptypes_selection;
static int query_id;
static int key_deleted;
+typedef struct {
+ OSSL_LIB_CTX *libctx;
+} PROV_FAKE_RSA_CTX;
+
+#define PROV_FAKE_RSA_LIBCTX_OF(provctx) (((PROV_FAKE_RSA_CTX *)provctx)->libctx)
+
+#define FAKE_RSA_STATUS_IMPORTED 1
+#define FAKE_RSA_STATUS_GENERATED 2
+#define FAKE_RSA_STATUS_DECODED 3
+
struct fake_rsa_keydata {
int selection;
int status;
@@ -86,7 +99,7 @@ static int fake_rsa_keymgmt_import(void *keydata, int selection,
struct fake_rsa_keydata *fake_rsa_key = keydata;
/* key was imported */
- fake_rsa_key->status = 1;
+ fake_rsa_key->status = FAKE_RSA_STATUS_IMPORTED;
return 1;
}
@@ -219,11 +232,11 @@ static void *fake_rsa_keymgmt_load(const void *reference, size_t reference_sz)
{
struct fake_rsa_keydata *key = NULL;
- if (reference_sz != sizeof(*key))
+ if (reference_sz != sizeof(key))
return NULL;
key = *(struct fake_rsa_keydata **)reference;
- if (key->status != 1)
+ if (key->status != FAKE_RSA_STATUS_IMPORTED && key->status != FAKE_RSA_STATUS_DECODED)
return NULL;
/* detach the reference */
@@ -258,7 +271,7 @@ static void *fake_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
if (!TEST_ptr(keydata = fake_rsa_keymgmt_new(NULL)))
return NULL;
- keydata->status = 2;
+ keydata->status = FAKE_RSA_STATUS_GENERATED;
return keydata;
}
@@ -638,7 +651,7 @@ static int fake_rsa_st_load(void *loaderctx,
/* The address of the key becomes the octet string */
params[2] =
OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
- &key, sizeof(*key));
+ &key, sizeof(key));
params[3] = OSSL_PARAM_construct_end();
rv = object_cb(params, object_cbarg);
*storectx = 1;
@@ -702,6 +715,502 @@ static const OSSL_ALGORITHM fake_rsa_store_algs[] = {
{ NULL, NULL, NULL }
};
+struct der2key_ctx_st; /* Forward declaration */
+typedef int check_key_fn(void *, struct der2key_ctx_st *ctx);
+typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx);
+typedef void free_key_fn(void *);
+typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long,
+ struct der2key_ctx_st *);
+struct keytype_desc_st {
+ const char *keytype_name;
+ const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */
+
+ /* The input structure name */
+ const char *structure_name;
+
+ /*
+ * The EVP_PKEY_xxx type macro. Should be zero for type specific
+ * structures, non-zero when the outermost structure is PKCS#8 or
+ * SubjectPublicKeyInfo. This determines which of the function
+ * pointers below will be used.
+ */
+ int evp_type;
+
+ /* The selection mask for OSSL_FUNC_decoder_does_selection() */
+ int selection_mask;
+
+ /* For type specific decoders, we use the corresponding d2i */
+ d2i_of_void *d2i_private_key; /* From type-specific DER */
+ d2i_of_void *d2i_public_key; /* From type-specific DER */
+ d2i_of_void *d2i_key_params; /* From type-specific DER */
+ d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PrivateKeyInfo */
+ d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */
+
+ /*
+ * For any key, we may need to check that the key meets expectations.
+ * This is useful when the same functions can decode several variants
+ * of a key.
+ */
+ check_key_fn *check_key;
+
+ /*
+ * For any key, we may need to make provider specific adjustments, such
+ * as ensure the key carries the correct library context.
+ */
+ adjust_key_fn *adjust_key;
+ /* {type}_free() */
+ free_key_fn *free_key;
+};
+
+/*
+ * Start blatant code steal. Alternative: Open up d2i_X509_PUBKEY_INTERNAL
+ * as per https://github.com/openssl/openssl/issues/16697 (TBD)
+ * Code from openssl/crypto/x509/x_pubkey.c as
+ * ossl_d2i_X509_PUBKEY_INTERNAL is presently not public
+ */
+struct X509_pubkey_st {
+ X509_ALGOR *algor;
+ ASN1_BIT_STRING *public_key;
+
+ EVP_PKEY *pkey;
+
+ /* extra data for the callback, used by d2i_PUBKEY_ex */
+ OSSL_LIB_CTX *libctx;
+ char *propq;
+};
+
+ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = {
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL)
+
+static X509_PUBKEY *fake_rsa_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp,
+ long len, OSSL_LIB_CTX *libctx)
+{
+ X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub));
+
+ if (xpub == NULL)
+ return NULL;
+ return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len,
+ ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
+ libctx, NULL);
+}
+/* end steal https://github.com/openssl/openssl/issues/16697 */
+
+/*
+ * Context used for DER to key decoding.
+ */
+struct der2key_ctx_st {
+ PROV_FAKE_RSA_CTX *provctx;
+ struct keytype_desc_st *desc;
+ /* The selection that is passed to fake_rsa_der2key_decode() */
+ int selection;
+ /* Flag used to signal that a failure is fatal */
+ unsigned int flag_fatal : 1;
+};
+
+static int fake_rsa_read_der(PROV_FAKE_RSA_CTX *provctx, OSSL_CORE_BIO *cin,
+ unsigned char **data, long *len)
+{
+ BUF_MEM *mem = NULL;
+ BIO *in = BIO_new_from_core_bio(provctx->libctx, cin);
+ int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+
+ if (ok) {
+ *data = (unsigned char *)mem->data;
+ *len = (long)mem->length;
+ OPENSSL_free(mem);
+ }
+ BIO_free(in);
+ return ok;
+}
+
+typedef void *key_from_pkcs8_t(const PKCS8_PRIV_KEY_INFO *p8inf,
+ OSSL_LIB_CTX *libctx, const char *propq);
+static void *fake_rsa_der2key_decode_p8(const unsigned char **input_der,
+ long input_der_len, struct der2key_ctx_st *ctx,
+ key_from_pkcs8_t *key_from_pkcs8)
+{
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ const X509_ALGOR *alg = NULL;
+ void *key = NULL;
+
+ if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len)) != NULL
+ && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)
+ && OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type)
+ key = key_from_pkcs8(p8inf, PROV_FAKE_RSA_LIBCTX_OF(ctx->provctx), NULL);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+
+ return key;
+}
+
+static struct fake_rsa_keydata *fake_rsa_d2i_PUBKEY(struct fake_rsa_keydata **a,
+ const unsigned char **pp, long length)
+{
+ struct fake_rsa_keydata *key = NULL;
+ X509_PUBKEY *xpk;
+
+ xpk = fake_rsa_d2i_X509_PUBKEY_INTERNAL(pp, length, NULL);
+ if (xpk == NULL)
+ goto err_exit;
+
+ key = fake_rsa_keymgmt_new(NULL);
+ if (key == NULL)
+ goto err_exit;
+
+ key->status = FAKE_RSA_STATUS_DECODED;
+
+ if (a != NULL) {
+ fake_rsa_keymgmt_free(*a);
+ *a = key;
+ }
+
+err_exit:
+ X509_PUBKEY_free(xpk);
+ return key;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
+static OSSL_FUNC_decoder_decode_fn fake_rsa_der2key_decode;
+static OSSL_FUNC_decoder_export_object_fn der2key_export_object;
+
+static struct der2key_ctx_st *
+der2key_newctx(void *provctx, struct keytype_desc_st *desc, const char *tls_name)
+{
+ struct der2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ if (ctx != NULL) {
+ ctx->provctx = provctx;
+ ctx->desc = desc;
+ if (desc->evp_type == 0)
+ ctx->desc->evp_type = OBJ_sn2nid(tls_name);
+ }
+ return ctx;
+}
+
+static void der2key_freectx(void *vctx)
+{
+ struct der2key_ctx_st *ctx = vctx;
+
+ OPENSSL_free(ctx);
+}
+
+static int der2key_check_selection(int selection,
+ const struct keytype_desc_st *desc)
+{
+ /*
+ * The selections are kinda sorta "levels", i.e. each selection given
+ * here is assumed to include those following.
+ */
+ int checks[] = {
+ OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
+ OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+ };
+ size_t i;
+
+ /* The decoder implementations made here support guessing */
+ if (selection == 0)
+ return 1;
+
+ for (i = 0; i < OSSL_NELEM(checks); i++) {
+ int check1 = (selection & checks[i]) != 0;
+ int check2 = (desc->selection_mask & checks[i]) != 0;
+
+ /*
+ * If the caller asked for the currently checked bit(s), return
+ * whether the decoder description says it's supported.
+ */
+ if (check1)
+ return check2;
+ }
+
+ /* This should be dead code, but just to be safe... */
+ return 0;
+}
+
+static int fake_rsa_der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
+ OSSL_CALLBACK *data_cb, void *data_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+ struct der2key_ctx_st *ctx = vctx;
+ unsigned char *der = NULL;
+ const unsigned char *derp;
+ long der_len = 0;
+ void *key = NULL;
+ int ok = 0;
+
+ ctx->selection = selection;
+ /*
+ * The caller is allowed to specify 0 as a selection mark, to have the
+ * structure and key type guessed. For type-specific structures, this
+ * is not recommended, as some structures are very similar.
+ * Note that 0 isn't the same as OSSL_KEYMGMT_SELECT_ALL, as the latter
+ * signifies a private key structure, where everything else is assumed
+ * to be present as well.
+ */
+ if (selection == 0)
+ selection = ctx->desc->selection_mask;
+ if ((selection & ctx->desc->selection_mask) == 0) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+
+ ok = fake_rsa_read_der(ctx->provctx, cin, &der, &der_len);
+ if (!ok)
+ goto next;
+
+ ok = 0; /* Assume that we fail */
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ derp = der;
+ if (ctx->desc->d2i_PKCS8 != NULL) {
+ key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx);
+ if (ctx->flag_fatal)
+ goto end;
+ } else if (ctx->desc->d2i_private_key != NULL) {
+ key = ctx->desc->d2i_private_key(NULL, &derp, der_len);
+ }
+ if (key == NULL && ctx->selection != 0)
+ goto next;
+ }
+ if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ derp = der;
+ if (ctx->desc->d2i_PUBKEY != NULL)
+ key = ctx->desc->d2i_PUBKEY(NULL, &derp, der_len);
+ else
+ key = ctx->desc->d2i_public_key(NULL, &derp, der_len);
+ if (key == NULL && ctx->selection != 0)
+ goto next;
+ }
+ if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) {
+ derp = der;
+ if (ctx->desc->d2i_key_params != NULL)
+ key = ctx->desc->d2i_key_params(NULL, &derp, der_len);
+ if (key == NULL && ctx->selection != 0)
+ goto next;
+ }
+
+ /*
+ * Last minute check to see if this was the correct type of key. This
+ * should never lead to a fatal error, i.e. the decoding itself was
+ * correct, it was just an unexpected key type. This is generally for
+ * classes of key types that have subtle variants, like RSA-PSS keys as
+ * opposed to plain RSA keys.
+ */
+ if (key != NULL
+ && ctx->desc->check_key != NULL
+ && !ctx->desc->check_key(key, ctx)) {
+ ctx->desc->free_key(key);
+ key = NULL;
+ }
+
+ if (key != NULL && ctx->desc->adjust_key != NULL)
+ ctx->desc->adjust_key(key, ctx);
+
+ next:
+ /*
+ * Indicated that we successfully decoded something, or not at all.
+ * Ending up "empty handed" is not an error.
+ */
+ ok = 1;
+
+ /*
+ * We free memory here so it's not held up during the callback, because
+ * we know the process is recursive and the allocated chunks of memory
+ * add up.
+ */
+ OPENSSL_free(der);
+ der = NULL;
+
+ if (key != NULL) {
+ OSSL_PARAM params[4];
+ int object_type = OSSL_OBJECT_PKEY;
+
+ params[0] =
+ OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
+ params[1] =
+ OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+ (char *)ctx->desc->keytype_name,
+ 0);
+ /* The address of the key becomes the octet string */
+ params[2] =
+ OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
+ &key, sizeof(key));
+ params[3] = OSSL_PARAM_construct_end();
+
+ ok = data_cb(params, data_cbarg);
+ }
+
+ end:
+ ctx->desc->free_key(key);
+ OPENSSL_free(der);
+
+ return ok;
+}
+
+static OSSL_FUNC_keymgmt_export_fn *
+fake_rsa_prov_get_keymgmt_export(const OSSL_DISPATCH *fns)
+{
+ /* Pilfer the keymgmt dispatch table */
+ for (; fns->function_id != 0; fns++)
+ if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT)
+ return OSSL_FUNC_keymgmt_export(fns);
+
+ return NULL;
+}
+
+static int der2key_export_object(void *vctx,
+ const void *reference, size_t reference_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg)
+{
+ struct der2key_ctx_st *ctx = vctx;
+ OSSL_FUNC_keymgmt_export_fn *export = fake_rsa_prov_get_keymgmt_export(ctx->desc->fns);
+ void *keydata;
+
+ if (reference_sz == sizeof(keydata) && export != NULL) {
+ /* The contents of the reference is the address to our object */
+ keydata = *(void **)reference;
+
+ return export(keydata, ctx->selection, export_cb, export_cbarg);
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct fake_rsa_keydata *fake_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ struct fake_rsa_keydata *key = fake_rsa_keymgmt_new(NULL);
+
+ if (key)
+ key->status = FAKE_RSA_STATUS_DECODED;
+ return key;
+}
+
+#define rsa_evp_type EVP_PKEY_RSA
+
+static void *fake_rsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
+ struct der2key_ctx_st *ctx)
+{
+ return fake_rsa_der2key_decode_p8(der, der_len, ctx,
+ (key_from_pkcs8_t *)fake_rsa_key_from_pkcs8);
+}
+
+static void fake_rsa_key_adjust(void *key, struct der2key_ctx_st *ctx)
+{
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define DO_PrivateKeyInfo(keytype) \
+ "PrivateKeyInfo", keytype##_evp_type, \
+ (OSSL_KEYMGMT_SELECT_PRIVATE_KEY), \
+ NULL, \
+ NULL, \
+ NULL, \
+ fake_rsa_d2i_PKCS8, \
+ NULL, \
+ NULL, \
+ fake_rsa_key_adjust, \
+ (free_key_fn *)fake_rsa_keymgmt_free
+
+#define DO_SubjectPublicKeyInfo(keytype) \
+ "SubjectPublicKeyInfo", keytype##_evp_type, \
+ (OSSL_KEYMGMT_SELECT_PUBLIC_KEY), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ (d2i_of_void *)fake_rsa_d2i_PUBKEY, \
+ NULL, \
+ fake_rsa_key_adjust, \
+ (free_key_fn *)fake_rsa_keymgmt_free
+
+/*
+ * MAKE_DECODER is the single driver for creating OSSL_DISPATCH tables.
+ * It takes the following arguments:
+ *
+ * keytype_name The implementation key type as a string.
+ * keytype The implementation key type. This must correspond exactly
+ * to our existing keymgmt keytype names... in other words,
+ * there must exist an ossl_##keytype##_keymgmt_functions.
+ * type The type name for the set of functions that implement the
+ * decoder for the key type. This isn't necessarily the same
+ * as keytype. For example, the key types ed25519, ed448,
+ * x25519 and x448 are all handled by the same functions with
+ * the common type name ecx.
+ * kind The kind of support to implement. This translates into
+ * the DO_##kind macros above, to populate the keytype_desc_st
+ * structure.
+ */
+#define MAKE_DECODER(keytype_name, keytype, type, kind) \
+ static struct keytype_desc_st kind##_##keytype##_desc = \
+ { keytype_name, fake_rsa_keymgmt_funcs, \
+ DO_##kind(keytype) }; \
+ \
+ static OSSL_FUNC_decoder_newctx_fn kind##_der2##keytype##_newctx; \
+ \
+ static void *kind##_der2##keytype##_newctx(void *provctx) \
+ { \
+ return der2key_newctx(provctx, &kind##_##keytype##_desc, keytype_name);\
+ } \
+ static int kind##_der2##keytype##_does_selection(void *provctx, \
+ int selection) \
+ { \
+ return der2key_check_selection(selection, \
+ &kind##_##keytype##_desc); \
+ } \
+ static const OSSL_DISPATCH \
+ fake_rsa_##kind##_der_to_##keytype##_decoder_functions[] = { \
+ { OSSL_FUNC_DECODER_NEWCTX, \
+ (void (*)(void))kind##_der2##keytype##_newctx }, \
+ { OSSL_FUNC_DECODER_FREECTX, \
+ (void (*)(void))der2key_freectx }, \
+ { OSSL_FUNC_DECODER_DOES_SELECTION, \
+ (void (*)(void))kind##_der2##keytype##_does_selection }, \
+ { OSSL_FUNC_DECODER_DECODE, \
+ (void (*)(void))fake_rsa_der2key_decode }, \
+ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \
+ (void (*)(void))der2key_export_object }, \
+ OSSL_DISPATCH_END \
+ }
+
+MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo);
+MAKE_DECODER("RSA", rsa, rsa, SubjectPublicKeyInfo);
+
+static const OSSL_ALGORITHM fake_rsa_decoder_algs[] = {
+#define DECODER_PROVIDER "fake-rsa"
+#define DECODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo"
+#define DECODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo"
+
+/* Arguments are prefixed with '_' to avoid build breaks on certain platforms */
+/*
+ * Obviously this is not FIPS approved, but in order to test in conjunction
+ * with the FIPS provider we pretend that it is.
+ */
+
+#define DECODER(_name, _input, _output) \
+ { _name, \
+ "provider=" DECODER_PROVIDER ",fips=yes,input=" #_input, \
+ (fake_rsa_##_input##_to_##_output##_decoder_functions) \
+ }
+#define DECODER_w_structure(_name, _input, _structure, _output) \
+ { _name, \
+ "provider=" DECODER_PROVIDER ",fips=yes,input=" #_input \
+ ",structure=" DECODER_STRUCTURE_##_structure, \
+ (fake_rsa_##_structure##_##_input##_to_##_output##_decoder_functions) \
+ }
+
+DECODER_w_structure("RSA:rsaEncryption", der, PrivateKeyInfo, rsa),
+DECODER_w_structure("RSA:rsaEncryption", der, SubjectPublicKeyInfo, rsa),
+#undef DECODER_PROVIDER
+ { NULL, NULL, NULL }
+};
+
static const OSSL_ALGORITHM *fake_rsa_query(void *provctx,
int operation_id,
int *no_cache)
@@ -716,13 +1225,24 @@ static const OSSL_ALGORITHM *fake_rsa_query(void *provctx,
case OSSL_OP_STORE:
return fake_rsa_store_algs;
+
+ case OSSL_OP_DECODER:
+ return fake_rsa_decoder_algs;
}
return NULL;
}
+static void fake_rsa_prov_teardown(void *provctx)
+{
+ PROV_FAKE_RSA_CTX *pctx = (PROV_FAKE_RSA_CTX *)provctx;
+
+ OSSL_LIB_CTX_free(pctx->libctx);
+ OPENSSL_free(pctx);
+}
+
/* Functions we provide to the core */
static const OSSL_DISPATCH fake_rsa_method[] = {
- { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free },
+ { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fake_rsa_prov_teardown },
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fake_rsa_query },
OSSL_DISPATCH_END
};
@@ -731,8 +1251,20 @@ static int fake_rsa_provider_init(const OSSL_CORE_HANDLE *handle,
const OSSL_DISPATCH *in,
const OSSL_DISPATCH **out, void **provctx)
{
- if (!TEST_ptr(*provctx = OSSL_LIB_CTX_new()))
+ OSSL_LIB_CTX *libctx;
+ PROV_FAKE_RSA_CTX *prov_ctx;
+
+ if (!TEST_ptr(libctx = OSSL_LIB_CTX_new_from_dispatch(handle, in)))
+ return 0;
+
+ if (!TEST_ptr(prov_ctx = OPENSSL_malloc(sizeof(*prov_ctx)))) {
+ OSSL_LIB_CTX_free(libctx);
return 0;
+ }
+
+ prov_ctx->libctx = libctx;
+
+ *provctx = prov_ctx;
*out = fake_rsa_method;
return 1;
}
diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c
index 032505a65e20..420d3b5acd58 100644
--- a/test/helpers/quictestlib.c
+++ b/test/helpers/quictestlib.c
@@ -72,6 +72,12 @@ struct qtest_fault {
struct noise_args_data_st noiseargs;
};
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+static int client_ready = 0;
+static CRYPTO_CONDVAR *client_ready_cond = NULL;
+static CRYPTO_MUTEX *client_ready_mutex = NULL;
+#endif
+
static void packet_plain_finish(void *arg);
static void handshake_finish(void *arg);
static OSSL_TIME qtest_get_time(void);
@@ -136,16 +142,28 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
BIO *tmpbio = NULL;
QTEST_DATA *bdata = NULL;
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+ if (client_ready_cond == NULL) {
+ client_ready_cond = ossl_crypto_condvar_new();
+ if (client_ready_cond == NULL)
+ return 0;
+ }
+
+ if (client_ready_mutex == NULL) {
+ client_ready_mutex = ossl_crypto_mutex_new();
+ if (client_ready_mutex == NULL) {
+ ossl_crypto_condvar_free(&client_ready_cond);
+ client_ready_cond = NULL;
+ return 0;
+ }
+ }
+#endif
+
bdata = OPENSSL_zalloc(sizeof(QTEST_DATA));
if (bdata == NULL)
return 0;
*qtserv = NULL;
- if (*cssl == NULL) {
- *cssl = SSL_new(clientctx);
- if (!TEST_ptr(*cssl))
- return 0;
- }
if (fault != NULL) {
*fault = OPENSSL_zalloc(sizeof(**fault));
@@ -154,6 +172,12 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
bdata->fault = *fault;
}
+ if (*cssl == NULL) {
+ *cssl = SSL_new(clientctx);
+ if (!TEST_ptr(*cssl))
+ goto err;
+ }
+
#ifndef OPENSSL_NO_SSL_TRACE
if ((flags & QTEST_FLAG_CLIENT_TRACE) != 0) {
tmpbio = BIO_new_fp(stdout, BIO_NOCLOSE);
@@ -433,7 +457,6 @@ static int globserverret = 0;
static TSAN_QUALIFIER int abortserverthread = 0;
static QUIC_TSERVER *globtserv;
static const thread_t thread_zero;
-
static void run_server_thread(void)
{
/*
@@ -495,6 +518,7 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
int retc = -1, rets = 0, abortctr = 0, ret = 0;
int clienterr = 0, servererr = 0;
#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+
/*
* Pointless initialisation to avoid bogus compiler warnings about using
* t uninitialised
@@ -503,6 +527,15 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
if (clientssl != NULL)
abortserverthread = 0;
+
+ /*
+ * Only set the client_ready flag to zero if we are the client
+ */
+ if (clientssl != NULL) {
+ ossl_crypto_mutex_lock(client_ready_mutex);
+ client_ready = 0;
+ ossl_crypto_mutex_unlock(client_ready_mutex);
+ }
#endif
if (!TEST_ptr(qtserv)) {
@@ -531,6 +564,12 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
if (!clienterr && retc <= 0) {
int err;
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+ ossl_crypto_mutex_lock(client_ready_mutex);
+ client_ready = 1;
+ ossl_crypto_condvar_broadcast(client_ready_cond);
+ ossl_crypto_mutex_unlock(client_ready_mutex);
+#endif
retc = SSL_connect(clientssl);
if (retc <= 0) {
err = SSL_get_error(clientssl, retc);
@@ -557,8 +596,18 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
qtest_add_time(1);
if (clientssl != NULL)
SSL_handle_events(clientssl);
- if (qtserv != NULL)
+ if (qtserv != NULL) {
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+ ossl_crypto_mutex_lock(client_ready_mutex);
+ for (;;) {
+ if (client_ready == 1)
+ break;
+ ossl_crypto_condvar_wait(client_ready_cond, client_ready_mutex);
+ }
+ ossl_crypto_mutex_unlock(client_ready_mutex);
+#endif
ossl_quic_tserver_tick(qtserv);
+ }
if (!servererr && rets <= 0) {
servererr = ossl_quic_tserver_is_term_any(qtserv);
@@ -587,6 +636,14 @@ int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
if (qtserv == NULL && rets > 0) {
#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+ /*
+ * Make sure we unblock the server before we wait on completion here
+ * in case it didn't happen in the connect loop above
+ */
+ ossl_crypto_mutex_lock(client_ready_mutex);
+ client_ready = 1;
+ ossl_crypto_condvar_broadcast(client_ready_cond);
+ ossl_crypto_mutex_unlock(client_ready_mutex);
if (!TEST_true(wait_for_thread(t)) || !TEST_true(globserverret))
goto err;
#else
@@ -632,6 +689,11 @@ int qtest_shutdown(QUIC_TSERVER *qtserv, SSL *clientssl)
* t uninitialised
*/
thread_t t = thread_zero;
+
+ ossl_crypto_condvar_free(&client_ready_cond);
+ client_ready_cond = NULL;
+ ossl_crypto_mutex_free(&client_ready_mutex);
+ client_ready_mutex = NULL;
#endif
if (SSL_get_blocking_mode(clientssl) > 0) {
diff --git a/test/helpers/ssltestlib.c b/test/helpers/ssltestlib.c
index e9a51c9c30d0..56d526f7525e 100644
--- a/test/helpers/ssltestlib.c
+++ b/test/helpers/ssltestlib.c
@@ -536,6 +536,40 @@ int mempacket_move_packet(BIO *bio, int d, int s)
return 1;
}
+int mempacket_dup_last_packet(BIO *bio)
+{
+ MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
+ MEMPACKET *thispkt, *duppkt;
+ int numpkts = sk_MEMPACKET_num(ctx->pkts);
+
+ /* We can only duplicate a packet if there is at least 1 pending */
+ if (numpkts <= 0)
+ return 0;
+
+ /* Get the last packet */
+ thispkt = sk_MEMPACKET_value(ctx->pkts, numpkts - 1);
+ if (thispkt == NULL)
+ return 0;
+
+ duppkt = OPENSSL_malloc(sizeof(*duppkt));
+ if (duppkt == NULL)
+ return 0;
+
+ *duppkt = *thispkt;
+ duppkt->data = OPENSSL_memdup(thispkt->data, thispkt->len);
+ if (duppkt->data == NULL) {
+ mempacket_free(duppkt);
+ return 0;
+ }
+ duppkt->num++;
+ if (sk_MEMPACKET_insert(ctx->pkts, duppkt, numpkts) <= 0) {
+ mempacket_free(duppkt);
+ return 0;
+ }
+
+ return 1;
+}
+
int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
int type)
{
@@ -1224,12 +1258,13 @@ int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
* has SSL_get_error() return the value in the |want| parameter. The connection
* attempt could be restarted by a subsequent call to this function.
*/
-int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
- int read, int listen)
+int create_bare_ssl_connection_ex(SSL *serverssl, SSL *clientssl, int want,
+ int read, int listen, int *cm_count, int *sm_count)
{
int retc = -1, rets = -1, err, abortctr = 0, ret = 0;
int clienterr = 0, servererr = 0;
int isdtls = SSL_is_dtls(serverssl);
+ int icm_count = 0, ism_count = 0;
#ifndef OPENSSL_NO_SOCK
BIO_ADDR *peer = NULL;
@@ -1255,6 +1290,7 @@ int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
retc = SSL_connect(clientssl);
if (retc <= 0)
err = SSL_get_error(clientssl, retc);
+ icm_count++;
}
if (!clienterr && retc <= 0 && err != SSL_ERROR_WANT_READ) {
@@ -1280,12 +1316,14 @@ int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
listen = 0;
rets = 0;
}
+ ism_count++;
} else
#endif
{
rets = SSL_accept(serverssl);
if (rets <= 0)
err = SSL_get_error(serverssl, rets);
+ ism_count++;
}
}
@@ -1311,6 +1349,7 @@ int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
TEST_info("Unexpected SSL_read() success!");
goto err;
}
+ ism_count++;
}
if (retc > 0 && rets <= 0) {
if (SSL_read(clientssl, buf, sizeof(buf)) > 0) {
@@ -1318,6 +1357,7 @@ int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
TEST_info("Unexpected SSL_read() success!");
goto err;
}
+ icm_count++;
}
}
if (++abortctr == MAXLOOPS) {
@@ -1336,23 +1376,36 @@ int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
ret = 1;
err:
+ if (cm_count != NULL)
+ *cm_count = icm_count;
+ if (sm_count != NULL)
+ *sm_count = ism_count;
#ifndef OPENSSL_NO_SOCK
BIO_ADDR_free(peer);
#endif
return ret;
}
+int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
+ int read, int listen)
+{
+ return create_bare_ssl_connection_ex(serverssl, clientssl, want, read,
+ listen, NULL, NULL);
+}
+
/*
* Create an SSL connection including any post handshake NewSessionTicket
* messages.
*/
-int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
+int create_ssl_connection_ex(SSL *serverssl, SSL *clientssl, int want,
+ int *cm_count, int *sm_count)
{
int i;
unsigned char buf;
size_t readbytes;
- if (!create_bare_ssl_connection(serverssl, clientssl, want, 1, 0))
+ if (!create_bare_ssl_connection_ex(serverssl, clientssl, want, 1, 0,
+ cm_count, sm_count))
return 0;
/*
@@ -1368,11 +1421,18 @@ int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
SSL_ERROR_WANT_READ)) {
return 0;
}
+ if (cm_count != NULL)
+ (*cm_count)++;
}
return 1;
}
+int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
+{
+ return create_ssl_connection_ex(serverssl, clientssl, want, NULL, NULL);
+}
+
void shutdown_ssl_connection(SSL *serverssl, SSL *clientssl)
{
SSL_shutdown(clientssl);
diff --git a/test/helpers/ssltestlib.h b/test/helpers/ssltestlib.h
index 5369bb6e9250..557b820efb5b 100644
--- a/test/helpers/ssltestlib.h
+++ b/test/helpers/ssltestlib.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2025 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
@@ -28,11 +28,15 @@ int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio);
int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
int read, int listen);
+int create_bare_ssl_connection_ex(SSL *serverssl, SSL *clientssl, int want,
+ int read, int listen, int *cm_count, int *sm_count);
int create_ssl_objects2(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
SSL **cssl, int sfd, int cfd);
int wait_until_sock_readable(int sock);
int create_test_sockets(int *cfdp, int *sfdp, int socktype, BIO_ADDR *saddr);
int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want);
+int create_ssl_connection_ex(SSL *serverssl, SSL *clientssl, int want,
+ int *cm_count, int *sm_count);
void shutdown_ssl_connection(SSL *serverssl, SSL *clientssl);
/* Note: Not thread safe! */
@@ -70,6 +74,7 @@ void bio_s_maybe_retry_free(void);
int mempacket_swap_epoch(BIO *bio);
int mempacket_move_packet(BIO *bio, int d, int s);
+int mempacket_dup_last_packet(BIO *bio);
int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
int type);
diff --git a/test/hmactest.c b/test/hmactest.c
index 28aba7f6309a..9ff180e21009 100644
--- a/test/hmactest.c
+++ b/test/hmactest.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 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
@@ -214,6 +214,29 @@ static int test_hmac_single_shot(void)
return 1;
}
+/* https://github.com/openssl/openssl/issues/13210 */
+static int test_hmac_final_update_fail(void)
+{
+ HMAC_CTX *ctx = NULL;
+ unsigned char buf[EVP_MAX_MD_SIZE];
+ unsigned int len;
+ int ret = 0;
+
+ /* HMAC_Update() after HMAC_Final() must return an error. */
+ if (!TEST_ptr(ctx = HMAC_CTX_new()))
+ goto err;
+ if (!TEST_true(HMAC_Init_ex(ctx, test[5].key, test[5].key_len, EVP_sha256(), NULL))
+ || !TEST_true(HMAC_Update(ctx, test[5].data, test[5].data_len))
+ || !TEST_true(HMAC_Final(ctx, buf, &len))
+ || !TEST_false(HMAC_Update(ctx, test[5].data, test[5].data_len))
+ || !TEST_false(HMAC_Final(ctx, buf, &len)))
+ goto err;
+
+ ret = 1;
+err:
+ HMAC_CTX_free(ctx);
+ return ret;
+}
static int test_hmac_copy(void)
{
@@ -435,6 +458,7 @@ int setup_tests(void)
ADD_TEST(test_hmac_single_shot);
ADD_TEST(test_hmac_bad);
ADD_TEST(test_hmac_run);
+ ADD_TEST(test_hmac_final_update_fail);
ADD_TEST(test_hmac_copy);
ADD_TEST(test_hmac_copy_uninited);
ADD_ALL_TESTS(test_hmac_chunks,
diff --git a/test/http_test.c b/test/http_test.c
index 548af69535a5..050db5b223a8 100644
--- a/test/http_test.c
+++ b/test/http_test.c
@@ -332,6 +332,16 @@ static int test_http_url_dns(void)
return test_http_url_ok("host:65535/path", 0, "host", "65535", "/path");
}
+static int test_http_url_timestamp(void)
+{
+ return test_http_url_ok("host/p/2017-01-03T00:00:00", 0, "host", "80",
+ "/p/2017-01-03T00:00:00")
+ && test_http_url_ok("http://host/p/2017-01-03T00:00:00", 0, "host",
+ "80", "/p/2017-01-03T00:00:00")
+ && test_http_url_ok("https://host/p/2017-01-03T00:00:00", 1, "host",
+ "443", "/p/2017-01-03T00:00:00");
+}
+
static int test_http_url_path_query(void)
{
return test_http_url_path_query_ok("http://usr@host:1/p?q=x#frag", "/p?q=x")
@@ -559,6 +569,7 @@ int setup_tests(void)
return 0;
ADD_TEST(test_http_url_dns);
+ ADD_TEST(test_http_url_timestamp);
ADD_TEST(test_http_url_path_query);
ADD_TEST(test_http_url_userinfo_query_fragment);
ADD_TEST(test_http_url_ipv4);
diff --git a/test/json_test.c b/test/json_test.c
index 33d9522dd07b..12a3ae4e39da 100644
--- a/test/json_test.c
+++ b/test/json_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -119,7 +119,6 @@ typedef void (*fp_pz_type)(OSSL_JSON_ENC *, const void *, size_t);
#define OPJ_BOOL(x) OP_CALL_I(ossl_json_bool, (x))
#define OPJ_U64(x) OP_CALL_U64(ossl_json_u64, (x))
#define OPJ_I64(x) OP_CALL_I64(ossl_json_i64, (x))
-#define OPJ_F64(x) OP_CALL_D(ossl_json_f64, (x))
#define OPJ_KEY(x) OP_CALL_P(ossl_json_key, (x))
#define OPJ_STR(x) OP_CALL_P(ossl_json_str, (x))
#define OPJ_STR_LEN(x, xl) OP_CALL_PZ(ossl_json_str_len, (x), (xl))
diff --git a/test/ossl_store_test.c b/test/ossl_store_test.c
index ba1bc6fdc50f..bc5c598b34ae 100644
--- a/test/ossl_store_test.c
+++ b/test/ossl_store_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 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
@@ -58,6 +58,75 @@ static int test_store_open(void)
return ret;
}
+#ifndef OPENSSL_NO_WINSTORE
+/*
+ * This is the one of the root certificate authorities from the
+ * microsoft cert store. We use it to extract the subject name
+ * so that we can search for it in the store
+ */
+static const unsigned char mscert[] = {
+ 0x30, 0x82, 0x01, 0x3b, 0x30, 0x81, 0xee, 0xa0, 0x03, 0x02, 0x01, 0x02,
+ 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x30, 0x81,
+ 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+ 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31,
+ 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
+ 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
+ 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
+ 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29,
+ 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x52, 0x6f,
+ 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+ 0x20, 0x32, 0x30, 0x31, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x35, 0x30,
+ 0x34, 0x32, 0x39, 0x30, 0x35, 0x34, 0x33, 0x33, 0x30, 0x5a, 0x18, 0x0f,
+ 0x32, 0x31, 0x32, 0x35, 0x30, 0x34, 0x32, 0x39, 0x30, 0x35, 0x34, 0x33,
+ 0x33, 0x30, 0x5a, 0x30, 0x00, 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b,
+ 0x65, 0x70, 0x03, 0x21, 0x00, 0x21, 0x86, 0x38, 0x28, 0x7d, 0xad, 0x35,
+ 0xad, 0xc3, 0x91, 0x07, 0x41, 0x65, 0x02, 0xe1, 0x72, 0x79, 0xf4, 0x0d,
+ 0xd5, 0xe2, 0xbb, 0xba, 0xd8, 0x81, 0x06, 0xad, 0xa0, 0x7b, 0x2a, 0x41,
+ 0x09, 0xa3, 0x02, 0x30, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70,
+ 0x03, 0x41, 0x00, 0x2e, 0xbb, 0xb9, 0x55, 0x59, 0x24, 0xb0, 0xdb, 0x18,
+ 0xd0, 0xb4, 0xa6, 0x8b, 0xa8, 0xbf, 0x4c, 0xbd, 0x83, 0x27, 0xe7, 0xc2,
+ 0xc8, 0x13, 0xc2, 0x81, 0xbe, 0xdf, 0x04, 0x7b, 0x09, 0x87, 0x08, 0x53,
+ 0x97, 0xd6, 0x7c, 0xb7, 0x6c, 0xa6, 0x78, 0x63, 0x3c, 0x27, 0x29, 0x81,
+ 0x85, 0xd0, 0x73, 0x92, 0x2d, 0x5c, 0x33, 0x8e, 0x88, 0x18, 0x9b, 0x1c,
+ 0xcf, 0xc3, 0x4a, 0xf0, 0x82, 0x05, 0x05
+};
+#define TEST_CERT_LEN 1521
+
+static int test_store_open_winstore(void)
+{
+ int ret = 0;
+ OSSL_STORE_CTX *sctx = NULL;
+ OSSL_STORE_SEARCH *search = NULL;
+ UI_METHOD *ui_method = NULL;
+ OSSL_STORE_INFO *info = NULL;
+ X509* testcert = NULL;
+ const unsigned char* certptr = mscert;
+
+ /*
+ * Test the winstore, by opening it, searching for the MS root certificate
+ * and ensure that it was found. Note that we have to search by
+ * subject name, as winstore only allows searches by that method
+ */
+ ret = TEST_ptr(testcert = d2i_X509(NULL, &certptr, TEST_CERT_LEN))
+ && TEST_ptr(search = OSSL_STORE_SEARCH_by_name(X509_get_issuer_name(testcert)))
+ && TEST_ptr(ui_method = UI_create_method("DummyUI"))
+ && TEST_ptr(sctx = OSSL_STORE_open_ex("org.openssl.winstore:", NULL,
+ NULL, ui_method, NULL, NULL,
+ NULL, NULL))
+ && TEST_true(OSSL_STORE_find(sctx, search))
+ && TEST_ptr(info = OSSL_STORE_load(sctx));
+ UI_destroy_method(ui_method);
+ OSSL_STORE_INFO_free(info);
+ OSSL_STORE_SEARCH_free(search);
+ OSSL_STORE_close(sctx);
+ X509_free(testcert);
+ return ret;
+}
+#endif
+
static int test_store_search_by_key_fingerprint_fail(void)
{
int ret;
@@ -230,6 +299,9 @@ int setup_tests(void)
if (infile != NULL)
ADD_TEST(test_store_open);
+#ifndef OPENSSL_NO_WINSTORE
+ ADD_TEST(test_store_open_winstore);
+#endif
ADD_TEST(test_store_search_by_key_fingerprint_fail);
ADD_ALL_TESTS(test_store_get_params, 3);
if (sm2file != NULL)
diff --git a/test/pairwise_fail_test.c b/test/pairwise_fail_test.c
index 0e46aba2ad79..9c40b0af92ec 100644
--- a/test/pairwise_fail_test.c
+++ b/test/pairwise_fail_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2025 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
@@ -133,6 +133,39 @@ static int test_keygen_pairwise_failure(void)
goto err;
if (!TEST_ptr_null(pkey))
goto err;
+ } else if (strncmp(pairwise_name, "ml-dsa", 6) == 0) {
+ if (!TEST_true(setup_selftest_pairwise_failure(type)))
+ goto err;
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "ML-DSA-87", NULL)))
+ goto err;
+ if (!TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1))
+ goto err;
+ if (!TEST_int_le(EVP_PKEY_keygen(ctx, &pkey), 0))
+ goto err;
+ if (!TEST_ptr_null(pkey))
+ goto err;
+ } else if (strncmp(pairwise_name, "slh-dsa", 7) == 0) {
+ if (!TEST_true(setup_selftest_pairwise_failure(type)))
+ goto err;
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "SLH-DSA-SHA2-256f", NULL)))
+ goto err;
+ if (!TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1))
+ goto err;
+ if (!TEST_int_le(EVP_PKEY_keygen(ctx, &pkey), 0))
+ goto err;
+ if (!TEST_ptr_null(pkey))
+ goto err;
+ } else if (strncmp(pairwise_name, "ml-kem", 6) == 0) {
+ if (!TEST_true(setup_selftest_pairwise_failure(type)))
+ goto err;
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "ML-KEM-1024", NULL)))
+ goto err;
+ if (!TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1))
+ goto err;
+ if (!TEST_int_le(EVP_PKEY_keygen(ctx, &pkey), 0))
+ goto err;
+ if (!TEST_ptr_null(pkey))
+ goto err;
}
ret = 1;
err:
diff --git a/test/params_api_test.c b/test/params_api_test.c
index 715c2718bb32..7fa4c7ca9014 100644
--- a/test/params_api_test.c
+++ b/test/params_api_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -42,9 +42,13 @@ static void le_copy(unsigned char *out, size_t outlen,
if (IS_LITTLE_ENDIAN) {
memcpy(out, in, outlen);
} else {
- if (outlen < inlen)
+ if (outlen < inlen) {
in = (const char *)in + inlen - outlen;
- swap_copy(out, in, outlen);
+ inlen = outlen;
+ }
+ if (!ossl_assert(outlen <= inlen))
+ return;
+ swap_copy(out, in, inlen);
}
}
@@ -815,6 +819,33 @@ static int test_param_copy_null(void)
OSSL_PARAM_free(cp1);
return ret;
}
+static int test_param_merge(void)
+{
+ int val, ret;
+ int values[] = {1, 2, 3, 4};
+ OSSL_PARAM *p = NULL, *cp = NULL;
+ OSSL_PARAM param[3], param1[3];
+
+ param[0] = OSSL_PARAM_construct_int("diff1", &values[0]);
+ param[1] = OSSL_PARAM_construct_int("same", &values[1]);
+ param[2] = OSSL_PARAM_construct_end();
+ param1[0] = OSSL_PARAM_construct_int("diff2", &values[2]);
+ param1[1] = OSSL_PARAM_construct_int("same", &values[3]);
+ param1[2] = OSSL_PARAM_construct_end();
+
+ ret = TEST_ptr(p = OSSL_PARAM_merge(param, param1))
+ && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff1"))
+ && TEST_true(OSSL_PARAM_get_int(p, &val))
+ && TEST_int_eq(val, values[0])
+ && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff2"))
+ && TEST_true(OSSL_PARAM_get_int(cp, &val))
+ && TEST_int_eq(val, values[2])
+ && TEST_ptr(cp = OSSL_PARAM_locate(p, "same"))
+ && TEST_true(OSSL_PARAM_get_int(cp, &val))
+ && TEST_int_eq(val, values[3]);
+ OSSL_PARAM_free(p);
+ return ret;
+}
int setup_tests(void)
{
@@ -834,5 +865,6 @@ int setup_tests(void)
ADD_ALL_TESTS(test_param_construct, 4);
ADD_TEST(test_param_modified);
ADD_TEST(test_param_copy_null);
+ ADD_TEST(test_param_merge);
return 1;
}
diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c
index 4abbdd33ec4d..cb656a62a650 100644
--- a/test/provider_pkey_test.c
+++ b/test/provider_pkey_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2021-2025 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
@@ -424,6 +424,292 @@ end:
return ret;
}
+#define DEFAULT_PROVIDER_IDX 0
+#define FAKE_RSA_PROVIDER_IDX 1
+
+static int reset_ctx_providers(OSSL_LIB_CTX **ctx, OSSL_PROVIDER *providers[2], const char *prop)
+{
+ OSSL_PROVIDER_unload(providers[DEFAULT_PROVIDER_IDX]);
+ providers[DEFAULT_PROVIDER_IDX] = NULL;
+ fake_rsa_finish(providers[FAKE_RSA_PROVIDER_IDX]);
+ providers[FAKE_RSA_PROVIDER_IDX] = NULL;
+ OSSL_LIB_CTX_free(*ctx);
+ *ctx = NULL;
+
+ if (!TEST_ptr(*ctx = OSSL_LIB_CTX_new())
+ || !TEST_ptr(providers[DEFAULT_PROVIDER_IDX] = OSSL_PROVIDER_load(*ctx, "default"))
+ || !TEST_ptr(providers[FAKE_RSA_PROVIDER_IDX] = fake_rsa_start(*ctx))
+ || !TEST_true(EVP_set_default_properties(*ctx, prop)))
+ return 0;
+ return 1;
+}
+
+struct test_pkey_decoder_properties_t {
+ const char *provider_props;
+ const char *explicit_props;
+ int curr_provider_idx;
+};
+
+static int test_pkey_provider_decoder_props(void)
+{
+ OSSL_LIB_CTX *my_libctx = NULL;
+ OSSL_PROVIDER *providers[2] = { NULL };
+ struct test_pkey_decoder_properties_t properties_test[] = {
+ { "?provider=fake-rsa", NULL, FAKE_RSA_PROVIDER_IDX },
+ { "?provider=default", NULL, DEFAULT_PROVIDER_IDX },
+ { NULL, "?provider=fake-rsa", FAKE_RSA_PROVIDER_IDX },
+ { NULL, "?provider=default", DEFAULT_PROVIDER_IDX },
+ { NULL, "provider=fake-rsa", FAKE_RSA_PROVIDER_IDX },
+ { NULL, "provider=default", DEFAULT_PROVIDER_IDX },
+ };
+ EVP_PKEY *pkey = NULL;
+ BIO *bio_priv = NULL;
+ unsigned char *encoded_pub = NULL;
+ int len_pub;
+ const unsigned char *p;
+ PKCS8_PRIV_KEY_INFO *p8 = NULL;
+ size_t i;
+ int ret = 0;
+ const char pem_rsa_priv_key[] = {
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50,
+ 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D,
+ 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45, 0x76, 0x51, 0x49, 0x42,
+ 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47,
+ 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43,
+ 0x42, 0x4B, 0x63, 0x77, 0x67, 0x67, 0x53, 0x6A, 0x41, 0x67, 0x45, 0x41,
+ 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x44, 0x45, 0x6B, 0x43, 0x34, 0x5A,
+ 0x57, 0x76, 0x33, 0x75, 0x63, 0x46, 0x62, 0x55, 0x0A, 0x46, 0x38, 0x59,
+ 0x77, 0x6C, 0x55, 0x72, 0x6D, 0x51, 0x6C, 0x4C, 0x43, 0x5A, 0x77, 0x41,
+ 0x67, 0x72, 0x34, 0x44, 0x50, 0x55, 0x41, 0x46, 0x56, 0x48, 0x6C, 0x2B,
+ 0x77, 0x46, 0x63, 0x58, 0x79, 0x70, 0x56, 0x67, 0x53, 0x63, 0x56, 0x59,
+ 0x34, 0x4B, 0x37, 0x51, 0x6D, 0x64, 0x57, 0x4B, 0x73, 0x59, 0x71, 0x62,
+ 0x38, 0x74, 0x70, 0x4F, 0x78, 0x71, 0x77, 0x30, 0x4E, 0x77, 0x5A, 0x57,
+ 0x58, 0x0A, 0x4F, 0x2B, 0x74, 0x61, 0x34, 0x2B, 0x79, 0x32, 0x37, 0x43,
+ 0x4F, 0x75, 0x66, 0x6F, 0x4F, 0x68, 0x52, 0x54, 0x4D, 0x77, 0x4E, 0x79,
+ 0x4E, 0x32, 0x4C, 0x77, 0x53, 0x4E, 0x54, 0x50, 0x4E, 0x33, 0x65, 0x45,
+ 0x6B, 0x34, 0x65, 0x65, 0x35, 0x51, 0x6E, 0x70, 0x70, 0x45, 0x79, 0x44,
+ 0x72, 0x71, 0x6F, 0x43, 0x67, 0x76, 0x54, 0x6C, 0x41, 0x41, 0x64, 0x54,
+ 0x6F, 0x46, 0x61, 0x58, 0x76, 0x6A, 0x0A, 0x78, 0x31, 0x33, 0x59, 0x62,
+ 0x6A, 0x37, 0x6A, 0x66, 0x68, 0x77, 0x4E, 0x37, 0x34, 0x71, 0x4B, 0x64,
+ 0x71, 0x73, 0x53, 0x45, 0x74, 0x50, 0x57, 0x79, 0x67, 0x67, 0x65, 0x6F,
+ 0x74, 0x69, 0x51, 0x53, 0x50, 0x79, 0x36, 0x4B, 0x79, 0x42, 0x49, 0x75,
+ 0x57, 0x74, 0x49, 0x78, 0x50, 0x41, 0x41, 0x38, 0x6A, 0x41, 0x76, 0x66,
+ 0x41, 0x6E, 0x51, 0x6A, 0x31, 0x65, 0x58, 0x68, 0x67, 0x68, 0x46, 0x0A,
+ 0x4E, 0x32, 0x4E, 0x78, 0x6B, 0x71, 0x67, 0x78, 0x76, 0x42, 0x59, 0x64,
+ 0x4E, 0x79, 0x31, 0x6D, 0x33, 0x2B, 0x6A, 0x58, 0x41, 0x43, 0x50, 0x4C,
+ 0x52, 0x7A, 0x63, 0x31, 0x31, 0x5A, 0x62, 0x4E, 0x48, 0x4B, 0x69, 0x77,
+ 0x68, 0x43, 0x59, 0x31, 0x2F, 0x48, 0x69, 0x53, 0x42, 0x6B, 0x77, 0x48,
+ 0x6C, 0x49, 0x4B, 0x2B, 0x2F, 0x56, 0x4C, 0x6A, 0x32, 0x73, 0x6D, 0x43,
+ 0x4B, 0x64, 0x55, 0x51, 0x0A, 0x67, 0x76, 0x4C, 0x58, 0x53, 0x6E, 0x6E,
+ 0x56, 0x67, 0x51, 0x75, 0x6C, 0x48, 0x69, 0x6F, 0x44, 0x36, 0x55, 0x67,
+ 0x59, 0x38, 0x78, 0x41, 0x32, 0x61, 0x34, 0x4D, 0x31, 0x72, 0x68, 0x59,
+ 0x75, 0x54, 0x56, 0x38, 0x42, 0x72, 0x50, 0x52, 0x5A, 0x34, 0x42, 0x46,
+ 0x78, 0x32, 0x6F, 0x30, 0x6A, 0x59, 0x57, 0x76, 0x47, 0x62, 0x41, 0x2F,
+ 0x48, 0x6C, 0x70, 0x37, 0x66, 0x54, 0x4F, 0x79, 0x2B, 0x0A, 0x46, 0x35,
+ 0x4F, 0x6B, 0x69, 0x48, 0x53, 0x37, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41,
+ 0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x59, 0x67, 0x43, 0x75, 0x38, 0x31,
+ 0x5A, 0x69, 0x51, 0x42, 0x56, 0x44, 0x76, 0x57, 0x69, 0x44, 0x47, 0x4B,
+ 0x72, 0x2B, 0x31, 0x70, 0x49, 0x66, 0x32, 0x43, 0x78, 0x70, 0x72, 0x47,
+ 0x4A, 0x45, 0x6D, 0x31, 0x68, 0x38, 0x36, 0x5A, 0x63, 0x45, 0x78, 0x33,
+ 0x4C, 0x37, 0x0A, 0x71, 0x46, 0x44, 0x57, 0x2B, 0x67, 0x38, 0x48, 0x47,
+ 0x57, 0x64, 0x30, 0x34, 0x53, 0x33, 0x71, 0x76, 0x68, 0x39, 0x4C, 0x75,
+ 0x62, 0x6C, 0x41, 0x4A, 0x7A, 0x65, 0x74, 0x41, 0x50, 0x78, 0x52, 0x58,
+ 0x4C, 0x39, 0x7A, 0x78, 0x33, 0x50, 0x58, 0x6A, 0x4A, 0x5A, 0x73, 0x37,
+ 0x65, 0x33, 0x48, 0x4C, 0x45, 0x75, 0x6E, 0x79, 0x33, 0x54, 0x61, 0x57,
+ 0x65, 0x7A, 0x30, 0x58, 0x49, 0x30, 0x4F, 0x0A, 0x34, 0x4C, 0x53, 0x59,
+ 0x38, 0x53, 0x38, 0x64, 0x36, 0x70, 0x56, 0x42, 0x50, 0x6D, 0x55, 0x45,
+ 0x74, 0x77, 0x47, 0x57, 0x4E, 0x34, 0x76, 0x59, 0x71, 0x48, 0x6E, 0x4B,
+ 0x4C, 0x58, 0x4F, 0x62, 0x34, 0x51, 0x51, 0x41, 0x58, 0x73, 0x34, 0x4D,
+ 0x7A, 0x66, 0x6B, 0x4D, 0x2F, 0x4D, 0x65, 0x2F, 0x62, 0x2B, 0x7A, 0x64,
+ 0x75, 0x31, 0x75, 0x6D, 0x77, 0x6A, 0x4D, 0x6C, 0x33, 0x44, 0x75, 0x64,
+ 0x0A, 0x35, 0x72, 0x56, 0x68, 0x6B, 0x67, 0x76, 0x74, 0x38, 0x75, 0x68,
+ 0x44, 0x55, 0x47, 0x33, 0x58, 0x53, 0x48, 0x65, 0x6F, 0x4A, 0x59, 0x42,
+ 0x4D, 0x62, 0x54, 0x39, 0x69, 0x6B, 0x4A, 0x44, 0x56, 0x4D, 0x4A, 0x35,
+ 0x31, 0x72, 0x72, 0x65, 0x2F, 0x31, 0x52, 0x69, 0x64, 0x64, 0x67, 0x78,
+ 0x70, 0x38, 0x53, 0x6B, 0x74, 0x56, 0x6B, 0x76, 0x47, 0x6D, 0x4D, 0x6C,
+ 0x39, 0x6B, 0x51, 0x52, 0x38, 0x0A, 0x38, 0x64, 0x76, 0x33, 0x50, 0x78,
+ 0x2F, 0x6B, 0x54, 0x4E, 0x39, 0x34, 0x45, 0x75, 0x52, 0x67, 0x30, 0x43,
+ 0x6B, 0x58, 0x42, 0x68, 0x48, 0x70, 0x6F, 0x47, 0x6F, 0x34, 0x71, 0x6E,
+ 0x4D, 0x33, 0x51, 0x33, 0x42, 0x35, 0x50, 0x6C, 0x6D, 0x53, 0x4B, 0x35,
+ 0x67, 0x6B, 0x75, 0x50, 0x76, 0x57, 0x79, 0x39, 0x6C, 0x38, 0x4C, 0x2F,
+ 0x54, 0x56, 0x74, 0x38, 0x4C, 0x62, 0x36, 0x2F, 0x7A, 0x4C, 0x0A, 0x42,
+ 0x79, 0x51, 0x57, 0x2B, 0x67, 0x30, 0x32, 0x77, 0x78, 0x65, 0x4E, 0x47,
+ 0x68, 0x77, 0x31, 0x66, 0x6B, 0x44, 0x2B, 0x58, 0x46, 0x48, 0x37, 0x4B,
+ 0x6B, 0x53, 0x65, 0x57, 0x6C, 0x2B, 0x51, 0x6E, 0x72, 0x4C, 0x63, 0x65,
+ 0x50, 0x4D, 0x30, 0x68, 0x51, 0x4B, 0x42, 0x67, 0x51, 0x44, 0x78, 0x6F,
+ 0x71, 0x55, 0x6B, 0x30, 0x50, 0x4C, 0x4F, 0x59, 0x35, 0x57, 0x67, 0x4F,
+ 0x6B, 0x67, 0x72, 0x0A, 0x75, 0x6D, 0x67, 0x69, 0x65, 0x2F, 0x4B, 0x31,
+ 0x57, 0x4B, 0x73, 0x2B, 0x69, 0x7A, 0x54, 0x74, 0x41, 0x70, 0x6A, 0x7A,
+ 0x63, 0x4D, 0x37, 0x36, 0x73, 0x7A, 0x61, 0x36, 0x33, 0x62, 0x35, 0x52,
+ 0x39, 0x77, 0x2B, 0x50, 0x2B, 0x4E, 0x73, 0x73, 0x4D, 0x56, 0x34, 0x61,
+ 0x65, 0x56, 0x39, 0x65, 0x70, 0x45, 0x47, 0x5A, 0x4F, 0x36, 0x38, 0x49,
+ 0x55, 0x6D, 0x69, 0x30, 0x51, 0x6A, 0x76, 0x51, 0x0A, 0x6E, 0x70, 0x6C,
+ 0x75, 0x51, 0x6F, 0x61, 0x64, 0x46, 0x59, 0x77, 0x65, 0x46, 0x77, 0x53,
+ 0x51, 0x31, 0x31, 0x42, 0x58, 0x48, 0x6F, 0x65, 0x51, 0x42, 0x41, 0x34,
+ 0x6E, 0x4E, 0x70, 0x6B, 0x72, 0x56, 0x35, 0x38, 0x68, 0x67, 0x7A, 0x5A,
+ 0x4E, 0x33, 0x6D, 0x39, 0x4A, 0x4C, 0x52, 0x37, 0x4A, 0x78, 0x79, 0x72,
+ 0x49, 0x71, 0x58, 0x73, 0x52, 0x6E, 0x55, 0x7A, 0x6C, 0x31, 0x33, 0x4B,
+ 0x6A, 0x0A, 0x47, 0x7A, 0x5A, 0x42, 0x43, 0x4A, 0x78, 0x43, 0x70, 0x4A,
+ 0x6A, 0x66, 0x54, 0x7A, 0x65, 0x2F, 0x79, 0x6D, 0x65, 0x38, 0x64, 0x33,
+ 0x70, 0x61, 0x35, 0x51, 0x4B, 0x42, 0x67, 0x51, 0x44, 0x51, 0x50, 0x35,
+ 0x6D, 0x42, 0x34, 0x6A, 0x49, 0x2B, 0x67, 0x33, 0x58, 0x48, 0x33, 0x4D,
+ 0x75, 0x4C, 0x79, 0x42, 0x6A, 0x4D, 0x6F, 0x54, 0x49, 0x76, 0x6F, 0x79,
+ 0x37, 0x43, 0x59, 0x4D, 0x68, 0x5A, 0x0A, 0x36, 0x2F, 0x2B, 0x4B, 0x6B,
+ 0x70, 0x77, 0x31, 0x33, 0x32, 0x4A, 0x31, 0x36, 0x6D, 0x71, 0x6B, 0x4C,
+ 0x72, 0x77, 0x55, 0x4F, 0x5A, 0x66, 0x54, 0x30, 0x65, 0x31, 0x72, 0x4A,
+ 0x42, 0x73, 0x43, 0x55, 0x6B, 0x45, 0x6F, 0x42, 0x6D, 0x67, 0x4B, 0x4E,
+ 0x74, 0x52, 0x6B, 0x48, 0x6F, 0x33, 0x2F, 0x53, 0x6A, 0x55, 0x49, 0x2F,
+ 0x39, 0x66, 0x48, 0x6A, 0x33, 0x75, 0x53, 0x74, 0x50, 0x48, 0x56, 0x0A,
+ 0x6F, 0x50, 0x63, 0x66, 0x58, 0x6A, 0x2F, 0x67, 0x46, 0x52, 0x55, 0x6B,
+ 0x44, 0x44, 0x7A, 0x59, 0x2B, 0x61, 0x75, 0x42, 0x33, 0x64, 0x48, 0x4F,
+ 0x4E, 0x46, 0x31, 0x55, 0x31, 0x7A, 0x30, 0x36, 0x45, 0x41, 0x4E, 0x6B,
+ 0x6B, 0x50, 0x43, 0x43, 0x33, 0x61, 0x35, 0x33, 0x38, 0x55, 0x41, 0x4E,
+ 0x42, 0x49, 0x61, 0x50, 0x6A, 0x77, 0x70, 0x52, 0x64, 0x42, 0x7A, 0x4E,
+ 0x77, 0x31, 0x78, 0x6C, 0x0A, 0x62, 0x76, 0x6E, 0x35, 0x61, 0x43, 0x74,
+ 0x33, 0x48, 0x77, 0x4B, 0x42, 0x67, 0x42, 0x66, 0x4F, 0x6C, 0x34, 0x6A,
+ 0x47, 0x45, 0x58, 0x59, 0x6D, 0x4E, 0x36, 0x4B, 0x2B, 0x75, 0x30, 0x65,
+ 0x62, 0x71, 0x52, 0x44, 0x6B, 0x74, 0x32, 0x67, 0x49, 0x6F, 0x57, 0x36,
+ 0x62, 0x46, 0x6F, 0x37, 0x58, 0x64, 0x36, 0x78, 0x63, 0x69, 0x2F, 0x67,
+ 0x46, 0x57, 0x6A, 0x6F, 0x56, 0x43, 0x4F, 0x42, 0x59, 0x0A, 0x67, 0x43,
+ 0x38, 0x47, 0x4C, 0x4D, 0x6E, 0x77, 0x33, 0x7A, 0x32, 0x71, 0x67, 0x61,
+ 0x76, 0x34, 0x63, 0x51, 0x49, 0x67, 0x38, 0x45, 0x44, 0x59, 0x70, 0x62,
+ 0x70, 0x45, 0x34, 0x46, 0x48, 0x51, 0x6E, 0x6E, 0x74, 0x50, 0x6B, 0x4B,
+ 0x57, 0x2F, 0x62, 0x72, 0x75, 0x30, 0x4E, 0x74, 0x33, 0x79, 0x61, 0x4E,
+ 0x62, 0x38, 0x69, 0x67, 0x79, 0x31, 0x61, 0x5A, 0x4F, 0x52, 0x66, 0x49,
+ 0x76, 0x5A, 0x0A, 0x71, 0x54, 0x4D, 0x4C, 0x45, 0x33, 0x6D, 0x65, 0x6C,
+ 0x63, 0x5A, 0x57, 0x37, 0x4C, 0x61, 0x69, 0x71, 0x65, 0x4E, 0x31, 0x56,
+ 0x30, 0x76, 0x48, 0x2F, 0x4D, 0x43, 0x55, 0x64, 0x70, 0x58, 0x39, 0x59,
+ 0x31, 0x34, 0x4B, 0x39, 0x43, 0x4A, 0x59, 0x78, 0x7A, 0x73, 0x52, 0x4F,
+ 0x67, 0x50, 0x71, 0x64, 0x45, 0x67, 0x4D, 0x57, 0x59, 0x44, 0x46, 0x41,
+ 0x6F, 0x47, 0x41, 0x41, 0x65, 0x39, 0x6C, 0x0A, 0x58, 0x4D, 0x69, 0x65,
+ 0x55, 0x4F, 0x68, 0x6C, 0x30, 0x73, 0x71, 0x68, 0x64, 0x5A, 0x59, 0x52,
+ 0x62, 0x4F, 0x31, 0x65, 0x69, 0x77, 0x54, 0x49, 0x4C, 0x58, 0x51, 0x36,
+ 0x79, 0x47, 0x4D, 0x69, 0x42, 0x38, 0x61, 0x65, 0x2F, 0x76, 0x30, 0x70,
+ 0x62, 0x42, 0x45, 0x57, 0x6C, 0x70, 0x6E, 0x38, 0x6B, 0x32, 0x2B, 0x4A,
+ 0x6B, 0x71, 0x56, 0x54, 0x77, 0x48, 0x67, 0x67, 0x62, 0x43, 0x41, 0x5A,
+ 0x0A, 0x6A, 0x4F, 0x61, 0x71, 0x56, 0x74, 0x58, 0x31, 0x6D, 0x55, 0x79,
+ 0x54, 0x59, 0x7A, 0x6A, 0x73, 0x54, 0x7A, 0x34, 0x5A, 0x59, 0x6A, 0x68,
+ 0x61, 0x48, 0x4A, 0x33, 0x6A, 0x31, 0x57, 0x6C, 0x65, 0x67, 0x6F, 0x4D,
+ 0x63, 0x73, 0x74, 0x64, 0x66, 0x54, 0x2B, 0x74, 0x78, 0x4D, 0x55, 0x37,
+ 0x34, 0x6F, 0x67, 0x64, 0x4F, 0x71, 0x4D, 0x7A, 0x68, 0x78, 0x53, 0x55,
+ 0x4F, 0x34, 0x35, 0x67, 0x38, 0x0A, 0x66, 0x39, 0x57, 0x38, 0x39, 0x6D,
+ 0x70, 0x61, 0x38, 0x62, 0x42, 0x6A, 0x4F, 0x50, 0x75, 0x2B, 0x79, 0x46,
+ 0x79, 0x36, 0x36, 0x74, 0x44, 0x61, 0x5A, 0x36, 0x73, 0x57, 0x45, 0x37,
+ 0x63, 0x35, 0x53, 0x58, 0x45, 0x48, 0x58, 0x6C, 0x38, 0x43, 0x67, 0x59,
+ 0x45, 0x41, 0x74, 0x41, 0x57, 0x77, 0x46, 0x50, 0x6F, 0x44, 0x53, 0x54,
+ 0x64, 0x7A, 0x6F, 0x58, 0x41, 0x77, 0x52, 0x6F, 0x66, 0x30, 0x0A, 0x51,
+ 0x4D, 0x4F, 0x30, 0x38, 0x2B, 0x50, 0x6E, 0x51, 0x47, 0x6F, 0x50, 0x62,
+ 0x4D, 0x4A, 0x54, 0x71, 0x72, 0x67, 0x78, 0x72, 0x48, 0x59, 0x43, 0x53,
+ 0x38, 0x75, 0x34, 0x63, 0x59, 0x53, 0x48, 0x64, 0x44, 0x4D, 0x4A, 0x44,
+ 0x43, 0x4F, 0x4D, 0x6F, 0x35, 0x67, 0x46, 0x58, 0x79, 0x43, 0x2B, 0x35,
+ 0x46, 0x66, 0x54, 0x69, 0x47, 0x77, 0x42, 0x68, 0x79, 0x35, 0x38, 0x7A,
+ 0x35, 0x62, 0x37, 0x0A, 0x67, 0x42, 0x77, 0x46, 0x4B, 0x49, 0x39, 0x52,
+ 0x67, 0x52, 0x66, 0x56, 0x31, 0x44, 0x2F, 0x4E, 0x69, 0x6D, 0x78, 0x50,
+ 0x72, 0x6C, 0x6A, 0x33, 0x57, 0x48, 0x79, 0x65, 0x63, 0x31, 0x2F, 0x43,
+ 0x73, 0x2B, 0x42, 0x72, 0x2B, 0x2F, 0x76, 0x65, 0x6B, 0x4D, 0x56, 0x46,
+ 0x67, 0x35, 0x67, 0x65, 0x6B, 0x65, 0x48, 0x72, 0x34, 0x61, 0x47, 0x53,
+ 0x46, 0x34, 0x62, 0x6B, 0x30, 0x41, 0x6A, 0x56, 0x0A, 0x54, 0x76, 0x2F,
+ 0x70, 0x51, 0x6A, 0x79, 0x52, 0x75, 0x5A, 0x41, 0x74, 0x36, 0x36, 0x49,
+ 0x62, 0x52, 0x5A, 0x64, 0x6C, 0x32, 0x49, 0x49, 0x3D, 0x0A, 0x2D, 0x2D,
+ 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41,
+ 0x54, 0x45, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D
+ };
+ /*
+ * PEM of pem_rsa_priv_key:
+ * -----BEGIN PRIVATE KEY-----
+ * MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDEkC4ZWv3ucFbU
+ * F8YwlUrmQlLCZwAgr4DPUAFVHl+wFcXypVgScVY4K7QmdWKsYqb8tpOxqw0NwZWX
+ * O+ta4+y27COufoOhRTMwNyN2LwSNTPN3eEk4ee5QnppEyDrqoCgvTlAAdToFaXvj
+ * x13Ybj7jfhwN74qKdqsSEtPWyggeotiQSPy6KyBIuWtIxPAA8jAvfAnQj1eXhghF
+ * N2NxkqgxvBYdNy1m3+jXACPLRzc11ZbNHKiwhCY1/HiSBkwHlIK+/VLj2smCKdUQ
+ * gvLXSnnVgQulHioD6UgY8xA2a4M1rhYuTV8BrPRZ4BFx2o0jYWvGbA/Hlp7fTOy+
+ * F5OkiHS7AgMBAAECggEAYgCu81ZiQBVDvWiDGKr+1pIf2CxprGJEm1h86ZcEx3L7
+ * qFDW+g8HGWd04S3qvh9LublAJzetAPxRXL9zx3PXjJZs7e3HLEuny3TaWez0XI0O
+ * 4LSY8S8d6pVBPmUEtwGWN4vYqHnKLXOb4QQAXs4MzfkM/Me/b+zdu1umwjMl3Dud
+ * 5rVhkgvt8uhDUG3XSHeoJYBMbT9ikJDVMJ51rre/1Riddgxp8SktVkvGmMl9kQR8
+ * 8dv3Px/kTN94EuRg0CkXBhHpoGo4qnM3Q3B5PlmSK5gkuPvWy9l8L/TVt8Lb6/zL
+ * ByQW+g02wxeNGhw1fkD+XFH7KkSeWl+QnrLcePM0hQKBgQDxoqUk0PLOY5WgOkgr
+ * umgie/K1WKs+izTtApjzcM76sza63b5R9w+P+NssMV4aeV9epEGZO68IUmi0QjvQ
+ * npluQoadFYweFwSQ11BXHoeQBA4nNpkrV58hgzZN3m9JLR7JxyrIqXsRnUzl13Kj
+ * GzZBCJxCpJjfTze/yme8d3pa5QKBgQDQP5mB4jI+g3XH3MuLyBjMoTIvoy7CYMhZ
+ * 6/+Kkpw132J16mqkLrwUOZfT0e1rJBsCUkEoBmgKNtRkHo3/SjUI/9fHj3uStPHV
+ * oPcfXj/gFRUkDDzY+auB3dHONF1U1z06EANkkPCC3a538UANBIaPjwpRdBzNw1xl
+ * bvn5aCt3HwKBgBfOl4jGEXYmN6K+u0ebqRDkt2gIoW6bFo7Xd6xci/gFWjoVCOBY
+ * gC8GLMnw3z2qgav4cQIg8EDYpbpE4FHQnntPkKW/bru0Nt3yaNb8igy1aZORfIvZ
+ * qTMLE3melcZW7LaiqeN1V0vH/MCUdpX9Y14K9CJYxzsROgPqdEgMWYDFAoGAAe9l
+ * XMieUOhl0sqhdZYRbO1eiwTILXQ6yGMiB8ae/v0pbBEWlpn8k2+JkqVTwHggbCAZ
+ * jOaqVtX1mUyTYzjsTz4ZYjhaHJ3j1WlegoMcstdfT+txMU74ogdOqMzhxSUO45g8
+ * f9W89mpa8bBjOPu+yFy66tDaZ6sWE7c5SXEHXl8CgYEAtAWwFPoDSTdzoXAwRof0
+ * QMO08+PnQGoPbMJTqrgxrHYCS8u4cYSHdDMJDCOMo5gFXyC+5FfTiGwBhy58z5b7
+ * gBwFKI9RgRfV1D/NimxPrlj3WHyec1/Cs+Br+/vekMVFg5gekeHr4aGSF4bk0AjV
+ * Tv/pQjyRuZAt66IbRZdl2II=
+ * -----END PRIVATE KEY-----
+ */
+
+ /* Load private key BIO, DER-encoded public key and PKCS#8 private key for testing */
+ if (!TEST_ptr(bio_priv = BIO_new(BIO_s_mem()))
+ || !TEST_int_gt(BIO_write(bio_priv, pem_rsa_priv_key, sizeof(pem_rsa_priv_key)), 0)
+ || !TEST_ptr(pkey = PEM_read_bio_PrivateKey_ex(bio_priv, NULL, NULL, NULL, NULL, NULL))
+ || !TEST_int_ge(BIO_seek(bio_priv, 0), 0)
+ || !TEST_int_gt((len_pub = i2d_PUBKEY(pkey, &encoded_pub)), 0)
+ || !TEST_ptr(p8 = EVP_PKEY2PKCS8(pkey)))
+ goto end;
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+
+ for (i = 0; i < OSSL_NELEM(properties_test); i++) {
+ const char *libctx_prop = properties_test[i].provider_props;
+ const char *explicit_prop = properties_test[i].explicit_props;
+ /* *curr_provider will be updated in reset_ctx_providers */
+ OSSL_PROVIDER **curr_provider = &providers[properties_test[i].curr_provider_idx];
+
+ /*
+ * Decoding a PEM-encoded key uses the properties to select the right provider.
+ * Using a PEM-encoding adds an extra decoder before the key is created.
+ */
+ if (!TEST_int_eq(reset_ctx_providers(&my_libctx, providers, libctx_prop), 1))
+ goto end;
+ if (!TEST_int_ge(BIO_seek(bio_priv, 0), 0)
+ || !TEST_ptr(pkey = PEM_read_bio_PrivateKey_ex(bio_priv, NULL, NULL, NULL, my_libctx,
+ explicit_prop))
+ || !TEST_ptr_eq(EVP_PKEY_get0_provider(pkey), *curr_provider))
+ goto end;
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+
+ /* Decoding a DER-encoded X509_PUBKEY uses the properties to select the right provider */
+ if (!TEST_int_eq(reset_ctx_providers(&my_libctx, providers, libctx_prop), 1))
+ goto end;
+ p = encoded_pub;
+ if (!TEST_ptr(pkey = d2i_PUBKEY_ex(NULL, &p, len_pub, my_libctx, explicit_prop))
+ || !TEST_ptr_eq(EVP_PKEY_get0_provider(pkey), *curr_provider))
+ goto end;
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+
+ /* Decoding a PKCS8_PRIV_KEY_INFO uses the properties to select the right provider */
+ if (!TEST_int_eq(reset_ctx_providers(&my_libctx, providers, libctx_prop), 1))
+ goto end;
+ if (!TEST_ptr(pkey = EVP_PKCS82PKEY_ex(p8, my_libctx, explicit_prop))
+ || !TEST_ptr_eq(EVP_PKEY_get0_provider(pkey), *curr_provider))
+ goto end;
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ }
+
+ ret = 1;
+
+end:
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ BIO_free(bio_priv);
+ OPENSSL_free(encoded_pub);
+ EVP_PKEY_free(pkey);
+ OSSL_PROVIDER_unload(providers[DEFAULT_PROVIDER_IDX]);
+ fake_rsa_finish(providers[FAKE_RSA_PROVIDER_IDX]);
+ OSSL_LIB_CTX_free(my_libctx);
+ return ret;
+}
+
int setup_tests(void)
{
libctx = OSSL_LIB_CTX_new();
@@ -436,6 +722,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_pkey_store, 2);
ADD_TEST(test_pkey_delete);
ADD_TEST(test_pkey_store_open_ex);
+ ADD_TEST(test_pkey_provider_decoder_props);
return 1;
}
diff --git a/test/quic-openssl-docker/hq-interop/quic-hq-interop.c b/test/quic-openssl-docker/hq-interop/quic-hq-interop.c
index 14375d178a77..80b93c68c91e 100644
--- a/test/quic-openssl-docker/hq-interop/quic-hq-interop.c
+++ b/test/quic-openssl-docker/hq-interop/quic-hq-interop.c
@@ -906,8 +906,6 @@ int main(int argc, char *argv[])
goto end;
}
}
- BIO_free(req_bio);
- req_bio = NULL;
reqnames[read_offset + 1] = '\0';
if (!setup_connection(hostname, port, &ctx, &ssl)) {
@@ -1037,6 +1035,7 @@ int main(int argc, char *argv[])
*/
BIO_ADDR_free(peer_addr);
OPENSSL_free(reqnames);
+ BIO_free(req_bio);
BIO_free(session_bio);
for (poll_idx = 0; poll_idx < poll_count; poll_idx++) {
BIO_free(outbiolist[poll_idx]);
diff --git a/test/quic_ackm_test.c b/test/quic_ackm_test.c
index 0f26e9d38a0e..7b42fa5410fa 100644
--- a/test/quic_ackm_test.c
+++ b/test/quic_ackm_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -104,7 +104,8 @@ static int helper_init(struct helper *h, size_t num_pkts)
/* Initialise ACK manager. */
h->ackm = ossl_ackm_new(fake_now, NULL, &h->statm,
- &ossl_cc_dummy_method, h->ccdata);
+ &ossl_cc_dummy_method, h->ccdata,
+ /* is_server */0);
if (!TEST_ptr(h->ackm))
goto err;
diff --git a/test/quic_fifd_test.c b/test/quic_fifd_test.c
index cfa5a77745b7..7f93ca40d924 100644
--- a/test/quic_fifd_test.c
+++ b/test/quic_fifd_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2025 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
@@ -329,7 +329,8 @@ static int test_fifd(int idx)
|| !TEST_ptr(info.ackm = ossl_ackm_new(fake_now, NULL,
&info.statm,
&ossl_cc_dummy_method,
- info.ccdata))
+ info.ccdata,
+ /* is_server */0))
|| !TEST_true(ossl_ackm_on_handshake_confirmed(info.ackm))
|| !TEST_ptr(info.cfq = ossl_quic_cfq_new())
|| !TEST_ptr(info.txpim = ossl_quic_txpim_new())
diff --git a/test/quic_multistream_test.c b/test/quic_multistream_test.c
index fa873a750630..bd3835e754cd 100644
--- a/test/quic_multistream_test.c
+++ b/test/quic_multistream_test.c
@@ -25,6 +25,16 @@
static const char *certfile, *keyfile;
+#if defined(_AIX)
+/*
+ * Some versions of AIX define macros for events and revents for use when
+ * accessing pollfd structures (see Github issue #24236). That interferes
+ * with our use of these names here. We simply undef them.
+ */
+# undef revents
+# undef events
+#endif
+
#if defined(OPENSSL_THREADS)
struct child_thread_args {
struct helper *h;
diff --git a/test/quic_txp_test.c b/test/quic_txp_test.c
index 329953a3bd75..bf576c31f2d5 100644
--- a/test/quic_txp_test.c
+++ b/test/quic_txp_test.c
@@ -182,7 +182,8 @@ static int helper_init(struct helper *h)
if (!TEST_ptr(h->args.ackm = ossl_ackm_new(fake_now, NULL,
&h->statm,
h->cc_method,
- h->cc_data)))
+ h->cc_data,
+ /* is_server */0)))
goto err;
if (!TEST_true(ossl_quic_stream_map_init(&h->qsm, NULL, NULL,
diff --git a/test/quicapitest.c b/test/quicapitest.c
index 38dd42c18460..b98a94055301 100644
--- a/test/quicapitest.c
+++ b/test/quicapitest.c
@@ -2502,6 +2502,18 @@ static int select_alpn(SSL *ssl, const unsigned char **out,
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
+static SSL_CTX *create_client_ctx(void)
+{
+ SSL_CTX *ssl_ctx;
+
+ if (!TEST_ptr(ssl_ctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()))) {
+ SSL_CTX_free(ssl_ctx);
+ ssl_ctx = NULL;
+ }
+
+ return ssl_ctx;
+}
+
static SSL_CTX *create_server_ctx(void)
{
SSL_CTX *ssl_ctx;
@@ -2687,6 +2699,170 @@ end:
return ret;
}
+static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx,
+ SSL **lssl, SSL **cssl)
+{
+ BIO_ADDR *addr = NULL;
+ struct in_addr ina;
+ BIO *cbio = NULL, *sbio = NULL;
+ int ret = 0;
+
+ *cssl = *lssl = NULL;
+ ina.s_addr = htonl(0x1f000001);
+
+ if (!TEST_true(BIO_new_bio_dgram_pair(&cbio, 0, &sbio, 0)))
+ goto err;
+
+ if (!TEST_ptr(addr = create_addr(&ina, 8040)))
+ goto err;
+
+ if (!TEST_true(bio_addr_bind(sbio, addr)))
+ goto err;
+ addr = NULL;
+
+ *lssl = ql_create(sctx, sbio);
+ sbio = NULL;
+ if (!TEST_ptr(*lssl))
+ goto err;
+
+ if (!TEST_ptr(*cssl = SSL_new(cctx)))
+ goto err;
+
+ if (!TEST_ptr(addr = create_addr(&ina, 8040)))
+ goto err;
+ if (!TEST_true(bio_addr_bind(cbio, addr)))
+ goto err;
+
+ if (!TEST_true(qc_init(*cssl, addr))) {
+ addr = NULL;
+ goto err;
+ }
+ addr = NULL;
+ SSL_set_bio(*cssl, cbio, cbio);
+ cbio = NULL;
+
+ ret = 1;
+
+ err:
+ if (!ret) {
+ SSL_free(*cssl);
+ SSL_free(*lssl);
+ *cssl = *lssl = NULL;
+ }
+ BIO_free(cbio);
+ BIO_free(sbio);
+ BIO_ADDR_free(addr);
+
+ return ret;
+}
+
+static int test_ssl_accept_connection(void)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL;
+ int testresult = 0;
+ int ret, i;
+
+ if (!TEST_ptr(sctx = create_server_ctx())
+ || !TEST_ptr(cctx = create_client_ctx()))
+ goto err;
+
+ if (!create_quic_ssl_objects(sctx, cctx, &qlistener, &clientssl))
+ goto err;
+
+ /* Calling SSL_accept() on a listener is expected to fail */
+ ret = SSL_accept(qlistener);
+ if (!TEST_int_le(ret, 0)
+ || !TEST_int_eq(SSL_get_error(qlistener, ret), SSL_ERROR_SSL))
+ goto err;
+
+ /* Send ClientHello and server retry */
+ for (i = 0; i < 2; i++) {
+ ret = SSL_connect(clientssl);
+ if (!TEST_int_le(ret, 0)
+ || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ))
+ goto err;
+ SSL_handle_events(qlistener);
+ }
+
+ /* We expect a server SSL object which has not yet completed its handshake */
+ serverssl = SSL_accept_connection(qlistener, 0);
+ if (!TEST_ptr(serverssl) || !TEST_false(SSL_is_init_finished(serverssl)))
+ goto err;
+
+ /* Call SSL_accept() and SSL_connect() until we are connected */
+ if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE, 0, 0)))
+ goto err;
+
+ testresult = 1;
+
+ err:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_free(qlistener);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
+static SSL *quic_verify_ssl = NULL;
+
+static int quic_verify_cb(int ok, X509_STORE_CTX *ctx)
+{
+ SSL *cssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+
+ /* Confirm we got the SSL object we were expecting */
+ return TEST_ptr_eq(cssl, quic_verify_ssl);
+}
+
+static int test_ssl_set_verify(void)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL;
+ int testresult = 0;
+ int ret, i;
+
+ if (!TEST_ptr(sctx = create_server_ctx())
+ || !TEST_ptr(cctx = create_client_ctx()))
+ goto err;
+
+ if (!create_quic_ssl_objects(sctx, cctx, &qlistener, &clientssl))
+ goto err;
+
+ quic_verify_ssl = clientssl;
+ SSL_set_verify(clientssl, SSL_VERIFY_PEER, quic_verify_cb);
+
+ /* Send ClientHello and server retry */
+ for (i = 0; i < 2; i++) {
+ ret = SSL_connect(clientssl);
+ if (!TEST_int_le(ret, 0)
+ || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ))
+ goto err;
+ SSL_handle_events(qlistener);
+ }
+
+ /* We expect a server SSL object which has not yet completed its handshake */
+ serverssl = SSL_accept_connection(qlistener, 0);
+
+ /* Call SSL_accept() and SSL_connect() until we are connected */
+ if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE, 0, 0)))
+ goto err;
+
+ testresult = 1;
+
+ err:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_free(qlistener);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
/***********************************************************************************/
OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n")
@@ -2786,6 +2962,8 @@ int setup_tests(void)
ADD_TEST(test_new_token);
#endif
ADD_TEST(test_server_method_with_ssl_new);
+ ADD_TEST(test_ssl_accept_connection);
+ ADD_TEST(test_ssl_set_verify);
return 1;
err:
cleanup_tests();
diff --git a/test/radix/quic_ops.c b/test/radix/quic_ops.c
index e3167a565ba4..d987cfeadec9 100644
--- a/test/radix/quic_ops.c
+++ b/test/radix/quic_ops.c
@@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
#include "internal/sockets.h"
+#include <openssl/rand.h>
static const unsigned char alpn_ossltest[] = {
/* "\x08ossltest" (hex for EBCDIC resilience) */
@@ -565,6 +566,40 @@ err:
return ok;
}
+DEF_FUNC(hf_write_rand)
+{
+ int ok = 0, r;
+ SSL *ssl;
+ void *buf = NULL;
+ size_t buf_len, bytes_written = 0;
+
+ F_POP(buf_len);
+ REQUIRE_SSL(ssl);
+
+ while (buf_len > 0) {
+ size_t thislen = buf_len > 1024 ? 1024 : buf_len;
+
+ if (buf == NULL)
+ buf = OPENSSL_malloc(thislen);
+ if (!TEST_ptr(buf))
+ goto err;
+ if (!TEST_int_eq(RAND_bytes(buf, thislen), 1))
+ goto err;
+ r = SSL_write_ex(ssl, buf, thislen, &bytes_written);
+ if (!TEST_true(r)
+ || !check_consistent_want(ssl, r)
+ || !TEST_size_t_eq(bytes_written, thislen))
+ goto err;
+
+ buf_len -= thislen;
+ }
+
+ ok = 1;
+err:
+ OPENSSL_free(buf);
+ return ok;
+}
+
DEF_FUNC(hf_write_ex2)
{
int ok = 0, r;
@@ -1112,6 +1147,11 @@ err:
OP_PUSH_BUFP(buf, buf_len), \
OP_FUNC(hf_write))
+#define OP_WRITE_RAND(name, buf_len) \
+ (OP_SELECT_SSL(0, name), \
+ OP_PUSH_SIZE(buf_len), \
+ OP_FUNC(hf_write_rand))
+
#define OP_WRITE_B(name, buf) \
OP_WRITE(name, (buf), sizeof(buf))
diff --git a/test/radix/quic_tests.c b/test/radix/quic_tests.c
index 2a29f1e80fe2..21ad05415da7 100644
--- a/test/radix/quic_tests.c
+++ b/test/radix/quic_tests.c
@@ -7,6 +7,16 @@
* https://www.openssl.org/source/license.html
*/
+#if defined(_AIX)
+/*
+ * Some versions of AIX define macros for events and revents for use when
+ * accessing pollfd structures (see Github issue #24236). That interferes
+ * with our use of these names here. We simply undef them.
+ */
+# undef revents
+# undef events
+#endif
+
/*
* Test Scripts
* ============================================================================
@@ -232,6 +242,58 @@ DEF_SCRIPT(ssl_poll,
}
}
+DEF_FUNC(check_writeable)
+{
+ int ok = 0;
+ SSL *ssl;
+ SSL_POLL_ITEM item;
+ size_t result_count = 0;
+ uint64_t expect;
+ const struct timeval z_timeout = {0}, *p_timeout = &z_timeout;
+
+ F_POP(expect);
+ REQUIRE_SSL(ssl);
+
+ item.desc = SSL_as_poll_descriptor(ssl);
+ item.events = SSL_POLL_EVENT_W;
+ item.revents = 0;
+
+ /* Zero-timeout call. */
+ result_count = SIZE_MAX;
+ if (!TEST_true(SSL_poll(&item, 1, sizeof(SSL_POLL_ITEM),
+ p_timeout, 0, &result_count)))
+ goto err;
+
+ ok = (!!(item.revents & SSL_POLL_EVENT_W) == expect);
+
+ err:
+ return ok;
+}
+
+DEF_SCRIPT(check_cwm, "check stream obeys cwm")
+{
+ OP_SIMPLE_PAIR_CONN();
+
+ /* Create the initial stream by writing some data */
+ OP_WRITE_RAND(C, 1024);
+
+ /* We should be writeable at the start */
+ OP_PUSH_U64(1);
+ OP_SELECT_SSL(0, C);
+ OP_FUNC(check_writeable);
+
+ /* Default stream cwm is 512k (we already sent 1k). Consume all the rest */
+ OP_WRITE_RAND(C, 511 * 1024);
+
+ /* Confirm we are no longer writeable */
+ OP_PUSH_U64(0);
+ OP_SELECT_SSL(0, C);
+ OP_FUNC(check_writeable);
+
+ /* We now expect writes to fail */
+ OP_WRITE_FAIL(C);
+}
+
/*
* List of Test Scripts
* ============================================================================
@@ -240,4 +302,5 @@ static SCRIPT_INFO *const scripts[] = {
USE(simple_conn)
USE(simple_thread)
USE(ssl_poll)
+ USE(check_cwm)
};
diff --git a/test/rand_test.c b/test/rand_test.c
index 0dd0e506ed5a..15a91e5b3e6b 100644
--- a/test/rand_test.c
+++ b/test/rand_test.c
@@ -15,6 +15,8 @@
#include "crypto/rand.h"
#include "testutil.h"
+static char *configfile;
+
static int test_rand(void)
{
EVP_RAND_CTX *privctx;
@@ -23,6 +25,7 @@ static int test_rand(void)
OSSL_PARAM params[2], *p = params;
unsigned char entropy1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
unsigned char entropy2[] = { 0xff, 0xfe, 0xfd };
+ unsigned char nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
unsigned char outbuf[3];
*p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
@@ -46,6 +49,13 @@ static int test_rand(void)
|| !TEST_mem_eq(outbuf, sizeof(outbuf), entropy2, sizeof(outbuf)))
return 0;
+ *params = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE,
+ nonce, sizeof(nonce));
+ if (!TEST_true(EVP_RAND_CTX_set_params(privctx, params))
+ || !TEST_true(EVP_RAND_nonce(privctx, outbuf, sizeof(outbuf)))
+ || !TEST_mem_eq(outbuf, sizeof(outbuf), nonce, sizeof(outbuf)))
+ return 0;
+
if (fips_provider_version_lt(NULL, 3, 4, 0)) {
/* Skip the rest and pass the test */
return 1;
@@ -244,9 +254,33 @@ static int test_rand_random_provider(void)
return res;
}
+static int test_rand_get0_primary(void)
+{
+ OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new();
+ int res = 0;
+
+ if (!TEST_ptr(ctx))
+ return 0;
+
+ if (!TEST_true(OSSL_LIB_CTX_load_config(ctx, configfile)))
+ goto err;
+
+ /* We simply test that we get a valid primary */
+ if (!TEST_ptr(RAND_get0_primary(ctx)))
+ goto err;
+
+ res = 1;
+ err:
+ OSSL_LIB_CTX_free(ctx);
+ return res;
+}
+
int setup_tests(void)
{
- char *configfile;
+ if (!test_skip_common_options()) {
+ TEST_error("Error parsing test options\n");
+ return 0;
+ }
if (!TEST_ptr(configfile = test_get_argument(0))
|| !TEST_true(RAND_set_DRBG_type(NULL, "TEST-RAND", "fips=no",
@@ -263,5 +297,9 @@ int setup_tests(void)
ADD_TEST(fips_health_tests);
ADD_TEST(test_rand_random_provider);
+
+ if (!OSSL_PROVIDER_available(NULL, "fips")
+ || fips_provider_version_ge(NULL, 3, 5, 1))
+ ADD_TEST(test_rand_get0_primary);
return 1;
}
diff --git a/test/recipes/15-test_ec.t b/test/recipes/15-test_ec.t
index c953fad9f1ec..9bf946e81b4b 100644
--- a/test/recipes/15-test_ec.t
+++ b/test/recipes/15-test_ec.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2025 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
@@ -18,7 +18,7 @@ setup("test_ec");
plan skip_all => 'EC is not supported in this build' if disabled('ec');
-plan tests => 15;
+plan tests => 16;
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
@@ -33,6 +33,16 @@ subtest 'EC conversions -- private key' => sub {
tconversion( -type => 'ec', -prefix => 'ec-priv',
-in => srctop_file("test","testec-p256.pem") );
};
+
+SKIP: {
+ skip "SM2 is not supported by this OpenSSL build", 1
+ if disabled("sm2");
+ subtest 'EC conversions -- private key' => sub {
+ tconversion( -type => 'ec', -prefix => 'sm2-priv',
+ -in => srctop_file("test","testec-sm2.pem") );
+ };
+}
+
subtest 'EC conversions -- private key PKCS#8' => sub {
tconversion( -type => 'ec', -prefix => 'ec-pkcs8',
-in => srctop_file("test","testec-p256.pem"),
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index 57f9081799fd..271f499690bf 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -10,6 +10,7 @@
use strict;
use warnings;
+use Cwd qw(abs_path);
use File::Spec::Functions qw/canonpath/;
use File::Copy;
use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir ok_nofips with/;
@@ -17,19 +18,19 @@ use OpenSSL::Test::Utils;
setup("test_verify");
+my @certspath = qw(test certs);
sub verify {
my ($cert, $purpose, $trusted, $untrusted, @opts) = @_;
- my @path = qw(test certs);
my @args = qw(openssl verify -auth_level 1);
push(@args, "-purpose", $purpose) if $purpose ne "";
push(@args, @opts);
- for (@$trusted) { push(@args, "-trusted", srctop_file(@path, "$_.pem")) }
- for (@$untrusted) { push(@args, "-untrusted", srctop_file(@path, "$_.pem")) }
- push(@args, srctop_file(@path, "$cert.pem"));
+ for (@$trusted) { push(@args, "-trusted", srctop_file(@certspath, "$_.pem")) }
+ for (@$untrusted) { push(@args, "-untrusted", srctop_file(@certspath, "$_.pem")) }
+ push(@args, srctop_file(@certspath, "$cert.pem"));
run(app([@args]));
}
-plan tests => 194;
+plan tests => 203;
# Canonical success
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -592,3 +593,31 @@ ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"],
"-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1",
"-explicit_policy"),
"Bad certificate policy");
+
+# CAstore option
+my $rootcertname = "root-cert";
+my $rootcert = srctop_file(@certspath, "${rootcertname}.pem");
+sub vfy_root { verify($rootcertname, "", [], [], @_) }
+ok(vfy_root("-CAfile", $rootcert), "CAfile");
+ok(vfy_root("-CAstore", $rootcert), "CAstore");
+ok(vfy_root("-CAstore", $rootcert, "-CAfile", $rootcert), "CAfile and existing CAstore");
+ok(!vfy_root("-CAstore", "non-existing", "-CAfile", $rootcert), "CAfile and non-existing CAstore");
+SKIP: {
+ skip "file names with colons aren't supported on Windows and VMS", 2
+ if $^O =~ /^(MsWin32|VMS)$/;
+ my $foo_file = "foo:cert.pem";
+ copy($rootcert, $foo_file);
+ ok(vfy_root("-CAstore", $foo_file), "CAstore foo:file");
+}
+my $foo_file = "cert.pem";
+copy($rootcert, $foo_file);
+ok(vfy_root("-CAstore", $foo_file), "CAstore foo:file");
+my $abs_cert = abs_path($rootcert);
+# Windows file: URIs should have a path part starting with a slash, i.e.
+# file://authority/C:/what/ever/foo.pem and file:///C:/what/ever/foo.pem
+# file://C:/what/ever/foo.pem is non-standard and may not be accepted.
+# See RFC 8089 for details.
+$abs_cert = "/" . $abs_cert if ($^O eq "MSWin32");
+ok(vfy_root("-CAstore", "file://".$abs_cert), "CAstore file:///path");
+ok(vfy_root("-CAstore", "file://localhost".$abs_cert), "CAstore file://localhost/path");
+ok(!vfy_root("-CAstore", "file://otherhost".$abs_cert), "CAstore file://otherhost/path");
diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t
index 09b61708ff8a..dfa0a428f5f0 100644
--- a/test/recipes/25-test_x509.t
+++ b/test/recipes/25-test_x509.t
@@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
setup("test_x509");
-plan tests => 134;
+plan tests => 138;
# Prevent MSys2 filename munging for arguments that look like file paths but
# aren't
@@ -110,6 +110,16 @@ ok(run(app(["openssl", "x509", "-new", "-force_pubkey", $key, "-subj", "/CN=EE",
&& run(app(["openssl", "verify", "-no_check_time",
"-trusted", $ca, "-partial_chain", $caout])));
+# test trust decoration
+ok(run(app(["openssl", "x509", "-in", $ca, "-addtrust", "emailProtection",
+ "-out", "ca-trusted.pem"])));
+cert_contains("ca-trusted.pem", "Trusted Uses: E-mail Protection",
+ 1, 'trusted use - E-mail Protection');
+ok(run(app(["openssl", "x509", "-in", $ca, "-addreject", "emailProtection",
+ "-out", "ca-rejected.pem"])));
+cert_contains("ca-rejected.pem", "Rejected Uses: E-mail Protection",
+ 1, 'rejected use - E-mail Protection');
+
subtest 'x509 -- x.509 v1 certificate' => sub {
tconversion( -type => 'x509', -prefix => 'x509v1',
-in => srctop_file("test", "testx509.pem") );
diff --git a/test/recipes/30-test_evp_data/evpciph_des3_common.txt b/test/recipes/30-test_evp_data/evpciph_des3_common.txt
index 1947e21f748d..6c74b65cef04 100644
--- a/test/recipes/30-test_evp_data/evpciph_des3_common.txt
+++ b/test/recipes/30-test_evp_data/evpciph_des3_common.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2001-2024 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2001-2025 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
@@ -74,7 +74,7 @@ Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
# Test that DES3 ECB mode encryption is not FIPS approved
-Availablein = fipss
+Availablein = fips
FIPSversion = >=3.4.0
Cipher = DES-EDE3-ECB
Operation = ENCRYPT
diff --git a/test/recipes/30-test_evp_data/evppkey_slh_dsa_keygen.txt b/test/recipes/30-test_evp_data/evppkey_slh_dsa_keygen.txt
index f136e718c05a..241771ae3be4 100644
--- a/test/recipes/30-test_evp_data/evppkey_slh_dsa_keygen.txt
+++ b/test/recipes/30-test_evp_data/evppkey_slh_dsa_keygen.txt
@@ -6,7 +6,7 @@
# https://www.openssl.org/source/license.html
# ACVP test data for SLH-DSA keyGen generated from
-# https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/SLH-DSA-keyGen-FIPS204/internalProjection.json
+# https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/SLH-DSA-keyGen-FIPS205/internalProjection.json
# [version 53]
FIPSversion = >=3.5.0
diff --git a/test/recipes/30-test_evp_data/evppkey_slh_dsa_siggen.txt b/test/recipes/30-test_evp_data/evppkey_slh_dsa_siggen.txt
index 397fe783acea..e17bf4ffa9d6 100644
--- a/test/recipes/30-test_evp_data/evppkey_slh_dsa_siggen.txt
+++ b/test/recipes/30-test_evp_data/evppkey_slh_dsa_siggen.txt
@@ -6,7 +6,7 @@
# https://www.openssl.org/source/license.html
# ACVP test data for SLH-DSA sigGen generated from
-# https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/SLH-DSA-sigGen-FIPS204/internalProjection.json
+# https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/SLH-DSA-sigGen-FIPS205/internalProjection.json
# [version 53]
PrivateKeyRaw = SLH_DSA_SHA2_128f_1:SLH-DSA-SHA2-128f:D5213BA4BB6470F1B9EDA88CBC94E6277A58A951EF7F2B81461DBAC41B5A6B83FA495FB834DEFEA7CC96A81309479135A67029E90668C5A58B96E60111491F3D
diff --git a/test/recipes/30-test_evp_data/evppkey_slh_dsa_sigver.txt b/test/recipes/30-test_evp_data/evppkey_slh_dsa_sigver.txt
index 647ac486a669..9aa165ae4bb6 100644
--- a/test/recipes/30-test_evp_data/evppkey_slh_dsa_sigver.txt
+++ b/test/recipes/30-test_evp_data/evppkey_slh_dsa_sigver.txt
@@ -6,7 +6,7 @@
# https://www.openssl.org/source/license.html
# ACVP test data for SLH-DSA sigVer generated from
-# https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/SLH-DSA-sigVer-FIPS204/internalProjection.json
+# https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/SLH-DSA-sigVer-FIPS205/internalProjection.json
# [version 53]
PublicKeyRaw = SLH_DSA_SHA2_128f_1:SLH-DSA-SHA2-128f:68669488582C94B7A609C9AB7EA5E15319A4F53DF851840326BE7E7BDD5B70CE
diff --git a/test/recipes/30-test_pairwise_fail.t b/test/recipes/30-test_pairwise_fail.t
index a101a26fb184..eaf0dbbb424f 100644
--- a/test/recipes/30-test_pairwise_fail.t
+++ b/test/recipes/30-test_pairwise_fail.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2023-2025 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
@@ -22,7 +22,7 @@ use lib bldtop_dir('.');
plan skip_all => "These tests are unsupported in a non fips build"
if disabled("fips");
-plan tests => 6;
+plan tests => 9;
my $provconf = srctop_file("test", "fips-and-base.cnf");
run(test(["fips_version_test", "-config", $provconf, ">=3.1.0"]),
@@ -77,3 +77,45 @@ SKIP: {
"-pairwise", "eddsa"])),
"fips provider eddsa keygen pairwise failure test");
}
+
+SKIP: {
+ skip "Skip ML-DSA test because of no ml-dsa in this build", 1
+ if disabled("ml-dsa");
+
+ run(test(["fips_version_test", "-config", $provconf, ">=3.5.0"]),
+ capture => 1, statusvar => \my $exit);
+ skip "FIPS provider version is too old", 1
+ if !$exit;
+
+ ok(run(test(["pairwise_fail_test", "-config", $provconf,
+ "-pairwise", "ml-dsa"])),
+ "fips provider ml-dsa keygen pairwise failure test");
+}
+
+SKIP: {
+ skip "Skip SLH-DSA test because of no slh-dsa in this build", 1
+ if disabled("slh-dsa");
+
+ run(test(["fips_version_test", "-config", $provconf, ">=3.5.0"]),
+ capture => 1, statusvar => \my $exit);
+ skip "FIPS provider version is too old", 1
+ if !$exit;
+
+ ok(run(test(["pairwise_fail_test", "-config", $provconf,
+ "-pairwise", "slh-dsa"])),
+ "fips provider slh-dsa keygen pairwise failure test");
+}
+
+SKIP: {
+ skip "Skip ML-KEM test because of no ml-kem in this build", 1
+ if disabled("ml-kem");
+
+ run(test(["fips_version_test", "-config", $provconf, ">=3.5.0"]),
+ capture => 1, statusvar => \my $exit);
+ skip "FIPS provider version is too old", 1
+ if !$exit;
+
+ ok(run(test(["pairwise_fail_test", "-config", $provconf,
+ "-pairwise", "ml-kem"])),
+ "fips provider ml-kem keygen pairwise failure test");
+}
diff --git a/test/recipes/70-test_sslkeylogfile.t b/test/recipes/70-test_sslkeylogfile.t
index acff862229af..2be202f785e3 100644
--- a/test/recipes/70-test_sslkeylogfile.t
+++ b/test/recipes/70-test_sslkeylogfile.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2024-2025 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
@@ -19,7 +19,12 @@ setup($test_name);
plan skip_all => "$test_name requires SSLKEYLOGFILE support"
if disabled("sslkeylog");
-plan tests => 1;
+my $tests = 1;
+if ($^O =~ /^(linux)$/) {
+ $tests = 2;
+}
+
+plan tests => $tests;
my $shlib_wrap = srctop_file("util", "wrap.pl");
@@ -75,3 +80,9 @@ kill 'HUP', $s_server_pid;
# Test 1: Compare the output of -keylogfile and SSLKEYLOGFILE, and make sure they match
# Note, the former adds a comment, that the latter does not, so ignore comments with -I in diff
ok(run(cmd(["diff", "-I" ,"^#.*\$", $sslkeylogfile, $trace_file])));
+
+# Test 2, linux-specific: the keylog file should have permission 0600
+if ($^O =~ /^(linux)$/) {
+ my $mode = sprintf("%04o", (stat($sslkeylogfile))[2] & 07777);
+ ok($mode eq "0600");
+}
diff --git a/test/recipes/70-test_sslrecords.t b/test/recipes/70-test_sslrecords.t
index 691db13b8a8e..299ecb60bea1 100644
--- a/test/recipes/70-test_sslrecords.t
+++ b/test/recipes/70-test_sslrecords.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2025 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
@@ -33,17 +33,17 @@ my $fatal_alert = undef; # set by filters at expected fatal alerts
my $sslv2testtype = undef;
my $proxy_start_success = 0;
-plan tests => 42;
+plan tests => 44;
SKIP: {
- skip "TLS 1.2 is disabled", 21 if disabled("tls1_2");
+ skip "TLS 1.2 is disabled", 22 if disabled("tls1_2");
# Run tests with TLS
run_tests(0);
}
SKIP: {
- skip "DTLS 1.2 is disabled", 21 if disabled("dtls1_2");
- skip "DTLSProxy does not work on Windows", 21 if $^O =~ /^(MSWin32)$/;
+ skip "DTLS 1.2 is disabled", 22 if disabled("dtls1_2");
+ skip "DTLSProxy does not work on Windows", 22 if $^O =~ /^(MSWin32)$/;
run_tests(1);
}
@@ -336,8 +336,17 @@ sub run_tests
}
}
}
-}
+ SKIP: {
+ skip "DTLS only record tests", 1 if $run_test_as_dtls != 1;
+ #Test 22: We should ignore empty app data records
+ $proxy->clear();
+ $proxy->filter(\&empty_app_data);
+ $proxy->start();
+ ok(TLSProxy::Message->success(), "Empty app data in DTLS");
+
+ }
+}
sub add_empty_recs_filter
{
@@ -864,3 +873,41 @@ sub not_on_record_boundary
}
}
+
+sub empty_app_data
+{
+ my $proxy = shift;
+
+ # We're only interested in the client's Certificate..Finished flight
+ if ($proxy->flight != 4) {
+ return;
+ }
+
+ my $data = pack "C52",
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, #IV
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, #One block of empty padded data
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13; #MAC, assume to be 20 bytes
+
+ # Add a zero length app data record at the end
+ # This will have the same sequence number as the subsequent app data record
+ # that s_client will send - which will cause that second record to be
+ # dropped. But that isn't important for this test.
+ my $record = TLSProxy::Record->new_dtls(
+ 4,
+ TLSProxy::Record::RT_APPLICATION_DATA,
+ TLSProxy::Record::VERS_DTLS_1_2,
+ 1,
+ 1,
+ length($data),
+ 0,
+ length($data),
+ 0,
+ $data,
+ ""
+ );
+ push @{$proxy->record_list}, $record;
+}
diff --git a/test/recipes/70-test_tls13downgrade.t b/test/recipes/70-test_tls13downgrade.t
index 999a79e62a84..35a4beee0695 100644
--- a/test/recipes/70-test_tls13downgrade.t
+++ b/test/recipes/70-test_tls13downgrade.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2025 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
@@ -24,9 +24,8 @@ plan skip_all => "$test_name needs the sock feature enabled"
if disabled("sock");
plan skip_all => "$test_name needs TLS1.3 and TLS1.2 enabled"
- if disabled("tls1_3")
- || (disabled("ec") && disabled("dh"))
- || disabled("tls1_2");
+ if disabled("tls1_3") || disabled("tls1_2")
+ || (disabled("ec") && disabled("dh"));
my $proxy = TLSProxy::Proxy->new(
undef,
@@ -39,89 +38,150 @@ use constant {
DOWNGRADE_TO_TLS_1_2 => 0,
DOWNGRADE_TO_TLS_1_1 => 1,
FALLBACK_FROM_TLS_1_3 => 2,
+ DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL => 3,
+ DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL => 4,
};
#Test 1: Downgrade from TLSv1.3 to TLSv1.2
$proxy->filter(\&downgrade_filter);
my $testtype = DOWNGRADE_TO_TLS_1_2;
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
-plan tests => 6;
-ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.2");
+plan tests => 8;
+ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.2");
-#Test 2: Downgrade from TLSv1.3 to TLSv1.1
+#Test 2: Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal)
$proxy->clear();
-$testtype = DOWNGRADE_TO_TLS_1_1;
+$testtype = DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL;
$proxy->start();
-ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.1");
+ok(is_illegal_parameter_client_alert(),
+ "Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal)");
-#Test 3: Downgrade from TLSv1.2 to TLSv1.1
-$proxy->clear();
-$proxy->clientflags("-no_tls1_3");
-$proxy->serverflags("-no_tls1_3");
-$proxy->start();
-ok(TLSProxy::Message->fail(), "Downgrade TLSv1.2 to TLSv1.1");
-
-#Test 4: Client falls back from TLSv1.3 (server does not support the fallback
+#Test 3: Client falls back from TLSv1.3 (server does not support the fallback
# SCSV)
$proxy->clear();
$testtype = FALLBACK_FROM_TLS_1_3;
$proxy->clientflags("-fallback_scsv -no_tls1_3");
$proxy->start();
-my $alert = TLSProxy::Message->alert();
-ok(TLSProxy::Message->fail()
- && !$alert->server()
- && $alert->description() == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER,
- "Fallback from TLSv1.3");
+ok(is_illegal_parameter_client_alert(), "Fallback from TLSv1.3");
SKIP: {
- skip "TLSv1.1 disabled", 2 if disabled("tls1_1");
- #Test 5: A client side protocol "hole" should not be detected as a downgrade
+ skip "TLSv1.1 disabled", 5 if disabled("tls1_1");
+
+ my $client_flags = "-min_protocol TLSv1.1 -cipher DEFAULT:\@SECLEVEL=0";
+ my $server_flags = "-min_protocol TLSv1.1";
+ my $ciphers = "AES128-SHA:\@SECLEVEL=0";
+
+ #Test 4: Downgrade from TLSv1.3 to TLSv1.1
+ $proxy->clear();
+ $testtype = DOWNGRADE_TO_TLS_1_1;
+ $proxy->clientflags($client_flags);
+ $proxy->serverflags($server_flags);
+ $proxy->ciphers($ciphers);
+ $proxy->start();
+ ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.1");
+
+ #Test 5: Downgrade from TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal)
+ $proxy->clear();
+ $testtype = DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL;
+ $proxy->clientflags($client_flags);
+ $proxy->serverflags($server_flags);
+ $proxy->ciphers($ciphers);
+ $proxy->start();
+ ok(is_illegal_parameter_client_alert(),
+ "Downgrade TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal)");
+
+ #Test 6: Downgrade from TLSv1.2 to TLSv1.1
+ $proxy->clear();
+ $testtype = DOWNGRADE_TO_TLS_1_1;
+ $proxy->clientflags($client_flags." -max_protocol TLSv1.2");
+ $proxy->serverflags($server_flags." -max_protocol TLSv1.2");
+ $proxy->ciphers($ciphers);
+ $proxy->start();
+ ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.2 to TLSv1.1");
+
+ #Test 7: A client side protocol "hole" should not be detected as a downgrade
$proxy->clear();
$proxy->filter(undef);
- $proxy->clientflags("-no_tls1_2");
- $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
+ $proxy->clientflags($client_flags." -no_tls1_2");
+ $proxy->serverflags($server_flags);
+ $proxy->ciphers($ciphers);
$proxy->start();
ok(TLSProxy::Message->success(), "TLSv1.2 client-side protocol hole");
- #Test 6: A server side protocol "hole" should not be detected as a downgrade
+ #Test 8: A server side protocol "hole" should not be detected as a downgrade
$proxy->clear();
$proxy->filter(undef);
- $proxy->serverflags("-no_tls1_2");
+ $proxy->clientflags($client_flags);
+ $proxy->serverflags($server_flags." -no_tls1_2");
+ $proxy->ciphers($ciphers);
$proxy->start();
ok(TLSProxy::Message->success(), "TLSv1.2 server-side protocol hole");
}
+# Validate that the exchange fails with an illegal parameter alert from
+# the client
+sub is_illegal_parameter_client_alert
+{
+ return 0 unless TLSProxy::Message->fail();
+ my $alert = TLSProxy::Message->alert();
+ return 1 if !$alert->server()
+ && $alert->description()
+ == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER;
+ return 0;
+}
+
sub downgrade_filter
{
my $proxy = shift;
- # We're only interested in the initial ClientHello
- if ($proxy->flight != 0) {
+ # We're only interested in the initial ClientHello and ServerHello
+ if ($proxy->flight > 1) {
return;
}
- my $message = ${$proxy->message_list}[0];
-
- my $ext;
- if ($testtype == FALLBACK_FROM_TLS_1_3) {
- #The default ciphersuite we use for TLSv1.2 without any SCSV
- my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA);
- $message->ciphersuite_len(2 * scalar @ciphersuites);
- $message->ciphersuites(\@ciphersuites);
- } else {
- if ($testtype == DOWNGRADE_TO_TLS_1_2) {
- $ext = pack "C3",
- 0x02, # Length
- 0x03, 0x03; #TLSv1.2
- } else {
- $ext = pack "C3",
- 0x02, # Length
- 0x03, 0x02; #TLSv1.1
+ my $message = ${$proxy->message_list}[$proxy->flight];
+
+ # ServerHello
+ if ($proxy->flight == 1 && defined($message)) {
+ # Update the last byte of the downgrade signal
+ if ($testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) {
+ $message->random(substr($message->random, 0, 31) . "\0");
+ $message->repack();
+ } elsif ($testtype == DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL) {
+ $message->random(substr($message->random, 0, 31) . "\1");
+ $message->repack();
}
- $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, $ext);
+ return;
}
- $message->repack();
+ # ClientHello
+ if ($proxy->flight == 0) {
+ my $ext;
+ if ($testtype == FALLBACK_FROM_TLS_1_3) {
+ #The default ciphersuite we use for TLSv1.2 without any SCSV
+ my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA);
+ $message->ciphersuite_len(2 * scalar @ciphersuites);
+ $message->ciphersuites(\@ciphersuites);
+ }
+ else {
+ if ($testtype == DOWNGRADE_TO_TLS_1_2
+ || $testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) {
+ $ext = pack "C3",
+ 0x02, # Length
+ 0x03, 0x03; #TLSv1.2
+ }
+ else {
+ $ext = pack "C3",
+ 0x02, # Length
+ 0x03, 0x02; #TLSv1.1
+ }
+
+ $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
+ $ext);
+ }
+
+ $message->repack();
+ }
}
diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t
index 916f952a0c3e..5fc620a1399e 100644
--- a/test/recipes/80-test_ca.t
+++ b/test/recipes/80-test_ca.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2015-2025 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
@@ -21,9 +21,7 @@ setup("test_ca");
$ENV{OPENSSL} = cmdstr(app(["openssl"]), display => 1);
my $cnf = srctop_file("test","ca-and-certs.cnf");
-my $std_openssl_cnf = '"'
- . srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf")
- . '"';
+my $std_openssl_cnf = srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf");
sub src_file {
return srctop_file("test", "certs", shift);
@@ -40,14 +38,14 @@ require_ok(srctop_file("test", "recipes", "tconversion.pl"));
$ENV{OPENSSL_CONFIG} = qq(-config "$cnf");
skip "failed creating CA structure", 4
if !ok(run(perlapp(["CA.pl","-newca",
- "-extra-req", "-key $cakey"], stdin => undef)),
+ "-extra-req", qq{-key "$cakey"}], stdin => undef)),
'creating CA structure');
my $eekey = src_file("ee-key.pem");
$ENV{OPENSSL_CONFIG} = qq(-config "$cnf");
skip "failed creating new certificate request", 3
if !ok(run(perlapp(["CA.pl","-newreq",
- '-extra-req', "-outform DER -section userreq -key $eekey"])),
+ '-extra-req', qq{-outform DER -section userreq -key "$eekey"}])),
'creating certificate request');
$ENV{OPENSSL_CONFIG} = qq(-rand_serial -inform DER -config "$std_openssl_cnf");
skip "failed to sign certificate request", 2
@@ -62,7 +60,8 @@ require_ok(srctop_file("test", "recipes", "tconversion.pl"));
my $eekey2 = src_file("ee-key-3072.pem");
$ENV{OPENSSL_CONFIG} = qq(-config "$cnf");
- ok(run(perlapp(["CA.pl", "-precert", '-extra-req', "-section userreq -key $eekey2"], stderr => undef)),
+ ok(run(perlapp(["CA.pl", "-precert",
+ '-extra-req', qq{-section userreq -key "$eekey2"}], stderr => undef)),
'creating new pre-certificate');
}
diff --git a/test/recipes/90-test_store_cases.t b/test/recipes/90-test_store_cases.t
index 05b00e6b4eb1..5915a1b76a53 100644
--- a/test/recipes/90-test_store_cases.t
+++ b/test/recipes/90-test_store_cases.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2023-2025 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
@@ -18,9 +18,10 @@ use OpenSSL::Test::Utils;
my $test_name = "test_store_cases";
setup($test_name);
-plan tests => 2;
+plan tests => 3;
my $stderr;
+my @stdout;
# The case of the garbage PKCS#12 DER file where a passphrase was
# prompted for. That should not have happened.
@@ -34,3 +35,24 @@ open DATA, $stderr;
close DATA;
ok(scalar @match > 0 ? 0 : 1,
"checking that storeutl didn't ask for a passphrase");
+
+ SKIP: {
+ skip "The objects in test-BER.p12 contain EC keys, which is disabled in this build", 1
+ if disabled("ec");
+ skip "test-BER.p12 has contents encrypted with DES-EDE3-CBC, which is disabled in this build", 1
+ if disabled("des");
+
+ # The case with a BER-encoded PKCS#12 file, using infinite + EOC
+ # constructs. There was a bug with those in OpenSSL 3.0 and newer,
+ # where OSSL_STORE_load() (and by consequence, 'openssl storeutl')
+ # only extracted the first available object from that file and
+ # ignored the rest.
+ # Our test file has a total of four objects, and this should be
+ # reflected in the total that 'openssl storeutl' outputs
+ @stdout = run(app(['openssl', 'storeutl', '-passin', 'pass:12345',
+ data_file('test-BER.p12')]),
+ capture => 1);
+ @stdout = map { my $x = $_; $x =~ s/\R$//; $x } @stdout; # Better chomp
+ ok((grep { $_ eq 'Total found: 4' } @stdout),
+ "Checking that 'openssl storeutl' with test-BER.p12 returns 4 objects");
+}
diff --git a/test/recipes/90-test_store_cases_data/test-BER.p12 b/test/recipes/90-test_store_cases_data/test-BER.p12
new file mode 100644
index 000000000000..256e697bac1a
--- /dev/null
+++ b/test/recipes/90-test_store_cases_data/test-BER.p12
Binary files differ
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 38d58e938743..b83dd6c552de 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -7315,18 +7315,6 @@ static int test_ssl_clear(int idx)
} else {
SSL_set_accept_state(serverssl);
}
- /*
- * A peculiarity of SSL_clear() is that it does not clear the session.
- * This is intended behaviour so that a client can create a new
- * connection and reuse the session. But this doesn't make much sense
- * on the server side - and causes incorrect behaviour due to the
- * handshake failing (even though the documentation does say SSL_clear()
- * is supposed to work on the server side). We clear the session
- * explicitly - although note that the documentation for
- * SSL_set_session() says that its only useful for clients!
- */
- if (!TEST_true(SSL_set_session(serverssl, NULL)))
- goto end;
SSL_free(clientssl);
clientssl = NULL;
} else {
@@ -12599,6 +12587,7 @@ struct quic_tls_test_data {
int alert;
int err;
int forcefail;
+ int sm_count;
};
static int clientquicdata = 0xff, serverquicdata = 0xfe;
@@ -12686,6 +12675,94 @@ static int crypto_release_rcd_cb(SSL *s, size_t bytes_read, void *arg)
return 1;
}
+struct secret_yield_entry {
+ uint8_t recorded;
+ int prot_level;
+ int direction;
+ int sm_generation;
+ SSL *ssl;
+};
+
+static struct secret_yield_entry secret_history[16];
+static int secret_history_idx = 0;
+/*
+ * Note, this enum needs to match the direction values passed
+ * to yield_secret_cb
+ */
+typedef enum {
+ LAST_DIR_READ = 0,
+ LAST_DIR_WRITE = 1,
+ LAST_DIR_UNSET = 2
+} last_dir_history_state;
+
+static int check_secret_history(SSL *s)
+{
+ int i;
+ int ret = 0;
+ last_dir_history_state last_state = LAST_DIR_UNSET;
+ int last_prot_level = 0;
+ int last_generation = 0;
+
+ TEST_info("Checking history for %p\n", (void *)s);
+ for (i = 0; secret_history[i].recorded == 1; i++) {
+ if (secret_history[i].ssl != s)
+ continue;
+ TEST_info("Got %s(%d) secret for level %d, last level %d, last state %d, gen %d\n",
+ secret_history[i].direction == 1 ? "Write" : "Read", secret_history[i].direction,
+ secret_history[i].prot_level, last_prot_level, last_state,
+ secret_history[i].sm_generation);
+
+ if (last_state == LAST_DIR_UNSET) {
+ last_prot_level = secret_history[i].prot_level;
+ last_state = secret_history[i].direction;
+ last_generation = secret_history[i].sm_generation;
+ continue;
+ }
+
+ switch(secret_history[i].direction) {
+ case 1:
+ /*
+ * write case
+ * NOTE: There is an odd corner case here. It may occur that
+ * in a single iteration of the state machine, the read key is yielded
+ * prior to the write key for the same level. This is undesireable
+ * for quic, but it is ok, as the general implementation of every 3rd
+ * party quic stack while prefering write keys before read, allows
+ * for read before write if both keys are yielded in the same call
+ * to SSL_do_handshake, as the tls adaptation code for that quic stack
+ * can then cache keys until both are available, so we allow read before
+ * write here iff they occur in the same iteration of SSL_do_handshake
+ * as represented by the recorded sm_generation value.
+ */
+ if (last_prot_level == secret_history[i].prot_level
+ && last_state == LAST_DIR_READ) {
+ if (last_generation == secret_history[i].sm_generation) {
+ TEST_info("Read before write key in same SSL state machine iteration is ok");
+ } else {
+ TEST_error("Got read key before write key");
+ goto end;
+ }
+ }
+ /* FALLTHROUGH */
+ case 0:
+ /*
+ * Read case
+ */
+ break;
+ default:
+ TEST_error("Unknown direction");
+ goto end;
+ }
+ last_prot_level = secret_history[i].prot_level;
+ last_state = secret_history[i].direction;
+ last_generation = secret_history[i].sm_generation;
+ }
+
+ ret = 1;
+end:
+ return ret;
+}
+
static int yield_secret_cb(SSL *s, uint32_t prot_level, int direction,
const unsigned char *secret, size_t secret_len,
void *arg)
@@ -12720,12 +12797,34 @@ static int yield_secret_cb(SSL *s, uint32_t prot_level, int direction,
goto err;
}
+ secret_history[secret_history_idx].direction = direction;
+ secret_history[secret_history_idx].prot_level = (int)prot_level;
+ secret_history[secret_history_idx].recorded = 1;
+ secret_history[secret_history_idx].ssl = s;
+ secret_history[secret_history_idx].sm_generation = data->sm_count;
+ secret_history_idx++;
return 1;
err:
data->err = 1;
return 0;
}
+static int yield_secret_cb_fail(SSL *s, uint32_t prot_level, int direction,
+ const unsigned char *secret, size_t secret_len,
+ void *arg)
+{
+ (void)s;
+ (void)prot_level;
+ (void)direction;
+ (void)secret;
+ (void)secret_len;
+ (void)arg;
+ /*
+ * This callback is to test double free in quic tls
+ */
+ return 0;
+}
+
static int got_transport_params_cb(SSL *s, const unsigned char *params,
size_t params_len,
void *arg)
@@ -12766,13 +12865,15 @@ static int alert_cb(SSL *s, unsigned char alert_code, void *arg)
* Test 0: Normal run
* Test 1: Force a failure
* Test 3: Use a CCM based ciphersuite
+ * Test 4: fail yield_secret_cb to see double free
+ * Test 5: Normal run with SNI
*/
static int test_quic_tls(int idx)
{
- SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL_CTX *sctx = NULL, *sctx2 = NULL, *cctx = NULL;
SSL *serverssl = NULL, *clientssl = NULL;
int testresult = 0;
- const OSSL_DISPATCH qtdis[] = {
+ OSSL_DISPATCH qtdis[] = {
{OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_SEND, (void (*)(void))crypto_send_cb},
{OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_RECV_RCD,
(void (*)(void))crypto_recv_rcd_cb},
@@ -12794,6 +12895,12 @@ static int test_quic_tls(int idx)
};
int i;
+ if (idx == 4)
+ qtdis[3].function = (void (*)(void))yield_secret_cb_fail;
+
+ snicb = 0;
+ memset(secret_history, 0, sizeof(secret_history));
+ secret_history_idx = 0;
memset(&sdata, 0, sizeof(sdata));
memset(&cdata, 0, sizeof(cdata));
sdata.peer = &cdata;
@@ -12806,6 +12913,18 @@ static int test_quic_tls(int idx)
&sctx, &cctx, cert, privkey)))
goto end;
+ if (idx == 5) {
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), NULL,
+ TLS1_3_VERSION, 0,
+ &sctx2, NULL, cert, privkey)))
+ goto end;
+
+ /* Set up SNI */
+ if (!TEST_true(SSL_CTX_set_tlsext_servername_callback(sctx, sni_cb))
+ || !TEST_true(SSL_CTX_set_tlsext_servername_arg(sctx, sctx2)))
+ goto end;
+ }
+
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
NULL)))
goto end;
@@ -12832,18 +12951,26 @@ static int test_quic_tls(int idx)
sizeof(sparams))))
goto end;
- if (idx != 1) {
- if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ if (idx != 1 && idx != 4) {
+ if (!TEST_true(create_ssl_connection_ex(serverssl, clientssl, SSL_ERROR_NONE,
+ &cdata.sm_count, &sdata.sm_count)))
goto end;
} else {
/* We expect this connection to fail */
- if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ if (!TEST_false(create_ssl_connection_ex(serverssl, clientssl, SSL_ERROR_NONE,
+ &cdata.sm_count, &sdata.sm_count)))
goto end;
testresult = 1;
sdata.err = 0;
goto end;
}
+ /* We should have had the SNI callback called exactly once */
+ if (idx == 5) {
+ if (!TEST_int_eq(snicb, 1))
+ goto end;
+ }
+
/* Check no problems during the handshake */
if (!TEST_false(sdata.alert)
|| !TEST_false(cdata.alert)
@@ -12860,6 +12987,14 @@ static int test_quic_tls(int idx)
goto end;
}
+ /*
+ * Check that our secret history yields write secrets before read secrets
+ */
+ if (!TEST_int_eq(check_secret_history(serverssl), 1))
+ goto end;
+ if (!TEST_int_eq(check_secret_history(clientssl), 1))
+ goto end;
+
/* Check the transport params */
if (!TEST_mem_eq(sdata.params, sdata.params_len, cparams, sizeof(cparams))
|| !TEST_mem_eq(cdata.params, cdata.params_len, sparams,
@@ -12877,6 +13012,7 @@ static int test_quic_tls(int idx)
end:
SSL_free(serverssl);
SSL_free(clientssl);
+ SSL_CTX_free(sctx2);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
@@ -12924,6 +13060,8 @@ static int test_quic_tls_early_data(void)
};
int i;
+ memset(secret_history, 0, sizeof(secret_history));
+ secret_history_idx = 0;
memset(&sdata, 0, sizeof(sdata));
memset(&cdata, 0, sizeof(cdata));
sdata.peer = &cdata;
@@ -12973,6 +13111,12 @@ static int test_quic_tls_early_data(void)
sizeof(sparams))))
goto end;
+ /*
+ * Reset our secret history so we get the record of the second connection
+ */
+ memset(secret_history, 0, sizeof(secret_history));
+ secret_history_idx = 0;
+
SSL_set_quic_tls_early_data_enabled(serverssl, 1);
SSL_set_quic_tls_early_data_enabled(clientssl, 1);
@@ -12993,7 +13137,10 @@ static int test_quic_tls_early_data(void)
|| !TEST_true(cdata.wenc_level == OSSL_RECORD_PROTECTION_LEVEL_EARLY))
goto end;
- if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ sdata.sm_count = 0;
+ cdata.sm_count = 0;
+ if (!TEST_true(create_ssl_connection_ex(serverssl, clientssl, SSL_ERROR_NONE,
+ &cdata.sm_count, &sdata.sm_count)))
goto end;
/* Check no problems during the handshake */
@@ -13012,6 +13159,11 @@ static int test_quic_tls_early_data(void)
goto end;
}
+ if (!TEST_int_eq(check_secret_history(serverssl), 1))
+ goto end;
+ if (!TEST_int_eq(check_secret_history(clientssl), 1))
+ goto end;
+
/* Check the transport params */
if (!TEST_mem_eq(sdata.params, sdata.params_len, cparams, sizeof(cparams))
|| !TEST_mem_eq(cdata.params, cdata.params_len, sparams,
@@ -13044,6 +13196,79 @@ static int test_quic_tls_early_data(void)
}
#endif /* !defined(OSSL_NO_USABLE_TLS1_3) */
+static int test_no_renegotiation(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0, ret;
+ int max_proto;
+ const SSL_METHOD *sm, *cm;
+ unsigned char buf[5];
+
+ if (idx == 0) {
+#ifndef OPENSSL_NO_TLS1_2
+ max_proto = TLS1_2_VERSION;
+ sm = TLS_server_method();
+ cm = TLS_client_method();
+#else
+ return TEST_skip("TLSv1.2 is disabled in this build");
+#endif
+ } else {
+#ifndef OPENSSL_NO_DTLS1_2
+ max_proto = DTLS1_2_VERSION;
+ sm = DTLS_server_method();
+ cm = DTLS_client_method();
+#else
+ return TEST_skip("DTLSv1.2 is disabled in this build");
+#endif
+ }
+ if (!TEST_true(create_ssl_ctx_pair(libctx, sm, cm, 0, max_proto,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ SSL_CTX_set_options(sctx, SSL_OP_NO_RENEGOTIATION);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
+ NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (!TEST_true(SSL_renegotiate(clientssl))
+ || !TEST_int_le(ret = SSL_connect(clientssl), 0)
+ || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ))
+ goto end;
+
+ /*
+ * We've not sent any application data, so we expect this to fail. It should
+ * also read the renegotiation attempt, and send back a no_renegotiation
+ * warning alert because we have renegotiation disabled.
+ */
+ if (!TEST_int_le(ret = SSL_read(serverssl, buf, sizeof(buf)), 0))
+ goto end;
+ if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_WANT_READ))
+ goto end;
+
+ /*
+ * The client should now see the no_renegotiation warning and fail the
+ * connection
+ */
+ if (!TEST_int_le(ret = SSL_connect(clientssl), 0)
+ || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_SSL)
+ || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_RENEGOTIATION))
+ goto end;
+
+ testresult = 1;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
int setup_tests(void)
@@ -13369,9 +13594,10 @@ int setup_tests(void)
#endif
ADD_ALL_TESTS(test_alpn, 4);
#if !defined(OSSL_NO_USABLE_TLS1_3)
- ADD_ALL_TESTS(test_quic_tls, 3);
+ ADD_ALL_TESTS(test_quic_tls, 6);
ADD_TEST(test_quic_tls_early_data);
#endif
+ ADD_ALL_TESTS(test_no_renegotiation, 2);
return 1;
err:
diff --git a/test/testec-sm2.pem b/test/testec-sm2.pem
new file mode 100644
index 000000000000..30e25613b38e
--- /dev/null
+++ b/test/testec-sm2.pem
@@ -0,0 +1,5 @@
+-----BEGIN SM2 PRIVATE KEY-----
+MHcCAQEEIKPB7gEYKGAwAkz0MfGwQm0BXclgzvSTxQG9bm4RCAxXoAoGCCqBHM9V
+AYItoUQDQgAE+FuibOpfjVfj716O3LglhK4HzjUR82mgn8kTZinQsEafw3FFZzZJ
+vwHIGHUsSKxVTRIEs+BICQDBg99OA3VU/Q==
+-----END SM2 PRIVATE KEY-----
diff --git a/test/testutil/testutil_init.c b/test/testutil/testutil_init.c
index 3301551ab2f7..64224186e477 100644
--- a/test/testutil/testutil_init.c
+++ b/test/testutil/testutil_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2025 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
@@ -92,6 +92,7 @@ static void setup_trace_category(int category)
"warning: unable to setup trace callback for category '%s'.\n",
OSSL_trace_get_category_name(category));
+ OPENSSL_free(trace_data);
OSSL_trace_set_callback(category, NULL, NULL);
BIO_free_all(channel);
}
diff --git a/test/threadstest.c b/test/threadstest.c
index e30a3e817d8c..76db07f3baf6 100644
--- a/test/threadstest.c
+++ b/test/threadstest.c
@@ -590,6 +590,29 @@ static int test_thread_local(void)
return 1;
}
+/*
+ * Basic test to ensure that we can repeatedly create and
+ * destroy local keys without leaking anything
+ */
+static int test_thread_local_multi_key(void)
+{
+ int dummy;
+ int i;
+
+ for (i = 0; i < 1000; i++) {
+ if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
+ thread_local_destructor)))
+ return 0;
+
+ if (!TEST_true(CRYPTO_THREAD_set_local(&thread_local_key, &dummy)))
+ return 0;
+
+ if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
+ return 0;
+ }
+ return 1;
+}
+
static int test_atomic(void)
{
int val = 0, ret = 0, testresult = 0;
@@ -1339,6 +1362,7 @@ int setup_tests(void)
#endif
ADD_TEST(test_once);
ADD_TEST(test_thread_local);
+ ADD_TEST(test_thread_local_multi_key);
ADD_TEST(test_atomic);
ADD_TEST(test_multi_load);
ADD_TEST(test_multi_general_worker_default_provider);
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
index 4dd1b4468279..9f33895a4fd9 100644
--- a/tools/c_rehash.in
+++ b/tools/c_rehash.in
@@ -1,7 +1,7 @@
#!{- $config{HASHBANGPERL} -}
{- use OpenSSL::Util; -}
# {- join("\n# ", @autowarntext) -}
-# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1999-2025 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
@@ -63,10 +63,10 @@ if (defined(&Cwd::getcwd)) {
my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':';
$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : "");
-if (! -x $openssl) {
+if (!(-f $openssl && -x $openssl)) {
my $found = 0;
foreach (split /$path_delim/, $ENV{PATH}) {
- if (-x "$_/$openssl") {
+ if (-f "$_/$openssl" && -x "$_/$openssl") {
$found = 1;
$openssl = "$_/$openssl";
last;
@@ -88,7 +88,7 @@ if (@ARGV) {
if (-d $dirlist[0]) {
chdir $dirlist[0];
- $openssl="$pwd/$openssl" if (!-x $openssl);
+ $openssl="$pwd/$openssl" if (!(-f $openssl && -x $openssl));
chdir $pwd;
}
diff --git a/util/check-format-test-negatives.c b/util/check-format-test-negatives.c
index f6b1bfb31920..753a280b0e72 100644
--- a/util/check-format-test-negatives.c
+++ b/util/check-format-test-negatives.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Siemens AG 2015-2022
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -10,7 +10,7 @@
/*
* A collection of test cases where check-format.pl should not report issues.
- * There are some known false positives, though, which are marked below.
+ * There are some known false positives, though, which are marked below using /*@
*/
#include <errno.h> /* should not report whitespace nits within <...> */
@@ -161,6 +161,13 @@ int g(void)
while (1);
while (2);
+ if (pcrl != NULL) {
+ 1;
+ 2;
+ } else if (pcrls != NULL) {
+ 1;
+ }
+
if (1)
f(a, b);
do
@@ -236,6 +243,9 @@ int g(void)
return 0;
}
break;
+ case 1: {
+ ;
+ }
default:
/* This should be dead code */
return 0;
@@ -254,7 +264,14 @@ int g(void)
&& expr_line3)
hanging_stmt;
}
-#define m \
+
+#define m1 \
+ if (ctx == NULL) \
+ return 0; \
+ if (ossl_param_is_empty(params)) \
+ return 1; \
+
+#define m2 \
do { /* should not be confused with function header followed by '{' */ \
} while (0)
@@ -279,6 +296,7 @@ const OPTIONS passwd_options[] = {
{NULL}
};
+typedef bool (*LOG_cb_t)(int lineno, severity level, const char *msg);
typedef * d(int)
x;
typedef (int)
diff --git a/util/check-format-test-positives.c b/util/check-format-test-positives.c
index e5dacdfe71b9..e6d4c2a12aae 100644
--- a/util/check-format-test-positives.c
+++ b/util/check-format-test-positives.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Siemens AG 2015-2022
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -15,12 +15,15 @@
*/
/*
- * The '@'s after '*' are used for self-tests: they mark lines containing
- * a single flaw that should be reported. Normally it should be reported
- * while handling the given line, but in case of delayed checks there is a
- * following digit indicating the number of reports expected for this line.
+ * The '@'s after leading '*' in comment lines are used for self-tests:
+ * they mark lines containing a single issue that should be reported.
+ * Normally it should be reported while handling the given line,
+ * but in case of delayed checks there is a following digit
+ * indicating the number of reports expected for this line.
*/
+/* this line is between 81 and 100 chars long, to be reported with -strict-len */
+
/* For each of the following set of lines the tool should complain once */
/*@ tab character: */
/*@ intra-line carriage return character: */
@@ -46,8 +49,7 @@
*/ /*@ multi-line comment end indent off by -1 (relative to comment start) */
*/ /*@ unexpected comment ending delimiter outside comment */
/*- '-' for formatted comment not allowed in intra-line comment */
-/*@ comment line is 4 columns tooooooooooooooooo wide, reported unless sloppy-len */
-/*@ comment line is 5 columns toooooooooooooooooooooooooooooooooooooooooooooo wide */
+/*@ comment line is toooooooooooo wide by 1 char, or by 21 chars in case strict-len option is used */
#if ~0 /*@ '#if' with constant condition */
#endif /*@ indent of preproc. directive off by 1 (must be 0) */
#define X (1 + 1) /*@0 extra space in body, reported unless sloppy-spc */
@@ -100,7 +102,7 @@ int f (int a, /*@ space after fn before '(', reported unless sloppy-spc */
b, /*@ expr indent as on line above, accepted if sloppy-hang */
b, /*@ expr indent off -8 but @ extra indent accepted if sloppy-hang */
"again aligned" /*@ expr indent off by -9 (left of stmt indent, */ "right",
- abc == /*@ .. so reported also with sloppy-hang; this line is too long */ 456
+ abc == /*@ .. so reported also with sloppy-hang; this line is too long by 6 or 26 chars */ 456
# define MAC(A) (A) /*@ nesting indent of preprocessor directive off by 1 */
? 1 /*@ hanging expr indent off by 1 */
: 2); /*@ hanging expr indent off by 2, or 1 for leading ':' */
diff --git a/util/check-format.pl b/util/check-format.pl
index 52981753d990..18a4924b29a1 100755
--- a/util/check-format.pl
+++ b/util/check-format.pl
@@ -1,6 +1,6 @@
#! /usr/bin/env perl
#
-# Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
# Copyright Siemens AG 2019-2022
#
# Licensed under the Apache License 2.0 (the "License").
@@ -62,7 +62,8 @@
# except within if ... else constructs where some branch contains more than one
# statement. Since the exception is hard to recognize when such branches occur
# after the current position (such that false positives would be reported)
-# the tool by checks for this rule by default only for do/while/for bodies.
+# the tool checks for this rule by default only for do/while/for bodies
+# and for 'if' without 'else'.
# Yet with the --1-stmt option false positives are preferred over negatives.
# False negatives occur if the braces are more than two non-blank lines apart.
#
@@ -168,9 +169,9 @@ my $local_offset; # current extra indent due to label, switch case/defa
my $line_body_start; # number of line where last function body started, or 0
my $line_function_start; # number of line where last function definition started, used for $line_body_start
my $last_function_header; # header containing name of last function defined, used if $line_body_start != 0
-my $line_opening_brace; # number of previous line with opening brace after if/do/while/for, optionally for 'else'
+my $line_opening_brace; # number of previous line with opening brace after if/do/while/for, partly for 'else/else if' - used for detection of { 1 stmt }
-my $keyword_opening_brace; # name of previous keyword, used if $line_opening_brace != 0
+my $keyword_opening_brace; # name of keyword (or combination 'else if') just before '{', used if $line_opening_brace != 0
my $block_indent; # currently required normal indentation at block/statement level
my $hanging_offset; # extra indent, which may be nested, for just one hanging statement or expr or typedef
my @in_do_hanging_offsets; # stack of hanging offsets for nested 'do' ... 'while'
@@ -465,7 +466,9 @@ sub update_nested_indents { # may reset $in_paren_expr and in this case also res
push @nested_block_indents, $block_indent;
push @nested_hanging_offsets, $in_expr ? $hanging_offset : 0;
push @nested_in_typedecl, $in_typedecl if $in_typedecl != 0;
- $block_indent += INDENT_LEVEL + $hanging_offset;
+ my $indent_inc = INDENT_LEVEL;
+ $indent_inc = 0 if (m/^[\s@]*(case|default)\W.*\{[\s@]*$/); # leading 'case' or 'default' and trailing '{'
+ $block_indent += $indent_inc + $hanging_offset;
$hanging_offset = 0;
}
if ($c ne "{" || $in_stmt) { # for '{' inside stmt/expr (not: decl), for '(', '[', or '?' anywhere
@@ -830,7 +833,8 @@ while (<>) { # loop over all lines of all input files
report("space after function/macro name")
if $intra_line =~ m/(\w+)\s+\(/ # fn/macro name with space before '('
&& !($1 =~ m/^(sizeof|if|else|while|do|for|switch|case|default|break|continue|goto|return|void|char|signed|unsigned|int|short|long|float|double|typedef|enum|struct|union|auto|extern|static|const|volatile|register)$/) # not keyword
- && !(m/^\s*#\s*define\s+\w+\s+\(/); # not a macro without parameters having a body that starts with '('
+ && !(m/^\s*#\s*define\s+\w+\s+\(/) # not a macro without parameters having a body that starts with '('
+ && !(m/^\s*typedef\W/); # not a typedef
report("missing space before '{'") if $intra_line =~ m/[^\s{(\[]\{/; # '{' without preceding space or {([
report("missing space after '}'") if $intra_line =~ m/\}[^\s,;\])}]/; # '}' without following space or ,;])}
}
@@ -911,8 +915,9 @@ while (<>) { # loop over all lines of all input files
}
if (m/^[\s@]*(case|default)(\W.*$|$)/) { # leading 'case' or 'default'
- my $keyword = $1;
- report("code after $keyword: ") if $2 =~ /:.*[^\s@].*$/;
+ my ($keyword, $rest) = ($1, $2);
+ report("code after $keyword: ") if $rest =~ /:.*[^\s@]/ && !
+ ($rest =~ /:[\s@]*\{[\s@]*$/); # after, ':', trailing '{';
$local_offset = -INDENT_LEVEL;
} else {
if (m/^([\s@]*)(\w+):/) { # (leading) label, cannot be "default"
@@ -978,7 +983,7 @@ while (<>) { # loop over all lines of all input files
my $next_word = $1;
if ($line_opening_brace > 0 &&
($keyword_opening_brace ne "if" ||
- $extended_1_stmt || $next_word ne "else") &&
+ $extended_1_stmt || $next_word ne "else") && # --1-stmt or 'if' without 'else'
($line_opening_brace == $line_before2 ||
$line_opening_brace == $line_before)
&& $contents_before =~ m/;/) { # there is at least one terminator ';', so there is some stmt
@@ -1016,8 +1021,9 @@ while (<>) { # loop over all lines of all input files
}
if ($paren_expr_start || $return_enum_start || $assignment_start)
{
- my ($head, $mid, $tail) = ($1, $3, $4);
+ my ($head, $pre, $mid, $tail) = ($1, $2, $3, $4);
$keyword_opening_brace = $mid if $mid ne "=";
+ $keyword_opening_brace = "else if" if $pre =~ m/(^|\W)else[\s@]+$/ && $mid eq "if" && !$extended_1_stmt; # prevent reporting "{ 1 stmt }" on "else if" unless --1-stmt
# to cope with multi-line expressions, do this also if !($tail =~ m/\{/)
push @in_if_hanging_offsets, $hanging_offset if $mid eq "if";
@@ -1135,10 +1141,10 @@ while (<>) { # loop over all lines of all input files
report("'{' not at line start") if length($head) != $preproc_offset && $head =~ m/\)\s*/; # at end of function definition header
$line_body_start = $contents =~ m/LONG BODY/ ? 0 : $line if $line_function_start != 0;
}
- } else {
- $line_opening_brace = $line if $keyword_opening_brace =~ m/if|do|while|for|(OSSL_)?LIST_FOREACH(_\w+)?/;
+ } else { # prepare detection of { 1 stmt }
+ $line_opening_brace = $line if $keyword_opening_brace =~ m/^(if|do|while|for|(OSSL_)?LIST_FOREACH(_\w+)?)$/;
# using, not assigning, $keyword_opening_brace here because it could be on an earlier line
- $line_opening_brace = $line if $keyword_opening_brace eq "else" && $extended_1_stmt &&
+ $line_opening_brace = $line if $keyword_opening_brace =~ m/else|else if/ && $extended_1_stmt &&
# TODO prevent false positives for if/else where braces around single-statement branches
# should be avoided but only if all branches have just single statements
# The following helps detecting the exception when handling multiple 'if ... else' branches:
diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm
index 0cc5cefe7ded..ccc4814f6fd2 100644
--- a/util/perl/TLSProxy/Proxy.pm
+++ b/util/perl/TLSProxy/Proxy.pm
@@ -27,6 +27,7 @@ use TLSProxy::NewSessionTicket;
use TLSProxy::NextProto;
my $have_IPv6;
+my $useINET6;
my $IP_factory;
BEGIN
@@ -49,6 +50,7 @@ BEGIN
if ($@ eq "") {
$IP_factory = sub { IO::Socket::INET6->new(Domain => AF_INET6, @_); };
$have_IPv6 = 1;
+ $useINET6 = 1;
} else {
eval {
require IO::Socket::IP;
@@ -63,9 +65,11 @@ BEGIN
if ($@ eq "") {
$IP_factory = sub { IO::Socket::IP->new(@_); };
$have_IPv6 = 1;
+ $useINET6 = 0;
} else {
$IP_factory = sub { IO::Socket::INET->new(@_); };
$have_IPv6 = 0;
+ $useINET6 = 0;
}
}
}
@@ -93,6 +97,23 @@ sub new_dtls {
sub init
{
+ my $useSockInet = 0;
+ eval {
+ require IO::Socket::IP;
+ my $s = IO::Socket::IP->new(
+ LocalAddr => "::1",
+ LocalPort => 0,
+ Listen=>1,
+ );
+ $s or die "\n";
+ $s->close();
+ };
+ if ($@ eq "") {
+ require IO::Socket::IP;
+ } else {
+ $useSockInet = 1;
+ }
+
my $class = shift;
my ($filter,
$execute,
@@ -100,10 +121,48 @@ sub init
$debug,
$isdtls) = @_;
+ my $test_client_port;
+
+ # Sometimes, our random selection of client ports gets unlucky
+ # And we randomly select a port thats already in use. This causes
+ # this test to fail, so lets harden ourselves against that by doing
+ # a test bind to the randomly selected port, and only continue once we
+ # find a port thats available.
+ my $test_client_addr = $have_IPv6 ? "[::1]" : "127.0.0.1";
+ my $found_port = 0;
+ for (my $i = 0; $i <= 10; $i++) {
+ $test_client_port = 49152 + int(rand(65535 - 49152));
+ my $test_sock;
+ if ($useINET6 == 0) {
+ if ($useSockInet == 0) {
+ $test_sock = IO::Socket::IP->new(LocalPort => $test_client_port,
+ LocalAddr => $test_client_addr);
+ } else {
+ $test_sock = IO::Socket::INET->new(LocalAddr => $test_client_addr,
+ LocalPort => $test_client_port);
+ }
+ } else {
+ $test_sock = IO::Socket::INET6->new(LocalAddr => $test_client_addr,
+ LocalPort => $test_client_port,
+ Domain => AF_INET6);
+ }
+ if ($test_sock) {
+ $found_port = 1;
+ $test_sock->close();
+ print "Found available client port ${test_client_port}\n";
+ last;
+ }
+ print "Port ${test_client_port} in use - $@\n";
+ }
+
+ if ($found_port == 0) {
+ die "Unable to find usable port for TLSProxy";
+ }
+
my $self = {
#Public read/write
- proxy_addr => $have_IPv6 ? "[::1]" : "127.0.0.1",
- client_addr => $have_IPv6 ? "[::1]" : "127.0.0.1",
+ proxy_addr => $test_client_addr,
+ client_addr => $test_client_addr,
filter => $filter,
serverflags => "",
clientflags => "",
@@ -114,7 +173,7 @@ sub init
#Public read
isdtls => $isdtls,
proxy_port => 0,
- client_port => 49152 + int(rand(65535 - 49152)),
+ client_port => $test_client_port,
server_port => 0,
serverpid => 0,
clientpid => 0,
diff --git a/util/platform_symbols/unix-symbols.txt b/util/platform_symbols/unix-symbols.txt
index 0820d4f264e7..d5d708025645 100644
--- a/util/platform_symbols/unix-symbols.txt
+++ b/util/platform_symbols/unix-symbols.txt
@@ -145,6 +145,7 @@ strdup
strlen
strncmp
strncpy
+strpbrk
strrchr
strspn
strstr
diff --git a/util/platform_symbols/windows-symbols.txt b/util/platform_symbols/windows-symbols.txt
index d0e6675a794b..69fb23bfc1e7 100644
--- a/util/platform_symbols/windows-symbols.txt
+++ b/util/platform_symbols/windows-symbols.txt
@@ -86,6 +86,7 @@ __current_exception
__C_specific_handler
wcsstr
__current_exception_context
+strlen
strstr
strchr
memmove
@@ -125,6 +126,7 @@ tolower
strspn
strcspn
strncpy
+strpbrk
strncmp
strcmp
strcat_s
diff --git a/util/wrap.pl.in b/util/wrap.pl.in
index 9b2b684c57eb..2c9cb29fec04 100644
--- a/util/wrap.pl.in
+++ b/util/wrap.pl.in
@@ -18,6 +18,38 @@ BEGIN {
OpenSSL::Util->import();
}
+sub quote_cmd_win32 {
+ my $cmd = "";
+
+ foreach my $arg (@_) {
+ if ($arg =~ m{\A[\w,-./@]+\z}) {
+ $cmd .= $arg . q{ };;
+ } else {
+ $cmd .= q{"} . quote_arg_win32($arg) . q{" };
+ }
+ }
+ return substr($cmd, 0, -1);
+}
+
+sub quote_arg_win32 {
+ my ($arg) = @_;
+ my $val = "";
+
+ pos($arg) = 0;
+ while (1) {
+ return $val if (pos($arg) == length($arg));
+ if ($arg =~ m{\G((?:(?>[\\]*)[^"\\]+)+)}ogc) {
+ $val .= $1;
+ } elsif ($arg =~ m{\G"}ogc) {
+ $val .= qq{\\"};
+ } elsif ($arg =~ m{\G((?>[\\]+)(?="|\z))}ogc) {
+ $val .= qq{\\} x (2 * length($1));
+ } else {
+ die sprintf("Internal error quoting: '%s'\n", $arg);
+ }
+ }
+}
+
my $there = canonpath(catdir(dirname($0), updir()));
my $std_engines = catdir($there, 'engines');
my $std_providers = catdir($there, 'providers');
@@ -90,7 +122,12 @@ if ($^O eq 'VMS') {
# The exec() statement on MSWin32 doesn't seem to give back the exit code
# from the call, so we resort to using system() instead.
-my $waitcode = system @cmd;
+my $waitcode;
+if ($^O eq 'MSWin32') {
+ $waitcode = system(quote_cmd_win32(@cmd));
+} else {
+ $waitcode = system @cmd;
+}
# According to documentation, -1 means that system() couldn't run the command,
# otherwise, the value is similar to the Unix wait() status value