aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Pronchery <khorben@FreeBSD.org>2025-07-11 21:17:50 +0000
committerPierre Pronchery <khorben@FreeBSD.org>2025-08-07 11:54:09 +0000
commit1095efe41feed8ea5a6fe5ca123c347ae0914801 (patch)
treec67facfd21376f5dc2aa6d670070675857adbf9d
parent09a25192275b21412a51e3a2d5d6ff0eb147425d (diff)
-rw-r--r--CHANGES.md29
-rw-r--r--Configurations/unix-Makefile.tmpl8
-rwxr-xr-xConfigure1
-rw-r--r--HACKING.md87
-rw-r--r--NEWS.md12
-rw-r--r--NOTES-WINDOWS.md5
-rw-r--r--VERSION.dat4
-rw-r--r--apps/CA.pl.in262
-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/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_pmeth.c4
-rw-r--r--crypto/ec/ecp_nistp384.c54
-rw-r--r--crypto/err/openssl.txt6
-rw-r--r--crypto/evp/asymcipher.c29
-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.c15
-rw-r--r--crypto/evp/legacy_sha.c4
-rw-r--r--crypto/evp/m_sigver.c110
-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.c22
-rw-r--r--crypto/rand/rand_lib.c49
-rw-r--r--crypto/sm3/asm/sm3-armv8.pl4
-rwxr-xr-xcrypto/sm4/asm/sm4-armv8.pl8
-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--demos/bio/sconnect.c6
-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/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.pod4
-rw-r--r--doc/man3/EVP_PKEY_sign.pod4
-rw-r--r--doc/man3/EVP_RAND.pod11
-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/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/man7/OSSL_PROVIDER-FIPS.pod13
-rw-r--r--doc/man7/ossl-guide-tls-introduction.pod4
-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--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_ssl.h4
-rw-r--r--include/internal/quic_tls.h2
-rw-r--r--include/openssl/evperr.h8
-rw-r--r--include/openssl/ssl.h.in4
-rw-r--r--providers/fips-sources.checksums68
-rw-r--r--providers/fips.checksum2
-rw-r--r--providers/fips/fipsprov.c10
-rw-r--r--providers/implementations/ciphers/cipher_chacha20_poly1305.c20
-rw-r--r--providers/implementations/digests/sha3_prov.c4
-rw-r--r--providers/implementations/kdfs/hkdf.c14
-rw-r--r--providers/implementations/keymgmt/ecx_kmgmt.c7
-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/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--ssl/quic/json_enc.c30
-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_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/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/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/quic_multistream_test.c10
-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/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/sslapitest.c264
-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.pm44
-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
189 files changed, 4284 insertions, 1428 deletions
diff --git a/CHANGES.md b/CHANGES.md
index aaf3fea1ca5e..2978ebfa2d10 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -28,6 +28,29 @@ OpenSSL Releases
OpenSSL 3.5
-----------
+### 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 +6609,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 +21227,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..e5fe94779035 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -23,6 +23,16 @@ OpenSSL Releases
OpenSSL 3.5
-----------
+### 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 +1899,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..f931934a1972 100644
--- a/VERSION.dat
+++ b/VERSION.dat
@@ -1,7 +1,7 @@
MAJOR=3
MINOR=5
-PATCH=0
+PATCH=1
PRE_RELEASE_TAG=
BUILD_METADATA=
-RELEASE_DATE="8 Apr 2025"
+RELEASE_DATE="1 Jul 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/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/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_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/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..975170c0aa09 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,12 @@ 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 : "";
+ ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
+ "%s encrypt:%s", cipher->type_name, desc);
return ret;
legacy:
@@ -280,6 +290,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 +307,13 @@ 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 : "";
+ ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
+ "%s decrypt:%s", cipher->type_name, desc);
+
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..f54684852b7c 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -451,9 +451,20 @@ 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);
+ }
+
+ ret = keymgmt->gen(genctx, cb, cbarg);
+ if (ret == NULL)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE,
+ "%s key generation:%s", keymgmt->type_name, desc);
+ 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..d5df497da770 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,19 @@ 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);
+ ret = signature->digest_sign_update(pctx->op.sig.algctx, data, dsize);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_sign_update:%s", signature->type_name, desc);
+ return ret;
legacy:
if (pctx != NULL) {
@@ -430,7 +446,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 +462,19 @@ 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);
+ ret = signature->digest_verify_update(pctx->op.sig.algctx, data, dsize);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_verify_update:%s", signature->type_name, desc);
+ return ret;
legacy:
if (pctx != NULL) {
@@ -466,6 +491,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 +508,26 @@ 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);
+
+ r = signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen,
+ sigret == NULL ? 0 : *siglen);
+ if (!r)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_sign_final:%s", signature->type_name, desc);
if (dctx == NULL && sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@@ -574,6 +612,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 +627,19 @@ 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);
+ ret = signature->digest_sign(pctx->op.sig.algctx, sigret, siglen,
+ sigret == NULL ? 0 : *siglen, tbs, tbslen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_sign:%s", signature->type_name, desc);
+ return ret;
}
} else {
/* legacy */
@@ -610,6 +655,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 +674,25 @@ 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);
+
+ r = signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen);
+ if (!r)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_verify_final:%s", signature->type_name, desc);
if (dctx == NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@@ -702,10 +760,16 @@ 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);
+ ret = signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen);
+ if (ret <= 0)
+ ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
+ "%s digest_verify:%s", signature->type_name, desc);
+ 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..0b675946485c 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);
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/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_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/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/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/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..72d129deff24 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()
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/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/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/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod
index 20d35fada87f..571a1e99e089 100644
--- a/doc/man7/OSSL_PROVIDER-FIPS.pod
+++ b/doc/man7/OSSL_PROVIDER-FIPS.pod
@@ -573,6 +573,19 @@ want to operate in a FIPS approved manner. The algorithms are:
=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
L<openssl-fipsinstall(1)>,
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-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/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_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/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/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..9f25bac77f3e 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
@@ -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
+73c956c97fd558b0fd267934657fb829fd8d9ab12dda2d96d3ca1521f0416ca8 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
+5cb9ddc6a7434bd7e063bf85455c2025fb34e4eb846d7d113dbcedc25eeac7a3 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
@@ -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
@@ -452,8 +452,8 @@ bbe5e52d84e65449a13e42cd2d6adce59b8ed6e73d6950917aa77dc1f3f5dff6 include/crypto
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
@@ -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
@@ -611,7 +611,7 @@ 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
+e9383013a79a8223784a69a66bb610d16d54e61ea978f67a3d31de9f48cd4627 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
@@ -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
@@ -699,25 +699,25 @@ b9f7fc5c19f637cee55b0a435b838f5de3a5573ca376ba602e90f70855a78852 providers/impl
24cc3cc8e8681c77b7f96c83293bd66045fd8ad69f756e673ca7f8ca9e82b0af providers/implementations/keymgmt/dsa_kmgmt.c
e10086c31aafae0562054e3b07f12409e39b87b5e96ee7668c231c37861aa447 providers/implementations/keymgmt/ec_kmgmt.c
258ae17bb2dd87ed1511a8eb3fe99eed9b77f5c2f757215ff6b3d0e8791fc251 providers/implementations/keymgmt/ec_kmgmt_imexport.inc
-b9646607ca2027919b591048bce0364349049a668468ccdda76b8a8082d7749c providers/implementations/keymgmt/ecx_kmgmt.c
+d042d687da861d2a39658c6b857a6507a70fa78cecdf883bd1dcdafcf102e084 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
+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..f9e822a7f9f1 100644
--- a/providers/fips.checksum
+++ b/providers/fips.checksum
@@ -1 +1 @@
-e52ef0424b1c707a55e63763491f5ffc6462cab120929199bae37bd876094761 providers/fips-sources.checksums
+cffe76b0bc6464c7c864d5e2eaaf528439cb6c9908dc75666d530aa8a65e152e providers/fips-sources.checksums
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 373cd1c2e4c5..4b9a0574625d 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"
@@ -887,6 +888,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.
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/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/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c
index 230a75cc5795..c2ac805ad1f6 100644
--- a/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -505,9 +505,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);
@@ -843,6 +845,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);
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/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/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_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_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/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/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/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/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/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/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/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..b76f9e931ec0 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,7 @@ sub new_dtls {
sub init
{
+ require IO::Socket::IP;
my $class = shift;
my ($filter,
$execute,
@@ -100,10 +105,43 @@ 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) {
+ $test_sock = IO::Socket::IP->new(LocalPort => $test_client_port,
+ LocalAddr => $test_client_addr);
+ } 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 +152,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