Commit 5bfa4514382 for nodejs
commit 5bfa4514382d09ea061290bfc92790aaa6b69230
Author: Node.js GitHub Bot <github-bot@iojs.org>
Date: Tue Sep 29 14:15:07 2026 +0000
deps: upgrade openssl sources to openssl-3.5.9
PR-URL: https://github.com/nodejs/node/pull/66396
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
diff --git a/deps/openssl/openssl/CHANGES.md b/deps/openssl/openssl/CHANGES.md
index b440f013313..64385e4fc22 100644
--- a/deps/openssl/openssl/CHANGES.md
+++ b/deps/openssl/openssl/CHANGES.md
@@ -28,6 +28,296 @@ OpenSSL Releases
OpenSSL 3.5
-----------
+### Changes between 3.5.8 and 3.5.9 [29 Sep 2026]
+
+ * Fixed DTLS retransmissions of handshake messages from a stale buffer offset.
+
+ Severity: High
+
+ Issue summary: The DTLS retransmission logic does not correctly handle
+ a handshake message write that is suspended part-way through.
+ The retransmitted message can be read past the message buffer
+ and the retransmission overwrites the internal state the suspended write
+ needs to resume correctly.
+
+ Impact summary: The retransmitted message can disclose a heap memory
+ to the peer as plaintext handshake data or cause a crash and a Denial
+ of Service when the read reaches an unmapped memory region.
+
+ Reported by: Laurent Gaffie (secorizon.com).
+
+ ([CVE-2026-84782])
+
+ *Ryan Hooper*
+
+ * Fixed excessive memory allocation in relative CRLDP processing.
+
+ Severity: Low
+
+ Issue summary: A certificate with many `nameRelativeToCRLIssuer` CRL
+ distribution points causes disproportionate heap growth when OpenSSL caches
+ X.509 extensions.
+
+ Impact summary: Receiving a crafted certificate from a malicious peer
+ can lead to significant memory pressure and possible Denial of Service
+ in clients or in servers that solicit client certificates.
+
+ Reported by: Fuzz0x (ZKSC Institute of Security Research).
+
+ ([CVE-2026-35189])
+
+ *Viktor Dukhovni*
+
+ * Fixed QUIC unvalidated amplification credit may be over-accounted.
+
+ Severity: Low
+
+ Issue summary: The OpenSSL QUIC server, when configured to not preform
+ address validation, can be forced to count incoming packets multiple times
+ in its unvalidated credit computation, leading to a violation
+ of the [RFC 9000] unvalidated connection amplification limit of 3 times
+ the amount of data received.
+
+ Impact summary: A remote attacker, who is able to spoof packets to a server
+ using the OpenSSL QUIC implementation, might use the server
+ for an amplification of a Distributed Denial of Service attack.
+
+ Reported by: Ali Firas and Nikolas Gauder (NVIDIA).
+
+ ([CVE-2026-35191])
+
+ *Neil Horman*
+
+ * Fixed potential CPU DoS via O(n^2) fragment reassembly in QUIC.
+
+ Severity: Low
+
+ Issue summary: The QUIC stream reassembly algorithm performance deteriorates
+ progressively as packets are arriving out of order. The worst case has
+ a quadratic complexity, proportional to the number of stream frames kept
+ in the buffer for the received stream data.
+
+ Impact summary: A remote QUIC peer that completes the handshake can create
+ a connection-scoped CPU pressure and potentially a Denial of Service using
+ compliant `STREAM` frames inside the advertised receive window, with low
+ attacker bandwidth.
+
+ Reported by: Saku0512 and Opal Wright (Trail of Bits) in collaboration
+ with OpenAI
+
+ ([CVE-2026-42772])
+ <!-- https://github.com/openssl/openssl/pull/32769 -->
+
+ *Alexandr Nedvědický*
+
+ * Fixed a timing side-channel in scalar multiplication for mon-NIST EC curves.
+
+ Severity: Low
+
+ Issue summary: The generic elliptic-curve scalar multiplication, used
+ for ECDSA and SM2 signature operations with curves that do not have
+ a dedicated implementation, leaks information about the secret nonce
+ through timing.
+
+ Impact summary: An attacker, who is able to measure signing times, may learn
+ information about the per-signature secret nonce, which over many signatures
+ can, via a Hidden Number Problem (lattice) attack, lead to recovery
+ of the private key.
+
+ Reported by: Alicja Kario and George Pantelakis (Red Hat), based
+ on the report of Youngjae Choi (Korea University).
+
+ ([CVE-2026-54872])
+
+ *Igor Ustinov*
+
+ * Fixed QUIC `STREAM` fragment metadata DoS.
+
+ Severity: Low
+
+ Issue summary: QUIC process may keep memory for QUIC packet buffer
+ for much longer period than necessary.
+
+ Impact summary: Remote peer can exploit this vulnerability by sending
+ maliciously crafted packets, making the local QUIC stack to keep the memory
+ for packet buffers allocated. The time for which the memory remains
+ allocated is entirely under the control of the potentially malicious remote
+ peer.
+
+ Reported by: Zhen Yan (AntAISecurityLab) and Bhabani Sankar Das.
+
+ ([CVE-2026-54873])
+ <!-- https://github.com/openssl/openssl/pull/32769 -->
+
+ *Alexandr Nedvědický*
+
+ * Fixed non-constant-time SM2 scalar multiplication on ARM64 and RISC-V.
+
+ Severity: Low
+
+ Issue summary: A non-constant-time optimized implementation of scalar
+ point multiplication is used for SM2 private key operations on ARM64
+ and RISC-V platforms.
+
+ Impact summary: An attacker able to measure the time taken by, or to observe
+ the cache-line access pattern of, SM2 signing or decryption on an affected
+ platform can learn information about the secret scalar.
+
+ Reported by: Abhinav Agarwal and Feng Xue.
+
+ ([CVE-2026-54875])
+
+ *Igor Ustinov*
+
+ * Fixed out-of-bounds access after `SSL_set_SSL_CTX()` during a handshake.
+
+ Severity: Low
+
+ Issue summary: A TLS server that calls `SSL_set_SSL_CTX()` to switch
+ a connection to a different `SSL_CTX` part way through a handshake may access
+ memory beyond the end of an internal array if the replacement context knows
+ about more provider signature algorithms than the context the connection was
+ created from. Applications that never call `SSL_set_SSL_CTX()`
+ are not affected.
+
+ Impact summary: A remote peer may be able to cause a small out-of-bounds
+ read, and, in some circumstances, a fixed-value out-of-bounds write,
+ on the server heap. This may lead to a Denial of Service.
+
+ Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI,
+ Brandon Luo, Luigino Camastra (Aisle Research), and Bhargava Shastry.
+
+ ([CVE-2026-72897])
+
+ *Matt Caswell*
+
+ * Fixed QUIC connection-level flow control was not enforced for streams.
+
+ Severity: Low
+
+ Issue summary: OpenSSL QUIC stack does not enforce connection-level flow
+ control for streams. Remote peers may send more bytes, as long as they fit
+ within the stream flow control limits.
+
+ Impact summary: A malicious remote peer may exploit the lack of connection
+ flow control for streams to make the QUIC stack receive ~100 MiB of memory
+ instead of 768 KiB (default flow control window size).
+
+ Reportedby: Moltenbit, Bhabani Sankar Das, Saiyowa Security Team, mzfr.
+
+ ([CVE-2026-75804])
+
+ *Alexandr Nedvědický*
+
+ * Fixed a NULL pointer dereference in CMP client revocation response handling.
+
+ Severity: Low
+
+ Issue summary: The OpenSSL Certificate Management Protocol (CMP) client
+ that requests a certificate revocation on the basis of a PKCS#10 CSR may
+ dereference a NULL pointer and terminate abnormally when processing a crafted
+ revocation response.
+
+ Impact summary: The NULL pointer dereference happens on a read, which
+ leads to a crash and a Denial of Service for the affected client application.
+
+ Reported by: Bhabani Sankar Das.
+
+ ([CVE-2026-75805])
+
+ *Bhabani Sankar Das and Norbert Pócs*
+
+ * Fixed an unauthenticated and undersized DTLS 1.2 AEAD record causing DoS.
+
+ Severity: Low
+
+ Issue summary: An established DTLS 1.2 association using an AEAD cipher suite
+ can be terminated by a single unauthenticated datagram whose encrypted
+ fragment is shorter than the mandatory explicit IV and authentication tag
+ overhead.
+
+ Impact summary: An attacker who can send a datagram that is routed
+ to an existing DTLS 1.2 association can tear that association down
+ without knowing any key material. This is a Denial of Service, limited
+ to the targeted association. There is no memory safety or confidentiality
+ impact.
+
+ Reported by: Mounir IDRASSI.
+
+ ([CVE-2026-75806])
+
+ *Mounir IDRASSI*
+
+ * Fixed a timing side-channel in SM2 signature generation.
+
+ Severity: Low
+
+ Issue summary: SM2 signature generation uses non-constant-time arithmetic
+ on secret values, forming a timing side-channel.
+
+ Impact summary: An attacker able to measure SM2 signing times may learn
+ information about the per-signature secret nonce, which over many signatures
+ can, via a Hidden Number Problem (lattice) attack, lead to recovery
+ of the private key.
+
+ Reported by: Vladimir Tokarev.
+
+ ([CVE-2026-77696])
+
+ *Igor Ustinov and Viktor Dukhovni*
+
+ * Fixed an unbounded `RETIRE_CONNECTION_ID` backlog in QUIC stack
+ implementation.
+
+ Severity: Low
+
+ Issue summary: A malicious remote peer may flood the local QUIC stack
+ with `NEW_CONNECTION_ID` frames by avoiding a limit check on how many
+ connection IDs the remote QUIC stack can use.
+
+ Impact summary: The local QUIC stack sends a `RETIRE_CONN_ID` frame
+ for every `NEW_CONNECTION_ID` frame it receives. The `RETIRE_CONN_ID`
+ frame is dispatched via the Control Frame Queue (CFQ). If the remote
+ peer also withholds ACKs, then it can force the local stack to allocate
+ up to ~400 MB (depending on ACK delay).
+
+ Reported by: Bhabani Sankar Das.
+
+ ([CVE-2026-84784])
+
+ *Alexandr Nedvědický*
+
+ * Fixed a bug where `EVP_DecryptFinal()` incorrectly reported a stale success
+ on AES-SIV authentication failure after a preciously successful message
+ decryption.
+ <!-- https://github.com/openssl/openssl/pull/31610 -->
+
+ *Abel Thomas*
+
+ * Fixed a bug in `OSSL_HTTP_get()` that allowed to perform HTTPS-to-HTTP
+ downgrade through a relative redirect.
+ <!-- https://github.com/openssl/openssl/pull/32694 -->
+
+ *Mounir IDRASSI*
+
+ * Changed the OpenSSL FIPS provider so that every algorithm advertised
+ with `fips=yes` property explicitly exposes a `fips-indicator` gettable
+ context parameter, that returns 1 for an approved operation. The absence
+ of an indicator is no longer interpreted as approval. Algorithms advertised
+ with `fips=no` property, including X448MLKEM1024, remain unapproved
+ and return 0 when they expose the indicator.
+ <!-- https://github.com/openssl/openssl/pull/32913 -->
+
+ *Shane Lontis*
+
+ * Changed the compiler flags supplied to MSVC targets to no longer include
+ `/Gs0` (resetting the minimum memory size occupied by local variables
+ for including stack probes to the default value of 4096), as it led
+ to mis-compilation of MD4 C implementation on ARM64.
+ <!-- https://github.com/openssl/openssl/pull/32872 -->
+
+ *Norbert Pócs*
+
### Changes between 3.5.7 and 3.5.8 [25 Aug 2026]
* Fixed QUIC server being able to trigger double free when processing `INITIAL`
@@ -22521,22 +22811,35 @@ ndif
[CVE-2026-34181]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-34181
[CVE-2026-34182]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-34182
[CVE-2026-34183]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-34183
+[CVE-2026-35189]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-35189
+[CVE-2026-35191]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-35191
[CVE-2026-42764]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42764
[CVE-2026-42766]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42766
[CVE-2026-42767]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42767
[CVE-2026-42768]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42768
[CVE-2026-42769]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42769
[CVE-2026-42770]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42770
+[CVE-2026-42772]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42772
[CVE-2026-45445]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45445
[CVE-2026-45446]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45446
[CVE-2026-45447]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45447
+[CVE-2026-54872]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54872
+[CVE-2026-54873]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54873
[CVE-2026-54874]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54874
+[CVE-2026-54875]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54875
[CVE-2026-63072]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63072
[CVE-2026-63073]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63073
[CVE-2026-63074]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63074
[CVE-2026-63075]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63075
[CVE-2026-63076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63076
+[CVE-2026-72897]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-72897
[CVE-2026-75803]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75803
+[CVE-2026-75804]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75804
+[CVE-2026-75805]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75805
+[CVE-2026-75806]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75806
+[CVE-2026-77696]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-77696
+[CVE-2026-84782]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-84782
+[CVE-2026-84784]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-84784
[ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations
[RFC 2578 (STD 58), section 3.5]: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
[RFC 3211]: https://datatracker.ietf.org/doc/html/rfc3211
@@ -22545,3 +22848,4 @@ ndif
[RFC 8446]: https://datatracker.ietf.org/doc/html/rfc8446
[RFC 8446 Section 4.6.1]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.1
[RFC 8452]: https://datatracker.ietf.org/doc/html/rfc8452
+[RFC 9000]: https://datatracker.ietf.org/doc/html/rfc9000
diff --git a/deps/openssl/openssl/Configurations/10-main.conf b/deps/openssl/openssl/Configurations/10-main.conf
index 692eccbfa1d..389b4a839a9 100644
--- a/deps/openssl/openssl/Configurations/10-main.conf
+++ b/deps/openssl/openssl/Configurations/10-main.conf
@@ -1566,7 +1566,7 @@ my %targets = (
template => 1,
CFLAGS => add(picker(debug => '/Od',
release => '/O2')),
- cflags => add(picker(default => '/Gs0 /GF /Gy',
+ cflags => add(picker(default => '/GF /Gy',
debug =>
sub {
($disabled{shared} ? "" : "/MDd");
diff --git a/deps/openssl/openssl/NEWS.md b/deps/openssl/openssl/NEWS.md
index 329b1772c34..157587f0f52 100644
--- a/deps/openssl/openssl/NEWS.md
+++ b/deps/openssl/openssl/NEWS.md
@@ -23,6 +23,56 @@ OpenSSL Releases
OpenSSL 3.5
-----------
+### Major changes between OpenSSL 3.5.8 and OpenSSL 3.5.9 [29 Sep 2026]
+
+OpenSSL 3.5.9 is a security patch release. The most severe CVE fixed
+in this release is High.
+
+This release incorporates the following bug fixes and mitigations:
+
+ * Fixed DTLS retransmissions of handshake messages from a stale buffer offset.
+ ([CVE-2026-84782])
+
+ * Fixed excessive memory allocation in relative CRLDP processing.
+ ([CVE-2026-35189])
+
+ * Fixed QUIC unvalidated amplification credit may be over-accounted.
+ ([CVE-2026-35191])
+
+ * Fixed potential CPU DoS via O(n^2) fragment reassembly in QUIC.
+ ([CVE-2026-42772])
+
+ * Fixed a timing side-channel in scalar multiplication for mon-NIST EC curves.
+ ([CVE-2026-54872])
+
+ * Fixed QUIC `STREAM` fragment metadata DoS.
+ ([CVE-2026-54873])
+
+ * Fixed non-constant-time SM2 scalar multiplication on ARM64 and RISC-V.
+ ([CVE-2026-54875])
+
+ * Fixed out-of-bounds access after `SSL_set_SSL_CTX()` during a handshake.
+ ([CVE-2026-72897])
+
+ * Fixed QUIC connection-level flow control was not enforced for streams.
+ ([CVE-2026-75804])
+
+ * Fixed a NULL pointer dereference in CMP client revocation response handling.
+ ([CVE-2026-75805])
+
+ * Fixed an unauthenticated and undersized DTLS 1.2 AEAD record causing DoS.
+ ([CVE-2026-75806])
+
+ * Fixed a timing side-channel in SM2 signature generation.
+ ([CVE-2026-77696])
+
+ * Fixed an unbounded `RETIRE_CONNECTION_ID` backlog in QUIC stack
+ implementation.
+ ([CVE-2026-84784])
+
+ * Fixed a bug where `EVP_DecryptFinal()` incorrectly reported a stale success
+ on AES-SIV authentication failure.
+
### Major changes between OpenSSL 3.5.7 and OpenSSL 3.5.8 [25 Aug 2026]
OpenSSL 3.5.8 is a security patch release. The most severe CVE fixed
@@ -2328,22 +2378,35 @@ OpenSSL 0.9.x
[CVE-2026-34181]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-34181
[CVE-2026-34182]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-34182
[CVE-2026-34183]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-34183
+[CVE-2026-35189]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-35189
+[CVE-2026-35191]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-35191
[CVE-2026-42764]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42764
[CVE-2026-42766]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42766
[CVE-2026-42767]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42767
[CVE-2026-42768]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42768
[CVE-2026-42769]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42769
[CVE-2026-42770]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42770
+[CVE-2026-42772]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-42772
[CVE-2026-45445]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45445
[CVE-2026-45446]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45446
[CVE-2026-45447]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45447
+[CVE-2026-54872]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54872
+[CVE-2026-54873]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54873
[CVE-2026-54874]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54874
+[CVE-2026-54875]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54875
[CVE-2026-63072]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63072
[CVE-2026-63073]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63073
[CVE-2026-63074]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63074
[CVE-2026-63075]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63075
[CVE-2026-63076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63076
+[CVE-2026-72897]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-72897
[CVE-2026-75803]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75803
+[CVE-2026-75804]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75804
+[CVE-2026-75805]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75805
+[CVE-2026-75806]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75806
+[CVE-2026-77696]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-77696
+[CVE-2026-84782]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-84782
+[CVE-2026-84784]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-84784
[ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations
[OpenSSL Guide]: https://www.openssl.org/docs/manmaster/man7/ossl-guide-introduction.html
[README-QUIC.md]: ./README-QUIC.md
diff --git a/deps/openssl/openssl/VERSION.dat b/deps/openssl/openssl/VERSION.dat
index bf654c1a771..5a9d96f9a63 100644
--- a/deps/openssl/openssl/VERSION.dat
+++ b/deps/openssl/openssl/VERSION.dat
@@ -1,7 +1,7 @@
MAJOR=3
MINOR=5
-PATCH=8
+PATCH=9
PRE_RELEASE_TAG=
BUILD_METADATA=
-RELEASE_DATE="25 Aug 2026"
+RELEASE_DATE="29 Sep 2026"
SHLIB_VERSION=3
diff --git a/deps/openssl/openssl/apps/ocsp.c b/deps/openssl/openssl/apps/ocsp.c
index e2c147ef097..e490ec43f8a 100644
--- a/deps/openssl/openssl/apps/ocsp.c
+++ b/deps/openssl/openssl/apps/ocsp.c
@@ -470,11 +470,15 @@ int ocsp_main(int argc, char **argv)
if (issuer == NULL)
goto end;
if (issuers == NULL) {
- if ((issuers = sk_X509_new_null()) == NULL)
+ if ((issuers = sk_X509_new_null()) == NULL) {
+ X509_free(issuer);
goto end;
+ }
}
- if (!sk_X509_push(issuers, issuer))
+ if (!sk_X509_push(issuers, issuer)) {
+ X509_free(issuer);
goto end;
+ }
break;
case OPT_CERT:
reset_unknown();
diff --git a/deps/openssl/openssl/crypto/asn1/a_dup.c b/deps/openssl/openssl/crypto/asn1/a_dup.c
index 48f5b3f6a4c..6aeaac96b1e 100644
--- a/deps/openssl/openssl/crypto/asn1/a_dup.c
+++ b/deps/openssl/openssl/crypto/asn1/a_dup.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 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
@@ -82,10 +82,15 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
p = b;
ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq);
OPENSSL_free(b);
+ if (ret == NULL)
+ return NULL;
if (asn1_cb != NULL
- && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x))
- goto auxerr;
+ && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x)) {
+ ASN1_item_free(ret, it);
+ ERR_raise_data(ERR_LIB_ASN1, ASN1_R_AUX_ERROR, "Type=%s", it->sname);
+ return NULL;
+ }
return ret;
diff --git a/deps/openssl/openssl/crypto/bio/bio_addr.c b/deps/openssl/openssl/crypto/bio/bio_addr.c
index cf3960a35d7..02f83eb2bf8 100644
--- a/deps/openssl/openssl/crypto/bio/bio_addr.c
+++ b/deps/openssl/openssl/crypto/bio/bio_addr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2026 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
@@ -629,7 +629,12 @@ static int addrinfo_wrap(int family, int socktype,
all right. */
BIO_ADDR *addr = BIO_ADDR_new();
if (addr != NULL) {
- BIO_ADDR_rawmake(addr, family, where, wherelen, port);
+ if (!BIO_ADDR_rawmake(addr, family, where, wherelen, port)) {
+ BIO_ADDR_free(addr);
+ BIO_ADDRINFO_free(*bai);
+ *bai = NULL;
+ return 0;
+ }
(*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
}
}
diff --git a/deps/openssl/openssl/crypto/bn/bn_intern.c b/deps/openssl/openssl/crypto/bn/bn_intern.c
index bd299cd1442..547738761cf 100644
--- a/deps/openssl/openssl/crypto/bn/bn_intern.c
+++ b/deps/openssl/openssl/crypto/bn/bn_intern.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014-2026 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
@@ -9,6 +9,7 @@
#include "internal/cryptlib.h"
#include "bn_local.h"
+#include "internal/constant_time.h"
/*
* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
@@ -152,6 +153,43 @@ void bn_set_all_zero(BIGNUM *a)
a->d[i] = 0;
}
+/*
+ * Zero-extend |a| so that it occupies exactly |words| words, flag it
+ * BN_FLG_FIXED_TOP and leave its numeric value unchanged.
+ *
+ * This is a companion to bn_correct_top(): where the latter minimises the top
+ * of a BIGNUM, this one pins the top to a caller-chosen, value-independent
+ * width. Constant-time code uses it to make the cost of subsequent word-wise
+ * operations (e.g. BN_uadd()/BN_add()) independent of the magnitude of a
+ * secret value. |words| must be greater than or equal to the current top.
+ *
+ * The routine is itself constant time with respect to the current a->top: it
+ * always sweeps a fixed |words| iterations and selects value-or-zero per word
+ * with an arithmetic mask, rather than looping over the (possibly secret)
+ * a->top..words range. Masking the high words with zero also launders any
+ * uninitialised padding, so it is safe for the memory sanitiser.
+ */
+int bn_set_top_fixed(BIGNUM *a, int words)
+{
+ size_t i, n = (size_t)words;
+ BN_ULONG mask;
+
+ if (words < a->top)
+ return 0;
+ if (bn_wexpand(a, words) == NULL) {
+ ERR_raise(ERR_LIB_BN, ERR_R_BN_LIB);
+ return 0;
+ }
+ for (i = 0; i < n; i++) {
+ /* mask = all ones iff i < a->top, else all zeros */
+ mask = value_barrier_bn((BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)));
+ a->d[i] &= mask;
+ }
+ a->top = words;
+ a->flags |= BN_FLG_FIXED_TOP;
+ return 1;
+}
+
int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size)
{
if (in->top > size)
diff --git a/deps/openssl/openssl/crypto/build.info b/deps/openssl/openssl/crypto/build.info
index aee5c467668..058bcc5c304 100644
--- a/deps/openssl/openssl/crypto/build.info
+++ b/deps/openssl/openssl/crypto/build.info
@@ -6,7 +6,7 @@ SUBDIRS=objects buffer bio stack lhash hashtable rand evp asn1 pem x509 conf \
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \
- ffc hpke thread ml_dsa slh_dsa
+ ffc hpke thread ml_dsa slh_dsa rbtree
LIBS=../libcrypto
diff --git a/deps/openssl/openssl/crypto/cmp/cmp_client.c b/deps/openssl/openssl/crypto/cmp/cmp_client.c
index d6a4230d243..0e0bff09f8f 100644
--- a/deps/openssl/openssl/crypto/cmp/cmp_client.c
+++ b/deps/openssl/openssl/crypto/cmp/cmp_client.c
@@ -999,16 +999,23 @@ int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx)
ret = 0;
goto err;
}
- if (X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
+ /*
+ * The issuer and serial number are absent if the certificate to be
+ * revoked was given as a PKCS#10 CSR, in which case there is nothing
+ * to check the CertId of the response against.
+ */
+ if (issuer != NULL
+ && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID_IN_RP);
ret = 0;
goto err;
#endif
}
- if (ASN1_INTEGER_cmp(serial,
- OSSL_CRMF_CERTID_get0_serialNumber(cid))
- != 0) {
+ if (serial != NULL
+ && ASN1_INTEGER_cmp(serial,
+ OSSL_CRMF_CERTID_get0_serialNumber(cid))
+ != 0) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_SERIAL_IN_RP);
ret = 0;
diff --git a/deps/openssl/openssl/crypto/cmp/cmp_server.c b/deps/openssl/openssl/crypto/cmp/cmp_server.c
index 9bf51a61a58..b9c1b8c91de 100644
--- a/deps/openssl/openssl/crypto/cmp/cmp_server.c
+++ b/deps/openssl/openssl/crypto/cmp/cmp_server.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Nokia 2007-2019
* Copyright Siemens AG 2015-2019
*
@@ -61,7 +61,6 @@ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq)
if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL)
goto err;
ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
- ctx->polling = 0;
/* all other elements are initialized to 0 or NULL, respectively */
return ctx;
@@ -577,6 +576,60 @@ static int unprotected_exception(const OSSL_CMP_CTX *ctx,
return 0;
}
+static int assuming_new_transaction(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req)
+{
+ int body_type = OSSL_CMP_MSG_get_bodytype(req);
+ ASN1_OCTET_STRING *tid;
+
+ if (ctx->transactionID == NULL) /* no currently active transaction */
+ return 1;
+
+ tid = OSSL_CMP_HDR_get0_transactionID(OSSL_CMP_MSG_get0_header(req));
+ if (tid != NULL && ASN1_OCTET_STRING_cmp(tid, ctx->transactionID) != 0) {
+ char *ctx_str = i2s_ASN1_OCTET_STRING(NULL, ctx->transactionID);
+ char *tid_str = i2s_ASN1_OCTET_STRING(NULL, tid);
+
+ ossl_cmp_log2(WARN, ctx, "Assuming that last transaction with ID=%s got aborted, new ID=%s",
+ ctx_str != NULL ? ctx_str : "(null)",
+ tid_str != NULL ? tid_str : "(null)");
+ OPENSSL_free(tid_str);
+ OPENSSL_free(ctx_str);
+ return 1;
+ }
+
+ switch (body_type) {
+ case OSSL_CMP_PKIBODY_IR:
+ case OSSL_CMP_PKIBODY_CR:
+ case OSSL_CMP_PKIBODY_P10CR:
+ case OSSL_CMP_PKIBODY_KUR:
+ case OSSL_CMP_PKIBODY_RR:
+ case OSSL_CMP_PKIBODY_GENM:
+ ossl_cmp_log1(WARN, ctx, "Assuming new transaction due to received body type %s",
+ ossl_cmp_bodytype_to_string(body_type));
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Prepare for next transaction */
+static int transaction_reinit(OSSL_CMP_SRV_CTX *srv_ctx)
+{
+ int ret = 1;
+
+ srv_ctx->ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */
+ srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
+ srv_ctx->polling = 0;
+
+ if (srv_ctx->clean_transaction != NULL)
+ ret = srv_ctx->clean_transaction(srv_ctx, srv_ctx->ctx->transactionID);
+ if (!OSSL_CMP_CTX_set1_transactionID(srv_ctx->ctx, NULL))
+ ret = 0;
+ if (!OSSL_CMP_CTX_set1_senderNonce(srv_ctx->ctx, NULL))
+ ret = 0;
+ return ret;
+}
+
/*
* returns created message and NULL on internal error
*/
@@ -613,42 +666,18 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
goto err;
- if (srv_ctx->polling && req_type != OSSL_CMP_PKIBODY_POLLREQ
- && req_type != OSSL_CMP_PKIBODY_ERROR) {
- ERR_raise(ERR_LIB_CMP, CMP_R_EXPECTED_POLLREQ);
- goto err;
- }
-
- switch (req_type) {
- case OSSL_CMP_PKIBODY_IR:
- case OSSL_CMP_PKIBODY_CR:
- case OSSL_CMP_PKIBODY_P10CR:
- case OSSL_CMP_PKIBODY_KUR:
- case OSSL_CMP_PKIBODY_RR:
- case OSSL_CMP_PKIBODY_GENM:
- case OSSL_CMP_PKIBODY_ERROR:
- if (ctx->transactionID != NULL) {
- char *tid = i2s_ASN1_OCTET_STRING(NULL, ctx->transactionID);
-
- if (tid != NULL)
- ossl_cmp_log1(WARN, ctx,
- "Assuming that last transaction with ID=%s got aborted",
- tid);
- OPENSSL_free(tid);
- }
- /* start of a new transaction, reset transactionID and senderNonce */
- if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL)
- || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL))
- goto err;
-
- if (srv_ctx->clean_transaction != NULL
- && !srv_ctx->clean_transaction(srv_ctx, NULL)) {
+ if (assuming_new_transaction(ctx, req)) {
+ /*
+ * Start of a new transaction, resetting transactionID and senderNonce.
+ * Must in this case reset transactionID beforehand such that the clean()
+ * callback function gets a NULL transactionID argument, as documented.
+ */
+ (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
+ if (!transaction_reinit(srv_ctx)) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
goto err;
}
-
- break;
- default:
+ } else {
/* transactionID should be already initialized */
if (ctx->transactionID == NULL) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
@@ -656,6 +685,11 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
goto err;
#endif
}
+ if (srv_ctx->polling && req_type != OSSL_CMP_PKIBODY_POLLREQ
+ && req_type != OSSL_CMP_PKIBODY_ERROR) {
+ ERR_raise(ERR_LIB_CMP, CMP_R_EXPECTED_POLLREQ);
+ goto err;
+ }
}
req_verified = ossl_cmp_msg_check_update(ctx, req, unprotected_exception,
@@ -741,13 +775,9 @@ err:
case OSSL_CMP_PKIBODY_PKICONF:
case OSSL_CMP_PKIBODY_GENP:
/* Other terminating response message types are not supported */
- srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID;
- /* Prepare for next transaction, ignoring any errors here: */
- if (srv_ctx->clean_transaction != NULL)
- (void)srv_ctx->clean_transaction(srv_ctx, ctx->transactionID);
- (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL);
- (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL);
- ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */
+
+ /* Prepare for next transaction, ignoring any errors here */
+ (void)transaction_reinit(srv_ctx);
default: /* not closing transaction in other cases */
break;
diff --git a/deps/openssl/openssl/crypto/comp/c_brotli.c b/deps/openssl/openssl/crypto/comp/c_brotli.c
index 74bbc74dc77..60f780a91a2 100644
--- a/deps/openssl/openssl/crypto/comp/c_brotli.c
+++ b/deps/openssl/openssl/crypto/comp/c_brotli.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2026 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
@@ -292,6 +292,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_brotli_init)
#define LIBBROTLIDEC "brotlidec"
#endif
+ ERR_set_mark();
brotli_encode_dso = DSO_load(NULL, LIBBROTLIENC, NULL, 0);
if (brotli_encode_dso != NULL) {
p_encode_init = (encode_init_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderCreateInstance");
@@ -318,9 +319,12 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_brotli_init)
|| p_decode_stream == NULL || p_decode_has_more == NULL || p_decode_end == NULL
|| p_decode_error == NULL || p_decode_error_string == NULL || p_decode_is_finished == NULL
|| p_decode_oneshot == NULL) {
+ ERR_clear_last_mark();
ossl_comp_brotli_cleanup();
return 0;
}
+ /* Do not leave errors behind on success. */
+ ERR_pop_to_mark();
#endif
return 1;
}
diff --git a/deps/openssl/openssl/crypto/comp/c_zlib.c b/deps/openssl/openssl/crypto/comp/c_zlib.c
index 7e970f81e9a..549bd4f0e5b 100644
--- a/deps/openssl/openssl/crypto/comp/c_zlib.c
+++ b/deps/openssl/openssl/crypto/comp/c_zlib.c
@@ -281,6 +281,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init)
#endif
#endif
+ ERR_set_mark();
zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);
if (zlib_dso != NULL) {
p_compress = (compress_ft)DSO_bind_func(zlib_dso, "compress");
@@ -298,9 +299,12 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init)
|| p_inflate == NULL || p_inflateInit_ == NULL
|| p_deflateEnd == NULL || p_deflate == NULL
|| p_deflateInit_ == NULL || p_zError == NULL) {
+ ERR_clear_last_mark();
ossl_comp_zlib_cleanup();
return 0;
}
+ /* Do not leave errors behind on success. */
+ ERR_pop_to_mark();
#endif
return 1;
}
diff --git a/deps/openssl/openssl/crypto/comp/c_zstd.c b/deps/openssl/openssl/crypto/comp/c_zstd.c
index 2cd3046050e..18f75f92f45 100644
--- a/deps/openssl/openssl/crypto/comp/c_zstd.c
+++ b/deps/openssl/openssl/crypto/comp/c_zstd.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2026 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
@@ -366,6 +366,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zstd_init)
#define LIBZSTD "zstd"
#endif
+ ERR_set_mark();
zstd_dso = DSO_load(NULL, LIBZSTD, NULL, 0);
if (zstd_dso != NULL) {
p_createCStream = (createCStream_ft)DSO_bind_func(zstd_dso, "ZSTD_createCStream");
@@ -392,9 +393,12 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zstd_init)
|| p_freeDStream == NULL || p_decompressStream == NULL || p_decompress == NULL
|| p_isError == NULL || p_getErrorName == NULL || p_DStreamInSize == NULL
|| p_CStreamInSize == NULL) {
+ ERR_clear_last_mark();
ossl_comp_zstd_cleanup();
return 0;
}
+ /* Do not leave errors behind on success. */
+ ERR_pop_to_mark();
#endif
return 1;
}
diff --git a/deps/openssl/openssl/crypto/dso/dso_win32.c b/deps/openssl/openssl/crypto/dso/dso_win32.c
index 3c1e0fbcf2b..77d45f7ee8c 100644
--- a/deps/openssl/openssl/crypto/dso/dso_win32.c
+++ b/deps/openssl/openssl/crypto/dso/dso_win32.c
@@ -55,6 +55,8 @@ static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
}
#endif
+#define GETPROCADDRESS(h, name, type) ((type)(void (*)(void))GetProcAddress((h), (name)))
+
/* Part of the hack in "win32_load" ... */
#define DSO_MAX_TRANSLATED_SIZE 256
@@ -177,7 +179,7 @@ static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
ERR_raise(ERR_LIB_DSO, DSO_R_NULL_HANDLE);
return NULL;
}
- sym.f = GetProcAddress(*ptr, symname);
+ sym.f = GETPROCADDRESS(*ptr, symname, FARPROC);
if (sym.p == NULL) {
ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE, "symname(%s)", symname);
return NULL;
@@ -485,12 +487,11 @@ typedef BOOL(WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
static int win32_pathbyaddr(void *addr, char *path, int sz)
{
- HMODULE dll;
- HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
- MODULEENTRY32 me32;
- CREATETOOLHELP32SNAPSHOT create_snap;
- CLOSETOOLHELP32SNAPSHOT close_snap;
- MODULE32 module_first, module_next;
+ HMODULE hModule = NULL;
+ const DWORD wpathSize = 32768; /* 32768 is the maximum possible path length on Windows */
+ WCHAR *wpath = NULL;
+ DWORD wlen, wsz;
+ int utf8len = -1;
if (addr == NULL) {
union {
@@ -502,89 +503,55 @@ static int win32_pathbyaddr(void *addr, char *path, int sz)
addr = t.p;
}
- dll = LoadLibrary(TEXT(DLLNAME));
- if (dll == NULL) {
- ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
- return -1;
+ if (!GetModuleHandleExW(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ (LPCWSTR)addr, &hModule)) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_SYM_FAILURE, "Unable to get module handle (%lu)\n",
+ GetLastError());
+ goto out;
}
-
- create_snap = (CREATETOOLHELP32SNAPSHOT)
- GetProcAddress(dll, "CreateToolhelp32Snapshot");
- if (create_snap == NULL) {
- FreeLibrary(dll);
- ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
- return -1;
+ wpath = (WCHAR *)OPENSSL_malloc(wpathSize * sizeof(WCHAR));
+ if (wpath == NULL) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_NULL_HANDLE, "Path allocation failure (%lu)\n",
+ GetLastError());
+ goto out;
+ }
+ wlen = GetModuleFileNameW(hModule, wpath, wpathSize);
+ if (wlen == 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED, "Module name fetch failed (%lu)\n",
+ GetLastError());
+ goto out;
}
- /* We take the rest for granted... */
-#ifdef _WIN32_WCE
- close_snap = (CLOSETOOLHELP32SNAPSHOT)
- GetProcAddress(dll, "CloseToolhelp32Snapshot");
-#else
- close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
-#endif
- module_first = (MODULE32)GetProcAddress(dll, "Module32First");
- module_next = (MODULE32)GetProcAddress(dll, "Module32Next");
/*
- * Take a snapshot of current process which includes
- * list of all involved modules.
+ * If we pass a size of 0 or less, invoke the size-query pattern,
+ * in which we do not actually copy the name to the path buffer,
+ * but return the size the path buffer needs to be for this object
*/
- hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE, 0);
- if (hModuleSnap == INVALID_HANDLE_VALUE) {
- FreeLibrary(dll);
- ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
- return -1;
+ if (sz <= 0) {
+ utf8len = (int)(wlen + 1);
+ goto out;
}
- me32.dwSize = sizeof(me32);
-
- if (!(*module_first)(hModuleSnap, &me32)) {
- (*close_snap)(hModuleSnap);
- FreeLibrary(dll);
- ERR_raise(ERR_LIB_DSO, DSO_R_FAILURE);
- return -1;
- }
-
- /* Enumerate the modules to find one which includes me. */
- do {
- if ((size_t)addr >= (size_t)me32.modBaseAddr && (size_t)addr < (size_t)(me32.modBaseAddr + me32.modBaseSize)) {
- (*close_snap)(hModuleSnap);
- FreeLibrary(dll);
-#ifdef _WIN32_WCE
-#if _WIN32_WCE >= 101
- return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1,
- path, sz, NULL, NULL);
-#else
- {
- int i, len = (int)wcslen(me32.szExePath);
- if (sz <= 0)
- return len + 1;
- if (len >= sz)
- len = sz - 1;
- for (i = 0; i < len; i++)
- path[i] = (char)me32.szExePath[i];
- path[len++] = '\0';
- return len;
- }
-#endif
-#else
- {
- int len = (int)strlen(me32.szExePath);
- if (sz <= 0)
- return len + 1;
- if (len >= sz)
- len = sz - 1;
- memcpy(path, me32.szExePath, len);
- path[len++] = '\0';
- return len;
- }
-#endif
- }
- } while ((*module_next)(hModuleSnap, &me32));
-
- (*close_snap)(hModuleSnap);
- FreeLibrary(dll);
- return 0;
+ /*
+ * Convert the wide path to UTF-8
+ */
+ wsz = (DWORD)sz;
+ utf8len = WideCharToMultiByte(CP_UTF8, 0, wpath, -1, NULL, 0, NULL, NULL);
+ if (utf8len <= 0 || (DWORD)utf8len > wsz) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED, "UTF8 query failed (%lu)\n",
+ GetLastError());
+ goto out;
+ }
+
+ if (WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, wsz, NULL, NULL) <= 0) {
+ ERR_raise_data(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED, "UTF8 translation failed (%lu)\n",
+ GetLastError());
+ goto out;
+ }
+out:
+ OPENSSL_free(wpath);
+ return utf8len;
}
static void *win32_globallookup(const char *name)
@@ -606,8 +573,7 @@ static void *win32_globallookup(const char *name)
return NULL;
}
- create_snap = (CREATETOOLHELP32SNAPSHOT)
- GetProcAddress(dll, "CreateToolhelp32Snapshot");
+ create_snap = GETPROCADDRESS(dll, "CreateToolhelp32Snapshot", CREATETOOLHELP32SNAPSHOT);
if (create_snap == NULL) {
FreeLibrary(dll);
ERR_raise(ERR_LIB_DSO, DSO_R_UNSUPPORTED);
@@ -615,13 +581,12 @@ static void *win32_globallookup(const char *name)
}
/* We take the rest for granted... */
#ifdef _WIN32_WCE
- close_snap = (CLOSETOOLHELP32SNAPSHOT)
- GetProcAddress(dll, "CloseToolhelp32Snapshot");
+ close_snap = GETPROCADDRESS(dll, "CloseToolhelp32Snapshot", CLOSETOOLHELP32SNAPSHOT);
#else
close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
#endif
- module_first = (MODULE32)GetProcAddress(dll, "Module32First");
- module_next = (MODULE32)GetProcAddress(dll, "Module32Next");
+ module_first = GETPROCADDRESS(dll, "Module32First", MODULE32);
+ module_next = GETPROCADDRESS(dll, "Module32Next", MODULE32);
hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE, 0);
if (hModuleSnap == INVALID_HANDLE_VALUE) {
@@ -639,7 +604,7 @@ static void *win32_globallookup(const char *name)
}
do {
- if ((ret.f = GetProcAddress(me32.hModule, name))) {
+ if ((ret.f = GETPROCADDRESS(me32.hModule, name, FARPROC))) {
(*close_snap)(hModuleSnap);
FreeLibrary(dll);
return ret.p;
diff --git a/deps/openssl/openssl/crypto/ec/ec_mult.c b/deps/openssl/openssl/crypto/ec/ec_mult.c
index 18f3d47d936..f7c6148eb25 100644
--- a/deps/openssl/openssl/crypto/ec/ec_mult.c
+++ b/deps/openssl/openssl/crypto/ec/ec_mult.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2026 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
@@ -213,6 +213,17 @@ int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
goto err;
}
+ /*
+ * Constant-timeness of this copy depends on the caller: BN_copy() moves
+ * scalar->top words unless |scalar| is flagged BN_FLG_CONSTTIME (in which
+ * case scalar->dmax words are moved). Secret scalars are therefore
+ * expected to arrive either BN_FLG_CONSTTIME or fixed-top, so that their
+ * top is a public, value-independent width and the copy length does not
+ * leak their magnitude. ECDSA satisfies this via
+ * ossl_bn_priv_rand_range_fixed_top(). The fixed-top pinning below makes
+ * the subsequent arithmetic constant time regardless, but cannot
+ * retroactively fix the copy length here.
+ */
if (!BN_copy(k, scalar)) {
ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
@@ -231,10 +242,36 @@ int ossl_ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
}
}
+ /*
+ * |k| may still carry a top that depends on the value of the secret
+ * scalar: callers pass either a fixed-top BIGNUM (e.g. the ECDSA nonce)
+ * or a minimal-top one (e.g. SM2), and BN_copy() above preserves that
+ * top. Pin |k| to a fixed number of words (matching the group
+ * cardinality) so that the additions below run in constant time,
+ * independently of the bit length of the scalar. Otherwise the work
+ * done by BN_add()/BN_uadd() depends on the operand tops and leaks the
+ * magnitude of the secret scalar.
+ */
+ if (!bn_set_top_fixed(k, group_top)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto err;
+ }
+
if (!BN_add(lambda, k, cardinality)) {
ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
goto err;
}
+ /*
+ * |lambda| = scalar + cardinality may or may not have produced a carry
+ * into an extra word depending on the secret scalar. Pin its top to one
+ * word above the group top so that the second addition, which consumes
+ * |lambda|, is likewise constant time and so that the BN_is_bit_set()
+ * below always inspects a defined word.
+ */
+ if (!bn_set_top_fixed(lambda, group_top + 1)) {
+ ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
+ goto err;
+ }
BN_set_flags(lambda, BN_FLG_CONSTTIME);
if (!BN_add(k, lambda, cardinality)) {
ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
diff --git a/deps/openssl/openssl/crypto/ec/ecp_sm2p256.c b/deps/openssl/openssl/crypto/ec/ecp_sm2p256.c
index 5cb5f1be994..e53e7ec5440 100644
--- a/deps/openssl/openssl/crypto/ec/ecp_sm2p256.c
+++ b/deps/openssl/openssl/crypto/ec/ecp_sm2p256.c
@@ -171,22 +171,35 @@ static ossl_inline void ecp_sm2p256_mod_inverse(BN_ULONG *out,
BN_MOD_INV(out, in, ecp_sm2p256_div_by_2, ecp_sm2p256_sub, def_p);
}
-/* Point double: R <- P + P */
-static void ecp_sm2p256_point_double(P256_POINT *R, const P256_POINT *P)
+/*
+ * Constant-time conditional copy: r = mask ? a : r, where mask is either 0 or
+ * all-ones. Used to select point-addition results without branching.
+ */
+static ossl_inline void ecp_sm2p256_cond_copy(P256_POINT *r,
+ const P256_POINT *a, BN_ULONG mask)
{
unsigned int i;
+
+ for (i = 0; i < P256_LIMBS; ++i) {
+ r->X[i] = constant_time_select_64(mask, a->X[i], r->X[i]);
+ r->Y[i] = constant_time_select_64(mask, a->Y[i], r->Y[i]);
+ r->Z[i] = constant_time_select_64(mask, a->Z[i], r->Z[i]);
+ }
+}
+
+/*
+ * Point double: R <- P + P
+ *
+ * Branch-free: the doubling formula already produces Z = 0 (the point at
+ * infinity) when the input Z is 0 (R->Z = 2*Y*Z), and the resulting X, Y are
+ * irrelevant for a Z = 0 point, so no is_zeros(P->Z) special case is needed.
+ */
+static void ecp_sm2p256_point_double(P256_POINT *R, const P256_POINT *P)
+{
ALIGN32 BN_ULONG tmp0[P256_LIMBS];
ALIGN32 BN_ULONG tmp1[P256_LIMBS];
ALIGN32 BN_ULONG tmp2[P256_LIMBS];
- /* zero-check P->Z */
- if (is_zeros(P->Z)) {
- for (i = 0; i < P256_LIMBS; ++i)
- R->Z[i] = 0;
-
- return;
- }
-
ecp_sm2p256_sqr(tmp0, P->Z);
ecp_sm2p256_sub(tmp1, P->X, tmp0);
ecp_sm2p256_add(tmp0, P->X, tmp0);
@@ -208,6 +221,13 @@ static void ecp_sm2p256_point_double(P256_POINT *R, const P256_POINT *P)
}
/* Point add affine: R <- P + Q */
+/*
+ * NB: this function is deliberately NOT constant time. It is used only to
+ * precompute the table of small multiples of the *public* input point (see
+ * ecp_sm2p256_point_P_mul_by_scalar); the secret scalar never flows through
+ * it, so its identity-dependent branches cannot leak it. Keeping the fast
+ * branchy formula here avoids the constant-time overhead on the table build.
+ */
static void ecp_sm2p256_point_add_affine(P256_POINT *R, const P256_POINT *P,
const P256_POINT_AFFINE *Q)
{
@@ -274,107 +294,164 @@ static void ecp_sm2p256_point_add_affine(P256_POINT *R, const P256_POINT *P,
static void ecp_sm2p256_point_add(P256_POINT *R, const P256_POINT *P,
const P256_POINT *Q)
{
- unsigned int i;
ALIGN32 BN_ULONG tmp0[P256_LIMBS] = { 0 };
ALIGN32 BN_ULONG tmp1[P256_LIMBS] = { 0 };
ALIGN32 BN_ULONG tmp2[P256_LIMBS] = { 0 };
-
- /* zero-check P | Q ->Z */
- if (is_zeros(P->Z)) {
- for (i = 0; i < P256_LIMBS; ++i) {
- R->X[i] = Q->X[i];
- R->Y[i] = Q->Y[i];
- R->Z[i] = Q->Z[i];
- }
-
- return;
- } else if (is_zeros(Q->Z)) {
- for (i = 0; i < P256_LIMBS; ++i) {
- R->X[i] = P->X[i];
- R->Y[i] = P->Y[i];
- R->Z[i] = P->Z[i];
- }
-
- return;
- } else if (is_point_equal(P, Q)) {
- ecp_sm2p256_point_double(R, Q);
-
- return;
- }
-
+ P256_POINT sum, dbl, res;
+ BN_ULONG p_inf, q_inf, is_dbl;
+
+ p_inf = is_zeros(P->Z);
+ q_inf = is_zeros(Q->Z);
+
+ /*
+ * General P + Q addition into |sum|, valid unless P or Q is infinity or
+ * P == +-Q. tmp0 = H and tmp1 = R are the coordinate differences: P and Q
+ * are the same point iff both are zero; P == -Q iff only H is zero (the
+ * formula then yields Z = 0, i.e. infinity, on its own).
+ */
ecp_sm2p256_sqr(tmp0, P->Z);
ecp_sm2p256_mul(tmp1, tmp0, P->Z);
ecp_sm2p256_mul(tmp0, tmp0, Q->X);
ecp_sm2p256_mul(tmp1, tmp1, Q->Y);
- ecp_sm2p256_mul(R->Y, P->Y, Q->Z);
- ecp_sm2p256_mul(R->Z, Q->Z, P->Z);
+ ecp_sm2p256_mul(sum.Y, P->Y, Q->Z);
+ ecp_sm2p256_mul(sum.Z, Q->Z, P->Z);
ecp_sm2p256_sqr(tmp2, Q->Z);
- ecp_sm2p256_mul(R->Y, tmp2, R->Y);
- ecp_sm2p256_mul(R->X, tmp2, P->X);
- ecp_sm2p256_sub(tmp0, tmp0, R->X);
- ecp_sm2p256_mul(R->Z, tmp0, R->Z);
- ecp_sm2p256_sub(tmp1, tmp1, R->Y);
+ ecp_sm2p256_mul(sum.Y, tmp2, sum.Y);
+ ecp_sm2p256_mul(sum.X, tmp2, P->X);
+ ecp_sm2p256_sub(tmp0, tmp0, sum.X);
+ ecp_sm2p256_mul(sum.Z, tmp0, sum.Z);
+ ecp_sm2p256_sub(tmp1, tmp1, sum.Y);
+ is_dbl = is_zeros(tmp0) & is_zeros(tmp1);
ecp_sm2p256_sqr(tmp2, tmp0);
ecp_sm2p256_mul(tmp0, tmp0, tmp2);
- ecp_sm2p256_mul(tmp2, tmp2, R->X);
- ecp_sm2p256_sqr(R->X, tmp1);
- ecp_sm2p256_sub(R->X, R->X, tmp2);
- ecp_sm2p256_sub(R->X, R->X, tmp2);
- ecp_sm2p256_sub(R->X, R->X, tmp0);
- ecp_sm2p256_sub(tmp2, tmp2, R->X);
+ ecp_sm2p256_mul(tmp2, tmp2, sum.X);
+ ecp_sm2p256_sqr(sum.X, tmp1);
+ ecp_sm2p256_sub(sum.X, sum.X, tmp2);
+ ecp_sm2p256_sub(sum.X, sum.X, tmp2);
+ ecp_sm2p256_sub(sum.X, sum.X, tmp0);
+ ecp_sm2p256_sub(tmp2, tmp2, sum.X);
ecp_sm2p256_mul(tmp2, tmp1, tmp2);
- ecp_sm2p256_mul(tmp0, tmp0, R->Y);
- ecp_sm2p256_sub(R->Y, tmp2, tmp0);
+ ecp_sm2p256_mul(tmp0, tmp0, sum.Y);
+ ecp_sm2p256_sub(sum.Y, tmp2, tmp0);
+
+ /* 2*P, for the P == Q case. */
+ ecp_sm2p256_point_double(&dbl, P);
+
+ /*
+ * Select the result without branching, in increasing priority:
+ * default -> sum (distinct points; also P == -Q which gives infinity)
+ * is_dbl -> dbl (P == Q)
+ * q_inf -> P (Q is infinity)
+ * p_inf -> Q (P is infinity; highest priority)
+ * All reads of P and Q happen before R is written, so R may alias P or Q.
+ */
+ memcpy(&res, &sum, sizeof(res));
+ ecp_sm2p256_cond_copy(&res, &dbl, is_dbl);
+ ecp_sm2p256_cond_copy(&res, P, q_inf);
+ ecp_sm2p256_cond_copy(&res, Q, p_inf);
+ memcpy(R, &res, sizeof(res));
}
#if !defined(OPENSSL_NO_SM2_PRECOMP)
/* Base point mul by scalar: k - scalar, G - base point */
+/*
+ * Constant-time gather of the affine entry |index| from a 256-entry sub-table.
+ * |sub| points to the sub-table for one 8-bit comb window; entry v is stored
+ * as X[P256_LIMBS] followed by Y[P256_LIMBS] at sub + v * (2 * P256_LIMBS).
+ * Entry 0 is not stored, so index 0 yields the all-zero (X, Y) placeholder,
+ * which the caller turns into the point at infinity.
+ */
+static void ecp_sm2p256_select_G(P256_POINT_AFFINE *R, const BN_ULONG *sub,
+ unsigned int index)
+{
+ unsigned int v, j;
+
+ memset(R, 0, sizeof(*R));
+ for (v = 1; v < 256; ++v) {
+ BN_ULONG mask = constant_time_is_zero_64((BN_ULONG)(index ^ v));
+ const BN_ULONG *e = sub + (size_t)v * (2 * P256_LIMBS);
+
+ for (j = 0; j < P256_LIMBS; ++j) {
+ R->X[j] |= constant_time_select_64(mask, e[j], 0);
+ R->Y[j] |= constant_time_select_64(mask, e[P256_LIMBS + j], 0);
+ }
+ }
+}
+
+/*
+ * R = k*G using the precomputed comb. Constant-time: every 8-bit window is
+ * gathered from its full 256-entry sub-table with a mask and lifted to a
+ * Jacobian point whose Z is 1 for a non-zero window and 0 (infinity) for a
+ * zero window, so the unconditional, branch-free addition contributes nothing
+ * for a zero window and no secret-dependent branch or table index remains.
+ */
static void ecp_sm2p256_point_G_mul_by_scalar(P256_POINT *R, const BN_ULONG *k)
{
- unsigned int i, index, mask = 0xff;
- P256_POINT_AFFINE Q;
+ unsigned int i, j, index;
+ P256_POINT_AFFINE Qaff;
+ P256_POINT QJ;
memset(R, 0, sizeof(P256_POINT));
- if (is_zeros(k))
- return;
+ for (i = 0; i < 32; ++i) {
+ index = (k[i / 8] >> (8 * (i % 8))) & 0xff;
+ ecp_sm2p256_select_G(&Qaff,
+ ecp_sm2p256_precomputed + (size_t)i * 256 * (2 * P256_LIMBS),
+ index);
- index = k[0] & mask;
- if (index) {
- index = index * 8;
- memcpy(R->X, ecp_sm2p256_precomputed + index, 32);
- memcpy(R->Y, ecp_sm2p256_precomputed + index + P256_LIMBS, 32);
- R->Z[0] = 1;
+ {
+ /* Z = 1 iff the window is non-zero, else 0 (point at infinity). */
+ BN_ULONG nz = ~constant_time_is_zero_64((BN_ULONG)index);
+
+ for (j = 0; j < P256_LIMBS; ++j) {
+ QJ.X[j] = Qaff.X[j];
+ QJ.Y[j] = Qaff.Y[j];
+ QJ.Z[j] = 0;
+ }
+ QJ.Z[0] = nz & 1;
+ }
+ ecp_sm2p256_point_add(R, R, &QJ);
}
+}
+#endif
+
+/*
+ * Constant-time gather of |index| from a 16-entry table of Jacobian points.
+ * Index 0 yields the all-zero point (Z = 0, i.e. the point at infinity).
+ */
+static void ecp_sm2p256_select_P(P256_POINT *R, const P256_POINT tbl[16],
+ unsigned int index)
+{
+ unsigned int i, j;
- for (i = 1; i < 32; ++i) {
- index = (k[i / 8] >> (8 * (i % 8))) & mask;
+ memset(R, 0, sizeof(*R));
+ for (i = 1; i < 16; ++i) {
+ BN_ULONG mask = constant_time_is_zero_64((BN_ULONG)(index ^ i));
- if (index) {
- index = index + i * 256;
- index = index * 8;
- memcpy(Q.X, ecp_sm2p256_precomputed + index, 32);
- memcpy(Q.Y, ecp_sm2p256_precomputed + index + P256_LIMBS, 32);
- ecp_sm2p256_point_add_affine(R, R, &Q);
+ for (j = 0; j < P256_LIMBS; ++j) {
+ R->X[j] |= constant_time_select_64(mask, tbl[i].X[j], 0);
+ R->Y[j] |= constant_time_select_64(mask, tbl[i].Y[j], 0);
+ R->Z[j] |= constant_time_select_64(mask, tbl[i].Z[j], 0);
}
}
}
-#endif
/*
* Affine point mul by scalar: k - scalar, P - affine point
+ *
+ * Constant-time windowed multiplication: every 4-bit window is processed
+ * uniformly with four doublings followed by a masked table gather and an
+ * unconditional, branch-free addition. There is no init/skip logic and no
+ * secret-dependent table index, so the running time and memory-access pattern
+ * do not depend on the value of the secret scalar.
*/
static void ecp_sm2p256_point_P_mul_by_scalar(P256_POINT *R, const BN_ULONG *k,
P256_POINT_AFFINE P)
{
- int i, init = 0;
+ int i;
unsigned int index, mask = 0x0f;
ALIGN64 P256_POINT precomputed[16];
-
- memset(R, 0, sizeof(P256_POINT));
-
- if (is_zeros(k))
- return;
+ P256_POINT T;
/* The first value of the precomputed table is P. */
memcpy(precomputed[1].X, P.X, 32);
@@ -391,22 +468,18 @@ static void ecp_sm2p256_point_P_mul_by_scalar(P256_POINT *R, const BN_ULONG *k,
for (i = 3; i < 16; ++i)
ecp_sm2p256_point_add_affine(&precomputed[i], &precomputed[i - 1], &P);
+ memset(R, 0, sizeof(*R)); /* R = point at infinity */
+
for (i = 64 - 1; i >= 0; --i) {
index = (k[i / 16] >> (4 * (i % 16))) & mask;
- if (init == 0) {
- if (index) {
- memcpy(R, &precomputed[index], sizeof(P256_POINT));
- init = 1;
- }
- } else {
- ecp_sm2p256_point_double(R, R);
- ecp_sm2p256_point_double(R, R);
- ecp_sm2p256_point_double(R, R);
- ecp_sm2p256_point_double(R, R);
- if (index)
- ecp_sm2p256_point_add(R, R, &precomputed[index]);
- }
+ ecp_sm2p256_point_double(R, R);
+ ecp_sm2p256_point_double(R, R);
+ ecp_sm2p256_point_double(R, R);
+ ecp_sm2p256_point_double(R, R);
+
+ ecp_sm2p256_select_P(&T, precomputed, index);
+ ecp_sm2p256_point_add(R, R, &T);
}
}
diff --git a/deps/openssl/openssl/crypto/err/err.c b/deps/openssl/openssl/crypto/err/err.c
index a995c4e2422..94c542cd3f5 100644
--- a/deps/openssl/openssl/crypto/err/err.c
+++ b/deps/openssl/openssl/crypto/err/err.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 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
@@ -312,6 +312,10 @@ int ERR_unload_strings(int lib, ERR_STRING_DATA *str)
if (!RUN_ONCE(&err_string_init, do_err_strings_init))
return 0;
+ /* The error string table may already have been cleaned up. */
+ if (err_string_lock == NULL)
+ return 1;
+
if (!CRYPTO_THREAD_write_lock(err_string_lock))
return 0;
/*
diff --git a/deps/openssl/openssl/crypto/evp/bio_enc.c b/deps/openssl/openssl/crypto/evp/bio_enc.c
index 861f7457ca6..4ffa366cb68 100644
--- a/deps/openssl/openssl/crypto/evp/bio_enc.c
+++ b/deps/openssl/openssl/crypto/evp/bio_enc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 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
@@ -383,9 +383,6 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
dctx = BIO_get_data(dbio);
- dctx->cipher = EVP_CIPHER_CTX_new();
- if (dctx->cipher == NULL)
- return 0;
ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
if (ret)
BIO_set_init(dbio, 1);
diff --git a/deps/openssl/openssl/crypto/evp/evp_lib.c b/deps/openssl/openssl/crypto/evp/evp_lib.c
index 95eeca3c4d4..652374ed43d 100644
--- a/deps/openssl/openssl/crypto/evp/evp_lib.c
+++ b/deps/openssl/openssl/crypto/evp/evp_lib.c
@@ -194,7 +194,9 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type,
break;
default:
- ret = EVP_CIPHER_get_asn1_iv(c, type) >= 0 ? 1 : -1;
+ ret = EVP_CIPHER_get_asn1_iv(c, type);
+ if (ret == 0 && EVP_CIPHER_CTX_get_iv_length(c) == 0)
+ ret = 1;
}
} else if (cipher->prov != NULL) {
/* We cheat, there's no need for an object ID for this use */
diff --git a/deps/openssl/openssl/crypto/http/http_client.c b/deps/openssl/openssl/crypto/http/http_client.c
index 3502766f6b7..701efe86d2d 100644
--- a/deps/openssl/openssl/crypto/http/http_client.c
+++ b/deps/openssl/openssl/crypto/http/http_client.c
@@ -1264,7 +1264,7 @@ BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url)
return resp;
}
-static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
+static int redirection_ok(int n_redir, int use_ssl, const char *new_url)
{
if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
ERR_raise(ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS);
@@ -1272,7 +1272,7 @@ static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
}
if (*new_url == '/') /* redirection to same server => same protocol */
return 1;
- if (HAS_PREFIX(old_url, OSSL_HTTPS_NAME ":") && !HAS_PREFIX(new_url, OSSL_HTTPS_NAME ":")) {
+ if (use_ssl && !HAS_PREFIX(new_url, OSSL_HTTPS_NAME ":")) {
ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
return 0;
}
@@ -1331,7 +1331,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
}
OPENSSL_free(path);
if (resp == NULL && redirection_url != NULL) {
- if (redirection_ok(++n_redirs, current_url, redirection_url)
+ if (redirection_ok(++n_redirs, use_ssl, redirection_url)
&& may_still_retry(max_time, &timeout)) {
(void)BIO_reset(bio);
OPENSSL_free(current_url);
diff --git a/deps/openssl/openssl/crypto/init.c b/deps/openssl/openssl/crypto/init.c
index ea29645b648..290bb0712c1 100644
--- a/deps/openssl/openssl/crypto/init.c
+++ b/deps/openssl/openssl/crypto/init.c
@@ -496,6 +496,7 @@ void OPENSSL_cleanup(void)
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
{
uint64_t tmp;
+ uint64_t optsdone_bits = opts;
int aloaddone = 0;
/* Applications depend on 0 being returned when cleanup was already done */
@@ -621,8 +622,15 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
if (opts & OPENSSL_INIT_LOAD_CONFIG) {
int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL;
- /* If called recursively from OBJ_ calls, just skip it. */
- if (!loading) {
+ /* If called recursively from OBJ_ calls during config loading,
+ * we have to mask OPENSSL_INIT_LOAD_CONFIG in optsdone to not
+ * advertise that config loading is complete, otherwise other
+ * threads may proceed, e.g., to fetching from a provider that
+ * is not yet loaded.
+ */
+ if (loading) {
+ optsdone_bits &= ~(uint64_t)OPENSSL_INIT_LOAD_CONFIG;
+ } else {
int ret;
if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1))
@@ -687,7 +695,7 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
}
#endif
- if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
+ if (!CRYPTO_atomic_or(&optsdone, optsdone_bits, &tmp, optsdone_lock))
return 0;
return 1;
diff --git a/deps/openssl/openssl/crypto/modes/siv128.c b/deps/openssl/openssl/crypto/modes/siv128.c
index 0ab183b37b5..456c1ae6639 100644
--- a/deps/openssl/openssl/crypto/modes/siv128.c
+++ b/deps/openssl/openssl/crypto/modes/siv128.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2026 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
@@ -276,23 +276,29 @@ int ossl_siv128_encrypt(SIV128_CONTEXT *ctx,
size_t len)
{
SIV_BLOCK q;
+ int ret = 0;
+ int final_ret_value = -1;
/* can only do one crypto operation */
if (ctx->crypto_ok == 0)
- return 0;
+ goto end;
ctx->crypto_ok--;
if (!siv128_do_s2v_p(ctx, &q, in, len))
- return 0;
+ goto end;
memcpy(ctx->tag.byte, &q, SIV_LEN);
q.byte[8] &= 0x7f;
q.byte[12] &= 0x7f;
if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q))
- return 0;
- ctx->final_ret = 0;
- return 1;
+ goto end;
+
+ ret = 1;
+ final_ret_value = 0;
+end:
+ ctx->final_ret = final_ret_value;
+ return ret;
}
/*
@@ -305,10 +311,12 @@ int ossl_siv128_decrypt(SIV128_CONTEXT *ctx,
unsigned char *p;
SIV_BLOCK t, q;
int i;
+ int ret = 0;
+ int final_ret_value = -1;
/* can only do one crypto operation */
if (ctx->crypto_ok == 0)
- return 0;
+ goto end;
ctx->crypto_ok--;
memcpy(&q, ctx->tag.byte, SIV_LEN);
@@ -317,7 +325,7 @@ int ossl_siv128_decrypt(SIV128_CONTEXT *ctx,
if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q)
|| !siv128_do_s2v_p(ctx, &t, out, len))
- return 0;
+ goto end;
p = ctx->tag.byte;
for (i = 0; i < SIV_LEN; i++)
@@ -325,10 +333,13 @@ int ossl_siv128_decrypt(SIV128_CONTEXT *ctx,
if ((t.word[0] | t.word[1]) != 0) {
OPENSSL_cleanse(out, len);
- return 0;
+ goto end;
}
- ctx->final_ret = 0;
- return 1;
+ ret = 1;
+ final_ret_value = 0;
+end:
+ ctx->final_ret = final_ret_value;
+ return ret;
}
/*
diff --git a/deps/openssl/openssl/crypto/ocsp/ocsp_cl.c b/deps/openssl/openssl/crypto/ocsp/ocsp_cl.c
index 8cf49ca4679..338d562328e 100644
--- a/deps/openssl/openssl/crypto/ocsp/ocsp_cl.c
+++ b/deps/openssl/openssl/crypto/ocsp/ocsp_cl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2026 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
@@ -310,7 +310,7 @@ int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
{
- int ret = 1;
+ int ret = 1, cmp;
time_t t_now, t_tmp;
time(&t_now);
@@ -320,16 +320,20 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
ret = 0;
} else {
t_tmp = t_now + nsec;
- if (X509_cmp_time(thisupd, &t_tmp) > 0) {
+ cmp = X509_cmp_time(thisupd, &t_tmp);
+ if (cmp == 0) {
+ ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
+ ret = 0;
+ } else if (cmp > 0) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID);
ret = 0;
}
/*
* If maxsec specified check thisUpdate is not more than maxsec in
- * the past
+ * the past. Skip this check if thisUpdate could not be compared above.
*/
- if (maxsec >= 0) {
+ if (cmp != 0 && maxsec >= 0) {
t_tmp = t_now - maxsec;
if (X509_cmp_time(thisupd, &t_tmp) < 0) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD);
@@ -347,7 +351,11 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
ret = 0;
} else {
t_tmp = t_now - nsec;
- if (X509_cmp_time(nextupd, &t_tmp) < 0) {
+ cmp = X509_cmp_time(nextupd, &t_tmp);
+ if (cmp == 0) {
+ ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
+ ret = 0;
+ } else if (cmp < 0) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED);
ret = 0;
}
diff --git a/deps/openssl/openssl/crypto/perlasm/x86asm.pl b/deps/openssl/openssl/crypto/perlasm/x86asm.pl
index 05b5ff94c54..2ec16c5571d 100644
--- a/deps/openssl/openssl/crypto/perlasm/x86asm.pl
+++ b/deps/openssl/openssl/crypto/perlasm/x86asm.pl
@@ -174,9 +174,9 @@ sub ::vprotd
sub ::endbranch
{
- &::generic("%ifdef __CET__\n");
+ &::generic("#ifdef __CET__\n");
&::data_byte(0xf3,0x0f,0x1e,0xfb);
- &::generic("%endif\n");
+ &::generic("#endif\n");
}
# label management
diff --git a/deps/openssl/openssl/crypto/property/property.c b/deps/openssl/openssl/crypto/property/property.c
index b702d03f613..210a3afe76b 100644
--- a/deps/openssl/openssl/crypto/property/property.c
+++ b/deps/openssl/openssl/crypto/property/property.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -64,7 +64,7 @@ typedef struct {
struct ossl_method_store_st {
OSSL_LIB_CTX *ctx;
- SPARSE_ARRAY_OF(ALGORITHM) * algs;
+ SPARSE_ARRAY_OF(ALGORITHM) *algs;
/*
* Lock to protect the |algs| array from concurrent writing, when
* individual implementations or queries are inserted. This is used
diff --git a/deps/openssl/openssl/crypto/provider_core.c b/deps/openssl/openssl/crypto/provider_core.c
index 507be352775..2a47a9e709a 100644
--- a/deps/openssl/openssl/crypto/provider_core.c
+++ b/deps/openssl/openssl/crypto/provider_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -1668,10 +1668,10 @@ int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name)
prov = ossl_provider_find(libctx, name, 0);
if (prov != NULL) {
- if (!CRYPTO_THREAD_read_lock(prov->flag_lock))
- return 0;
- available = prov->flag_activated;
- CRYPTO_THREAD_unlock(prov->flag_lock);
+ if (CRYPTO_THREAD_read_lock(prov->flag_lock)) {
+ available = prov->flag_activated;
+ CRYPTO_THREAD_unlock(prov->flag_lock);
+ }
ossl_provider_free(prov);
}
return available;
diff --git a/deps/openssl/openssl/crypto/rbtree/build.info b/deps/openssl/openssl/crypto/rbtree/build.info
new file mode 100644
index 00000000000..79f9ff01e67
--- /dev/null
+++ b/deps/openssl/openssl/crypto/rbtree/build.info
@@ -0,0 +1,3 @@
+LIBS=../../libcrypto
+SOURCE[../../libcrypto]=\
+ rbtree.c
diff --git a/deps/openssl/openssl/crypto/rbtree/rbtree.c b/deps/openssl/openssl/crypto/rbtree/rbtree.c
new file mode 100644
index 00000000000..f1d89166e56
--- /dev/null
+++ b/deps/openssl/openssl/crypto/rbtree/rbtree.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2016 David Gwynne <david@gwynne.id.au>
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * The code here comes from David Gwynne <david@gwynne.id.au>. The original
+ * version can be found:
+ * https://github.com/dgwynne/data-structures/
+ * file bst.h. The same code is also part of OpenBSD OS where it is shipped
+ * under BSD license.
+ *
+ * David Gwynne agrees to include modified version to OpenSSL and ship it
+ * under OpenSSL Apache 2.0 license.
+ */
+
+#include "internal/ossl_rbtree.h"
+
+#ifndef NDEBUG
+#include <assert.h>
+#endif
+
+#define OSSL_RBT_BLACK 0
+#define OSSL_RBT_RED 1
+
+static struct ossl_rbt_entry *
+rbt_n2e(const struct ossl_rbt_type *t, void *node)
+{
+ uintptr_t addr = (uintptr_t)node;
+
+ return (struct ossl_rbt_entry *)(addr + t->t_offset);
+}
+
+static void *
+rbt_e2n(const struct ossl_rbt_type *t, struct ossl_rbt_entry *rbe)
+{
+ uintptr_t addr = (uintptr_t)rbe;
+
+ return (void *)(addr - t->t_offset);
+}
+
+#define OSSL_RBE_LEFT(_rbe) (_rbe)->rb_left
+#define OSSL_RBE_RIGHT(_rbe) (_rbe)->rb_right
+#define OSSL_RBE_PARENT(_rbe) (_rbe)->rb_parent
+#define OSSL_RBE_COLOR(_rbe) (_rbe)->rb_color
+
+#define OSSL_RBH_ROOT(_rbt) (_rbt)->rb_root
+
+static void
+rbe_set(struct ossl_rbt_entry *rbe, struct ossl_rbt_entry *parent)
+{
+ OSSL_RBE_PARENT(rbe) = parent;
+ OSSL_RBE_LEFT(rbe) = OSSL_RBE_RIGHT(rbe) = NULL;
+ OSSL_RBE_COLOR(rbe) = OSSL_RBT_RED;
+}
+
+static void
+rbe_set_blackred(struct ossl_rbt_entry *black, struct ossl_rbt_entry *red)
+{
+ OSSL_RBE_COLOR(black) = OSSL_RBT_BLACK;
+ OSSL_RBE_COLOR(red) = OSSL_RBT_RED;
+}
+
+static void
+rbe_rotate_left(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
+{
+ struct ossl_rbt_entry *parent;
+ struct ossl_rbt_entry *tmp;
+
+ tmp = OSSL_RBE_RIGHT(rbe);
+ OSSL_RBE_RIGHT(rbe) = OSSL_RBE_LEFT(tmp);
+ if (OSSL_RBE_RIGHT(rbe) != NULL)
+ OSSL_RBE_PARENT(OSSL_RBE_LEFT(tmp)) = rbe;
+
+ parent = OSSL_RBE_PARENT(rbe);
+ OSSL_RBE_PARENT(tmp) = parent;
+ if (parent != NULL) {
+ if (rbe == OSSL_RBE_LEFT(parent))
+ OSSL_RBE_LEFT(parent) = tmp;
+ else
+ OSSL_RBE_RIGHT(parent) = tmp;
+ } else
+ OSSL_RBH_ROOT(rbt) = tmp;
+
+ OSSL_RBE_LEFT(tmp) = rbe;
+ OSSL_RBE_PARENT(rbe) = tmp;
+}
+
+static void
+rbe_rotate_right(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
+{
+ struct ossl_rbt_entry *parent;
+ struct ossl_rbt_entry *tmp;
+
+ tmp = OSSL_RBE_LEFT(rbe);
+ OSSL_RBE_LEFT(rbe) = OSSL_RBE_RIGHT(tmp);
+ if (OSSL_RBE_LEFT(rbe) != NULL)
+ OSSL_RBE_PARENT(OSSL_RBE_RIGHT(tmp)) = rbe;
+
+ parent = OSSL_RBE_PARENT(rbe);
+ OSSL_RBE_PARENT(tmp) = parent;
+ if (parent != NULL) {
+ if (rbe == OSSL_RBE_LEFT(parent))
+ OSSL_RBE_LEFT(parent) = tmp;
+ else
+ OSSL_RBE_RIGHT(parent) = tmp;
+ } else
+ OSSL_RBH_ROOT(rbt) = tmp;
+
+ OSSL_RBE_RIGHT(tmp) = rbe;
+ OSSL_RBE_PARENT(rbe) = tmp;
+}
+
+static void
+rbe_insert_color(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
+{
+ struct ossl_rbt_entry *parent, *gparent, *tmp;
+
+ while ((parent = OSSL_RBE_PARENT(rbe)) != NULL && OSSL_RBE_COLOR(parent) == OSSL_RBT_RED) {
+ gparent = OSSL_RBE_PARENT(parent);
+
+ if (parent == OSSL_RBE_LEFT(gparent)) {
+ tmp = OSSL_RBE_RIGHT(gparent);
+ if (tmp != NULL && OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
+ OSSL_RBE_COLOR(tmp) = OSSL_RBT_BLACK;
+ rbe_set_blackred(parent, gparent);
+ rbe = gparent;
+ continue;
+ }
+
+ if (OSSL_RBE_RIGHT(parent) == rbe) {
+ rbe_rotate_left(rbt, parent);
+ tmp = parent;
+ parent = rbe;
+ rbe = tmp;
+ }
+
+ rbe_set_blackred(parent, gparent);
+ rbe_rotate_right(rbt, gparent);
+ } else {
+ tmp = OSSL_RBE_LEFT(gparent);
+ if (tmp != NULL && OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
+ OSSL_RBE_COLOR(tmp) = OSSL_RBT_BLACK;
+ rbe_set_blackred(parent, gparent);
+ rbe = gparent;
+ continue;
+ }
+
+ if (OSSL_RBE_LEFT(parent) == rbe) {
+ rbe_rotate_right(rbt, parent);
+ tmp = parent;
+ parent = rbe;
+ rbe = tmp;
+ }
+
+ rbe_set_blackred(parent, gparent);
+ rbe_rotate_left(rbt, gparent);
+ }
+ }
+
+ OSSL_RBE_COLOR(OSSL_RBH_ROOT(rbt)) = OSSL_RBT_BLACK;
+}
+
+static void
+rbe_remove_color(struct ossl_rbt_tree *rbt,
+ struct ossl_rbt_entry *parent, struct ossl_rbt_entry *rbe)
+{
+ struct ossl_rbt_entry *tmp;
+
+ while ((rbe == NULL || OSSL_RBE_COLOR(rbe) == OSSL_RBT_BLACK) && rbe != OSSL_RBH_ROOT(rbt)) {
+ if (OSSL_RBE_LEFT(parent) == rbe) {
+ tmp = OSSL_RBE_RIGHT(parent);
+ if (OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
+ rbe_set_blackred(tmp, parent);
+ rbe_rotate_left(rbt, parent);
+ tmp = OSSL_RBE_RIGHT(parent);
+ }
+ if ((OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) && (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK)) {
+ OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
+ rbe = parent;
+ parent = OSSL_RBE_PARENT(rbe);
+ } else {
+ if (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK) {
+ struct ossl_rbt_entry *oleft;
+
+ oleft = OSSL_RBE_LEFT(tmp);
+ if (oleft != NULL)
+ OSSL_RBE_COLOR(oleft) = OSSL_RBT_BLACK;
+
+ OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
+ rbe_rotate_right(rbt, tmp);
+ tmp = OSSL_RBE_RIGHT(parent);
+ }
+
+ OSSL_RBE_COLOR(tmp) = OSSL_RBE_COLOR(parent);
+ OSSL_RBE_COLOR(parent) = OSSL_RBT_BLACK;
+ if (OSSL_RBE_RIGHT(tmp))
+ OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) = OSSL_RBT_BLACK;
+
+ rbe_rotate_left(rbt, parent);
+ rbe = OSSL_RBH_ROOT(rbt);
+ break;
+ }
+ } else {
+ tmp = OSSL_RBE_LEFT(parent);
+ if (OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) {
+ rbe_set_blackred(tmp, parent);
+ rbe_rotate_right(rbt, parent);
+ tmp = OSSL_RBE_LEFT(parent);
+ }
+
+ if ((OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) && (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK)) {
+ OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
+ rbe = parent;
+ parent = OSSL_RBE_PARENT(rbe);
+ } else {
+ if (OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) {
+ struct ossl_rbt_entry *oright;
+
+ oright = OSSL_RBE_RIGHT(tmp);
+ if (oright != NULL)
+ OSSL_RBE_COLOR(oright) = OSSL_RBT_BLACK;
+
+ OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED;
+ rbe_rotate_left(rbt, tmp);
+ tmp = OSSL_RBE_LEFT(parent);
+ }
+
+ OSSL_RBE_COLOR(tmp) = OSSL_RBE_COLOR(parent);
+ OSSL_RBE_COLOR(parent) = OSSL_RBT_BLACK;
+ if (OSSL_RBE_LEFT(tmp) != NULL)
+ OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) = OSSL_RBT_BLACK;
+
+ rbe_rotate_right(rbt, parent);
+ rbe = OSSL_RBH_ROOT(rbt);
+ break;
+ }
+ }
+ }
+
+ if (rbe != NULL)
+ OSSL_RBE_COLOR(rbe) = OSSL_RBT_BLACK;
+}
+
+static struct ossl_rbt_entry *
+rbe_remove(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe)
+{
+ struct ossl_rbt_entry *child, *parent, *old = rbe;
+ unsigned int color;
+
+ if (OSSL_RBE_LEFT(rbe) == NULL)
+ child = OSSL_RBE_RIGHT(rbe);
+ else if (OSSL_RBE_RIGHT(rbe) == NULL)
+ child = OSSL_RBE_LEFT(rbe);
+ else {
+ struct ossl_rbt_entry *tmp;
+
+ rbe = OSSL_RBE_RIGHT(rbe);
+ while ((tmp = OSSL_RBE_LEFT(rbe)) != NULL)
+ rbe = tmp;
+
+ child = OSSL_RBE_RIGHT(rbe);
+ parent = OSSL_RBE_PARENT(rbe);
+ color = OSSL_RBE_COLOR(rbe);
+ if (child != NULL)
+ OSSL_RBE_PARENT(child) = parent;
+ if (parent != NULL) {
+ if (OSSL_RBE_LEFT(parent) == rbe)
+ OSSL_RBE_LEFT(parent) = child;
+ else
+ OSSL_RBE_RIGHT(parent) = child;
+ } else
+ OSSL_RBH_ROOT(rbt) = child;
+ if (OSSL_RBE_PARENT(rbe) == old)
+ parent = rbe;
+ *rbe = *old;
+
+ tmp = OSSL_RBE_PARENT(old);
+ if (tmp != NULL) {
+ if (OSSL_RBE_LEFT(tmp) == old)
+ OSSL_RBE_LEFT(tmp) = rbe;
+ else
+ OSSL_RBE_RIGHT(tmp) = rbe;
+ } else
+ OSSL_RBH_ROOT(rbt) = rbe;
+
+ OSSL_RBE_PARENT(OSSL_RBE_LEFT(old)) = rbe;
+ if (OSSL_RBE_RIGHT(old))
+ OSSL_RBE_PARENT(OSSL_RBE_RIGHT(old)) = rbe;
+ goto color;
+ }
+
+ parent = OSSL_RBE_PARENT(rbe);
+ color = OSSL_RBE_COLOR(rbe);
+
+ if (child != NULL)
+ OSSL_RBE_PARENT(child) = parent;
+ if (parent != NULL) {
+ if (OSSL_RBE_LEFT(parent) == rbe)
+ OSSL_RBE_LEFT(parent) = child;
+ else
+ OSSL_RBE_RIGHT(parent) = child;
+ } else
+ OSSL_RBH_ROOT(rbt) = child;
+color:
+ if (color == OSSL_RBT_BLACK)
+ rbe_remove_color(rbt, parent, child);
+
+#ifndef NDEBUG
+ if (old != NULL) {
+ OSSL_RBE_PARENT(old) = NULL;
+ OSSL_RBE_LEFT(old) = NULL;
+ OSSL_RBE_RIGHT(old) = NULL;
+ }
+#endif
+
+ return old;
+}
+
+void *
+ossl_rbt_remove(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, void *elm)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
+ struct ossl_rbt_entry *old;
+
+ old = rbe_remove(rbt, rbe);
+
+ return old == NULL ? NULL : rbt_e2n(t, old);
+}
+
+void *
+ossl_rbt_insert(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, void *elm)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
+ struct ossl_rbt_entry *tmp;
+ struct ossl_rbt_entry *parent = NULL;
+ void *node;
+ int comp = 0;
+
+#ifndef NDEBUG
+ assert(rbe->rb_parent == NULL);
+ assert(rbe->rb_left == NULL);
+ assert(rbe->rb_right == NULL);
+#endif
+
+ tmp = OSSL_RBH_ROOT(rbt);
+ while (tmp != NULL) {
+ parent = tmp;
+
+ node = rbt_e2n(t, tmp);
+ comp = (*t->t_compare)(elm, node);
+ if (comp < 0)
+ tmp = OSSL_RBE_LEFT(tmp);
+ else if (comp > 0)
+ tmp = OSSL_RBE_RIGHT(tmp);
+ else
+ return node;
+ }
+
+ rbe_set(rbe, parent);
+
+ if (parent != NULL) {
+ if (comp < 0)
+ OSSL_RBE_LEFT(parent) = rbe;
+ else
+ OSSL_RBE_RIGHT(parent) = rbe;
+ } else
+ OSSL_RBH_ROOT(rbt) = rbe;
+
+ rbe_insert_color(rbt, rbe);
+
+ return NULL;
+}
+
+/* Finds the node with the same key as elm */
+void *
+ossl_rbt_find(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, const void *key)
+{
+ struct ossl_rbt_entry *tmp = OSSL_RBH_ROOT(rbt);
+ void *node;
+ int comp;
+
+ while (tmp != NULL) {
+ node = rbt_e2n(t, tmp);
+ comp = (*t->t_compare)(key, node);
+ if (comp < 0)
+ tmp = OSSL_RBE_LEFT(tmp);
+ else if (comp > 0)
+ tmp = OSSL_RBE_RIGHT(tmp);
+ else
+ return node;
+ }
+
+ return NULL;
+}
+
+/* Finds the first node greater than or equal to the search key */
+void *
+ossl_rbt_nfind(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, const void *key)
+{
+ struct ossl_rbt_entry *tmp = OSSL_RBH_ROOT(rbt);
+ void *node;
+ void *res = NULL;
+ int comp;
+
+ while (tmp != NULL) {
+ node = rbt_e2n(t, tmp);
+ comp = (*t->t_compare)(key, node);
+ if (comp < 0) {
+ res = node;
+ tmp = OSSL_RBE_LEFT(tmp);
+ } else if (comp > 0)
+ tmp = OSSL_RBE_RIGHT(tmp);
+ else
+ return node;
+ }
+
+ return res;
+}
+
+void *
+ossl_rbt_next(const struct ossl_rbt_type *t, void *elm)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
+
+ if (OSSL_RBE_RIGHT(rbe) != NULL) {
+ rbe = OSSL_RBE_RIGHT(rbe);
+ while (OSSL_RBE_LEFT(rbe) != NULL)
+ rbe = OSSL_RBE_LEFT(rbe);
+ } else {
+ if (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_LEFT(OSSL_RBE_PARENT(rbe))))
+ rbe = OSSL_RBE_PARENT(rbe);
+ else {
+ while (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_RIGHT(OSSL_RBE_PARENT(rbe))))
+ rbe = OSSL_RBE_PARENT(rbe);
+ rbe = OSSL_RBE_PARENT(rbe);
+ }
+ }
+
+ return rbe == NULL ? NULL : rbt_e2n(t, rbe);
+}
+
+void *
+ossl_rbt_prev(const struct ossl_rbt_type *t, void *elm)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, elm);
+
+ if (OSSL_RBE_LEFT(rbe)) {
+ rbe = OSSL_RBE_LEFT(rbe);
+ while (OSSL_RBE_RIGHT(rbe))
+ rbe = OSSL_RBE_RIGHT(rbe);
+ } else {
+ if (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_RIGHT(OSSL_RBE_PARENT(rbe))))
+ rbe = OSSL_RBE_PARENT(rbe);
+ else {
+ while (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_LEFT(OSSL_RBE_PARENT(rbe))))
+ rbe = OSSL_RBE_PARENT(rbe);
+ rbe = OSSL_RBE_PARENT(rbe);
+ }
+ }
+
+ return rbe == NULL ? NULL : rbt_e2n(t, rbe);
+}
+
+void *
+ossl_rbt_root(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt)
+{
+ struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt);
+
+ return rbe == NULL ? rbe : rbt_e2n(t, rbe);
+}
+
+void *
+ossl_rbt_min(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt)
+{
+ struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt);
+ struct ossl_rbt_entry *parent = NULL;
+
+ while (rbe != NULL) {
+ parent = rbe;
+ rbe = OSSL_RBE_LEFT(rbe);
+ }
+
+ return parent == NULL ? NULL : rbt_e2n(t, parent);
+}
+
+void *
+ossl_rbt_max(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt)
+{
+ struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt);
+ struct ossl_rbt_entry *parent = NULL;
+
+ while (rbe != NULL) {
+ parent = rbe;
+ rbe = OSSL_RBE_RIGHT(rbe);
+ }
+
+ return parent == NULL ? NULL : rbt_e2n(t, parent);
+}
+
+void *
+ossl_rbt_left(const struct ossl_rbt_type *t, void *node)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+ rbe = OSSL_RBE_LEFT(rbe);
+ return rbe == NULL ? NULL : rbt_e2n(t, rbe);
+}
+
+void *
+ossl_rbt_right(const struct ossl_rbt_type *t, void *node)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+ rbe = OSSL_RBE_RIGHT(rbe);
+ return rbe == NULL ? NULL : rbt_e2n(t, rbe);
+}
+
+void *
+ossl_rbt_parent(const struct ossl_rbt_type *t, void *node)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+ rbe = OSSL_RBE_PARENT(rbe);
+ return rbe == NULL ? NULL : rbt_e2n(t, rbe);
+}
+
+void ossl_rbt_set_left(const struct ossl_rbt_type *t, void *node, void *left)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+ struct ossl_rbt_entry *rbl = (left == NULL) ? NULL : rbt_n2e(t, left);
+
+ OSSL_RBE_LEFT(rbe) = rbl;
+}
+
+void ossl_rbt_set_right(const struct ossl_rbt_type *t, void *node, void *right)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+ struct ossl_rbt_entry *rbr = (right == NULL) ? NULL : rbt_n2e(t, right);
+
+ OSSL_RBE_RIGHT(rbe) = rbr;
+}
+
+void ossl_rbt_set_parent(const struct ossl_rbt_type *t, void *node, void *parent)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+ struct ossl_rbt_entry *rbp = (parent == NULL) ? NULL : rbt_n2e(t, parent);
+
+ OSSL_RBE_PARENT(rbe) = rbp;
+}
+
+void ossl_rbt_init_rbe(const struct ossl_rbt_type *t, void *node)
+{
+ struct ossl_rbt_entry *rbe = rbt_n2e(t, node);
+
+ OSSL_RBE_PARENT(rbe) = NULL;
+ OSSL_RBE_LEFT(rbe) = NULL;
+ OSSL_RBE_RIGHT(rbe) = NULL;
+}
diff --git a/deps/openssl/openssl/crypto/sm2/sm2_sign.c b/deps/openssl/openssl/crypto/sm2/sm2_sign.c
index 9389c70817a..2ba4914357b 100644
--- a/deps/openssl/openssl/crypto/sm2/sm2_sign.c
+++ b/deps/openssl/openssl/crypto/sm2/sm2_sign.c
@@ -14,6 +14,7 @@
#include "crypto/sm2.h"
#include "crypto/sm2err.h"
#include "crypto/ec.h" /* ossl_ec_group_do_inverse_ord() */
+#include "crypto/bn.h" /* fixed-top / Montgomery constant-time BN helpers */
#include "internal/numbers.h"
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -215,17 +216,22 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
EC_POINT *kG = NULL;
BN_CTX *ctx = NULL;
BIGNUM *k = NULL;
- BIGNUM *rk = NULL;
BIGNUM *r = NULL;
BIGNUM *s = NULL;
BIGNUM *x1 = NULL;
BIGNUM *tmp = NULL;
+ BN_MONT_CTX *mont = EC_GROUP_get_mont_data(group);
OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key);
if (dA == NULL) {
ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY);
goto done;
}
+
+ if (mont == NULL) {
+ ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB);
+ goto done;
+ }
kG = EC_POINT_new(group);
if (kG == NULL) {
ERR_raise(ERR_LIB_SM2, ERR_R_EC_LIB);
@@ -239,7 +245,6 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
BN_CTX_start(ctx);
k = BN_CTX_get(ctx);
- rk = BN_CTX_get(ctx);
x1 = BN_CTX_get(ctx);
tmp = BN_CTX_get(ctx);
if (tmp == NULL) {
@@ -273,6 +278,18 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
goto done;
}
+ /*
+ * Pin the nonce to a fixed, value-independent width and flag it
+ * BN_FLG_CONSTTIME, so its magnitude does not leak through operand
+ * lengths in the scalar copy inside the ladder or in the arithmetic
+ * below. BN_priv_rand_range_ex() is kept so the nonce value itself
+ * is unchanged; only its representation is pinned.
+ */
+ BN_set_flags(k, BN_FLG_CONSTTIME);
+ if (!bn_set_top_fixed(k, bn_get_top(order))) {
+ ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
+ goto done;
+ }
if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
|| !EC_POINT_get_affine_coordinates(group, kG, x1, NULL,
@@ -282,23 +299,49 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
goto done;
}
- /* try again if r == 0 or r+k == n */
+ /* try again if r == 0 or r + k == n */
if (BN_is_zero(r))
continue;
- if (!BN_add(rk, r, k)) {
- ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR);
+ /*
+ * Since 0 < r < n and 0 < k < n, r + k == n is the same as
+ * k == n - r. Both operands of the subtraction are public, so
+ * compute it in the open and then compare against the nonce with a
+ * fixed-width constant-time comparison. A BN_cmp() on r + k would
+ * branch on whether the sum carried into an extra word, which
+ * depends on the value of k.
+ */
+ if (!BN_sub(tmp, order, r)
+ || !bn_set_top_fixed(tmp, bn_get_top(order))) {
+ ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
goto done;
}
- if (BN_cmp(rk, order) == 0)
+ if (CRYPTO_memcmp(bn_get_words(k), bn_get_words(tmp),
+ bn_get_top(order) * sizeof(BN_ULONG))
+ == 0)
continue;
+ /*
+ * s = ((1 + dA)^-1 * (k - r * dA)) mod order
+ *
+ * Computed with fixed-top / Montgomery constant-time primitives, so
+ * that the running time does not depend on the secret k or dA (the
+ * generic BN_mod_mul()/BN_sub() used previously reduce via BN_div(),
+ * whose timing is value dependent). This mirrors the ECDSA path.
+ *
+ * s holds (1 + dA)^-1 throughout; the (k - r * dA) term is built in
+ * tmp. bn_mul_mont_fixed_top() with one operand in the Montgomery
+ * domain yields the plain product, and the final
+ * BN_mod_mul_montgomery() returns the user-visible, normalised value.
+ */
if (!BN_add(s, dA, BN_value_one())
|| !ossl_ec_group_do_inverse_ord(group, s, s, ctx)
- || !BN_mod_mul(tmp, dA, r, order, ctx)
- || !BN_sub(tmp, k, tmp)
- || !BN_mod_mul(s, s, tmp, order, ctx)) {
+ || !bn_to_mont_fixed_top(tmp, r, mont, ctx)
+ || !bn_mul_mont_fixed_top(tmp, tmp, dA, mont, ctx)
+ || !bn_mod_sub_fixed_top(tmp, k, tmp, order)
+ || !bn_to_mont_fixed_top(tmp, tmp, mont, ctx)
+ || !BN_mod_mul_montgomery(s, tmp, s, mont, ctx)) {
ERR_raise(ERR_LIB_SM2, ERR_R_BN_LIB);
goto done;
}
diff --git a/deps/openssl/openssl/crypto/x509/v3_conf.c b/deps/openssl/openssl/crypto/x509/v3_conf.c
index f9350d63813..ba2ecd73733 100644
--- a/deps/openssl/openssl/crypto/x509/v3_conf.c
+++ b/deps/openssl/openssl/crypto/x509/v3_conf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -58,7 +58,14 @@ static X509_EXTENSION *X509V3_EXT_nconf_int(CONF *conf, X509V3_CTX *ctx,
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
const char *value)
{
- return X509V3_EXT_nconf_int(conf, ctx, NULL, name, value);
+ X509V3_CTX tmpctx;
+
+ if (ctx == NULL) {
+ X509V3_set_ctx(&tmpctx, NULL, NULL, NULL, NULL, 0);
+ X509V3_set_nconf(&tmpctx, conf);
+ }
+
+ return X509V3_EXT_nconf_int(conf, ctx ? ctx : &tmpctx, NULL, name, value);
}
X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
@@ -66,12 +73,18 @@ X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
{
int crit;
int ext_type;
+ X509V3_CTX tmpctx;
+
+ if (ctx == NULL) {
+ X509V3_set_ctx(&tmpctx, NULL, NULL, NULL, NULL, 0);
+ X509V3_set_nconf(&tmpctx, conf);
+ }
crit = v3_check_critical(&value);
if ((ext_type = v3_check_generic(&value)))
return v3_generic_extension(OBJ_nid2sn(ext_nid),
- value, crit, ext_type, ctx);
- return do_ext_nconf(conf, ctx, ext_nid, crit, value);
+ value, crit, ext_type, ctx ? ctx : &tmpctx);
+ return do_ext_nconf(conf, ctx ? ctx : &tmpctx, ext_nid, crit, value);
}
/* CONF *conf: Config file */
@@ -313,6 +326,13 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
STACK_OF(CONF_VALUE) *nval;
const CONF_VALUE *val;
int i, akid = -1, skid = -1;
+ X509V3_CTX tmpctx;
+
+ if (ctx == NULL) {
+ X509V3_set_ctx(&tmpctx, NULL, NULL, NULL, NULL, 0);
+ X509V3_set_nconf(&tmpctx, conf);
+ ctx = &tmpctx;
+ }
if ((nval = NCONF_get_section(conf, section)) == NULL)
return 0;
diff --git a/deps/openssl/openssl/crypto/x509/v3_crld.c b/deps/openssl/openssl/crypto/x509/v3_crld.c
index 56715439a4a..7ce1036d696 100644
--- a/deps/openssl/openssl/crypto/x509/v3_crld.c
+++ b/deps/openssl/openssl/crypto/x509/v3_crld.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2026 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
@@ -522,33 +522,43 @@ static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
return 1;
}
-/* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */
-int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname)
+/*
+ * Return a new X509_NAME consisting of iname with the nameRelativeToCRLIssuer
+ * fragment of dpn appended, with its DER encoding already cached.
+ * dpn must be a relative name (type 1). Returns NULL on error.
+ */
+X509_NAME *ossl_dist_point_name_full(const DIST_POINT_NAME *dpn,
+ const X509_NAME *iname)
{
int i;
- STACK_OF(X509_NAME_ENTRY) *frag;
+ STACK_OF(X509_NAME_ENTRY) *frag = dpn->name.relativename;
X509_NAME_ENTRY *ne;
+ X509_NAME *dpname = X509_NAME_dup(iname);
- if (dpn == NULL || dpn->type != 1)
- return 1;
- frag = dpn->name.relativename;
- X509_NAME_free(dpn->dpname); /* just in case it was already set */
- dpn->dpname = X509_NAME_dup(iname);
- if (dpn->dpname == NULL)
- return 0;
+ if (dpname == NULL)
+ return NULL;
for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
ne = sk_X509_NAME_ENTRY_value(frag, i);
- if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1))
+ if (!X509_NAME_add_entry(dpname, ne, -1, i ? 0 : 1))
goto err;
}
/* generate cached encoding of name */
- if (i2d_X509_NAME(dpn->dpname, NULL) >= 0)
- return 1;
+ if (i2d_X509_NAME(dpname, NULL) >= 0)
+ return dpname;
err:
- X509_NAME_free(dpn->dpname);
- dpn->dpname = NULL;
- return 0;
+ X509_NAME_free(dpname);
+ return NULL;
+}
+
+/* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname)
+{
+ if (dpn == NULL || dpn->type != 1)
+ return 1;
+ X509_NAME_free(dpn->dpname); /* just in case it was already set */
+ dpn->dpname = ossl_dist_point_name_full(dpn, iname);
+ return dpn->dpname != NULL;
}
ASN1_SEQUENCE(OSSL_AA_DIST_POINT) = {
diff --git a/deps/openssl/openssl/crypto/x509/v3_purp.c b/deps/openssl/openssl/crypto/x509/v3_purp.c
index 3c1bdd84a7e..29b55903847 100644
--- a/deps/openssl/openssl/crypto/x509/v3_purp.c
+++ b/deps/openssl/openssl/crypto/x509/v3_purp.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2026 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
@@ -345,12 +345,17 @@ int X509_supported_extension(X509_EXTENSION *ex)
return 0;
}
-/* Returns 1 on success, 0 if x is invalid, -1 on (internal) error. */
-static int setup_dp(const X509 *x, DIST_POINT *dp)
+/*
+ * The full name of a nameRelativeToCRLIssuer distribution point is not
+ * computed here. Doing so for every parsed certificate cost an
+ * X509_NAME_dup() of the issuer name per relative distribution point,
+ * which a certificate with many such entries could turn into hundreds of
+ * megabytes of heap on a plain TLS handshake, while the result is only
+ * needed when a CRL is actually being matched against the certificate.
+ * That name is now built on demand in the CRL checking code instead.
+ */
+static int setup_dp(DIST_POINT *dp)
{
- const X509_NAME *iname = NULL;
- int i;
-
if (dp->distpoint == NULL && sk_GENERAL_NAME_num(dp->CRLissuer) <= 0) {
ERR_raise(ERR_LIB_X509, X509_R_INVALID_DISTPOINT);
return 0;
@@ -364,30 +369,10 @@ static int setup_dp(const X509 *x, DIST_POINT *dp)
} else {
dp->dp_reasons = CRLDP_ALL_REASONS;
}
- if (dp->distpoint == NULL || dp->distpoint->type != 1)
- return 1;
-
- /* Handle name fragment given by nameRelativeToCRLIssuer */
- /*
- * Note that the below way of determining iname is not really compliant
- * with https://tools.ietf.org/html/rfc5280#section-4.2.1.13
- * According to it, sk_GENERAL_NAME_num(dp->CRLissuer) MUST be <= 1
- * and any CRLissuer could be of type different to GEN_DIRNAME.
- */
- for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
- GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
-
- if (gen->type == GEN_DIRNAME) {
- iname = gen->d.directoryName;
- break;
- }
- }
- if (iname == NULL)
- iname = X509_get_issuer_name(x);
- return DIST_POINT_set_dpname(dp->distpoint, iname) ? 1 : -1;
+ return 1;
}
-/* Return 1 on success, 0 if x is invalid, -1 on (internal) error. */
+/* Return 1 on success, 0 on error. */
static int setup_crldp(X509 *x)
{
int i;
@@ -397,10 +382,8 @@ static int setup_crldp(X509 *x)
return 0;
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
- int res = setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
-
- if (res < 1)
- return res;
+ if (!setup_dp(sk_DIST_POINT_value(x->crldp, i)))
+ return 0;
}
return 1;
}
diff --git a/deps/openssl/openssl/crypto/x509/x509_vfy.c b/deps/openssl/openssl/crypto/x509/x509_vfy.c
index b3df8c9b71e..091c1530898 100644
--- a/deps/openssl/openssl/crypto/x509/x509_vfy.c
+++ b/deps/openssl/openssl/crypto/x509/x509_vfy.c
@@ -1521,16 +1521,59 @@ static int check_crl_chain(X509_STORE_CTX *ctx,
return X509_cmp(cert_ta, crl_ta) == 0;
}
+/*
+ * Return the full name of the certificate CRL distribution point dp, whose
+ * distpoint is a nameRelativeToCRLIssuer fragment: the CRL issuer name with
+ * the fragment appended. The CRL issuer is the directoryName in
+ * dp->CRLissuer if there is one, else the issuer of the certificate.
+ *
+ * The result is a fresh X509_NAME owned by the caller. It is deliberately
+ * not stored in dp->distpoint->dpname: once its extension cache has been
+ * published a certificate is shared between threads without locking, and
+ * computing the name here rather than when the certificate is parsed keeps
+ * a certificate with many relative distribution points from costing a copy
+ * of the issuer name per entry on every parse. Returns NULL on error.
+ */
+static X509_NAME *crldp_full_name(const X509 *x, const DIST_POINT *dp)
+{
+ const X509_NAME *iname = NULL;
+ int i;
+
+ /*
+ * Note that the below way of determining iname is not really compliant
+ * with https://tools.ietf.org/html/rfc5280#section-4.2.1.13
+ * According to it, sk_GENERAL_NAME_num(dp->CRLissuer) MUST be <= 1
+ * and any CRLissuer could be of type different to GEN_DIRNAME.
+ */
+ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+
+ if (gen->type == GEN_DIRNAME) {
+ iname = gen->d.directoryName;
+ break;
+ }
+ }
+ if (iname == NULL)
+ iname = X509_get_issuer_name(x);
+ return ossl_dist_point_name_full(dp->distpoint, iname);
+}
+
/*-
* Check for match between two dist point names: three separate cases.
* 1. Both are relative names and compare X509_NAME types.
* 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
* 3. Both are full names and compare two GENERAL_NAMES.
* 4. One is NULL: automatic match.
+ *
+ * a is the certificate's distribution point name and b the CRL's issuing
+ * distribution point name. When a is a relative name, aname is its full
+ * name as built by crldp_full_name(); a->dpname itself is not consulted.
+ * For b the full name is the cached b->dpname set when the CRL was parsed.
*/
-static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
+static int idp_check_dp(DIST_POINT_NAME *a, const X509_NAME *aname,
+ DIST_POINT_NAME *b)
{
- X509_NAME *nm = NULL;
+ const X509_NAME *nm = NULL;
GENERAL_NAMES *gens = NULL;
GENERAL_NAME *gena, *genb;
int i, j;
@@ -1538,16 +1581,16 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
if (a == NULL || b == NULL)
return 1;
if (a->type == 1) {
- if (a->dpname == NULL)
+ if (aname == NULL)
return 0;
/* Case 1: two X509_NAME */
if (b->type == 1) {
if (b->dpname == NULL)
return 0;
- return X509_NAME_cmp(a->dpname, b->dpname) == 0;
+ return X509_NAME_cmp(aname, b->dpname) == 0;
}
/* Case 2: set name and GENERAL_NAMES appropriately */
- nm = a->dpname;
+ nm = aname;
gens = b->name.fullname;
} else if (b->type == 1) {
if (b->dpname == NULL)
@@ -1620,13 +1663,28 @@ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
*preasons = crl->idp_reasons;
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
+ X509_NAME *dpname = NULL;
+ int match;
- if (crldp_check_crlissuer(dp, crl, crl_score)) {
- if (crl->idp == NULL
- || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
- *preasons &= dp->dp_reasons;
- return 1;
- }
+ if (!crldp_check_crlissuer(dp, crl, crl_score))
+ continue;
+ if (crl->idp == NULL) {
+ match = 1;
+ } else {
+ /*
+ * A relative distribution point name is only comparable in
+ * full form. Build it for this one comparison and discard it;
+ * if that fails the entry simply does not match.
+ */
+ if (dp->distpoint != NULL && dp->distpoint->type == 1
+ && (dpname = crldp_full_name(x, dp)) == NULL)
+ continue;
+ match = idp_check_dp(dp->distpoint, dpname, crl->idp->distpoint);
+ X509_NAME_free(dpname);
+ }
+ if (match) {
+ *preasons &= dp->dp_reasons;
+ return 1;
}
}
return (crl->idp == NULL || crl->idp->distpoint == NULL)
diff --git a/deps/openssl/openssl/doc/build.info b/deps/openssl/openssl/doc/build.info
index ce2125a4d3f..62c6152c3d8 100644
--- a/deps/openssl/openssl/doc/build.info
+++ b/deps/openssl/openssl/doc/build.info
@@ -2911,6 +2911,10 @@ DEPEND[html/man3/UI_new.html]=man3/UI_new.pod
GENERATE[html/man3/UI_new.html]=man3/UI_new.pod
DEPEND[man/man3/UI_new.3]=man3/UI_new.pod
GENERATE[man/man3/UI_new.3]=man3/UI_new.pod
+DEPEND[html/man3/X509V3_EXT_nconf_nid.html]=man3/X509V3_EXT_nconf_nid.pod
+GENERATE[html/man3/X509V3_EXT_nconf_nid.html]=man3/X509V3_EXT_nconf_nid.pod
+DEPEND[man/man3/X509V3_EXT_nconf_nid.3]=man3/X509V3_EXT_nconf_nid.pod
+GENERATE[man/man3/X509V3_EXT_nconf_nid.3]=man3/X509V3_EXT_nconf_nid.pod
DEPEND[html/man3/X509V3_EXT_print.html]=man3/X509V3_EXT_print.pod
GENERATE[html/man3/X509V3_EXT_print.html]=man3/X509V3_EXT_print.pod
DEPEND[man/man3/X509V3_EXT_print.3]=man3/X509V3_EXT_print.pod
@@ -3801,6 +3805,7 @@ html/man3/UI_STRING.html \
html/man3/UI_UTIL_read_pw.html \
html/man3/UI_create_method.html \
html/man3/UI_new.html \
+html/man3/X509V3_EXT_nconf_nid.html \
html/man3/X509V3_EXT_print.html \
html/man3/X509V3_get_d2i.html \
html/man3/X509V3_set_ctx.html \
@@ -4480,6 +4485,7 @@ man/man3/UI_STRING.3 \
man/man3/UI_UTIL_read_pw.3 \
man/man3/UI_create_method.3 \
man/man3/UI_new.3 \
+man/man3/X509V3_EXT_nconf_nid.3 \
man/man3/X509V3_EXT_print.3 \
man/man3/X509V3_get_d2i.3 \
man/man3/X509V3_set_ctx.3 \
diff --git a/deps/openssl/openssl/exporters/cmake/OpenSSLConfig.cmake.in b/deps/openssl/openssl/exporters/cmake/OpenSSLConfig.cmake.in
index 125b94704a2..d8d82fec958 100644
--- a/deps/openssl/openssl/exporters/cmake/OpenSSLConfig.cmake.in
+++ b/deps/openssl/openssl/exporters/cmake/OpenSSLConfig.cmake.in
@@ -224,7 +224,7 @@ else()
set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
set(OPENSSL_SSL_LIBRARY ${OPENSSL_LIBSSL_SHARED})
set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
- set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES})
+ set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
{- output_on() if $lib_info{libcrypto}->{shared_import}; "" -}
{- output_on() if $no_shared; "" -}
endif()
diff --git a/deps/openssl/openssl/include/crypto/bn.h b/deps/openssl/openssl/include/crypto/bn.h
index 952840be5e6..b729b39f418 100644
--- a/deps/openssl/openssl/include/crypto/bn.h
+++ b/deps/openssl/openssl/include/crypto/bn.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -18,6 +18,7 @@ BIGNUM *bn_wexpand(BIGNUM *a, int words);
BIGNUM *bn_expand2(BIGNUM *a, int words);
void bn_correct_top(BIGNUM *a);
+int bn_set_top_fixed(BIGNUM *a, int words);
/*
* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
diff --git a/deps/openssl/openssl/include/crypto/bn_conf.h b/deps/openssl/openssl/include/crypto/bn_conf.h
deleted file mode 100644
index 79400c6472a..00000000000
--- a/deps/openssl/openssl/include/crypto/bn_conf.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/bn_conf.h"
diff --git a/deps/openssl/openssl/include/crypto/dso_conf.h b/deps/openssl/openssl/include/crypto/dso_conf.h
deleted file mode 100644
index e7f2afa9872..00000000000
--- a/deps/openssl/openssl/include/crypto/dso_conf.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/dso_conf.h"
diff --git a/deps/openssl/openssl/include/crypto/sparse_array.h b/deps/openssl/openssl/include/crypto/sparse_array.h
index 6529b461513..5ac2e359ee6 100644
--- a/deps/openssl/openssl/include/crypto/sparse_array.h
+++ b/deps/openssl/openssl/include/crypto/sparse_array.h
@@ -20,52 +20,52 @@ extern "C" {
#define SPARSE_ARRAY_OF(type) struct sparse_array_st_##type
-#define DEFINE_SPARSE_ARRAY_OF_INTERNAL(type, ctype) \
- SPARSE_ARRAY_OF(type); \
- static ossl_unused ossl_inline SPARSE_ARRAY_OF(type) * ossl_sa_##type##_new(void) \
- { \
- return (SPARSE_ARRAY_OF(type) *)ossl_sa_new(); \
- } \
- static ossl_unused ossl_inline void \
- ossl_sa_##type##_free(SPARSE_ARRAY_OF(type) * sa) \
- { \
- ossl_sa_free((OPENSSL_SA *)sa); \
- } \
- static ossl_unused ossl_inline void \
- ossl_sa_##type##_free_leaves(SPARSE_ARRAY_OF(type) * sa) \
- { \
- ossl_sa_free_leaves((OPENSSL_SA *)sa); \
- } \
- static ossl_unused ossl_inline size_t \
- ossl_sa_##type##_num(const SPARSE_ARRAY_OF(type) * sa) \
- { \
- return ossl_sa_num((OPENSSL_SA *)sa); \
- } \
- static ossl_unused ossl_inline void \
- ossl_sa_##type##_doall(const SPARSE_ARRAY_OF(type) * sa, \
- void (*leaf)(ossl_uintmax_t, type *)) \
- { \
- ossl_sa_doall((OPENSSL_SA *)sa, \
- (void (*)(ossl_uintmax_t, void *))leaf); \
- } \
- static ossl_unused ossl_inline void \
- ossl_sa_##type##_doall_arg(const SPARSE_ARRAY_OF(type) * sa, \
- void (*leaf)(ossl_uintmax_t, type *, void *), \
- void *arg) \
- { \
- ossl_sa_doall_arg((OPENSSL_SA *)sa, \
- (void (*)(ossl_uintmax_t, void *, void *))leaf, arg); \
- } \
- static ossl_unused ossl_inline ctype *ossl_sa_##type##_get(const SPARSE_ARRAY_OF(type) * sa, ossl_uintmax_t n) \
- { \
- return (type *)ossl_sa_get((OPENSSL_SA *)sa, n); \
- } \
- static ossl_unused ossl_inline int \
- ossl_sa_##type##_set(SPARSE_ARRAY_OF(type) * sa, \
- ossl_uintmax_t n, ctype *val) \
- { \
- return ossl_sa_set((OPENSSL_SA *)sa, n, (void *)val); \
- } \
+#define DEFINE_SPARSE_ARRAY_OF_INTERNAL(type, ctype) \
+ SPARSE_ARRAY_OF(type); \
+ static ossl_unused ossl_inline SPARSE_ARRAY_OF(type) *ossl_sa_##type##_new(void) \
+ { \
+ return (SPARSE_ARRAY_OF(type) *)ossl_sa_new(); \
+ } \
+ static ossl_unused ossl_inline void \
+ ossl_sa_##type##_free(SPARSE_ARRAY_OF(type) *sa) \
+ { \
+ ossl_sa_free((OPENSSL_SA *)sa); \
+ } \
+ static ossl_unused ossl_inline void \
+ ossl_sa_##type##_free_leaves(SPARSE_ARRAY_OF(type) *sa) \
+ { \
+ ossl_sa_free_leaves((OPENSSL_SA *)sa); \
+ } \
+ static ossl_unused ossl_inline size_t \
+ ossl_sa_##type##_num(const SPARSE_ARRAY_OF(type) *sa) \
+ { \
+ return ossl_sa_num((OPENSSL_SA *)sa); \
+ } \
+ static ossl_unused ossl_inline void \
+ ossl_sa_##type##_doall(const SPARSE_ARRAY_OF(type) *sa, \
+ void (*leaf)(ossl_uintmax_t, type *)) \
+ { \
+ ossl_sa_doall((OPENSSL_SA *)sa, \
+ (void (*)(ossl_uintmax_t, void *))leaf); \
+ } \
+ static ossl_unused ossl_inline void \
+ ossl_sa_##type##_doall_arg(const SPARSE_ARRAY_OF(type) *sa, \
+ void (*leaf)(ossl_uintmax_t, type *, void *), \
+ void *arg) \
+ { \
+ ossl_sa_doall_arg((OPENSSL_SA *)sa, \
+ (void (*)(ossl_uintmax_t, void *, void *))leaf, arg); \
+ } \
+ static ossl_unused ossl_inline ctype *ossl_sa_##type##_get(const SPARSE_ARRAY_OF(type) *sa, ossl_uintmax_t n) \
+ { \
+ return (type *)ossl_sa_get((OPENSSL_SA *)sa, n); \
+ } \
+ static ossl_unused ossl_inline int \
+ ossl_sa_##type##_set(SPARSE_ARRAY_OF(type) *sa, \
+ ossl_uintmax_t n, ctype *val) \
+ { \
+ return ossl_sa_set((OPENSSL_SA *)sa, n, (void *)val); \
+ } \
SPARSE_ARRAY_OF(type)
#define DEFINE_SPARSE_ARRAY_OF(type) \
diff --git a/deps/openssl/openssl/include/crypto/x509.h b/deps/openssl/openssl/include/crypto/x509.h
index fa085edeb8a..f83e807f2be 100644
--- a/deps/openssl/openssl/include/crypto/x509.h
+++ b/deps/openssl/openssl/include/crypto/x509.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2026 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 "internal/refcount.h"
#include <openssl/asn1.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include <openssl/conf.h>
#include "crypto/types.h"
@@ -313,6 +314,8 @@ int ossl_a2i_ipadd(unsigned char *ipout, const char *ipasc);
int ossl_x509_set1_time(int *modified, ASN1_TIME **ptm, const ASN1_TIME *tm);
int ossl_x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags);
int ossl_x509v3_cache_extensions(X509 *x);
+X509_NAME *ossl_dist_point_name_full(const struct DIST_POINT_NAME_st *dpn,
+ const X509_NAME *iname);
int ossl_x509_init_sig_info(X509 *x);
int ossl_x509_set0_libctx(X509 *x, OSSL_LIB_CTX *libctx, const char *propq);
diff --git a/deps/openssl/openssl/include/internal/list.h b/deps/openssl/openssl/include/internal/list.h
index 270e3f1dbb9..82d851538a1 100644
--- a/deps/openssl/openssl/include/internal/list.h
+++ b/deps/openssl/openssl/include/internal/list.h
@@ -25,28 +25,28 @@
(p) != NULL; \
(p) = ossl_list_##name##_next(p))
#define OSSL_LIST_FOREACH(p, name, l) \
- OSSL_LIST_FOREACH_FROM(p, name, ossl_list_##name##_head(l))
+ OSSL_LIST_FOREACH_FROM (p, name, ossl_list_##name##_head(l))
#define OSSL_LIST_FOREACH_REV_FROM(p, name, init) \
for ((p) = (init); \
(p) != NULL; \
(p) = ossl_list_##name##_prev(p))
#define OSSL_LIST_FOREACH_REV(p, name, l) \
- OSSL_LIST_FOREACH_FROM(p, name, ossl_list_##name##_tail(l))
+ OSSL_LIST_FOREACH_FROM (p, name, ossl_list_##name##_tail(l))
#define OSSL_LIST_FOREACH_DELSAFE_FROM(p, pn, name, init) \
for ((p) = (init); \
(p) != NULL && (((pn) = ossl_list_##name##_next(p)), 1); \
(p) = (pn))
#define OSSL_LIST_FOREACH_DELSAFE(p, pn, name, l) \
- OSSL_LIST_FOREACH_DELSAFE_FROM(p, pn, name, ossl_list_##name##_head(l))
+ OSSL_LIST_FOREACH_DELSAFE_FROM (p, pn, name, ossl_list_##name##_head(l))
#define OSSL_LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, init) \
for ((p) = (init); \
(p) != NULL && (((pn) = ossl_list_##name##_prev(p)), 1); \
(p) = (pn))
#define OSSL_LIST_FOREACH_REV_DELSAFE(p, pn, name, l) \
- OSSL_LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, ossl_list_##name##_tail(l))
+ OSSL_LIST_FOREACH_REV_DELSAFE_FROM (p, pn, name, ossl_list_##name##_tail(l))
/* Define a list structure */
#define OSSL_LIST(name) OSSL_LIST_##name
@@ -67,7 +67,7 @@
#define DEFINE_LIST_OF_IMPL(name, type) \
static ossl_unused ossl_inline void \
- ossl_list_##name##_init(OSSL_LIST(name) * list) \
+ ossl_list_##name##_init(OSSL_LIST(name) *list) \
{ \
memset(list, 0, sizeof(*list)); \
} \
@@ -78,24 +78,24 @@
sizeof(elem->ossl_list_##name)); \
} \
static ossl_unused ossl_inline int \
- ossl_list_##name##_is_empty(const OSSL_LIST(name) * list) \
+ ossl_list_##name##_is_empty(const OSSL_LIST(name) *list) \
{ \
return list->num_elems == 0; \
} \
static ossl_unused ossl_inline size_t \
- ossl_list_##name##_num(const OSSL_LIST(name) * list) \
+ ossl_list_##name##_num(const OSSL_LIST(name) *list) \
{ \
return list->num_elems; \
} \
static ossl_unused ossl_inline type * \
- ossl_list_##name##_head(const OSSL_LIST(name) * list) \
+ ossl_list_##name##_head(const OSSL_LIST(name) *list) \
{ \
assert(list->alpha == NULL \
|| list->alpha->ossl_list_##name.list == list); \
return list->alpha; \
} \
static ossl_unused ossl_inline type * \
- ossl_list_##name##_tail(const OSSL_LIST(name) * list) \
+ ossl_list_##name##_tail(const OSSL_LIST(name) *list) \
{ \
assert(list->omega == NULL \
|| list->omega->ossl_list_##name.list == list); \
@@ -120,7 +120,7 @@
return elem->ossl_list_##name.prev; \
} \
static ossl_unused ossl_inline void \
- ossl_list_##name##_remove(OSSL_LIST(name) * list, type * elem) \
+ ossl_list_##name##_remove(OSSL_LIST(name) *list, type *elem) \
{ \
assert(elem->ossl_list_##name.list == list); \
OSSL_LIST_DBG(elem->ossl_list_##name.list = NULL) \
@@ -137,7 +137,7 @@
sizeof(elem->ossl_list_##name)); \
} \
static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_head(OSSL_LIST(name) * list, type * elem) \
+ ossl_list_##name##_insert_head(OSSL_LIST(name) *list, type *elem) \
{ \
assert(elem->ossl_list_##name.list == NULL); \
OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \
@@ -151,7 +151,7 @@
list->num_elems++; \
} \
static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_tail(OSSL_LIST(name) * list, type * elem) \
+ ossl_list_##name##_insert_tail(OSSL_LIST(name) *list, type *elem) \
{ \
assert(elem->ossl_list_##name.list == NULL); \
OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \
@@ -165,8 +165,8 @@
list->num_elems++; \
} \
static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_before(OSSL_LIST(name) * list, type * e, \
- type * elem) \
+ ossl_list_##name##_insert_before(OSSL_LIST(name) *list, type *e, \
+ type *elem) \
{ \
assert(elem->ossl_list_##name.list == NULL); \
OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \
@@ -180,8 +180,8 @@
list->num_elems++; \
} \
static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_after(OSSL_LIST(name) * list, type * e, \
- type * elem) \
+ ossl_list_##name##_insert_after(OSSL_LIST(name) *list, type *e, \
+ type *elem) \
{ \
assert(elem->ossl_list_##name.list == NULL); \
OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \
@@ -195,7 +195,7 @@
list->num_elems++; \
} \
static ossl_unused ossl_inline void \
- ossl_list_##name##_join(OSSL_LIST(name) * lh, OSSL_LIST(name) * lt) \
+ ossl_list_##name##_join(OSSL_LIST(name) *lh, OSSL_LIST(name) *lt) \
{ \
OSSL_LIST_DBG(type * _p); /* local variable '_p' when debug */ \
if (lt == NULL || lh == NULL || lt->num_elems == 0 || lh == lt) \
diff --git a/deps/openssl/openssl/include/internal/ossl_rbtree.h b/deps/openssl/openssl/include/internal/ossl_rbtree.h
new file mode 100644
index 00000000000..053ed99478b
--- /dev/null
+++ b/deps/openssl/openssl/include/internal/ossl_rbtree.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2016 David Gwynne <david@gwynne.id.au>
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * The code here comes from David Gwynne <david@gwynne.id.au>. The original
+ * version can be found:
+ * https://github.com/dgwynne/data-structures/
+ * file bst.h. The same code is also part of OpenBSD OS where it is shipped
+ * under BSD license.
+ *
+ * David Gwynne agrees to include modified version to OpenSSL and ship it
+ * under OpenSSL Apache 2.0 license.
+ */
+#ifndef _OSSL_INTERNAL_RBTREE_H_
+#define _OSSL_INTERNAL_RBTREE_H_
+
+#include "internal/e_os.h"
+
+/*
+ * List of changes against upstream version:
+ * augmentation mechanism is removed in OpenSSL as there is no demand for it
+ *
+ * prefix changed from rb/rbt to ossl_rbt
+ *
+ * debug version of OSSL_RBT_REMOVE() sets parent, left, right members
+ * to NULL
+ *
+ * cstyle is changed to match OpenSSL.
+ */
+struct ossl_rbt_type {
+ int (*t_compare)(const void *, const void *);
+ uintptr_t t_offset; /* offset of ossl_rbt_entry in type */
+};
+
+struct ossl_rbt_tree {
+ struct ossl_rbt_entry *rb_root;
+};
+
+struct ossl_rbt_entry {
+ struct ossl_rbt_entry *rb_parent;
+ struct ossl_rbt_entry *rb_left;
+ struct ossl_rbt_entry *rb_right;
+ unsigned int rb_color;
+};
+
+#define OSSL_RBT_HEAD(_name, _type) \
+ struct _name { \
+ struct ossl_rbt_tree rbh_root; \
+ }
+
+#define OSSL_RBT_ENTRY(_type) struct ossl_rbt_entry
+
+static ossl_inline void
+ossl_rbt_init(struct ossl_rbt_tree *rb)
+{
+ rb->rb_root = NULL;
+}
+
+static ossl_inline int
+ossl_rbt_empty(struct ossl_rbt_tree *rb)
+{
+ return rb->rb_root == NULL;
+}
+
+void *ossl_rbt_insert(const struct ossl_rbt_type *, struct ossl_rbt_tree *, void *);
+void *ossl_rbt_remove(const struct ossl_rbt_type *, struct ossl_rbt_tree *, void *);
+void *ossl_rbt_find(const struct ossl_rbt_type *, struct ossl_rbt_tree *, const void *);
+void *ossl_rbt_nfind(const struct ossl_rbt_type *, struct ossl_rbt_tree *, const void *);
+void *ossl_rbt_root(const struct ossl_rbt_type *, struct ossl_rbt_tree *);
+void *ossl_rbt_min(const struct ossl_rbt_type *, struct ossl_rbt_tree *);
+void *ossl_rbt_max(const struct ossl_rbt_type *, struct ossl_rbt_tree *);
+void *ossl_rbt_next(const struct ossl_rbt_type *, void *);
+void *ossl_rbt_prev(const struct ossl_rbt_type *, void *);
+void *ossl_rbt_left(const struct ossl_rbt_type *, void *);
+void *ossl_rbt_right(const struct ossl_rbt_type *, void *);
+void *ossl_rbt_parent(const struct ossl_rbt_type *, void *);
+void ossl_rbt_set_left(const struct ossl_rbt_type *, void *, void *);
+void ossl_rbt_set_right(const struct ossl_rbt_type *, void *, void *);
+void ossl_rbt_set_parent(const struct ossl_rbt_type *, void *, void *);
+void ossl_rbt_init_rbe(const struct ossl_rbt_type *, void *);
+
+#define OSSL_RBT_INITIALIZER(_head) \
+ { \
+ { \
+ NULL \
+ } \
+ }
+
+#define OSSL_RBT_PROTOTYPE(_name, _type, _field, _cmp) \
+ extern const struct ossl_rbt_type *const _name##_OSSL_RBT_TYPE; \
+ \
+ ossl_unused static ossl_inline void \
+ _name##_OSSL_RBT_INIT(struct _name *head) \
+ { \
+ ossl_rbt_init(&head->rbh_root); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_INSERT(struct _name *head, struct _type *elm) \
+ { \
+ return ossl_rbt_insert(_name##_OSSL_RBT_TYPE, &head->rbh_root, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_REMOVE(struct _name *head, struct _type *elm) \
+ { \
+ return ossl_rbt_remove(_name##_OSSL_RBT_TYPE, &head->rbh_root, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_FIND(struct _name *head, const struct _type *key) \
+ { \
+ return ossl_rbt_find(_name##_OSSL_RBT_TYPE, &head->rbh_root, key); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_NFIND(struct _name *head, const struct _type *key) \
+ { \
+ return ossl_rbt_nfind(_name##_OSSL_RBT_TYPE, &head->rbh_root, key); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_ROOT(struct _name *head) \
+ { \
+ return ossl_rbt_root(_name##_OSSL_RBT_TYPE, &head->rbh_root); \
+ } \
+ \
+ ossl_unused static ossl_inline int \
+ _name##_OSSL_RBT_EMPTY(struct _name *head) \
+ { \
+ return ossl_rbt_empty(&head->rbh_root); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_MIN(struct _name *head) \
+ { \
+ return ossl_rbt_min(_name##_OSSL_RBT_TYPE, &head->rbh_root); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_MAX(struct _name *head) \
+ { \
+ return ossl_rbt_max(_name##_OSSL_RBT_TYPE, &head->rbh_root); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_NEXT(struct _type *elm) \
+ { \
+ return ossl_rbt_next(_name##_OSSL_RBT_TYPE, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_PREV(struct _type *elm) \
+ { \
+ return ossl_rbt_prev(_name##_OSSL_RBT_TYPE, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_LEFT(struct _type *elm) \
+ { \
+ return ossl_rbt_left(_name##_OSSL_RBT_TYPE, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_RIGHT(struct _type *elm) \
+ { \
+ return ossl_rbt_right(_name##_OSSL_RBT_TYPE, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline struct _type * \
+ _name##_OSSL_RBT_PARENT(struct _type *elm) \
+ { \
+ return ossl_rbt_parent(_name##_OSSL_RBT_TYPE, elm); \
+ } \
+ \
+ ossl_unused static ossl_inline void \
+ _name##_OSSL_RBT_SET_LEFT(struct _type *elm, struct _type *left) \
+ { \
+ ossl_rbt_set_left(_name##_OSSL_RBT_TYPE, elm, left); \
+ } \
+ \
+ ossl_unused static ossl_inline void \
+ _name##_OSSL_RBT_SET_RIGHT(struct _type *elm, struct _type *right) \
+ { \
+ ossl_rbt_set_right(_name##_OSSL_RBT_TYPE, elm, right); \
+ } \
+ \
+ ossl_unused static ossl_inline void \
+ _name##_OSSL_RBT_SET_PARENT(struct _type *elm, struct _type *parent) \
+ { \
+ ossl_rbt_set_parent(_name##_OSSL_RBT_TYPE, elm, parent); \
+ } \
+ ossl_unused static ossl_inline void \
+ _name##_OSSL_RBT_INIT_RBE(struct _type *elm) \
+ { \
+ ossl_rbt_init_rbe(_name##_OSSL_RBT_TYPE, elm); \
+ }
+
+#define OSSL_RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp) \
+ static int \
+ _name##_OSSL_RBT_COMPARE(const void *lptr, const void *rptr) \
+ { \
+ const struct _type *l = lptr, *r = rptr; \
+ return _cmp(l, r); \
+ } \
+ static const struct ossl_rbt_type _name##_OSSL_RBT_INFO = { \
+ _name##_OSSL_RBT_COMPARE, \
+ offsetof(struct _type, _field), \
+ }; \
+ const struct ossl_rbt_type *const _name##_OSSL_RBT_TYPE = &_name##_OSSL_RBT_INFO
+
+#define OSSL_RBT_GENERATE(_name, _type, _field, _cmp) \
+ OSSL_RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp)
+
+#define OSSL_RBT_INIT(_name, _head) _name##_OSSL_RBT_INIT(_head)
+#define OSSL_RBT_INSERT(_name, _head, _elm) _name##_OSSL_RBT_INSERT(_head, _elm)
+#define OSSL_RBT_REMOVE(_name, _head, _elm) _name##_OSSL_RBT_REMOVE(_head, _elm)
+#define OSSL_RBT_FIND(_name, _head, _key) _name##_OSSL_RBT_FIND(_head, _key)
+#define OSSL_RBT_NFIND(_name, _head, _key) _name##_OSSL_RBT_NFIND(_head, _key)
+#define OSSL_RBT_ROOT(_name, _head) _name##_OSSL_RBT_ROOT(_head)
+#define OSSL_RBT_EMPTY(_name, _head) _name##_OSSL_RBT_EMPTY(_head)
+#define OSSL_RBT_MIN(_name, _head) _name##_OSSL_RBT_MIN(_head)
+#define OSSL_RBT_MAX(_name, _head) _name##_OSSL_RBT_MAX(_head)
+#define OSSL_RBT_NEXT(_name, _elm) _name##_OSSL_RBT_NEXT(_elm)
+#define OSSL_RBT_PREV(_name, _elm) _name##_OSSL_RBT_PREV(_elm)
+#define OSSL_RBT_LEFT(_name, _elm) _name##_OSSL_RBT_LEFT(_elm)
+#define OSSL_RBT_RIGHT(_name, _elm) _name##_OSSL_RBT_RIGHT(_elm)
+#define OSSL_RBT_PARENT(_name, _elm) _name##_OSSL_RBT_PARENT(_elm)
+#define OSSL_RBT_SET_LEFT(_name, _elm, _l) _name##_OSSL_RBT_SET_LEFT(_elm, _l)
+#define OSSL_RBT_SET_RIGHT(_name, _elm, _r) _name##_OSSL_RBT_SET_RIGHT(_elm, _r)
+#define OSSL_RBT_SET_PARENT(_name, _elm, _p) _name##_OSSL_RBT_SET_PARENT(_elm, _p)
+#ifndef NDEBUG
+#define OSSL_RBT_INIT_RBE(_name, _elm) _name##_OSSL_RBT_INIT_RBE(_elm)
+#else
+#define OSSL_RBT_INIT_RBE(_name, _elm) (void)(0)
+#endif
+
+#define OSSL_RBT_FOREACH(_e, _name, _head) \
+ for ((_e) = OSSL_RBT_MIN(_name, (_head)); \
+ (_e) != NULL; \
+ (_e) = OSSL_RBT_NEXT(_name, (_e)))
+
+#define OSSL_RBT_FOREACH_SAFE(_e, _name, _head, _n) \
+ for ((_e) = OSSL_RBT_MIN(_name, (_head)); \
+ (_e) != NULL && ((_n) = OSSL_RBT_NEXT(_name, (_e)), 1); \
+ (_e) = (_n))
+
+#define OSSL_RBT_FOREACH_REVERSE(_e, _name, _head) \
+ for ((_e) = OSSL_RBT_MAX(_name, (_head)); \
+ (_e) != NULL; \
+ (_e) = OSSL_RBT_PREV(_name, (_e)))
+
+#define OSSL_RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
+ for ((_e) = OSSL_RBT_MAX(_name, (_head)); \
+ (_e) != NULL && ((_n) = OSSL_RBT_PREV(_name, (_e)), 1); \
+ (_e) = (_n))
+
+#endif /* _OSSL_INTERNAL_RBTREE_H_ */
diff --git a/deps/openssl/openssl/include/internal/param_names.h b/deps/openssl/openssl/include/internal/param_names.h
deleted file mode 100644
index 2878ad3c8c3..00000000000
--- a/deps/openssl/openssl/include/internal/param_names.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/param_names.h"
diff --git a/deps/openssl/openssl/include/internal/priority_queue.h b/deps/openssl/openssl/include/internal/priority_queue.h
index 067c8815961..9941f4e27d5 100644
--- a/deps/openssl/openssl/include/internal/priority_queue.h
+++ b/deps/openssl/openssl/include/internal/priority_queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -16,56 +16,56 @@
#define PRIORITY_QUEUE_OF(type) OSSL_PRIORITY_QUEUE_##type
-#define DEFINE_PRIORITY_QUEUE_OF_INTERNAL(type, ctype) \
- typedef struct ossl_priority_queue_st_##type PRIORITY_QUEUE_OF(type); \
- static ossl_unused ossl_inline PRIORITY_QUEUE_OF(type) * ossl_pqueue_##type##_new(int (*compare)(const ctype *, const ctype *)) \
- { \
- return (PRIORITY_QUEUE_OF(type) *)ossl_pqueue_new( \
- (int (*)(const void *, const void *))compare); \
- } \
- static ossl_unused ossl_inline void \
- ossl_pqueue_##type##_free(PRIORITY_QUEUE_OF(type) * pq) \
- { \
- ossl_pqueue_free((OSSL_PQUEUE *)pq); \
- } \
- static ossl_unused ossl_inline void \
- ossl_pqueue_##type##_pop_free(PRIORITY_QUEUE_OF(type) * pq, \
- void (*freefunc)(ctype *)) \
- { \
- ossl_pqueue_pop_free((OSSL_PQUEUE *)pq, (void (*)(void *))freefunc); \
- } \
- static ossl_unused ossl_inline int \
- ossl_pqueue_##type##_reserve(PRIORITY_QUEUE_OF(type) * pq, size_t n) \
- { \
- return ossl_pqueue_reserve((OSSL_PQUEUE *)pq, n); \
- } \
- static ossl_unused ossl_inline size_t \
- ossl_pqueue_##type##_num(const PRIORITY_QUEUE_OF(type) * pq) \
- { \
- return ossl_pqueue_num((OSSL_PQUEUE *)pq); \
- } \
- static ossl_unused ossl_inline int \
- ossl_pqueue_##type##_push(PRIORITY_QUEUE_OF(type) * pq, \
- ctype * data, size_t *elem) \
- { \
- return ossl_pqueue_push((OSSL_PQUEUE *)pq, (void *)data, elem); \
- } \
- static ossl_unused ossl_inline ctype * \
- ossl_pqueue_##type##_peek(const PRIORITY_QUEUE_OF(type) * pq) \
- { \
- return (type *)ossl_pqueue_peek((OSSL_PQUEUE *)pq); \
- } \
- static ossl_unused ossl_inline ctype * \
- ossl_pqueue_##type##_pop(PRIORITY_QUEUE_OF(type) * pq) \
- { \
- return (type *)ossl_pqueue_pop((OSSL_PQUEUE *)pq); \
- } \
- static ossl_unused ossl_inline ctype * \
- ossl_pqueue_##type##_remove(PRIORITY_QUEUE_OF(type) * pq, \
- size_t elem) \
- { \
- return (type *)ossl_pqueue_remove((OSSL_PQUEUE *)pq, elem); \
- } \
+#define DEFINE_PRIORITY_QUEUE_OF_INTERNAL(type, ctype) \
+ typedef struct ossl_priority_queue_st_##type PRIORITY_QUEUE_OF(type); \
+ static ossl_unused ossl_inline PRIORITY_QUEUE_OF(type) *ossl_pqueue_##type##_new(int (*compare)(const ctype *, const ctype *)) \
+ { \
+ return (PRIORITY_QUEUE_OF(type) *)ossl_pqueue_new( \
+ (int (*)(const void *, const void *))compare); \
+ } \
+ static ossl_unused ossl_inline void \
+ ossl_pqueue_##type##_free(PRIORITY_QUEUE_OF(type) *pq) \
+ { \
+ ossl_pqueue_free((OSSL_PQUEUE *)pq); \
+ } \
+ static ossl_unused ossl_inline void \
+ ossl_pqueue_##type##_pop_free(PRIORITY_QUEUE_OF(type) *pq, \
+ void (*freefunc)(ctype *)) \
+ { \
+ ossl_pqueue_pop_free((OSSL_PQUEUE *)pq, (void (*)(void *))freefunc); \
+ } \
+ static ossl_unused ossl_inline int \
+ ossl_pqueue_##type##_reserve(PRIORITY_QUEUE_OF(type) *pq, size_t n) \
+ { \
+ return ossl_pqueue_reserve((OSSL_PQUEUE *)pq, n); \
+ } \
+ static ossl_unused ossl_inline size_t \
+ ossl_pqueue_##type##_num(const PRIORITY_QUEUE_OF(type) *pq) \
+ { \
+ return ossl_pqueue_num((OSSL_PQUEUE *)pq); \
+ } \
+ static ossl_unused ossl_inline int \
+ ossl_pqueue_##type##_push(PRIORITY_QUEUE_OF(type) *pq, \
+ ctype *data, size_t *elem) \
+ { \
+ return ossl_pqueue_push((OSSL_PQUEUE *)pq, (void *)data, elem); \
+ } \
+ static ossl_unused ossl_inline ctype * \
+ ossl_pqueue_##type##_peek(const PRIORITY_QUEUE_OF(type) *pq) \
+ { \
+ return (type *)ossl_pqueue_peek((OSSL_PQUEUE *)pq); \
+ } \
+ static ossl_unused ossl_inline ctype * \
+ ossl_pqueue_##type##_pop(PRIORITY_QUEUE_OF(type) *pq) \
+ { \
+ return (type *)ossl_pqueue_pop((OSSL_PQUEUE *)pq); \
+ } \
+ static ossl_unused ossl_inline ctype * \
+ ossl_pqueue_##type##_remove(PRIORITY_QUEUE_OF(type) *pq, \
+ size_t elem) \
+ { \
+ return (type *)ossl_pqueue_remove((OSSL_PQUEUE *)pq, elem); \
+ } \
struct ossl_priority_queue_st_##type
#define DEFINE_PRIORITY_QUEUE_OF(type) \
diff --git a/deps/openssl/openssl/include/internal/quic_predef.h b/deps/openssl/openssl/include/internal/quic_predef.h
index c8d4ad470f5..7ed19fcb2e0 100644
--- a/deps/openssl/openssl/include/internal/quic_predef.h
+++ b/deps/openssl/openssl/include/internal/quic_predef.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2026 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
@@ -44,6 +44,7 @@ typedef struct quic_conn_st QUIC_CONNECTION;
typedef struct quic_xso_st QUIC_XSO;
typedef struct quic_listener_st QUIC_LISTENER;
typedef struct quic_domain_st QUIC_DOMAIN;
+typedef struct quic_rstream_qparm_st QUIC_RSTREAM_QPARM;
#endif
diff --git a/deps/openssl/openssl/include/internal/quic_sf_list.h b/deps/openssl/openssl/include/internal/quic_sf_list.h
deleted file mode 100644
index 1a22cc3f387..00000000000
--- a/deps/openssl/openssl/include/internal/quic_sf_list.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#ifndef OSSL_QUIC_SF_LIST_H
-#define OSSL_QUIC_SF_LIST_H
-
-#include "internal/common.h"
-#include "internal/uint_set.h"
-#include "internal/quic_record_rx.h"
-
-/*
- * Stream frame list
- * =================
- *
- * This data structure supports similar operations as uint64 set but
- * it has slightly different invariants and also carries data associated with
- * the ranges in the list.
- *
- * Operations:
- * Insert frame (optimized insertion at the beginning and at the end).
- * Iterated peek into the frame(s) from the beginning.
- * Dropping frames from the beginning up to an offset (exclusive).
- *
- * Invariant: The frames in the list are sorted by the start and end bounds.
- * Invariant: There are no fully overlapping frames or frames that would
- * be fully encompassed by another frame in the list.
- * Invariant: No frame has start > end.
- * Invariant: The range start is inclusive the end is exclusive to be
- * able to mark an empty frame.
- * Invariant: The offset never points further than into the first frame.
- */
-#ifndef OPENSSL_NO_QUIC
-
-typedef struct stream_frame_st STREAM_FRAME;
-
-typedef struct sframe_list_st {
- STREAM_FRAME *head, *tail;
- /* Is the tail frame final. */
- unsigned int fin;
- /* Number of stream frames in the list. */
- size_t num_frames;
- /* Offset of data not yet dropped */
- uint64_t offset;
- /* Is head locked ? */
- int head_locked;
- /* Cleanse data on release? */
- int cleanse;
-} SFRAME_LIST;
-
-/*
- * Initializes the stream frame list fl.
- */
-void ossl_sframe_list_init(SFRAME_LIST *fl);
-
-/*
- * Destroys the stream frame list fl releasing any data
- * still present inside it.
- */
-void ossl_sframe_list_destroy(SFRAME_LIST *fl);
-
-/*
- * Insert a stream frame data into the list.
- * The data covers an offset range (range.start is inclusive,
- * range.end is exclusive).
- * fin should be set if this is the final frame of the stream.
- * Returns an error if a frame cannot be inserted - due to
- * STREAM_FRAME allocation error, or in case of erroneous
- * fin flag (this is an ossl_assert() check so a caller must
- * check it on its own too).
- */
-int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range,
- OSSL_QRX_PKT *pkt,
- const unsigned char *data, int fin);
-
-/*
- * Iterator to peek at the contiguous frames at the beginning
- * of the frame list fl.
- * The *data covers an offset range (range.start is inclusive,
- * range.end is exclusive).
- * *fin is set if this is the final frame of the stream.
- * Opaque iterator *iter can be used to peek at the subsequent
- * frame if there is any without any gap before it.
- * Returns 1 on success.
- * Returns 0 if there is no further contiguous frame. In that
- * case *fin is set, if the end of the stream is reached.
- */
-int ossl_sframe_list_peek(const SFRAME_LIST *fl, void **iter,
- UINT_RANGE *range, const unsigned char **data,
- int *fin);
-
-/*
- * Drop all frames up to the offset limit.
- * Also unlocks the head frame if locked.
- * Returns 1 on success.
- * Returns 0 when trying to drop frames at offsets that were not
- * received yet. (ossl_assert() is used to check, so this is an invalid call.)
- */
-int ossl_sframe_list_drop_frames(SFRAME_LIST *fl, uint64_t limit);
-
-/*
- * Locks and returns the head frame of fl if it is readable - read offset is
- * at the beginning or middle of the frame.
- * range is set to encompass the not yet read part of the head frame,
- * data pointer is set to appropriate offset within the frame if the read
- * offset points in the middle of the frame,
- * fin is set to 1 if the head frame is also the tail frame.
- * Returns 1 on success, 0 if there is no readable data or the head
- * frame is already locked.
- */
-int ossl_sframe_list_lock_head(SFRAME_LIST *fl, UINT_RANGE *range,
- const unsigned char **data,
- int *fin);
-
-/*
- * Just returns whether the head frame is locked by previous
- * ossl_sframe_list_lock_head() call.
- */
-int ossl_sframe_list_is_head_locked(SFRAME_LIST *fl);
-
-/*
- * Callback function type to write stream frame data to some
- * side storage before the packet containing the frame data
- * is released.
- * It should return 1 on success or 0 if there is not enough
- * space available in the side storage.
- */
-typedef int(sframe_list_write_at_cb)(uint64_t logical_offset,
- const unsigned char *buf,
- size_t buf_len,
- void *cb_arg);
-
-/*
- * Move the frame data in all the stream frames in the list fl
- * from the packets to the side storage using the write_at_cb
- * callback.
- * Returns 1 if all the calls to the callback return 1.
- * If the callback returns 0, the function stops processing further
- * frames and returns 0.
- */
-int ossl_sframe_list_move_data(SFRAME_LIST *fl,
- sframe_list_write_at_cb *write_at_cb,
- void *cb_arg);
-#endif
-
-#endif
diff --git a/deps/openssl/openssl/include/internal/quic_stream.h b/deps/openssl/openssl/include/internal/quic_stream.h
index 824d4b89696..eb22aeb9a4a 100644
--- a/deps/openssl/openssl/include/internal/quic_stream.h
+++ b/deps/openssl/openssl/include/internal/quic_stream.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 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
@@ -318,11 +318,9 @@ void ossl_quic_sstream_set_cleanse(QUIC_SSTREAM *qss, int cleanse);
* controller and statistics module. They can be NULL for unit testing.
* If they are non-NULL, the `rxfc` is called when receive stream data
* is read by application. `statm` is queried for current rtt.
- * `rbuf_size` is the initial size of the ring buffer to be used
- * when ossl_quic_rstream_move_to_rbuf() is called.
*/
QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
- OSSL_STATM *statm, size_t rbuf_size);
+ OSSL_STATM *statm, QUIC_RSTREAM_QPARM *rsqp);
/*
* Frees a QUIC_RSTREAM and any associated storage.
@@ -330,10 +328,10 @@ QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
void ossl_quic_rstream_free(QUIC_RSTREAM *qrs);
/*
- * Adds received stream frame data to `qrs`. The `pkt_wrap` refcount is
- * incremented if the `data` is queued directly without copying.
- * It can be NULL for unit-testing purposes, i.e. if `data` is static or
- * never released before calling ossl_quic_rstream_free().
+ * Adds received stream frame data to `qrs`. `pkt` must be the packet
+ * carrying `data`; its refcount is incremented if the data is kept
+ * referenced on the packet rather than copied. `pkt` and `data` can
+ * be NULL only for an empty frame indicating `fin`.
* The `offset` is the absolute offset of the data in the stream.
* `data_len` can be 0 - can be useful for indicating `fin` for empty stream.
* Or to indicate `fin` without any further data added to the stream.
@@ -378,8 +376,6 @@ int ossl_quic_rstream_available(QUIC_RSTREAM *qrs, size_t *avail, int *fin);
* Returns 1 on success (including calls if no record is available, or
* after end of the stream - in that case *fin will be set to 1 and
* *rec_len to 0), 0 on error.
- * It is an error to call ossl_quic_rstream_get_record() multiple times
- * without calling ossl_quic_rstream_release_record() in between.
*/
int ossl_quic_rstream_get_record(QUIC_RSTREAM *qrs,
const unsigned char **record, size_t *rec_len,
@@ -394,35 +390,26 @@ int ossl_quic_rstream_get_record(QUIC_RSTREAM *qrs,
* call to ossl_quic_rstream_get_record() is needed to obtain further
* stream data.
* Returns 1 on success, 0 on error.
- * It is an error to call ossl_quic_rstream_release_record() multiple
- * times without calling ossl_quic_rstream_get_record() in between.
*/
int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len);
/*
- * Moves received frame data from decrypted packets to ring buffer.
- * This should be called when there are too many decrypted packets allocated.
- * Returns 1 on success, 0 when it was not possible to release all
- * referenced packets due to an insufficient size of the ring buffer.
- * Exception is the packet from the record returned previously by
- * ossl_quic_rstream_get_record() - that one will be always skipped.
+ * Sets flag to cleanse the buffered data when user reads it.
*/
-int ossl_quic_rstream_move_to_rbuf(QUIC_RSTREAM *qrs);
+void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse);
/*
- * Resizes the internal ring buffer to a new `rbuf_size` size.
- * Returns 1 on success, 0 on error.
- * Possible error conditions are an allocation failure, trying to resize
- * the ring buffer when ossl_quic_rstream_get_record() was called and
- * not yet released, or trying to resize the ring buffer to a smaller size
- * than currently occupied.
+ * returns the number of stream chunks kept in rstream
*/
-int ossl_quic_rstream_resize_rbuf(QUIC_RSTREAM *qrs, size_t rbuf_size);
+size_t ossl_quic_rstream_get_chunk_count(QUIC_RSTREAM *qrs);
/*
- * Sets flag to cleanse the buffered data when user reads it.
+ * returns the number of stream ranges kept in rstream
*/
-void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse);
+size_t ossl_quic_rstream_get_range_count(QUIC_RSTREAM *qrs);
+
+QUIC_RSTREAM_QPARM *ossl_quic_rstream_qparm_new(QUIC_CHANNEL *ch);
+void ossl_quic_rstream_qparm_destroy(QUIC_RSTREAM_QPARM *rsqp);
#endif
#endif
diff --git a/deps/openssl/openssl/include/internal/quic_stream_map.h b/deps/openssl/openssl/include/internal/quic_stream_map.h
index 155fca5b84a..53ed1fe94c9 100644
--- a/deps/openssl/openssl/include/internal/quic_stream_map.h
+++ b/deps/openssl/openssl/include/internal/quic_stream_map.h
@@ -832,6 +832,15 @@ void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm,
*/
QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm);
+/*
+ * Retires an incoming stream for the purposes of MAX_STREAMS RXFC, so that the
+ * peer is granted credit for another stream. rtt is the estimated connection
+ * RTT. Must be called at most once for a given stream.
+ */
+void ossl_quic_stream_map_retire_stream_credit(QUIC_STREAM_MAP *qsm,
+ QUIC_STREAM *s,
+ OSSL_TIME rtt);
+
/*
* Removes a stream from the accept queue. rtt is the estimated connection RTT.
* The stream is retired for the purposes of MAX_STREAMS RXFC.
diff --git a/deps/openssl/openssl/include/internal/quic_strm_reas.h b/deps/openssl/openssl/include/internal/quic_strm_reas.h
new file mode 100644
index 00000000000..a2d958a7adc
--- /dev/null
+++ b/deps/openssl/openssl/include/internal/quic_strm_reas.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_QUIC_STRM_REAS_H
+#define OSSL_QUIC_STRM_REAS_H
+
+#include "internal/common.h"
+#include "internal/uint_set.h"
+#include "internal/quic_record_rx.h"
+
+#ifndef OPENSSL_NO_QUIC
+#include "internal/ossl_rbtree.h"
+
+typedef struct sframe_set_t {
+ OSSL_RBT_HEAD(srange, sframe_set_t)
+ ranges;
+ /* Is the tail frame final. */
+ unsigned int fin;
+ uint64_t fin_off;
+ /* Number of stream frames in the list. */
+ size_t stream_ranges;
+ size_t stream_chunks;
+ /* Offset of data not yet dropped */
+ uint64_t offset;
+ /* Cleanse data on release? */
+ int cleanse;
+ int move_buffers;
+ QUIC_RSTREAM_QPARM *rsqp;
+} SFRAME_SET;
+
+/*
+ * Initializes the stream frame list fs.
+ */
+void ossl_sframe_set_init(SFRAME_SET *fs, QUIC_RSTREAM_QPARM *rsqp);
+
+/*
+ * Destroys the stream frame list fs releasing any data
+ * still present inside it.
+ */
+void ossl_sframe_set_destroy_ranges(SFRAME_SET *fs);
+
+/*
+ * Insert a stream frame data into the list.
+ * The data covers an offset range (range.start is inclusive,
+ * range.end is exclusive).
+ * fin should be set if this is the final frame of the stream.
+ * Returns an error if a frame cannot be inserted - due to
+ * STREAM_FRAME allocation error, or in case of erroneous
+ * fin flag.
+ */
+int ossl_sframe_set_insert(SFRAME_SET *fs, UINT_RANGE *range,
+ OSSL_QRX_PKT *pkt,
+ const unsigned char *data, int fin);
+
+/*
+ * Iterator to peek at the contiguous frames at the beginning
+ * of the frame set (the first stream range).
+ * The *data covers an offset range (range.start is inclusive,
+ * range.end is exclusive).
+ * *fin is set if this is the final frame of the stream.
+ * Opaque iterator *iter can be used to peek at the subsequent
+ * frame if there is any without any gap before it.
+ * Returns 1 on success.
+ * Returns 0 if there is no further contiguous frame. In that
+ * case *fin is set, if the end of the stream is reached.
+ */
+int ossl_sframe_set_peek(SFRAME_SET *fs, void **iter,
+ UINT_RANGE *range, const unsigned char **data,
+ int *fin);
+
+/*
+ * moves reading offset to new position, discarding all consumed
+ * chunks (which end offset is less than offset).
+ */
+int ossl_sframe_set_move_offset(SFRAME_SET *fs, uint64_t offset);
+
+/*
+ * returns how many bytes is available to read from stream.
+ */
+int ossl_sframe_set_avail(SFRAME_SET *fs, uint64_t *avail, int *fin);
+
+#endif
+
+#endif
diff --git a/deps/openssl/openssl/include/internal/refcount.h b/deps/openssl/openssl/include/internal/refcount.h
index 61eb78ae412..52a588bc3cb 100644
--- a/deps/openssl/openssl/include/internal/refcount.h
+++ b/deps/openssl/openssl/include/internal/refcount.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2026 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
@@ -103,27 +103,28 @@ static __inline__ int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
}
#elif defined(__ICL) && defined(_WIN32)
+#include <intrin.h>
#define HAVE_ATOMICS 1
typedef struct {
- volatile int val;
+ volatile long val;
} CRYPTO_REF_COUNT;
static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
{
- *ret = _InterlockedExchangeAdd((void *)&refcnt->val, 1) + 1;
+ *ret = _InterlockedExchangeAdd(&refcnt->val, 1) + 1;
return 1;
}
static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
{
- *ret = _InterlockedExchangeAdd((void *)&refcnt->val, -1) - 1;
+ *ret = _InterlockedExchangeAdd(&refcnt->val, -1) - 1;
return 1;
}
static __inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
{
- *ret = _InterlockedExchangeAdd((void *)&refcnt->val, 0);
+ *ret = _InterlockedExchangeAdd(&refcnt->val, 0);
return 1;
}
@@ -132,7 +133,7 @@ static __inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
#define HAVE_ATOMICS 1
typedef struct {
- volatile int val;
+ volatile long val;
} CRYPTO_REF_COUNT;
#if (defined(_M_ARM) && _M_ARM >= 7 && !defined(_WIN32_WCE)) || defined(_M_ARM64)
@@ -155,7 +156,7 @@ static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
static __inline int CRYPTO_GET_REF(CRYPTO_REF_COUNT *refcnt, int *ret)
{
- *ret = _InterlockedExchangeAdd_acq((void *)&refcnt->val, 0);
+ *ret = _InterlockedExchangeAdd_acq(&refcnt->val, 0);
return 1;
}
diff --git a/deps/openssl/openssl/include/openssl/asn1.h b/deps/openssl/openssl/include/openssl/asn1.h
deleted file mode 100644
index cd9fc7cc706..00000000000
--- a/deps/openssl/openssl/include/openssl/asn1.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/asn1.h"
diff --git a/deps/openssl/openssl/include/openssl/asn1t.h b/deps/openssl/openssl/include/openssl/asn1t.h
deleted file mode 100644
index 6ff4f574949..00000000000
--- a/deps/openssl/openssl/include/openssl/asn1t.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/asn1t.h"
diff --git a/deps/openssl/openssl/include/openssl/bio.h b/deps/openssl/openssl/include/openssl/bio.h
deleted file mode 100644
index dcece3cb4d6..00000000000
--- a/deps/openssl/openssl/include/openssl/bio.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/bio.h"
diff --git a/deps/openssl/openssl/include/openssl/cmp.h b/deps/openssl/openssl/include/openssl/cmp.h
deleted file mode 100644
index 7c8a6dc96fc..00000000000
--- a/deps/openssl/openssl/include/openssl/cmp.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/cmp.h"
diff --git a/deps/openssl/openssl/include/openssl/cms.h b/deps/openssl/openssl/include/openssl/cms.h
deleted file mode 100644
index 33a00775c9f..00000000000
--- a/deps/openssl/openssl/include/openssl/cms.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/cms.h"
diff --git a/deps/openssl/openssl/include/openssl/comp.h b/deps/openssl/openssl/include/openssl/comp.h
deleted file mode 100644
index 2c5927233fc..00000000000
--- a/deps/openssl/openssl/include/openssl/comp.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/comp.h"
diff --git a/deps/openssl/openssl/include/openssl/conf.h b/deps/openssl/openssl/include/openssl/conf.h
deleted file mode 100644
index 2712886cafc..00000000000
--- a/deps/openssl/openssl/include/openssl/conf.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/conf.h"
diff --git a/deps/openssl/openssl/include/openssl/configuration.h b/deps/openssl/openssl/include/openssl/configuration.h
deleted file mode 100644
index 8ffad996047..00000000000
--- a/deps/openssl/openssl/include/openssl/configuration.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/configuration.h"
diff --git a/deps/openssl/openssl/include/openssl/core_names.h b/deps/openssl/openssl/include/openssl/core_names.h
deleted file mode 100644
index b7b7d7c73d1..00000000000
--- a/deps/openssl/openssl/include/openssl/core_names.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/core_names.h"
diff --git a/deps/openssl/openssl/include/openssl/crmf.h b/deps/openssl/openssl/include/openssl/crmf.h
deleted file mode 100644
index 4103852ecb2..00000000000
--- a/deps/openssl/openssl/include/openssl/crmf.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/crmf.h"
diff --git a/deps/openssl/openssl/include/openssl/crypto.h b/deps/openssl/openssl/include/openssl/crypto.h
deleted file mode 100644
index 6d0e701ebd3..00000000000
--- a/deps/openssl/openssl/include/openssl/crypto.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/crypto.h"
diff --git a/deps/openssl/openssl/include/openssl/ct.h b/deps/openssl/openssl/include/openssl/ct.h
deleted file mode 100644
index 7ebb8438713..00000000000
--- a/deps/openssl/openssl/include/openssl/ct.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/ct.h"
diff --git a/deps/openssl/openssl/include/openssl/err.h b/deps/openssl/openssl/include/openssl/err.h
deleted file mode 100644
index bf482070474..00000000000
--- a/deps/openssl/openssl/include/openssl/err.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/err.h"
diff --git a/deps/openssl/openssl/include/openssl/ess.h b/deps/openssl/openssl/include/openssl/ess.h
deleted file mode 100644
index 64cc0162251..00000000000
--- a/deps/openssl/openssl/include/openssl/ess.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/ess.h"
diff --git a/deps/openssl/openssl/include/openssl/fipskey.h b/deps/openssl/openssl/include/openssl/fipskey.h
deleted file mode 100644
index c012013d98d..00000000000
--- a/deps/openssl/openssl/include/openssl/fipskey.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/fipskey.h"
diff --git a/deps/openssl/openssl/include/openssl/lhash.h b/deps/openssl/openssl/include/openssl/lhash.h
deleted file mode 100644
index 8d824f5cfe6..00000000000
--- a/deps/openssl/openssl/include/openssl/lhash.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/lhash.h"
diff --git a/deps/openssl/openssl/include/openssl/ocsp.h b/deps/openssl/openssl/include/openssl/ocsp.h
deleted file mode 100644
index 5b13afedf36..00000000000
--- a/deps/openssl/openssl/include/openssl/ocsp.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/ocsp.h"
diff --git a/deps/openssl/openssl/include/openssl/opensslv.h b/deps/openssl/openssl/include/openssl/opensslv.h
deleted file mode 100644
index 078cfba40fb..00000000000
--- a/deps/openssl/openssl/include/openssl/opensslv.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/opensslv.h"
diff --git a/deps/openssl/openssl/include/openssl/pkcs12.h b/deps/openssl/openssl/include/openssl/pkcs12.h
deleted file mode 100644
index 2d7e2c08e99..00000000000
--- a/deps/openssl/openssl/include/openssl/pkcs12.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/pkcs12.h"
diff --git a/deps/openssl/openssl/include/openssl/pkcs7.h b/deps/openssl/openssl/include/openssl/pkcs7.h
deleted file mode 100644
index b553f9d0f05..00000000000
--- a/deps/openssl/openssl/include/openssl/pkcs7.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/pkcs7.h"
diff --git a/deps/openssl/openssl/include/openssl/safestack.h b/deps/openssl/openssl/include/openssl/safestack.h
deleted file mode 100644
index 989eafb3302..00000000000
--- a/deps/openssl/openssl/include/openssl/safestack.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/safestack.h"
diff --git a/deps/openssl/openssl/include/openssl/srp.h b/deps/openssl/openssl/include/openssl/srp.h
deleted file mode 100644
index 9df42dad4c3..00000000000
--- a/deps/openssl/openssl/include/openssl/srp.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/srp.h"
diff --git a/deps/openssl/openssl/include/openssl/ssl.h b/deps/openssl/openssl/include/openssl/ssl.h
deleted file mode 100644
index eb74ca98a97..00000000000
--- a/deps/openssl/openssl/include/openssl/ssl.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/ssl.h"
diff --git a/deps/openssl/openssl/include/openssl/ui.h b/deps/openssl/openssl/include/openssl/ui.h
deleted file mode 100644
index f5edb766b4f..00000000000
--- a/deps/openssl/openssl/include/openssl/ui.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/ui.h"
diff --git a/deps/openssl/openssl/include/openssl/x509.h b/deps/openssl/openssl/include/openssl/x509.h
deleted file mode 100644
index ed28bd68cb2..00000000000
--- a/deps/openssl/openssl/include/openssl/x509.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/x509.h"
diff --git a/deps/openssl/openssl/include/openssl/x509_acert.h b/deps/openssl/openssl/include/openssl/x509_acert.h
deleted file mode 100644
index 331904d4184..00000000000
--- a/deps/openssl/openssl/include/openssl/x509_acert.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/x509_acert.h"
diff --git a/deps/openssl/openssl/include/openssl/x509_vfy.h b/deps/openssl/openssl/include/openssl/x509_vfy.h
deleted file mode 100644
index 9270a3ee097..00000000000
--- a/deps/openssl/openssl/include/openssl/x509_vfy.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/x509_vfy.h"
diff --git a/deps/openssl/openssl/include/openssl/x509v3.h b/deps/openssl/openssl/include/openssl/x509v3.h
deleted file mode 100644
index 5629ae9a3a9..00000000000
--- a/deps/openssl/openssl/include/openssl/x509v3.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../../config/x509v3.h"
diff --git a/deps/openssl/openssl/providers/common/capabilities.c b/deps/openssl/openssl/providers/common/capabilities.c
index eb96627a67e..48bc7eb79d4 100644
--- a/deps/openssl/openssl/providers/common/capabilities.c
+++ b/deps/openssl/openssl/providers/common/capabilities.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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 @@ typedef struct tls_group_constants_st {
int maxtls; /* Maximum TLS version (or 0 for undefined) */
int mindtls; /* Minimum DTLS version, -1 unsupported */
int maxdtls; /* Maximum DTLS version (or 0 for undefined) */
- int is_kem; /* Indicates utility as KEM */
+ unsigned int is_kem; /* Indicates utility as KEM */
} TLS_GROUP_CONSTANTS;
/*
@@ -109,14 +109,14 @@ static const TLS_GROUP_CONSTANTS group_list[] = {
OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, \
(unsigned int *)&group_list[idx].secbits), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, \
- (unsigned int *)&group_list[idx].mintls), \
+ (int *)&group_list[idx].mintls), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, \
- (unsigned int *)&group_list[idx].maxtls), \
+ (int *)&group_list[idx].maxtls), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, \
- (unsigned int *)&group_list[idx].mindtls), \
+ (int *)&group_list[idx].mindtls), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, \
- (unsigned int *)&group_list[idx].maxdtls), \
- OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, \
+ (int *)&group_list[idx].maxdtls), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, \
(unsigned int *)&group_list[idx].is_kem), \
OSSL_PARAM_END \
}
@@ -302,13 +302,13 @@ static const TLS_SIGALG_CONSTANTS sigalg_constants_list[3] = {
OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS, \
(unsigned int *)&sigalg_constants_list[idx].sec_bits), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS, \
- (unsigned int *)&sigalg_constants_list[idx].min_tls), \
+ (int *)&sigalg_constants_list[idx].min_tls), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, \
- (unsigned int *)&sigalg_constants_list[idx].max_tls), \
+ (int *)&sigalg_constants_list[idx].max_tls), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS, \
- (unsigned int *)&sigalg_constants_list[idx].min_dtls), \
+ (int *)&sigalg_constants_list[idx].min_dtls), \
OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS, \
- (unsigned int *)&sigalg_constants_list[idx].max_dtls), \
+ (int *)&sigalg_constants_list[idx].max_dtls), \
OSSL_PARAM_END \
}
diff --git a/deps/openssl/openssl/providers/fips-sources.checksums b/deps/openssl/openssl/providers/fips-sources.checksums
index 85af251d79e..0da9e82cb00 100644
--- a/deps/openssl/openssl/providers/fips-sources.checksums
+++ b/deps/openssl/openssl/providers/fips-sources.checksums
@@ -95,7 +95,7 @@ f1e98f178356791a3d54f586c19d1639d8e89b2cf6e6a4de783327ceada296a2 crypto/bn/bn_e
ce5219203bf869561297978d6d416357a441864cd801865503dfd455c481960c crypto/bn/bn_exp2.c
18ac3f6fe64225f72243689199839ea2ce2aa61d80b084bc4cd9efe1c7cc9d89 crypto/bn/bn_gcd.c
b643fdcd91ad7dfcfa97a0bb235221b024b8a77faa7890f0bcb9681ea2c64c49 crypto/bn/bn_gf2m.c
-73ee247467879d4ec984c9900dfe7761233c5b889b8762be37c7e8fdd6d1d210 crypto/bn/bn_intern.c
+b736a80e3b66f414a803a36ab0c4b9333cf70fda21d873c4584450dfaac52902 crypto/bn/bn_intern.c
ff147e5e032cc7c772b73a91fc6e24d8d9516e642d29354445d1f82d64b1d924 crypto/bn/bn_kron.c
c4bae573e4e7132106b1151e8983cb63200dd9e49dc464e805f0fc50d55374d0 crypto/bn/bn_lib.c
cd7bade0f2e223fe34f6e2f8cc87098ac8f0af96ec62ada5e67f6a2344d48ef0 crypto/bn/bn_local.h
@@ -189,7 +189,7 @@ b94eb087740dde2bf697cfbc5e8a17efd80e84c5072c9c72f8ed2f9155976d37 crypto/ec/ec_k
35515133fb3c33c5736a9f744e835b9fc0775193357ab2492f11d0f63503c65e crypto/ec/ec_kmeth.c
652a1544120bf0fecde46a8e18cc28fffcb7cd864be2e2b84c99d571ba320e64 crypto/ec/ec_lib.c
0d113ac5dbdb420ba3d1c060f4fa3300fc0a81b571a919c2b176022fdca89878 crypto/ec/ec_local.h
-b545e4539ef2483982f35ee05866060478722e329cfbc4990293b46ccfe5c93c crypto/ec/ec_mult.c
+714bb2e01c5f814dd3d63296b93111a9a94b50a441ba85291a9cf9ee5748f42e crypto/ec/ec_mult.c
c2a81f5f56d304038183ba6b02fdcba8767833f61773ec483e73b330b67ae59b crypto/ec/ec_oct.c
c7fba2f2c33f67dafa23caef8c3abd12f5336274a9a07d412b83be0366969ee6 crypto/ec/ecdh_kdf.c
b86a943ae62145438a7214539ceb3e0de5a30e17a6e59742c6e30991db730ab6 crypto/ec/ecdh_ossl.c
@@ -304,12 +304,12 @@ ed6956c34da5127fbf8f1a067654b617c261039743a12fd1d296a1dd01b05c26 crypto/params_
1a81e7483e250ef96f7024f75be884b8830801b47cbdb2d4159637666681b350 crypto/ppccap.c
46fa4994a6234a98a2845d9337475913f6bc229f1928abc82224de7edf2784b8 crypto/ppccpuid.pl
42eff8da564cd8004f2d17fb01686d24977d931c37c7e6de693e7d414c2d7914 crypto/property/defn_cache.c
-3b8088da0a7df3aa44bd703e56c9674d9ff8b75af754a89cf8e57152f0ead48c crypto/property/property.c
+f6c43fb6fee4b40dfcafbc388d6081b72a8030aac0557ae1e3a501f4011acf00 crypto/property/property.c
7f936270992015923e5f6e81b1afad0148b9034693d3cf4665465f839a28c81f crypto/property/property_local.h
71ccd54b74799afe44ec12e1ec8b6b7ece60bc25a00b9b49044ade025a2c39f8 crypto/property/property_parse.c
237079e82943c40d4df9cb6214cf9bc9a84905e4f799eee19a5e0ee4c2d4be4c crypto/property/property_query.c
5b35510efa119157e9e217996870778d1ab5f69612cc1bcc8a6df372a625e875 crypto/property/property_string.c
-fcafd9ac56254e921f43dda47aa6d19ff42b3461ff3a72e0bff1840793f96701 crypto/provider_core.c
+979017d686a02761b6ccd5188bd938a0ca1092e6d70dd24de13dbb806448a2b4 crypto/provider_core.c
aa58d7800d3ccf2989b0de3c2e2710dfac36c88dc51659129897b0dfd2162527 crypto/provider_local.h
5ba2e1c74ddcd0453d02e32612299d1eef18eff8493a7606c15d0dc3738ad1d9 crypto/provider_predefined.c
1e919f7f3c860eb21bf2f6f868dae076c64c53f1ad794c6764f69329724c3fc2 crypto/rand/rand_lib.c
@@ -424,7 +424,7 @@ a4692ad34bd148e06344672e08a3ba928719ca5af4d11ba54d97926759dcda0b crypto/threads
6486afb23846d3c11c3a655e7e6cae24f8cdaf5dd4d6a887b5a04c53f52895b0 include/crypto/aes_platform.h
8b68c7b69b8da6e729789dbd99d45c341458786e2bc0e2c6c6a341e6792d6b10 include/crypto/asn1.h
9acd69adc80fbf9fa88fed4bcc7b3c0ba87e2add98d7ba311d8b092a2d5a0d2c include/crypto/asn1_dsa.h
-21084935a7f88a5926a087832afe8bc6705b1a7813fe226eb4c0df12c753d3a4 include/crypto/bn.h
+6bde5251ab151b60da8d420536a17c214b38bd19f2bc37f0d924b3af4b8dfc22 include/crypto/bn.h
ef5ff8ad445370d0c8ef519bb791265bc09eead2ed0a086e1ec06bb7ed846b38 include/crypto/bn_conf.h.in
7a43a4898fcc8446065e6c99249bcc14e475716e8c1d40d50408c0ab179520e6 include/crypto/bn_dh.h
f63ce4d5b80d0927cddd2e0e2d791b96ffa3cc9ef00a4f3ab921ff50ca6bcf50 include/crypto/cmac.h
@@ -449,7 +449,7 @@ fd4a274688b694aaf010235e6ffd3fd1afd87bc5cee9cae1e4e8be69bf96a5cf include/crypto
3f28391ed526d791a578e76a40961592e15ae2bf62b81d5924525e1f21684659 include/crypto/security_bits.h
70b36014254ca6cbe4126573ea6a71069cc278a6ceaa36412343f19b204c4c13 include/crypto/sha.h
127ede705ecfa8ec504e57cdee1210c5d7a9044121ff05d1dcf72955958346ed include/crypto/slh_dsa.h
-df915f569207111cdb011e85ee0f40bcd169ac0a413cc858ccee0b5001cefbb5 include/crypto/sparse_array.h
+688facd89683d1df2428ba08b22128a4fcbf93c844570518a4764146af87a231 include/crypto/sparse_array.h
eb1f4f50bafdd357aa15b54f60f5ecde10876253038f00bf518fbf60840addc1 include/crypto/types.h
fd5e610fe38804f5de05931706b8efc717663a892f74aa6aee30301ff5e31a25 include/internal/bio.h
d32565e2b426131dc2415e60a97c94570ca982d29ddd97d2e23d6b9f73b1d81c include/internal/common.h
@@ -480,7 +480,7 @@ ee75ecd35b3ae90c51ace957ab7ce06de3c7d5064b97a878241ff65cc943a6db include/intern
7aeac9a78efb9ea5147f639cd474e6c2538acc1b9d255ba19dc661fe22bcd94d include/internal/propertyerr.h
5b108c19f064ec47fffe1b3fe310d4693b6db3920b8cc2e5dc05595751ab0f3b include/internal/provider.h
097ff0f3c25c99df484ec9defca0834fcbdab81ee7e4f40ddc64b95e845dc794 include/internal/rcu.h
-b6e33da6011b2b74d27e39f27cf98e6f123fe47826562b6479d0dbd5c758c4c2 include/internal/refcount.h
+524dc86da257175bc489d80d3ff9b57ea2e74cd0548f6575e2543a1344c9639e include/internal/refcount.h
f77c0844cc44bd92965647cd8cb6addb210f0300a8d1090da8c26e4382e87c2c include/internal/safe_math.h
7d5f4c3db807f108096590f28dd1ae92c05b2af25f827309157e727abb783e7a include/internal/sha3.h
8e672cc0620606b044f63b8446125f5233d64e3eea59df54c1fcca6bc90ba537 include/internal/sizes.h
@@ -498,6 +498,8 @@ a8fa7ddc1e54ca296bda9ee05a7a39bb7e803eb0567cc75a9b949b80cada7552 include/intern
17136e1636365f445ffad27a1fa41aa5e148429d38538ee273034b38a72cc8ba include/openssl/asn1.h.in
0e28b492fc1f2da095ea42267480c9961a4f8cde3314e409f90395af8c65357e include/openssl/asn1err.h
77a9f9595cee6448c6217a8388127593a34a0d0a585197a5f8100fcb792f76ec include/openssl/asn1t.h.in
+aebe1d2efd1f7667f3fe5552ec8d5e9bd3d5659fca7d201d47c58b41d1070be1 include/openssl/async.h
+92c66c0660117eef03d49e586625e47b3b35a35189c66ed2ec57aa71f14c4da1 include/openssl/asyncerr.h
1af8a6c86dedb83887e9baae99ea7dba6576eeb6a991f62865b10d5efdd9d6fa include/openssl/bio.h.in
40491414172d977a4667589fa2f269d7deaae675555b8348d96f315d1a6253bb include/openssl/bioerr.h
bbf263e1e83951f12893f063fc7dd1e2c03773f109ee2262111b61b0a05fd696 include/openssl/bn.h
@@ -506,6 +508,8 @@ c70499c9109b083beb69d1b17807266b041d0ff28694d5bc1ab7cf2a59331c39 include/openss
5bce6559638266f060eaa16b3b90738bbd5292d62230b6b3b1e22b88836a5030 include/openssl/buffererr.h
2a83e38101abb3c2da0e07f9bf7012d8167a3c1588df65c36652c4f72aeafc27 include/openssl/byteorder.h
3c38e3f1d500263b971b851b1c92b69a29252b44991e8afaaf3c36ceda1dd700 include/openssl/cmac.h
+a11471a2d9f47686ba4cc005f305000913a7a1af3efb324fa114b541cae012bb include/openssl/comp.h.in
+759d8087b2861f806f510d22e0cb40e760170ed07176ec0568807e35cbd0de10 include/openssl/comperr.h
1cd9648cc536f25cff10656096ebb1d9353adf3ad855d1c25a22b142ec1705e0 include/openssl/conf.h.in
3517c480b3211d384d4b36fa48d8dce8923fcccd99fefae68635b3f82eb0acb6 include/openssl/conferr.h
4e195b6f7a734756e21c4269cc245b292e1a563aaec5644402929d0eac423c41 include/openssl/configuration.h.in
@@ -516,6 +520,8 @@ b47e5195bcf209e120858a2c671eaf0589fbd1baf1c5f69237ab94651772808a include/openss
e623d4e8d36d7e0f0825fe5cb48e1176be19c0bedc5053fce488aa48602f351c include/openssl/crypto.h.in
128ef415305b704d51461ab98c688c69fde868acb5f5f74c92b2d0517823e71a include/openssl/cryptoerr.h
9a636172a3453f4e23b48198effdd92dee425c9359996b498e388a3d21d16dc5 include/openssl/cryptoerr_legacy.h
+b0e905aec1814217d0a67e3fefbea1dd309fda7c06f554277e0f2ab38ad0254d include/openssl/ct.h.in
+3b37f5f3481829692b206d24791ba34ef0c54e19c54806beb1e8a0d3e0b877cd include/openssl/cterr.h
a147bf48583b902b3db0d30dd2a9565f1c9f3ec94dd57652e31be4c67b7d2593 include/openssl/decoder.h
8d8a2f1286cf40264a80e090d377edaabfa4b040dc0e5314ac41406e0dcb0fdc include/openssl/decodererr.h
402c76d3a33378f6dad64778503581e4f80e2ec46ac24c84646234a06acac5dc include/openssl/des.h
@@ -523,7 +529,9 @@ f5c9ba84d4395938de063bcf9946ab73b41432f6e60e7c1a47f369b5d07041f8 include/openss
5658c7f5cd57d74c7644c63c6328e80469fab9d3e29dd734f1433cf3019dd4ab include/openssl/dherr.h
5eff0626259806221a6dff0e6b50de3298444e3e82a2464cfe2ffce32f1c2f3d include/openssl/dsa.h
d526f8def9e4bb31ff85dbc9494e6b3fe1ab15f424a8e53b3b8fff9dcc40c803 include/openssl/dsaerr.h
+68eef9eb4bafb28fa290eda68dfe2c318d48dc10da3151a424027edd7a454203 include/openssl/dtls1.h
b18230928e536447af72346cf8d98da599c99f8fef74bd5f7bdd7a8dbb012f33 include/openssl/e_os2.h
+11ec3d0149e69d8ed089a8bdf6aee0c6d61dc1a304f3b566fc1987559f5cc723 include/openssl/e_ostime.h
fcb8e2174725eef1279ba8ed046e56c99805796a13eb789ff78aadf7a73e6c76 include/openssl/ebcdic.h
b1b7e6f9a0d0e5fc3d37ef73f0eac099cb6164c2cd4dfc750c3607f6e0736598 include/openssl/ec.h
9c56b594bfde630c9b8df2fe0c691c74cf79fffb1c1b5e2034ade844e6e3c7d3 include/openssl/ecerr.h
@@ -549,11 +557,14 @@ a4127bd23a35828e90addb54b6a1cdfa6a1864038690fcc63053604629fb6f3f include/openss
76386f806a801eba4c0172c52dc0e04e2deb192aa867f9d3e9d98a4d5a932d4a include/openssl/opensslv.h.in
4c4640740b5de9debbc82bcb5b3e02282c145e440e40dea478a804b8c3498065 include/openssl/param_build.h
a9d03ecff3e67ba62eeb03663843148607c0b15c1a91ba3e28d4f7c5335c31bc include/openssl/params.h
+ba1c36e0244a980f619eb956f05c16402d395ce88ed80963a7e3513ef55db70d include/openssl/pem.h
+53d727f596ec45e747a4d79de98d62b1e36c7900d6e0b4269774d118d6c341f2 include/openssl/pemerr.h
2fa9d02862a00a33fd3841640654fc705ae3d88cb91c1978fa09e87bf2976504 include/openssl/pkcs7.h.in
2b25ec134dace5f5e1b0d52650d72c61c2243720358c0b3e645ad956b27d897b include/openssl/pkcs7err.h
a15b0b69bc1e31d0091ad32f04021d4fba9750cf9e3c9c0d2509358543cac380 include/openssl/prov_ssl.h
21a6860d346cfed56d6ba85424a9725bcfc30105697d942b51fe11a4cf7f52d2 include/openssl/proverr.h
d0fffeeaf8a20f6c86e8a6bfaeb1eab7c00188b1844c109ead4232c8dfb3705b include/openssl/provider.h
+0adc54a200e16d7decdba93d7df19dffb99317bce2edd6cfeff6bd6444cf12dc include/openssl/quic.h
c467dcada2506c820e2dcb002dff9d797aaf9527c8778871d79d79a93bc673e7 include/openssl/rand.h
23d76dfea708747bdc2ffac41e25b156a22d2d0cb744323a3b9859c54bfbb98a include/openssl/randerr.h
06dd86ec673693fc7c47a8b8489a72b648a56a667469064fbbfc91bcf20ad650 include/openssl/rsa.h
@@ -561,16 +572,23 @@ c467dcada2506c820e2dcb002dff9d797aaf9527c8778871d79d79a93bc673e7 include/openss
546e4277a9897ed5c01b9ab30168e82f4acf9a6a20da430ebf7dd698d5f888fc include/openssl/safestack.h.in
695683de2485c3b83d9116877f5d5ca3eb84a3bbb599f6bb02c9e595e7102b41 include/openssl/self_test.h
4ab7b74e5d3810eac254c05b74a26a33af9ed526a06530feca758276593d3b2f include/openssl/sha.h
+7a885aefe6213df0e0ba5136ba504e862cdfd8f05e1248b69dba03b8d4049f40 include/openssl/srtp.h
+b1b74cafc5ec9a5ec91df8c88e33d759e30476c3a2b2cd0dc23c20a22503963a include/openssl/ssl.h.in
+bd952356cadf11d266630f4800a340d15f86d01a129ed20891d6357b4cb55a34 include/openssl/ssl2.h
+5915184833e25d2ec0e745583ba190a492100b797c30197f163af1a89183ca93 include/openssl/ssl3.h
+6c7312595fe8b200f06c9ddef7eacc358381f4fa712775850d8c6fb0858b9ab4 include/openssl/sslerr.h
+149f6038fb11f9090b5ab141d46c2da66ef244d06f5c5ba4a8ccf4063b31ab78 include/openssl/sslerr_legacy.h
07f25b18b5acfb8733db85a258c6f3aac0c8f436f0a3095c8d885a741f6287f4 include/openssl/stack.h
d381d0b4113f0fa18b3e421eae303fc84daf84eacb1236cb6e9976409a2d33a9 include/openssl/symhacks.h
fc527427bafa6862d9e3847c961dd6cbbcccc39d25762c65ad3b99fae9599e2e include/openssl/thread.h
+cdd1dab6344a7d700e8146191882d82766e158e9b789f994c3f9984ccff1c656 include/openssl/tls1.h
a481e8762c694b3dac0e74aac8626fe60fa94962a14914f1f6969ea1214c40b1 include/openssl/trace.h
9e04a3e9ca5352adffbdd75a5ea5237e8ff96a8c0a842368cc3a29de006b2ee7 include/openssl/types.h
62e0cddeedfc217ac02bf37f3669ccea8d0822a88a74a8ec82b844a85b2700aa include/openssl/x509.h.in
869959c3d557d2ace84f38b7a8d0f23b3b0854de7f952f46310e828af04554dd include/openssl/x509_vfy.h.in
53a45ca5d00026ef0a256f7ff27f5708d5af0a44177a0fc4b209ec054d44e18c include/openssl/x509err.h
c0a9551efccf43f3dd748d4fd8ec897ddaabbc629c00ec1ad76ce983e1195a13 providers/common/bio_prov.c
-6d25e1b61731cc558c2f801350d0cd874d3c19a3b0a03f52394c11fcaf2d51a5 providers/common/capabilities.c
+b45ed8347714ba15d91fb52e80c75b5670bcf27a9f36a75430c7953eafd8097f providers/common/capabilities.c
f94b7435d4ec888ec30df1c611afa8b9eedbb59e905a2c7cb17cfc8c4b9b85b8 providers/common/der/der_digests_gen.c.in
424d7b2ece984a0904b80c73e541400c6e2d50a285c397dd323b440a4f2a8d8e providers/common/der/der_dsa_gen.c.in
27ff361a5fbfc97cd41690ab26639708961d0507b60912f55f5919649842c6ae providers/common/der/der_dsa_key.c
@@ -610,9 +628,9 @@ ca5a852a6aa77140bd3cea619bd48f8e807a6be4ba5cd760b1790189fc16dc19 providers/comm
b10730f4d302344579c09f43d5f9c5538bb6b4acd60de7430c24269fc522d5a5 providers/common/securitycheck.c
e2f8f00519d81aa16f1c30e8cbf9a0d8e898a1cb5c8b38bb01dd9ab513e34c9e providers/common/securitycheck_fips.c
abd5997bc33b681a4ab275978b92aebca0806a4a3f0c2f41dacf11b3b6f4e101 providers/fips/fips_entry.c
-d8cb05784ae8533a7d9569d4fbaaea4175b63a7c9f4fb0f254215224069dea6b providers/fips/fipsindicator.c
+76030d77364e05fb61253e7c6a33bee9881046d141fb087a58bb88aa5b413629 providers/fips/fipsindicator.c
f0f1486219ddb5817b5105c36f384cb9ef095ddceec50966fe178f4b4177028c providers/fips/fipsprov.c
-8f52eead96febbce9e7f2bf5aaea557efe8f94ce078044959e80e5ae78432539 providers/fips/include/fips/fipsindicator.h
+a348a9ff9480f20fff582093c7cb16bbf9e341648a32f54328f023c4e748314f providers/fips/include/fips/fipsindicator.h
ef204adc49776214dbb299265bc4f2c40b48848cbea4c25b8029f2b46a5c9797 providers/fips/include/fips_indicator_params.inc
f2581d7b4e105f2bb6d30908f3c2d9959313be08cec6dbeb49030c125a7676d3 providers/fips/include/fips_selftest_params.inc
7b80823bb5613e17e8576789ec77712d89c81e7beb6ce50b58037e925e465abd providers/fips/include/fipscommon.h
@@ -623,7 +641,7 @@ aab0bbdaa8e70f6cf9c3871d62b1efc6029cbe386c5d6318d7bc730da0fa8f19 providers/fips
d942921caa433ae9e62959b0ad1caad277b50d005ffc439c6d0e7b0886dba882 providers/implementations/asymciphers/rsa_enc.c
c2f1b12c64fc369dfc3b9bc9e76a76de7280e6429adaee55d332eb1971ad1879 providers/implementations/ciphers/cipher_aes.c
6ba7d817081cf0d87ba7bfb38cd9d70e41505480bb8bc796ef896f68d4514ea6 providers/implementations/ciphers/cipher_aes.h
-693a3a667bf13d3703601dc4d1daca9d890ca4f193ba26b8d77571f79507de16 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
+92b66f5bb84cfd8424fe56ce07bc3d639dc01c2a9d6c4359acd820e8b8b252ef providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
1b4f19be0c2bbea99e5fce0f93189c687a03cac634f0e37a51466ee7e3510735 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h
a579a933e7756b502510a42679e06dca2737bda9e53edda578e28eae56b98577 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c
4e5e5c6478cf72f6840aa5d9edc50fe27aaa3ea39a428f602056172b0f00d541 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c
@@ -653,26 +671,26 @@ dc4626becaabc3990549483d9ef5f05c7dd9a9c2cf9be96ade3ba6a6e203f7f5 providers/impl
9cfdcc860a03b6e7ced8cc21bcbbc1c070c89aefab04b07f213c7a3db1895553 providers/implementations/ciphers/cipher_tdes.h
00b931090e26ce9a62ee4ea125586f439a9906db5d7b914ffc67d293a57c7c00 providers/implementations/ciphers/cipher_tdes_common.c
cca34f1c7baf3a98964f7ce19a59e06d1eaf2ada121a0d4a438f4078a072b325 providers/implementations/ciphers/cipher_tdes_hw.c
-d2f418806c7ed45f118683bc13329573804592684e522efced0fd0921f4548fd providers/implementations/ciphers/ciphercommon.c
+b3d0f1a614a8a15bd9cff60dcfa0371c3bcc26d597c58c07fe9dc1c290aee84a providers/implementations/ciphers/ciphercommon.c
ab9a2edb23aa61cf31da6addd8674a6028f93399eceeeee35a56ee770338fd6c providers/implementations/ciphers/ciphercommon_block.c
-fafb07c3fd77a89cff1d2efbb6edc0767132fc30c57f9e282080da04e6762499 providers/implementations/ciphers/ciphercommon_ccm.c
+de3a998c57842a6de643ec8fd9e4fd6763c7092afb3cb5e83be87016c5d4cc01 providers/implementations/ciphers/ciphercommon_ccm.c
6632a555d5bcd5af67d0355ce46c2906bb3a0dcdf1651595b29189c40a5ca675 providers/implementations/ciphers/ciphercommon_ccm_hw.c
-ab51261da6aea5a3cca74a7561e4b89e6ce83f2ac497a5c766ecd3c3bff95152 providers/implementations/ciphers/ciphercommon_gcm.c
+bc12afbe8844ea598837427b0addec6b608cfda26abc07c96767d38b6b4147f9 providers/implementations/ciphers/ciphercommon_gcm.c
bb67eaa7a98494ca938726f9218213870fc97dd87b56bda950626cc794baf20b providers/implementations/ciphers/ciphercommon_gcm_hw.c
8bf2b4bef8167740ae3fffc9f0cf73327a1b4ee361e63da22c257cca0e1e2971 providers/implementations/ciphers/ciphercommon_hw.c
c4b1cb143de15acc396ce2e03fdd165defd25ebc831de9cdfacf408ea883c666 providers/implementations/ciphers/ciphercommon_local.h
-39b47b6ef9d71852964c26e07ef0e9b23f04c7493b1b16ba7c3dba7074b6b70d providers/implementations/digests/digestcommon.c
+8968fa98952f8f265661c70f2f7e723fca0f80b62ab3faa911025bc41e544a02 providers/implementations/digests/digestcommon.c
ae449102b3434800656536ed7ede4a2786ec97350c01df8c45d0431c12e9e700 providers/implementations/digests/sha2_prov.c
-20ae19c3d85d2e02780948c52ff5c2fd8e2593a001897ca47a47d23280dd579d providers/implementations/digests/sha3_prov.c
+0ec4b36a2c3401df5f3c814371867c9bda1055843c88107a319ffd05288d586a providers/implementations/digests/sha3_prov.c
5b2e4b63e416cc9cd81c27f7acd547df1c580838ac2051d6db56fa9d5569cc8f providers/implementations/exchange/dh_exch.c
e1b33fcc05c60254849b9a01e416885ce93ea9e315b9877ac7ab420003b2ec3c providers/implementations/exchange/ecdh_exch.c
d44c5a6d3156392757415f34afc1ab164fb0e9cd1e97977386d7cd13f3555df5 providers/implementations/exchange/ecx_exch.c
b1115636f53bf70f417b183cafeb6d38e230d11d8de731e6896ba60cc850d931 providers/implementations/exchange/kdf_exch.c
-1644609260b996c1a46610d02474f991e1ee4bdff5d8175e759c49a92f2b5107 providers/implementations/include/prov/ciphercommon.h
+6ec1132020ff0ea45eb2f3e43cf1e5f29f0d2ce1d3adde27431befa626eb3f62 providers/implementations/include/prov/ciphercommon.h
f1dd49b30604d9b8e948c135329a270a4d3e04857f7f9159a3e84f46a024d59d providers/implementations/include/prov/ciphercommon_aead.h
af38be5b3d16c3ced0028bc9b3fbe957a6a817e23967bacc7df65566ba107edb providers/implementations/include/prov/ciphercommon_ccm.h
35d1c063e840c9cd5114c5e57b007a19868982a82d8e40a99b2935c9f1f5e05e providers/implementations/include/prov/ciphercommon_gcm.h
-35596c97faf324823d19a01e1b5674c7a15f1a6e7ff1ef1c7d46400c2a68f63b providers/implementations/include/prov/digestcommon.h
+624f0f709ba1ad87579cda6f2dd76ca0b17c332969a76baba9acecd05a749713 providers/implementations/include/prov/digestcommon.h
1baf1c06b20a0eb8ec271452544922d67c1cc168dbe9853b259191de4bd99918 providers/implementations/include/prov/ecx.h
b0d1f6fc3c9220fe6d4656e487bad8df16b6f840054018b95b2752ea9aef822d providers/implementations/include/prov/hmac_drbg.h
3542340567e409ab68be299aac67cdb1045ab8e8987023d4fc3c209c9779a0ba providers/implementations/include/prov/implementations.h
@@ -691,24 +709,24 @@ abe2b0f3711eaa34846e155cffc9242e4051c45de896f747afd5ac9d87f637dc providers/impl
005016cd3d2b9f9d7288d5b7cc71eff3f603199117f6758464dc9778e1ddfc18 providers/implementations/kdfs/sshkdf.c
a9a5a3ba575b1a372f5a09135667ac1b0e303f8b19b0707804390aba9e266eca providers/implementations/kdfs/sskdf.c
f01cbd7c5351d4aa9ae667627503b2cfef6fc0695e7a42296b7bf015c9a418b3 providers/implementations/kdfs/tls1_prf.c
-39207243a84beb670cb0e64b6d0fe7bfc6a3dd84000617b647a3ecf52a1da3c2 providers/implementations/kdfs/x942kdf.c
-b1431361b8a3448b73f4a46c48b3a4f9fd378c2abba67563f4407b1c7f007fca providers/implementations/kem/ml_kem_kem.c
-926e08e60171cc867220e0f106533ed155132a034690bddea1e7793a879ebf73 providers/implementations/kem/mlx_kem.c
+79122582eb010bd151e9e682f4bed44cb434a378781d33e95700f5b1365b1847 providers/implementations/kdfs/x942kdf.c
+e8d1737df0d274d2d7b00ecf3fc3de7a4482b993bd40ef4fcd2c0f3fab3bc3ea providers/implementations/kem/ml_kem_kem.c
+23ff6d6f0f716c7f79ea7b60433530455843b2c7f387217aec639b67cd2139e7 providers/implementations/kem/mlx_kem.c
ff22e920552b82db3dab51b09f9dd2fd038ef0d57fb76cea5578e703653d28c9 providers/implementations/kem/rsa_kem.c
-6599ad60eef3554741e049c3ff1bd9cc6064d4f3d1835e1ea5dec3a0c14c80bb providers/implementations/keymgmt/dh_kmgmt.c
+728b75a11d47584e2b4d1035609dbd79be98814b706c06445ae678485e266cb7 providers/implementations/keymgmt/dh_kmgmt.c
c0446d1b2101ddd977063516b87d23f424cdca33473f293db4c3974b674169b0 providers/implementations/keymgmt/dsa_kmgmt.c
45480796e6ea50cbe9529c17f9fa04228a9126dc7e7e32971519eeb6d6ac267c providers/implementations/keymgmt/ec_kmgmt.c
258ae17bb2dd87ed1511a8eb3fe99eed9b77f5c2f757215ff6b3d0e8791fc251 providers/implementations/keymgmt/ec_kmgmt_imexport.inc
-c559f1f265388e7b1c8195188fcc71ac8af09b3398530ec8ed7a9afd7b41281e providers/implementations/keymgmt/ecx_kmgmt.c
+c505dadc65ef749c18655df5594b77926a61a015764cf78ced39ee348a4909aa providers/implementations/keymgmt/ecx_kmgmt.c
daf35a7ab961ef70aefca981d80407935904c5da39dca6692432d6e6bc98759d providers/implementations/keymgmt/kdf_legacy_kmgmt.c
-69b509e9c7fe9692622d1059917c3adb991c0047e11bc116f0a393a3a0539445 providers/implementations/keymgmt/mac_legacy_kmgmt.c
-7d197679dc4ae59f0e697749c56cb76399fc5eed88e94585dfd5ebdb23466e53 providers/implementations/keymgmt/ml_dsa_kmgmt.c
-2df9ca1a68a9b6e1d1b108148b54ccf5454da3afa34e510beb2f4516e473e4c6 providers/implementations/keymgmt/ml_kem_kmgmt.c
-4cec24edda3df01c08bef98a0a177ccdd1f8ba84e37c399dc568e010d7c0b29f providers/implementations/keymgmt/mlx_kmgmt.c
-cd4b8129eaccbd77f9b6c725d3cb57b71109c4649115ec786b6495100afaddf2 providers/implementations/keymgmt/rsa_kmgmt.c
-92621573e975489b821884151d2de751e462fcf91efa83cb3bf8f4fd40cd241b providers/implementations/keymgmt/slh_dsa_kmgmt.c
+b89dfb851375a78f255183a2777bdba41c85d4ba85786a4bf0678851d23b6720 providers/implementations/keymgmt/mac_legacy_kmgmt.c
+4caf110da5fbe9c2cc2bbf765ccc53ef15e69f8bd47f7158f691d4b97b846670 providers/implementations/keymgmt/ml_dsa_kmgmt.c
+966aba7035631c53c0cd84f831784353f1d9871dadd0623cb1bcdeef34010796 providers/implementations/keymgmt/ml_kem_kmgmt.c
+a649bf60a638a42521f6e5b8b3010b5524fb7e2478e7f03f8c82bbfdd83c2f73 providers/implementations/keymgmt/mlx_kmgmt.c
+0c66b24fa26849c1bd09bf8086d24c4a34bcefc3aa876c6186017b9b5f0bedfa providers/implementations/keymgmt/rsa_kmgmt.c
+1aa554eee1a5aad4add58f72497e0c25c37f52b42b6c6eec6d16e6d70c92fcdf providers/implementations/keymgmt/slh_dsa_kmgmt.c
2a66bc54579cb1fcd72674a1e60a7a1f798c13ab964a45e5603bed699268354f providers/implementations/macs/cmac_prov.c
-a3bb4d7914f45cf82f86cd92135e20a712274ca153d9ed5ad24db7f33710726c providers/implementations/macs/gmac_prov.c
+78d1c62a30c458357d3c70adf4b66a7fa9a391135da9328560341a70b3b52934 providers/implementations/macs/gmac_prov.c
2d6b8c42c67e3e43d8d0035463cbff590dabb7da815f9e437a3a72d4b6596319 providers/implementations/macs/hmac_prov.c
40686337be4261685f176bb10042d903d46ab10c90e10ac42d3842e9b5ddd960 providers/implementations/macs/kmac_prov.c
0ebc5a48655a697231918644397308e64914c32421e9b8ee7afd7779b6a2fdb8 providers/implementations/rands/drbg.c
@@ -719,12 +737,12 @@ e624059b1c9f878655d6a21a4c295c43d147ea913f638a2d007a1a68379180f8 providers/impl
355bd437dde9ecd1da89f42691147f2b5cf9a012ff5f55062bf83b6bead1e181 providers/implementations/rands/fips_crng_test.c
90ea602ec88f7c0a78f3e7c801cdd3574a221f04497121a9ea7dcb05b7ee6765 providers/implementations/rands/test_rng.c
c6c709dfd8b1be036e2a5232d3b21dc25f0150f2aae24cc7db6b09cd790a04ee providers/implementations/signature/dsa_sig.c
-d10d611713a6d9aa5cdbe636f1ba90404043431fd1df01fc1a1ce8499bf96ad0 providers/implementations/signature/ecdsa_sig.c
-a837f69cb1aa5d0327372e26a63a8492b6ffb1156325f66e880c202011d07cbe providers/implementations/signature/eddsa_sig.c
-e0e67e402ff19b0d2eb5228d7ebd70b9477c12595ac34d6f201373d7c8a516f4 providers/implementations/signature/mac_legacy_sig.c
-51251a1ca4c0b6faea059de5d5268167fe47565163317177d09db39978134f78 providers/implementations/signature/ml_dsa_sig.c
-6b293ca81102cd2f234d60f52f839e5bd7a746a42df3fe8a4489e6c214108f50 providers/implementations/signature/rsa_sig.c
-ec630d49078bdd901132e7651eaf3478ff3b04e5558c435ffd7c77dcb62e46b3 providers/implementations/signature/slh_dsa_sig.c
+cda60439dd7eaa7e90e599f789cb3092967b57bee36c7b58dce2477793b5f487 providers/implementations/signature/ecdsa_sig.c
+218bcd28611b02027314f8f7b7d6b5b5164574873b5188efc2a9e6a907aeeb33 providers/implementations/signature/eddsa_sig.c
+31f588fe2e38fe1c6c5a3cb9cdffedf5a4b3994357c57fae2ff900702d75ff23 providers/implementations/signature/mac_legacy_sig.c
+3f4449310fa024ee485121e6aaa4b11fca2c0b9c9a9484990f9cea5723de7e4c providers/implementations/signature/ml_dsa_sig.c
+5712b5a289cc279a9136238d979b86febe83c9af15120f78a48fd0c1dd107e5a providers/implementations/signature/rsa_sig.c
+abf792c38bbb727ea7c4e574453150f40d096a8f8e188e6bae95d1a37057b10f providers/implementations/signature/slh_dsa_sig.c
21f537f9083f0341d9d1b0ace090a8d8f0b2b9e9cf76771c359b6ea00667a469 providers/implementations/skeymgmt/aes_skmgmt.c
2dbf9b8e738fad556c3248fb554ff4cc269ade3c86fa3d2786ba9b6d6016bf22 providers/implementations/skeymgmt/generic.c
9ba8db9b0e18847ef79ecb77fbc383d8762694be29dfb7d269df6f02dc977222 providers/implementations/skeymgmt/skeymgmt_lcl.h
diff --git a/deps/openssl/openssl/providers/fips.checksum b/deps/openssl/openssl/providers/fips.checksum
index f236b8ff81a..f65a3e29770 100644
--- a/deps/openssl/openssl/providers/fips.checksum
+++ b/deps/openssl/openssl/providers/fips.checksum
@@ -1 +1 @@
-ee77588030ee4df89ad9ff70a12118a9b89ebc4fde306fd25e9c01ef719d0b26 providers/fips-sources.checksums
+ee49eb47504f27ba763309e94f373e49f3d2fd1f6f750fce28329184bfdb1f01 providers/fips-sources.checksums
diff --git a/deps/openssl/openssl/providers/fips.module.sources b/deps/openssl/openssl/providers/fips.module.sources
index 5ee6c0dab20..765df15d284 100644
--- a/deps/openssl/openssl/providers/fips.module.sources
+++ b/deps/openssl/openssl/providers/fips.module.sources
@@ -498,6 +498,8 @@ include/openssl/aes.h
include/openssl/asn1.h.in
include/openssl/asn1err.h
include/openssl/asn1t.h.in
+include/openssl/async.h
+include/openssl/asyncerr.h
include/openssl/bio.h.in
include/openssl/bioerr.h
include/openssl/bn.h
@@ -506,6 +508,8 @@ include/openssl/buffer.h
include/openssl/buffererr.h
include/openssl/byteorder.h
include/openssl/cmac.h
+include/openssl/comp.h.in
+include/openssl/comperr.h
include/openssl/conf.h.in
include/openssl/conferr.h
include/openssl/configuration.h.in
@@ -516,6 +520,8 @@ include/openssl/core_names.h.in
include/openssl/crypto.h.in
include/openssl/cryptoerr.h
include/openssl/cryptoerr_legacy.h
+include/openssl/ct.h.in
+include/openssl/cterr.h
include/openssl/decoder.h
include/openssl/decodererr.h
include/openssl/des.h
@@ -523,7 +529,9 @@ include/openssl/dh.h
include/openssl/dherr.h
include/openssl/dsa.h
include/openssl/dsaerr.h
+include/openssl/dtls1.h
include/openssl/e_os2.h
+include/openssl/e_ostime.h
include/openssl/ebcdic.h
include/openssl/ec.h
include/openssl/ecerr.h
@@ -549,11 +557,14 @@ include/openssl/opensslconf.h
include/openssl/opensslv.h.in
include/openssl/param_build.h
include/openssl/params.h
+include/openssl/pem.h
+include/openssl/pemerr.h
include/openssl/pkcs7.h.in
include/openssl/pkcs7err.h
include/openssl/prov_ssl.h
include/openssl/proverr.h
include/openssl/provider.h
+include/openssl/quic.h
include/openssl/rand.h
include/openssl/randerr.h
include/openssl/rsa.h
@@ -561,9 +572,16 @@ include/openssl/rsaerr.h
include/openssl/safestack.h.in
include/openssl/self_test.h
include/openssl/sha.h
+include/openssl/srtp.h
+include/openssl/ssl.h.in
+include/openssl/ssl2.h
+include/openssl/ssl3.h
+include/openssl/sslerr.h
+include/openssl/sslerr_legacy.h
include/openssl/stack.h
include/openssl/symhacks.h
include/openssl/thread.h
+include/openssl/tls1.h
include/openssl/trace.h
include/openssl/types.h
include/openssl/x509.h.in
diff --git a/deps/openssl/openssl/providers/fips/fipsindicator.c b/deps/openssl/openssl/providers/fips/fipsindicator.c
index 05d5f5aed54..8aba61a007c 100644
--- a/deps/openssl/openssl/providers/fips/fipsindicator.c
+++ b/deps/openssl/openssl/providers/fips/fipsindicator.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 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
@@ -98,6 +98,35 @@ int ossl_FIPS_IND_get_ctx_param(const OSSL_FIPS_IND *ind, OSSL_PARAM params[])
return p == NULL || OSSL_PARAM_set_int(p, ind->approved);
}
+int ossl_FIPS_IND_get_ctx_param_conditional(const OSSL_FIPS_IND *ind,
+ OSSL_PARAM params[], int condition)
+{
+ OSSL_PARAM *p = OSSL_PARAM_locate(params,
+ OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR);
+
+ return p == NULL || OSSL_PARAM_set_int(p, condition && (ind == NULL || ind->approved));
+}
+
+const OSSL_PARAM *ossl_FIPS_IND_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+ static const OSSL_PARAM gettable_ctx_params[] = {
+ OSSL_PARAM_int(OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR, NULL),
+ OSSL_PARAM_END
+ };
+
+ return gettable_ctx_params;
+}
+
+int ossl_FIPS_IND_get_ctx_param_approved(ossl_unused void *ctx,
+ OSSL_PARAM params[])
+{
+ OSSL_PARAM *p = OSSL_PARAM_locate(params,
+ OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR);
+
+ return p == NULL || OSSL_PARAM_set_int(p, 1);
+}
+
/*
* Can be used during application testing to log that an indicator was
* triggered. The callback will return 1 if the application wants an error
diff --git a/deps/openssl/openssl/providers/fips/include/fips/fipsindicator.h b/deps/openssl/openssl/providers/fips/include/fips/fipsindicator.h
index 6b3cd5646dd..a6fe5dec7f4 100644
--- a/deps/openssl/openssl/providers/fips/include/fips/fipsindicator.h
+++ b/deps/openssl/openssl/providers/fips/include/fips/fipsindicator.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2026 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
@@ -7,6 +7,9 @@
* https://www.openssl.org/source/license.html
*/
+#ifndef OSSL_PROVIDERS_FIPSINDICATOR_H
+#define OSSL_PROVIDERS_FIPSINDICATOR_H
+
#ifdef FIPS_MODULE
#include <openssl/core.h> /* OSSL_CALLBACK, OSSL_LIB_CTX */
@@ -73,6 +76,10 @@ int ossl_FIPS_IND_set_ctx_param(OSSL_FIPS_IND *ind, int id,
const OSSL_PARAM params[], const char *name);
int ossl_FIPS_IND_get_ctx_param(const OSSL_FIPS_IND *ind,
OSSL_PARAM params[]);
+int ossl_FIPS_IND_get_ctx_param_conditional(const OSSL_FIPS_IND *ind,
+ OSSL_PARAM params[], int condition);
+const OSSL_PARAM *ossl_FIPS_IND_gettable_ctx_params(void *ctx, void *provctx);
+int ossl_FIPS_IND_get_ctx_param_approved(void *ctx, OSSL_PARAM params[]);
void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src);
/* Place this in the algorithm ctx structure */
@@ -115,6 +122,20 @@ void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src);
#define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, prms) \
ossl_FIPS_IND_get_ctx_param(&((ctx)->indicator), prms)
+#define OSSL_FIPS_IND_GET_CTX_PARAM_CONDITIONAL(ctx, prms, condition) \
+ ossl_FIPS_IND_get_ctx_param_conditional(&((ctx)->indicator), prms, condition)
+
+#define OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, prms) \
+ ossl_FIPS_IND_get_ctx_param_approved(ctx, prms)
+
+#define OSSL_FIPS_IND_DISPATCH(get_id, gettable_id, get_fn) \
+ { get_id, (void (*)(void))get_fn }, \
+ { gettable_id, (void (*)(void))ossl_FIPS_IND_gettable_ctx_params },
+
+#define OSSL_FIPS_IND_APPROVED_DISPATCH(get_id, gettable_id) \
+ OSSL_FIPS_IND_DISPATCH(get_id, gettable_id, \
+ ossl_FIPS_IND_get_ctx_param_approved)
+
#define OSSL_FIPS_IND_GET(ctx) (&((ctx)->indicator))
#define OSSL_FIPS_IND_GET_PARAM(ctx, p, settable, id, name) \
@@ -147,6 +168,12 @@ int ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND *ind, int id,
#define OSSL_FIPS_IND_SET_CTX_PARAM(ctx, id, params, name) 1
#define OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
#define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params) 1
+#define OSSL_FIPS_IND_GET_CTX_PARAM_CONDITIONAL(ctx, params, condition) 1
+#define OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, params) 1
+#define OSSL_FIPS_IND_DISPATCH(get_id, gettable_id, get_fn)
+#define OSSL_FIPS_IND_APPROVED_DISPATCH(get_id, gettable_id)
#define OSSL_FIPS_IND_COPY(dst, src)
#endif
+
+#endif /* OSSL_PROVIDERS_FIPSINDICATOR_H */
diff --git a/deps/openssl/openssl/providers/implementations/ciphers/build.info b/deps/openssl/openssl/providers/implementations/ciphers/build.info
index 1837070c211..5dd16565c2e 100644
--- a/deps/openssl/openssl/providers/implementations/ciphers/build.info
+++ b/deps/openssl/openssl/providers/implementations/ciphers/build.info
@@ -6,6 +6,12 @@
# variables already now, to switch the non-FIPSable TDES to legacy if needed.
$COMMON_GOAL=../../libcommon.a
+$AEAD_COMMON_GOAL=../../libdefault.a ../../libfips.a
+IF[{- !$disabled{module} -}]
+ $CIPHER_COMMON_GOAL=../../libdefault.a ../../libfips.a ../../liblegacy.a
+ELSE
+ $CIPHER_COMMON_GOAL=../../libdefault.a ../../libfips.a
+ENDIF
$NULL_GOAL=../../libdefault.a
$AES_GOAL=../../libdefault.a ../../libfips.a
@@ -84,11 +90,14 @@ IF[{- !$disabled{asm} -}]
ENDIF
ENDIF
-# This source is common building blocks for all ciphers in all our providers.
+# These building blocks do not depend on the provider being built.
SOURCE[$COMMON_GOAL]=\
- ciphercommon.c ciphercommon_hw.c ciphercommon_block.c \
- ciphercommon_gcm.c ciphercommon_gcm_hw.c \
- ciphercommon_ccm.c ciphercommon_ccm_hw.c
+ ciphercommon_hw.c ciphercommon_block.c \
+ ciphercommon_gcm_hw.c ciphercommon_ccm_hw.c
+
+# These sources contain FIPS-provider-specific parameter handling.
+SOURCE[$CIPHER_COMMON_GOAL]=ciphercommon.c
+SOURCE[$AEAD_COMMON_GOAL]=ciphercommon_gcm.c ciphercommon_ccm.c
IF[{- !$disabled{des} -}]
SOURCE[$TDES_1_GOAL]=cipher_tdes.c cipher_tdes_common.c cipher_tdes_hw.c
diff --git a/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c b/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
index 0c1efa9b323..3bb92e7f655 100644
--- a/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
+++ b/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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,9 +19,11 @@
/* For SSL3_VERSION and TLS1_VERSION */
#include <openssl/prov_ssl.h>
#include <openssl/proverr.h>
+#include <openssl/ssl3.h>
#include "cipher_aes_cbc_hmac_sha.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
+#include "fips/fipsindicator.h"
#ifndef AES_CBC_HMAC_SHA_CAPABLE
#define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags) \
@@ -33,6 +35,21 @@
#define AES_CBC_HMAC_SHA_FLAGS (PROV_CIPHER_FLAG_AEAD \
| PROV_CIPHER_FLAG_TLS1_MULTIBLOCK)
+#if !defined(OPENSSL_NO_MULTIBLOCK)
+static int aes_get_multiblock_interleave(const OSSL_PARAM *p,
+ unsigned int *interleave)
+{
+ return p != NULL
+ && OSSL_PARAM_get_uint(p, interleave)
+ && (*interleave == 4 || *interleave == 8);
+}
+
+static unsigned int tls1_aad_plaintext_len(const unsigned char *aad)
+{
+ return ((unsigned int)aad[11] << 8) | aad[12];
+}
+#endif /* !defined(OPENSSL_NO_MULTIBLOCK) */
+
static OSSL_FUNC_cipher_encrypt_init_fn aes_einit;
static OSSL_FUNC_cipher_decrypt_init_fn aes_dinit;
static OSSL_FUNC_cipher_freectx_fn aes_cbc_hmac_sha1_freectx;
@@ -69,7 +86,7 @@ static const OSSL_PARAM cipher_aes_known_settable_ctx_params[] = {
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
#if !defined(OPENSSL_NO_MULTIBLOCK)
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, NULL),
- OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, NULL),
+ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, NULL, 0),
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, NULL, 0),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, NULL, 0),
@@ -127,8 +144,12 @@ static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params,
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE);
if (p->data_type != OSSL_PARAM_OCTET_STRING
- || p1 == NULL
- || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) {
+ || p->data == NULL
+ || p->data_size < EVP_AEAD_TLS1_AAD_LEN
+ || !aes_get_multiblock_interleave(p1, &mb_param.interleave)
+ || tls1_aad_plaintext_len(p->data) > SSL3_RT_MAX_PLAIN_LENGTH
+ || p->data_size
+ > (size_t)SSL3_RT_MAX_PLAIN_LENGTH * mb_param.interleave) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return 0;
}
@@ -155,10 +176,15 @@ static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN);
if (p->data_type != OSSL_PARAM_OCTET_STRING
+ || p->data == NULL
|| pin == NULL
|| pin->data_type != OSSL_PARAM_OCTET_STRING
- || p1 == NULL
- || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) {
+ || pin->data == NULL
+ || pin->data_size == 0
+ || p->data_size != pin->data_size
+ || !aes_get_multiblock_interleave(p1, &mb_param.interleave)
+ || pin->data_size
+ > (size_t)SSL3_RT_MAX_PLAIN_LENGTH * mb_param.interleave) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return 0;
}
@@ -281,7 +307,7 @@ static int aes_get_ctx_params(void *vctx, OSSL_PARAM params[])
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
- return 1;
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, params);
}
static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = {
@@ -296,7 +322,8 @@ static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
const OSSL_PARAM *aes_gettable_ctx_params(ossl_unused void *cctx,
ossl_unused void *provctx)
diff --git a/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon.c b/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon.c
index 9b6930e5c49..7f53cf6cdf9 100644
--- a/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon.c
+++ b/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon.c
@@ -19,6 +19,7 @@
#include "prov/providercommon.h"
#include "internal/skey.h"
#include "crypto/types.h"
+#include "fips/fipsindicator.h"
/*-
* Generic cipher functions for OSSL_PARAM gettables and settables
@@ -155,7 +156,8 @@ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_AEAD_IV_GENERATED, NULL),
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params(
ossl_unused void *cctx, ossl_unused void *provctx)
@@ -638,7 +640,7 @@ int ossl_cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
- return 1;
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, params);
}
int ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
diff --git a/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_ccm.c b/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_ccm.c
index 7a70b1b0999..8f5839afd20 100644
--- a/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_ccm.c
+++ b/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_ccm.c
@@ -13,6 +13,7 @@
#include "prov/ciphercommon.h"
#include "prov/ciphercommon_ccm.h"
#include "prov/providercommon.h"
+#include "fips/fipsindicator.h"
static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
size_t *padlen, const unsigned char *in,
@@ -219,7 +220,7 @@ int ossl_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[])
ctx->iv_set = 0;
ctx->len_set = 0;
}
- return 1;
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, params);
}
static int ccm_init(void *vctx, const unsigned char *key, size_t keylen,
diff --git a/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_gcm.c b/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_gcm.c
index a1fdf104012..3bc45c2f962 100644
--- a/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_gcm.c
+++ b/deps/openssl/openssl/providers/implementations/ciphers/ciphercommon_gcm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -16,6 +16,7 @@
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "internal/param_names.h"
+#include "fips/fipsindicator.h"
static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len);
static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
@@ -26,6 +27,14 @@ static int gcm_cipher_internal(PROV_GCM_CTX *ctx, unsigned char *out,
size_t *padlen, const unsigned char *in,
size_t len);
+#ifdef FIPS_MODULE
+static int gcm_fips_taglen_approved(size_t taglen)
+{
+ return taglen == UNINITIALISED_SIZET || taglen == 4 || taglen == 8
+ || (taglen >= 12 && taglen <= GCM_TAG_MAX_SIZE);
+}
+#endif
+
/*
* Called from EVP_CipherInit when there is currently no context via
* the new_ctx() function
@@ -238,7 +247,14 @@ int ossl_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[])
return 0;
}
}
+#ifdef FIPS_MODULE
+ /* Externally supplied IVs are permitted but not approved for encryption. */
+ return ossl_FIPS_IND_get_ctx_param_conditional(NULL, params,
+ (!ctx->enc || ctx->iv_gen_rand)
+ && gcm_fips_taglen_approved(ctx->taglen));
+#else
return 1;
+#endif
}
int ossl_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[])
@@ -503,6 +519,7 @@ static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
/* Special case: -1 length restores whole IV */
if (len == (size_t)-1) {
memcpy(ctx->iv, iv, ctx->ivlen);
+ ctx->iv_gen_rand = 0;
ctx->iv_gen = 1;
ctx->iv_state = IV_STATE_BUFFERED;
return 1;
diff --git a/deps/openssl/openssl/providers/implementations/digests/build.info b/deps/openssl/openssl/providers/implementations/digests/build.info
index d30975028e9..5e6d06d341f 100644
--- a/deps/openssl/openssl/providers/implementations/digests/build.info
+++ b/deps/openssl/openssl/providers/implementations/digests/build.info
@@ -1,7 +1,11 @@
# We make separate GOAL variables for each algorithm, to make it easy to
# switch each to the Legacy provider when needed.
-$COMMON_GOAL=../../libcommon.a
+IF[{- !$disabled{module} -}]
+ $DIGEST_COMMON_GOAL=../../libdefault.a ../../libfips.a ../../liblegacy.a
+ELSE
+ $DIGEST_COMMON_GOAL=../../libdefault.a ../../libfips.a
+ENDIF
$SHA1_GOAL=../../libdefault.a ../../libfips.a
$SHA2_GOAL=../../libdefault.a ../../libfips.a
@@ -21,8 +25,8 @@ ELSE
$RIPEMD_GOAL=../../libdefault.a
ENDIF
-# This source is common for all digests in all our providers.
-SOURCE[$COMMON_GOAL]=digestcommon.c
+# This source contains FIPS-provider-specific parameter handling.
+SOURCE[$DIGEST_COMMON_GOAL]=digestcommon.c
SOURCE[$SHA2_GOAL]=sha2_prov.c
SOURCE[$SHA3_GOAL]=sha3_prov.c
diff --git a/deps/openssl/openssl/providers/implementations/digests/digestcommon.c b/deps/openssl/openssl/providers/implementations/digests/digestcommon.c
index f385dc4931f..299834e8c70 100644
--- a/deps/openssl/openssl/providers/implementations/digests/digestcommon.c
+++ b/deps/openssl/openssl/providers/implementations/digests/digestcommon.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -10,6 +10,7 @@
#include <openssl/err.h>
#include <openssl/proverr.h>
#include "prov/digestcommon.h"
+#include "fips/fipsindicator.h"
int ossl_digest_default_get_params(OSSL_PARAM params[], size_t blksz,
size_t paramsz, unsigned long flags)
@@ -52,3 +53,18 @@ const OSSL_PARAM *ossl_digest_default_gettable_params(void *provctx)
{
return digest_default_known_gettable_params;
}
+
+const OSSL_PARAM *ossl_digest_default_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+#ifdef FIPS_MODULE
+ return ossl_FIPS_IND_gettable_ctx_params(ctx, provctx);
+#else
+ return NULL;
+#endif
+}
+
+int ossl_digest_default_get_ctx_params(void *ctx, OSSL_PARAM params[])
+{
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, params);
+}
diff --git a/deps/openssl/openssl/providers/implementations/digests/sha3_prov.c b/deps/openssl/openssl/providers/implementations/digests/sha3_prov.c
index 80692ee7a0a..037a0af38e6 100644
--- a/deps/openssl/openssl/providers/implementations/digests/sha3_prov.c
+++ b/deps/openssl/openssl/providers/implementations/digests/sha3_prov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -18,6 +18,7 @@
#include "internal/sha3.h"
#include "prov/digestcommon.h"
#include "prov/implementations.h"
+#include "fips/fipsindicator.h"
#define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)
@@ -530,10 +531,18 @@ static PROV_SHA3_METHOD shake_ARMSHA3_md = {
{ OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))keccak_copyctx }, \
PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)
+#ifdef FIPS_MODULE
+#define PROV_SHA3_FIPS_GET_CTX_PARAMS \
+ PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS,
+#else
+#define PROV_SHA3_FIPS_GET_CTX_PARAMS
+#endif
+
#define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags) \
PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \
- PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
+ PROV_SHA3_FIPS_GET_CTX_PARAMS \
+ PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
#define PROV_FUNC_SHAKE_DIGEST(name, bitlen, blksize, dgstsize, flags) \
PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \
@@ -579,7 +588,8 @@ static const OSSL_PARAM *shake_gettable_ctx_params(ossl_unused void *ctx,
static const OSSL_PARAM known_shake_gettable_ctx_params[] = {
{ OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },
{ OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
return known_shake_gettable_ctx_params;
}
@@ -605,7 +615,7 @@ static int shake_get_ctx_params(void *vctx, OSSL_PARAM params[])
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
return 0;
}
- return 1;
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(ctx, params);
}
static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *ctx,
diff --git a/deps/openssl/openssl/providers/implementations/include/prov/ciphercommon.h b/deps/openssl/openssl/providers/implementations/include/prov/ciphercommon.h
index 429d27cc862..578529ee4af 100644
--- a/deps/openssl/openssl/providers/implementations/include/prov/ciphercommon.h
+++ b/deps/openssl/openssl/providers/implementations/include/prov/ciphercommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -18,6 +18,13 @@
#include "internal/cryptlib.h"
#include "crypto/modes.h"
+#ifdef FIPS_MODULE
+#define CIPHER_FIPS_IND_GETTABLE_CTX_PARAM() \
+ OSSL_PARAM_int(OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR, NULL),
+#else
+#define CIPHER_FIPS_IND_GETTABLE_CTX_PARAM()
+#endif
+
#define MAXCHUNK ((size_t)1 << 30)
#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))
@@ -330,14 +337,15 @@ PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128;
dst->ks = &dctx->ks.ks; \
}
-#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \
- static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \
- OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \
- OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \
- OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \
- OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \
- OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),
+#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \
+ static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \
+ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \
+ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \
+ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \
+ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \
+ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), \
+ CIPHER_FIPS_IND_GETTABLE_CTX_PARAM()
#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \
OSSL_PARAM_END \
diff --git a/deps/openssl/openssl/providers/implementations/include/prov/digestcommon.h b/deps/openssl/openssl/providers/implementations/include/prov/digestcommon.h
index 14adc5507f7..48b0fd4d239 100644
--- a/deps/openssl/openssl/providers/implementations/include/prov/digestcommon.h
+++ b/deps/openssl/openssl/providers/implementations/include/prov/digestcommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -37,6 +37,21 @@ extern "C" {
(void (*)(void))ossl_digest_default_gettable_params \
}
+#ifdef FIPS_MODULE
+#define PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS \
+ { OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS, \
+ (void (*)(void))ossl_digest_default_gettable_ctx_params }, \
+ { \
+ OSSL_FUNC_DIGEST_GET_CTX_PARAMS, \
+ (void (*)(void))ossl_digest_default_get_ctx_params \
+ }
+#define PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS_APPEND \
+ , PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS
+#else
+#define PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS
+#define PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS_APPEND
+#endif
+
#define PROV_FUNC_DIGEST_FINAL(name, dgstsize, fin) \
static OSSL_FUNC_digest_final_fn name##_internal_final; \
static int name##_internal_final(void *ctx, unsigned char *out, size_t *outl, \
@@ -87,7 +102,8 @@ extern "C" {
{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))name##_freectx }, \
{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))name##_dupctx }, \
{ OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))name##_copyctx }, \
- PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)
+ PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) \
+ PROV_DISPATCH_FUNC_DIGEST_GET_CTX_PARAMS_APPEND
#define PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END \
{ \
@@ -129,6 +145,9 @@ extern "C" {
const OSSL_PARAM *ossl_digest_default_gettable_params(void *provctx);
int ossl_digest_default_get_params(OSSL_PARAM params[], size_t blksz,
size_t paramsz, unsigned long flags);
+const OSSL_PARAM *ossl_digest_default_gettable_ctx_params(void *ctx,
+ void *provctx);
+int ossl_digest_default_get_ctx_params(void *ctx, OSSL_PARAM params[]);
#ifdef __cplusplus
}
diff --git a/deps/openssl/openssl/providers/implementations/kdfs/krb5kdf.c b/deps/openssl/openssl/providers/implementations/kdfs/krb5kdf.c
index deeb6430786..936640aaec7 100644
--- a/deps/openssl/openssl/providers/implementations/kdfs/krb5kdf.c
+++ b/deps/openssl/openssl/providers/implementations/kdfs/krb5kdf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2026 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
@@ -423,7 +423,7 @@ static int KRB5KDF(const EVP_CIPHER *cipher, ENGINE *engine,
goto out;
}
- if (constant_len > blocksize) {
+ if (constant_len == 0 || constant_len > blocksize) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONSTANT_LENGTH);
ret = 0;
goto out;
diff --git a/deps/openssl/openssl/providers/implementations/kdfs/x942kdf.c b/deps/openssl/openssl/providers/implementations/kdfs/x942kdf.c
index d173887ae35..e6bdbbcb165 100644
--- a/deps/openssl/openssl/providers/implementations/kdfs/x942kdf.c
+++ b/deps/openssl/openssl/providers/implementations/kdfs/x942kdf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -257,9 +257,11 @@ x942_encode_otherinfo(size_t keylen,
goto err;
*out_ctr = (pcounter + 2);
*der = der_buf;
+ der_buf = NULL;
*der_len = der_buflen;
ret = 1;
err:
+ OPENSSL_free(der_buf);
WPACKET_cleanup(&pkt);
return ret;
}
diff --git a/deps/openssl/openssl/providers/implementations/kem/ml_kem_kem.c b/deps/openssl/openssl/providers/implementations/kem/ml_kem_kem.c
index 14c670784c5..5cc3fcacf02 100644
--- a/deps/openssl/openssl/providers/implementations/kem/ml_kem_kem.c
+++ b/deps/openssl/openssl/providers/implementations/kem/ml_kem_kem.c
@@ -35,6 +35,7 @@ typedef struct {
uint8_t entropy_buf[ML_KEM_RANDOM_BYTES];
uint8_t *entropy;
int op;
+ int test_entropy_used;
} PROV_ML_KEM_CTX;
static void *ml_kem_newctx(void *provctx)
@@ -47,6 +48,7 @@ static void *ml_kem_newctx(void *provctx)
ctx->key = NULL;
ctx->entropy = NULL;
ctx->op = 0;
+ ctx->test_entropy_used = 0;
return ctx;
}
@@ -68,9 +70,22 @@ static int ml_kem_init(void *vctx, int op, void *key,
return 0;
ctx->key = key;
ctx->op = op;
+ ctx->test_entropy_used = 0;
return ml_kem_set_ctx_params(vctx, params);
}
+#ifdef FIPS_MODULE
+static int ml_kem_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ PROV_ML_KEM_CTX *ctx = vctx;
+
+ if (ctx == NULL)
+ return 0;
+ return ossl_FIPS_IND_get_ctx_param_conditional(NULL, params,
+ !ctx->test_entropy_used);
+}
+#endif
+
static int ml_kem_encapsulate_init(void *vctx, void *vkey,
const OSSL_PARAM params[])
{
@@ -120,8 +135,10 @@ static int ml_kem_set_ctx_params(void *vctx, const OSSL_PARAM params[])
ctx->entropy = ctx->entropy_buf;
if (OSSL_PARAM_get_octet_string(p, (void **)&ctx->entropy,
len, &len)
- && len == ML_KEM_RANDOM_BYTES)
+ && len == ML_KEM_RANDOM_BYTES) {
+ ctx->test_entropy_used = 1;
return 1;
+ }
/* Possibly, but much less likely wrong type */
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH);
@@ -265,5 +282,11 @@ const OSSL_DISPATCH ossl_ml_kem_asym_kem_functions[] = {
{ OSSL_FUNC_KEM_FREECTX, (OSSL_FUNC)ml_kem_freectx },
{ OSSL_FUNC_KEM_SET_CTX_PARAMS, (OSSL_FUNC)ml_kem_set_ctx_params },
{ OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, (OSSL_FUNC)ml_kem_settable_ctx_params },
+#ifdef FIPS_MODULE
+ { OSSL_FUNC_KEM_GET_CTX_PARAMS,
+ (OSSL_FUNC)ml_kem_get_ctx_params },
+ { OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS,
+ (OSSL_FUNC)ossl_FIPS_IND_gettable_ctx_params },
+#endif
OSSL_DISPATCH_END
};
diff --git a/deps/openssl/openssl/providers/implementations/kem/mlx_kem.c b/deps/openssl/openssl/providers/implementations/kem/mlx_kem.c
index a917fa93d5c..fd4b400f172 100644
--- a/deps/openssl/openssl/providers/implementations/kem/mlx_kem.c
+++ b/deps/openssl/openssl/providers/implementations/kem/mlx_kem.c
@@ -12,6 +12,7 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
+#include <openssl/obj_mac.h>
#include <openssl/params.h>
#include <openssl/proverr.h>
#include <openssl/rand.h>
@@ -19,6 +20,7 @@
#include "prov/mlx_kem.h"
#include "prov/provider_ctx.h"
#include "prov/providercommon.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_kem_newctx_fn mlx_kem_newctx;
static OSSL_FUNC_kem_freectx_fn mlx_kem_freectx;
@@ -103,6 +105,25 @@ mlx_kem_set_ctx_params(void *vctx, const OSSL_PARAM params[])
return 1;
}
+#ifdef FIPS_MODULE
+static int mlx_kem_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ PROV_MLX_KEM_CTX *ctx = vctx;
+ OSSL_PARAM *p;
+ int approved;
+
+ if (ctx == NULL || ctx->key == NULL || ctx->key->xinfo == NULL)
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_KEM_PARAM_FIPS_APPROVED_INDICATOR);
+ if (p != NULL) {
+ approved = strcmp(ctx->key->xinfo->algorithm_name, SN_X448) != 0;
+ if (!OSSL_PARAM_set_int(p, approved))
+ return 0;
+ }
+ return 1;
+}
+#endif
+
static int mlx_kem_encapsulate(void *vctx, unsigned char *ctext, size_t *clen,
unsigned char *shsec, size_t *slen)
{
@@ -346,5 +367,10 @@ const OSSL_DISPATCH ossl_mlx_kem_asym_kem_functions[] = {
{ OSSL_FUNC_KEM_FREECTX, (OSSL_FUNC)mlx_kem_freectx },
{ OSSL_FUNC_KEM_SET_CTX_PARAMS, (OSSL_FUNC)mlx_kem_set_ctx_params },
{ OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, (OSSL_FUNC)mlx_kem_settable_ctx_params },
+#ifdef FIPS_MODULE
+ { OSSL_FUNC_KEM_GET_CTX_PARAMS, (OSSL_FUNC)mlx_kem_get_ctx_params },
+ { OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS,
+ (OSSL_FUNC)ossl_FIPS_IND_gettable_ctx_params },
+#endif
OSSL_DISPATCH_END
};
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/dh_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/dh_kmgmt.c
index eac99a4fed0..54c31e2e864 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/dh_kmgmt.c
@@ -26,6 +26,7 @@
#include "crypto/dh.h"
#include "internal/fips.h"
#include "internal/sizes.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_keymgmt_new_fn dh_newdata;
static OSSL_FUNC_keymgmt_free_fn dh_freedata;
@@ -868,7 +869,9 @@ const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export },
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types },
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup },
- OSSL_DISPATCH_END
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS,
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS)
+ OSSL_DISPATCH_END
};
/* For any DH key, we use the "DH" algorithms regardless of sub-type. */
@@ -902,5 +905,7 @@ const OSSL_DISPATCH ossl_dhx_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))dhx_query_operation_name },
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup },
- OSSL_DISPATCH_END
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS,
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS)
+ OSSL_DISPATCH_END
};
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/ecx_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/ecx_kmgmt.c
index 42a0b9d7aa6..001777c616d 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -26,6 +26,7 @@
#include "prov/provider_ctx.h"
#include "prov/ecx.h"
#include "prov/securitycheck.h"
+#include "fips/fipsindicator.h"
#ifdef S390X_EC_ASM
#include "s390x_arch.h"
#include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */
@@ -103,6 +104,19 @@ static ossl_inline int ecx_key_type_is_ed(ECX_KEY_TYPE type)
return type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448;
}
+#ifdef FIPS_MODULE
+static int ecx_gen_get_params(void *genctx, OSSL_PARAM params[])
+{
+ struct ecx_gen_ctx *gctx = genctx;
+ OSSL_PARAM *p;
+
+ if (gctx == NULL)
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR);
+ return p == NULL || OSSL_PARAM_set_int(p, ecx_key_type_is_ed(gctx->type));
+}
+#endif
+
static void *x25519_new_key(void *provctx)
{
if (!ossl_prov_is_running())
@@ -1034,7 +1048,9 @@ static void ecx_free_key(void *keydata)
{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
{ OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \
- OSSL_DISPATCH_END \
+ OSSL_FIPS_IND_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, \
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS, ecx_gen_get_params) \
+ OSSL_DISPATCH_END \
};
MAKE_KEYMGMT_FUNCTIONS(x25519)
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/mac_legacy_kmgmt.c
index e53e9dcd9b2..19a648fd9cd 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/mac_legacy_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/mac_legacy_kmgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2026 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
@@ -26,6 +26,7 @@
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "prov/macsignature.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_keymgmt_new_fn mac_new;
static OSSL_FUNC_keymgmt_free_fn mac_free;
@@ -543,7 +544,9 @@ const OSSL_DISPATCH ossl_mac_legacy_keymgmt_functions[] = {
(void (*)(void))mac_gen_settable_params },
{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },
{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },
- OSSL_DISPATCH_END
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS,
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS)
+ OSSL_DISPATCH_END
};
const OSSL_DISPATCH ossl_cmac_legacy_keymgmt_functions[] = {
@@ -565,5 +568,7 @@ const OSSL_DISPATCH ossl_cmac_legacy_keymgmt_functions[] = {
(void (*)(void))cmac_gen_settable_params },
{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen },
{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup },
- OSSL_DISPATCH_END
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS,
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS)
+ OSSL_DISPATCH_END
};
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/ml_dsa_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/ml_dsa_kmgmt.c
index 70e943ff5a0..283b789cb66 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/ml_dsa_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/ml_dsa_kmgmt.c
@@ -20,6 +20,7 @@
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "prov/ml_dsa.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_keymgmt_free_fn ml_dsa_free_key;
static OSSL_FUNC_keymgmt_has_fn ml_dsa_has;
@@ -581,7 +582,9 @@ static void ml_dsa_gen_cleanup(void *genctx)
{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
(void (*)(void))ml_dsa_gen_settable_params }, \
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ml_dsa_dup_key }, \
- OSSL_DISPATCH_END \
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, \
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS) \
+ OSSL_DISPATCH_END \
}
MAKE_KEYMGMT_FUNCTIONS(44);
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/ml_kem_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/ml_kem_kmgmt.c
index 1422a3775c7..5029f1faee0 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/ml_kem_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/ml_kem_kmgmt.c
@@ -24,6 +24,7 @@
#include "prov/provider_ctx.h"
#include "prov/securitycheck.h"
#include "prov/ml_kem.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_keymgmt_new_fn ml_kem_512_new;
static OSSL_FUNC_keymgmt_new_fn ml_kem_768_new;
@@ -865,7 +866,9 @@ static void ml_kem_free_key(void *keydata)
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (OSSL_FUNC)ml_kem_imexport_types }, \
{ OSSL_FUNC_KEYMGMT_EXPORT, (OSSL_FUNC)ml_kem_export }, \
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (OSSL_FUNC)ml_kem_imexport_types }, \
- OSSL_DISPATCH_END \
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, \
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS) \
+ OSSL_DISPATCH_END \
}
DECLARE_VARIANT(512);
DECLARE_VARIANT(768);
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/mlx_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/mlx_kmgmt.c
index 75267f88e76..a36caff871c 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/mlx_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/mlx_kmgmt.c
@@ -10,6 +10,7 @@
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
+#include <openssl/obj_mac.h>
#include <openssl/param_build.h>
#include <openssl/params.h>
#include <openssl/proverr.h>
@@ -22,6 +23,7 @@
#include "prov/provider_ctx.h"
#include "prov/providercommon.h"
#include "prov/securitycheck.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_keymgmt_gen_fn mlx_kem_gen;
static OSSL_FUNC_keymgmt_gen_cleanup_fn mlx_kem_gen_cleanup;
@@ -192,9 +194,8 @@ static int export_sub_cb(const OSSL_PARAM *params, void *varg)
return 0;
if (len != sub_arg->prvlen) {
ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR,
- "Unexpected %s private key length %lu != %lu",
- sub_arg->algorithm_name, (unsigned long)len,
- (unsigned long)sub_arg->publen);
+ "Unexpected %s private key length %zu != %zu",
+ sub_arg->algorithm_name, len, sub_arg->prvlen);
return 0;
}
++sub_arg->prvcount;
@@ -692,6 +693,27 @@ static const OSSL_PARAM *mlx_kem_gen_settable_params(ossl_unused void *vgctx,
return settable;
}
+#ifdef FIPS_MODULE
+static int mlx_kem_gen_get_params(void *vgctx, OSSL_PARAM params[])
+{
+ PROV_ML_KEM_GEN_CTX *gctx = vgctx;
+ OSSL_PARAM *p;
+ int approved;
+
+ if (gctx == NULL || gctx->evp_type >= OSSL_NELEM(hybrid_vtable))
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR);
+ if (p != NULL) {
+ approved = strcmp(hybrid_vtable[gctx->evp_type].algorithm_name,
+ SN_X448)
+ != 0;
+ if (!OSSL_PARAM_set_int(p, approved))
+ return 0;
+ }
+ return 1;
+}
+#endif
+
static void *mlx_kem_gen(void *vgctx, OSSL_CALLBACK *osslcb, void *cbarg)
{
PROV_ML_KEM_GEN_CTX *gctx = vgctx;
@@ -820,7 +842,9 @@ static void *mlx_kem_dup(const void *vkey, int selection)
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (OSSL_FUNC)mlx_kem_imexport_types }, \
{ OSSL_FUNC_KEYMGMT_EXPORT, (OSSL_FUNC)mlx_kem_export }, \
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (OSSL_FUNC)mlx_kem_imexport_types }, \
- OSSL_DISPATCH_END \
+ OSSL_FIPS_IND_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, \
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS, mlx_kem_gen_get_params) \
+ OSSL_DISPATCH_END \
}
/* See |hybrid_vtable| above */
DECLARE_DISPATCH(p256, 0);
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/rsa_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/rsa_kmgmt.c
index 3582936d67f..d9f70149f44 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/rsa_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/rsa_kmgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -27,6 +27,7 @@
#include "crypto/cryptlib.h"
#include "internal/fips.h"
#include "internal/param_build_set.h"
+#include "fips/fipsindicator.h"
static OSSL_FUNC_keymgmt_new_fn rsa_newdata;
static OSSL_FUNC_keymgmt_new_fn rsapss_newdata;
@@ -35,6 +36,9 @@ static OSSL_FUNC_keymgmt_gen_init_fn rsapss_gen_init;
static OSSL_FUNC_keymgmt_gen_set_params_fn rsa_gen_set_params;
static OSSL_FUNC_keymgmt_gen_settable_params_fn rsa_gen_settable_params;
static OSSL_FUNC_keymgmt_gen_settable_params_fn rsapss_gen_settable_params;
+#ifdef FIPS_MODULE
+static OSSL_FUNC_keymgmt_gen_get_params_fn rsa_gen_get_params;
+#endif
static OSSL_FUNC_keymgmt_gen_fn rsa_gen;
static OSSL_FUNC_keymgmt_gen_cleanup_fn rsa_gen_cleanup;
static OSSL_FUNC_keymgmt_load_fn rsa_load;
@@ -568,6 +572,21 @@ static const OSSL_PARAM *rsapss_gen_settable_params(ossl_unused void *genctx,
return settable;
}
+#ifdef FIPS_MODULE
+static int rsa_gen_get_params(void *genctx, OSSL_PARAM params[])
+{
+ struct rsa_gen_ctx *gctx = genctx;
+ int approved = 1;
+
+ if (gctx == NULL)
+ return 0;
+#ifndef OPENSSL_NO_ACVP_TESTS
+ approved = gctx->acvp_test_params == NULL;
+#endif
+ return ossl_FIPS_IND_get_ctx_param_conditional(NULL, params, approved);
+}
+#endif
+
static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
{
struct rsa_gen_ctx *gctx = genctx;
@@ -709,7 +728,9 @@ const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export },
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types },
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup },
- OSSL_DISPATCH_END
+ OSSL_FIPS_IND_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS,
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS, rsa_gen_get_params)
+ OSSL_DISPATCH_END
};
const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = {
@@ -734,5 +755,7 @@ const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))rsa_query_operation_name },
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup },
- OSSL_DISPATCH_END
+ OSSL_FIPS_IND_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS,
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS, rsa_gen_get_params)
+ OSSL_DISPATCH_END
};
diff --git a/deps/openssl/openssl/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/deps/openssl/openssl/providers/implementations/keymgmt/slh_dsa_kmgmt.c
index 8799df6be6d..f35be004987 100644
--- a/deps/openssl/openssl/providers/implementations/keymgmt/slh_dsa_kmgmt.c
+++ b/deps/openssl/openssl/providers/implementations/keymgmt/slh_dsa_kmgmt.c
@@ -18,6 +18,7 @@
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
+#include "fips/fipsindicator.h"
#ifdef FIPS_MODULE
static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key,
@@ -469,7 +470,9 @@ static void slh_dsa_gen_cleanup(void *genctx)
(void (*)(void))slh_dsa_gen_set_params }, \
{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
(void (*)(void))slh_dsa_gen_settable_params }, \
- OSSL_DISPATCH_END \
+ OSSL_FIPS_IND_APPROVED_DISPATCH(OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, \
+ OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS) \
+ OSSL_DISPATCH_END \
}
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-128s", sha2_128s);
diff --git a/deps/openssl/openssl/providers/implementations/macs/gmac_prov.c b/deps/openssl/openssl/providers/implementations/macs/gmac_prov.c
index 36d089abfb9..926d5274130 100644
--- a/deps/openssl/openssl/providers/implementations/macs/gmac_prov.c
+++ b/deps/openssl/openssl/providers/implementations/macs/gmac_prov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2026 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,6 +19,7 @@
#include "prov/provider_ctx.h"
#include "prov/provider_util.h"
#include "prov/providercommon.h"
+#include "fips/fipsindicator.h"
/*
* Forward declaration of everything implemented here. This is not strictly
@@ -184,6 +185,30 @@ static int gmac_get_params(OSSL_PARAM params[])
return 1;
}
+#ifdef FIPS_MODULE
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *gmac_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+ return known_gettable_ctx_params;
+}
+
+static int gmac_get_ctx_params(void *ctx, OSSL_PARAM params[])
+{
+ OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE);
+ if (p != NULL && !OSSL_PARAM_set_size_t(p, gmac_size()))
+ return 0;
+ return ossl_FIPS_IND_get_ctx_param_approved(ctx, params);
+}
+#endif
+
static const OSSL_PARAM known_settable_ctx_params[] = {
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0),
@@ -253,6 +278,11 @@ const OSSL_DISPATCH ossl_gmac_functions[] = {
{ OSSL_FUNC_MAC_FINAL, (void (*)(void))gmac_final },
{ OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))gmac_gettable_params },
{ OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))gmac_get_params },
+#ifdef FIPS_MODULE
+ { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+ (void (*)(void))gmac_gettable_ctx_params },
+ { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))gmac_get_ctx_params },
+#endif
{ OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
(void (*)(void))gmac_settable_ctx_params },
{ OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))gmac_set_ctx_params },
diff --git a/deps/openssl/openssl/providers/implementations/rands/seed_src_jitter.c b/deps/openssl/openssl/providers/implementations/rands/seed_src_jitter.c
index fa6d931aceb..8df7fb5423f 100644
--- a/deps/openssl/openssl/providers/implementations/rands/seed_src_jitter.c
+++ b/deps/openssl/openssl/providers/implementations/rands/seed_src_jitter.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 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,6 +21,7 @@
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "prov/providercommon.h"
+#include "fips/fipsindicator.h"
#include "crypto/rand.h"
#include "crypto/rand_pool.h"
@@ -243,7 +244,7 @@ static int jitter_get_ctx_params(void *vseed, OSSL_PARAM params[])
p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
if (p != NULL && !OSSL_PARAM_set_size_t(p, 128))
return 0;
- return 1;
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(s, params);
}
static const OSSL_PARAM *jitter_gettable_ctx_params(ossl_unused void *vseed,
@@ -253,7 +254,8 @@ static const OSSL_PARAM *jitter_gettable_ctx_params(ossl_unused void *vseed,
OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),
OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
return known_gettable_ctx_params;
}
diff --git a/deps/openssl/openssl/providers/implementations/signature/ecdsa_sig.c b/deps/openssl/openssl/providers/implementations/signature/ecdsa_sig.c
index 3ce4cd0d2a8..3cbceed8a24 100644
--- a/deps/openssl/openssl/providers/implementations/signature/ecdsa_sig.c
+++ b/deps/openssl/openssl/providers/implementations/signature/ecdsa_sig.c
@@ -698,7 +698,8 @@ static int ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params)
return 0;
#endif
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+ if (!OSSL_FIPS_IND_GET_CTX_PARAM_CONDITIONAL(ctx, params,
+ ctx->verify_message))
return 0;
return 1;
}
diff --git a/deps/openssl/openssl/providers/implementations/signature/eddsa_sig.c b/deps/openssl/openssl/providers/implementations/signature/eddsa_sig.c
index d67f98e558b..6b99a04ed89 100644
--- a/deps/openssl/openssl/providers/implementations/signature/eddsa_sig.c
+++ b/deps/openssl/openssl/providers/implementations/signature/eddsa_sig.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2026 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,6 +22,7 @@
#include "prov/provider_ctx.h"
#include "prov/der_ecx.h"
#include "crypto/ecx.h"
+#include "fips/fipsindicator.h"
#ifdef S390X_EC_ASM
#include "s390x_arch.h"
@@ -806,14 +807,15 @@ static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
peddsactx->aid_len))
return 0;
- return 1;
+ return OSSL_FIPS_IND_GET_CTX_PARAM_APPROVED(peddsactx, params);
}
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
diff --git a/deps/openssl/openssl/providers/implementations/signature/mac_legacy_sig.c b/deps/openssl/openssl/providers/implementations/signature/mac_legacy_sig.c
index 1aa13a56927..8c5746113c6 100644
--- a/deps/openssl/openssl/providers/implementations/signature/mac_legacy_sig.c
+++ b/deps/openssl/openssl/providers/implementations/signature/mac_legacy_sig.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -10,6 +10,7 @@
/* We need to use some engine deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED
+#include <stdbool.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/core_dispatch.h>
@@ -24,6 +25,9 @@
#include "prov/provider_ctx.h"
#include "prov/macsignature.h"
#include "prov/providercommon.h"
+#include "prov/securitycheck.h"
+#include "internal/fips.h"
+#include "internal/common.h"
static OSSL_FUNC_signature_newctx_fn mac_hmac_newctx;
static OSSL_FUNC_signature_newctx_fn mac_siphash_newctx;
@@ -45,6 +49,10 @@ typedef struct {
char *propq;
MAC_KEY *key;
EVP_MAC_CTX *macctx;
+#ifdef FIPS_MODULE
+ bool hmac_keysize_check;
+ OSSL_FIPS_IND_DECLARE
+#endif
} PROV_MAC_CTX;
static void *mac_newctx(void *provctx, const char *propq, const char *macname)
@@ -72,7 +80,11 @@ static void *mac_newctx(void *provctx, const char *propq, const char *macname)
goto err;
EVP_MAC_free(mac);
-
+#ifdef FIPS_MODULE
+ pmacctx->hmac_keysize_check = (strcmp(macname, "HMAC") == 0);
+ /* Set FIPS indicator to approved */
+ OSSL_FIPS_IND_INIT(pmacctx)
+#endif
return pmacctx;
err:
@@ -93,6 +105,28 @@ MAC_NEWCTX(siphash, "SIPHASH")
MAC_NEWCTX(poly1305, "POLY1305")
MAC_NEWCTX(cmac, "CMAC")
+#ifdef FIPS_MODULE
+/*
+ * The fips indicator check is done at this level because HMAC will be created
+ * as an 'internal' sub-algorithm which will not perform the tests in hmac_prov.c
+ */
+static int hmac_check_key(PROV_MAC_CTX *macctx, const unsigned char *key,
+ size_t keylen)
+{
+ int approved = ossl_mac_check_key_size(keylen);
+
+ if (!approved) {
+ if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
+ macctx->libctx, "HMAC", "keysize",
+ ossl_fips_config_hmac_key_check)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
const OSSL_PARAM params[])
{
@@ -130,6 +164,12 @@ static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
NULL, 0))
return 0;
+#ifdef FIPS_MODULE
+ if (pmacctx->hmac_keysize_check
+ && !hmac_check_key(pmacctx, pmacctx->key->priv_key,
+ pmacctx->key->priv_key_len))
+ return 0;
+#endif
if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key,
pmacctx->key->priv_key_len, params))
return 0;
@@ -209,6 +249,21 @@ static int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[])
{
PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
+#ifdef FIPS_MODULE
+ if (ctx->hmac_keysize_check) {
+ const OSSL_PARAM *p;
+
+ if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0,
+ params, OSSL_MAC_PARAM_FIPS_KEY_CHECK))
+ return 0;
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
+ if (p->data_type != OSSL_PARAM_OCTET_STRING)
+ return 0;
+ if (!hmac_check_key(ctx, p->data, p->data_size))
+ return 0;
+ }
+ }
+#endif
return EVP_MAC_CTX_set_params(ctx->macctx, params);
}
@@ -229,6 +284,53 @@ static const OSSL_PARAM *mac_settable_ctx_params(ossl_unused void *ctx,
return params;
}
+static const OSSL_PARAM mac_known_gettable_ctx_params[] = {
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *mac_gettable_ctx_params(ossl_unused void *vctx,
+ ossl_unused void *provctx)
+{
+ return mac_known_gettable_ctx_params;
+}
+
+static int mac_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ PROV_MAC_CTX *ctx = vctx;
+#ifdef FIPS_MODULE
+ OSSL_PARAM *p;
+#endif
+
+ if (ctx == NULL)
+ return 0;
+
+#ifdef FIPS_MODULE
+ p = OSSL_PARAM_locate(params, OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR);
+ if (p != NULL) {
+ int approved = OSSL_FIPS_IND_GET(ctx)->approved;
+
+ /* Internal HMAC delegates its indicator checks to this wrapper. */
+ if (!ctx->hmac_keysize_check) {
+ int mac_approved = 0;
+ OSSL_PARAM mac_params[2];
+
+ mac_params[0] = OSSL_PARAM_construct_int(
+ OSSL_MAC_PARAM_FIPS_APPROVED_INDICATOR, &mac_approved);
+ mac_params[1] = OSSL_PARAM_construct_end();
+
+ if (!EVP_MAC_CTX_get_params(ctx->macctx, mac_params)
+ || !OSSL_PARAM_modified(mac_params))
+ return 0;
+ approved &= mac_approved;
+ }
+ if (!OSSL_PARAM_set_int(p, approved))
+ return 0;
+ }
+#endif
+ return 1;
+}
+
#define MAC_SETTABLE_CTX_PARAMS(funcname, macname) \
static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \
void *provctx) \
@@ -256,6 +358,10 @@ MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC")
(void (*)(void))mac_set_ctx_params }, \
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
(void (*)(void))mac_##funcname##_settable_ctx_params }, \
+ { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
+ (void (*)(void))mac_get_ctx_params }, \
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
+ (void (*)(void))mac_gettable_ctx_params }, \
OSSL_DISPATCH_END \
};
diff --git a/deps/openssl/openssl/providers/implementations/signature/ml_dsa_sig.c b/deps/openssl/openssl/providers/implementations/signature/ml_dsa_sig.c
index c7c21675beb..6033f149cb3 100644
--- a/deps/openssl/openssl/providers/implementations/signature/ml_dsa_sig.c
+++ b/deps/openssl/openssl/providers/implementations/signature/ml_dsa_sig.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 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,6 +22,7 @@
#include "crypto/ml_dsa.h"
#include "internal/packet.h"
#include "internal/sizes.h"
+#include "fips/fipsindicator.h"
#define ML_DSA_MESSAGE_ENCODE_RAW 0
#define ML_DSA_MESSAGE_ENCODE_PURE 1
@@ -301,7 +302,8 @@ static const OSSL_PARAM *ml_dsa_settable_ctx_params(void *vctx,
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
static const OSSL_PARAM *ml_dsa_gettable_ctx_params(ossl_unused void *vctx,
@@ -325,7 +327,13 @@ static int ml_dsa_get_ctx_params(void *vctx, OSSL_PARAM *params)
ctx->aid_len))
return 0;
+#ifdef FIPS_MODULE
+ return ossl_FIPS_IND_get_ctx_param_conditional(NULL, params,
+ ctx->test_entropy_len == 0
+ && ctx->msg_encode == ML_DSA_MESSAGE_ENCODE_PURE);
+#else
return 1;
+#endif
}
#define MAKE_SIGNATURE_FUNCTIONS(alg) \
diff --git a/deps/openssl/openssl/providers/implementations/signature/rsa_sig.c b/deps/openssl/openssl/providers/implementations/signature/rsa_sig.c
index 4980474ac03..e29a0656574 100644
--- a/deps/openssl/openssl/providers/implementations/signature/rsa_sig.c
+++ b/deps/openssl/openssl/providers/implementations/signature/rsa_sig.c
@@ -1508,7 +1508,8 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
return 0;
#endif
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(prsactx, params))
+ if (!OSSL_FIPS_IND_GET_CTX_PARAM_CONDITIONAL(prsactx, params,
+ prsactx->verify_message))
return 0;
return 1;
}
diff --git a/deps/openssl/openssl/providers/implementations/signature/slh_dsa_sig.c b/deps/openssl/openssl/providers/implementations/signature/slh_dsa_sig.c
index 6d43be32f4d..13f6f149d9e 100644
--- a/deps/openssl/openssl/providers/implementations/signature/slh_dsa_sig.c
+++ b/deps/openssl/openssl/providers/implementations/signature/slh_dsa_sig.c
@@ -17,6 +17,7 @@
#include "prov/der_slh_dsa.h"
#include "crypto/slh_dsa.h"
#include "internal/sizes.h"
+#include "fips/fipsindicator.h"
#define SLH_DSA_MAX_ADD_RANDOM_LEN 32
@@ -314,7 +315,8 @@ static const OSSL_PARAM *slh_dsa_settable_ctx_params(void *vctx,
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
- OSSL_PARAM_END
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
};
static const OSSL_PARAM *slh_dsa_gettable_ctx_params(ossl_unused void *vctx,
@@ -338,7 +340,12 @@ static int slh_dsa_get_ctx_params(void *vctx, OSSL_PARAM *params)
ctx->aid_len))
return 0;
+#ifdef FIPS_MODULE
+ return ossl_FIPS_IND_get_ctx_param_conditional(NULL, params,
+ ctx->add_random_len == 0);
+#else
return 1;
+#endif
}
#define MAKE_SIGNATURE_FUNCTIONS(alg, fn) \
diff --git a/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c b/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c
index f73c5fd5c83..e251f0ad2cc 100644
--- a/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c
+++ b/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c
@@ -570,7 +570,8 @@ static int file_load_file(struct file_ctx_st *ctx,
data.object_cb = object_cb;
data.object_cbarg = object_cbarg;
- OSSL_DECODER_CTX_set_construct_data(ctx->_.file.decoderctx, &data);
+ if (!OSSL_DECODER_CTX_set_construct_data(ctx->_.file.decoderctx, &data))
+ return 0;
OSSL_DECODER_CTX_set_passphrase_cb(ctx->_.file.decoderctx, pw_cb, pw_cbarg);
/* Launch */
diff --git a/deps/openssl/openssl/providers/implementations/storemgmt/winstore_store.c b/deps/openssl/openssl/providers/implementations/storemgmt/winstore_store.c
index 9da24b4f55c..1d6d1c57374 100644
--- a/deps/openssl/openssl/providers/implementations/storemgmt/winstore_store.c
+++ b/deps/openssl/openssl/providers/implementations/storemgmt/winstore_store.c
@@ -280,7 +280,8 @@ static int winstore_load_using(struct winstore_ctx_st *ctx,
data.object_cb = object_cb;
data.object_cbarg = object_cbarg;
- OSSL_DECODER_CTX_set_construct_data(ctx->dctx, &data);
+ if (!OSSL_DECODER_CTX_set_construct_data(ctx->dctx, &data))
+ return 0;
OSSL_DECODER_CTX_set_passphrase_cb(ctx->dctx, pw_cb, pw_cbarg);
if (OSSL_DECODER_from_data(ctx->dctx, &der_, &der_len_) == 0)
diff --git a/deps/openssl/openssl/providers/legacyprov.c b/deps/openssl/openssl/providers/legacyprov.c
index 63fb8e53ea4..eb782a12604 100644
--- a/deps/openssl/openssl/providers/legacyprov.c
+++ b/deps/openssl/openssl/providers/legacyprov.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2026 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
@@ -246,6 +246,10 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
}
#endif
+#ifndef STATIC_LEGACY
+ OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, NULL);
+#endif
+
if ((*provctx = ossl_prov_ctx_new()) == NULL
|| (libctx = OSSL_LIB_CTX_new_child(handle, in)) == NULL) {
OSSL_LIB_CTX_free(libctx);
diff --git a/deps/openssl/openssl/ssl/build.info b/deps/openssl/openssl/ssl/build.info
index 7f4ecaa68f5..515d5db5d40 100644
--- a/deps/openssl/openssl/ssl/build.info
+++ b/deps/openssl/openssl/ssl/build.info
@@ -21,7 +21,8 @@ SOURCE[../libssl]=\
# For shared builds we need to include the libcrypto packet.c and quic_vlint.c
# in libssl as well.
SHARED_SOURCE[../libssl]=\
- ../crypto/packet.c ../crypto/quic_vlint.c ../crypto/time.c
+ ../crypto/packet.c ../crypto/quic_vlint.c ../crypto/time.c \
+ ../crypto/rbtree/rbtree.c
IF[{- !$disabled{'deprecated-3.0'} -}]
SOURCE[../libssl]=ssl_rsa_legacy.c
diff --git a/deps/openssl/openssl/ssl/d1_lib.c b/deps/openssl/openssl/ssl/d1_lib.c
index ad1bc7d8c83..6dc4bae3c84 100644
--- a/deps/openssl/openssl/ssl/d1_lib.c
+++ b/deps/openssl/openssl/ssl/d1_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2026 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
@@ -406,6 +406,23 @@ int dtls1_handle_timeout(SSL_CONNECTION *s)
}
dtls1_start_timer(s);
+
+ /*
+ * If write_state is anything other than WRITE_STATE_TRANSITION, a write
+ * is still parked mid-flight (WANT_WRITE) from a previous call into the
+ * state machine - the current flight hasn't actually finished going out
+ * yet, so there's nothing valid to retransmit. Retransmitting anyway
+ * would reconstruct an already-sent message from the retransmit queue
+ * into s->init_buf/s->init_off/s->init_num/s->d1->w_msg - the same
+ * fields the parked write is still using - corrupting that write's
+ * state out from under it. Leave it alone and let the next
+ * SSL_read()/SSL_write()/SSL_accept()/SSL_connect() call resume the
+ * parked write normally instead.
+ */
+ if (s->statem.state == MSG_FLOW_WRITING
+ && s->statem.write_state != WRITE_STATE_TRANSITION)
+ return 0;
+
/* Calls SSLfatal() if required */
return dtls1_retransmit_buffered_messages(s);
}
diff --git a/deps/openssl/openssl/ssl/quic/build.info b/deps/openssl/openssl/ssl/quic/build.info
index 230341db762..c13c6dffbf6 100644
--- a/deps/openssl/openssl/ssl/quic/build.info
+++ b/deps/openssl/openssl/ssl/quic/build.info
@@ -10,7 +10,7 @@ IF[{- !$disabled{quic} -}]
SOURCE[$LIBSSL]=quic_fc.c uint_set.c
SOURCE[$LIBSSL]=quic_cfq.c quic_txpim.c quic_fifd.c quic_txp.c
SOURCE[$LIBSSL]=quic_stream_map.c
- SOURCE[$LIBSSL]=quic_sf_list.c quic_rstream.c quic_sstream.c
+ SOURCE[$LIBSSL]=quic_strm_reas.c quic_rstream.c quic_sstream.c
SOURCE[$LIBSSL]=quic_reactor.c
SOURCE[$LIBSSL]=quic_reactor_wait_ctx.c
SOURCE[$LIBSSL]=quic_channel.c quic_port.c quic_engine.c
diff --git a/deps/openssl/openssl/ssl/quic/quic_channel.c b/deps/openssl/openssl/ssl/quic/quic_channel.c
index 9534cbcaf7f..2427db85e92 100644
--- a/deps/openssl/openssl/ssl/quic/quic_channel.c
+++ b/deps/openssl/openssl/ssl/quic/quic_channel.c
@@ -101,6 +101,11 @@ static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state);
DEFINE_LHASH_OF_EX(QUIC_SRT_ELEM);
+typedef struct cfq_data_retire_cid {
+ uint64_t rtcid_seq;
+ QUIC_CHANNEL *rtcid_ch;
+} CFQ_DATA_RETIRE_CID_T;
+
QUIC_NEEDS_LOCK
static QLOG *ch_get_qlog(QUIC_CHANNEL *ch)
{
@@ -332,8 +337,12 @@ static int ch_init(QUIC_CHANNEL *ch)
goto err;
}
+ ch->rsqp = ossl_quic_rstream_qparm_new(ch);
+ if (ch->rsqp == NULL)
+ goto err;
+
for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) {
- ch->crypto_recv[pn_space] = ossl_quic_rstream_new(NULL, NULL, 0);
+ ch->crypto_recv[pn_space] = ossl_quic_rstream_new(NULL, NULL, ch->rsqp);
if (ch->crypto_recv[pn_space] == NULL)
goto err;
}
@@ -395,8 +404,12 @@ static void ch_cleanup(QUIC_CHANNEL *ch)
++pn_space)
ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space);
- ossl_quic_lcidm_cull(ch->lcidm, ch);
- ossl_quic_srtm_cull(ch->srtm, ch);
+ if (ch->lcidm != NULL)
+ ossl_quic_lcidm_cull(ch->lcidm, ch);
+
+ if (ch->srtm != NULL)
+ ossl_quic_srtm_cull(ch->srtm, ch);
+
ossl_quic_tx_packetiser_free(ch->txp);
ossl_quic_txpim_free(ch->txpim);
ossl_quic_cfq_free(ch->cfq);
@@ -415,6 +428,9 @@ static void ch_cleanup(QUIC_CHANNEL *ch)
ossl_quic_rstream_free(ch->crypto_recv[pn_space]);
}
+ ossl_quic_rstream_qparm_destroy(ch->rsqp);
+ ch->rsqp = NULL;
+
ossl_qrx_pkt_release(ch->qrx_pkt);
ch->qrx_pkt = NULL;
@@ -3230,19 +3246,33 @@ void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch,
ch_start_terminating(ch, &tcause, 0);
}
-static void free_frame_data(unsigned char *buf, size_t buf_len, void *arg)
+static void free_frame_rtcid(unsigned char *buf, size_t buf_len, void *arg)
{
+ CFQ_DATA_RETIRE_CID_T *cfq_data_rtcid = (CFQ_DATA_RETIRE_CID_T *)arg;
+ QUIC_CHANNEL *ch = cfq_data_rtcid->rtcid_ch;
+
+ if (ch->cur_retire_prior_to < cfq_data_rtcid->rtcid_seq)
+ ch->cur_retire_prior_to = cfq_data_rtcid->rtcid_seq;
+
OPENSSL_free(buf);
+ OPENSSL_free(cfq_data_rtcid);
}
static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num)
{
+ CFQ_DATA_RETIRE_CID_T *cfq_data_rtcid = NULL;
BUF_MEM *buf_mem = NULL;
WPACKET wpkt;
size_t l;
ossl_quic_srtm_remove(ch->srtm, ch, seq_num);
+ cfq_data_rtcid = OPENSSL_malloc(sizeof(CFQ_DATA_RETIRE_CID_T));
+ if (cfq_data_rtcid == NULL)
+ goto err;
+ cfq_data_rtcid->rtcid_seq = seq_num;
+ cfq_data_rtcid->rtcid_ch = ch;
+
if ((buf_mem = BUF_MEM_new()) == NULL)
goto err;
@@ -3261,7 +3291,7 @@ static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num)
if (ossl_quic_cfq_add_frame(ch->cfq, 1, QUIC_PN_SPACE_APP,
OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, 0,
(unsigned char *)buf_mem->data, l,
- free_frame_data, NULL)
+ free_frame_rtcid, cfq_data_rtcid)
== NULL)
goto err;
@@ -3275,6 +3305,7 @@ err:
OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,
"internal error enqueueing retire conn id");
BUF_MEM_free(buf_mem);
+ OPENSSL_free(cfq_data_rtcid);
return 0;
}
@@ -3283,6 +3314,7 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,
{
uint64_t new_remote_seq_num = ch->cur_remote_seq_num;
uint64_t new_retire_prior_to = ch->cur_retire_prior_to;
+ uint64_t retire_prior_to;
if (!ossl_quic_channel_is_active(ch))
return;
@@ -3381,10 +3413,10 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,
* that NEW_CONNECTION_ID frame, by definition this will always be met.
* This may change in future when we change our CID handling.
*/
- while (new_retire_prior_to > ch->cur_retire_prior_to) {
- if (!ch_enqueue_retire_conn_id(ch, ch->cur_retire_prior_to))
- break;
- ++ch->cur_retire_prior_to;
+ retire_prior_to = ch->cur_retire_prior_to;
+ while (new_retire_prior_to > retire_prior_to) {
+ ch_enqueue_retire_conn_id(ch, retire_prior_to);
+ retire_prior_to++;
}
}
@@ -3753,7 +3785,7 @@ static int ch_init_new_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs,
goto err;
if (can_recv)
- if ((qs->rstream = ossl_quic_rstream_new(NULL, NULL, 0)) == NULL)
+ if ((qs->rstream = ossl_quic_rstream_new(NULL, NULL, ch->rsqp)) == NULL)
goto err;
/* TXFC */
@@ -3938,6 +3970,8 @@ void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch,
void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs)
{
+ OSSL_RTT_INFO rtt_info;
+
ossl_quic_stream_map_stop_sending_recv_part(&ch->qsm, qs,
ch->incoming_stream_auto_reject_aec);
@@ -3945,6 +3979,15 @@ void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs)
ch->incoming_stream_auto_reject_aec);
qs->deleted = 1;
+ /*
+ * A rejected stream is never placed on the accept queue, so it would
+ * otherwise never be retired and would consume the peer's stream credit
+ * for the lifetime of the connection.
+ */
+ ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ch), &rtt_info);
+ ossl_quic_stream_map_retire_stream_credit(&ch->qsm, qs,
+ rtt_info.smoothed_rtt);
+
ossl_quic_stream_map_update_state(&ch->qsm, qs);
}
diff --git a/deps/openssl/openssl/ssl/quic/quic_channel_local.h b/deps/openssl/openssl/ssl/quic/quic_channel_local.h
index eb082d6cea7..385dbfb2c40 100644
--- a/deps/openssl/openssl/ssl/quic/quic_channel_local.h
+++ b/deps/openssl/openssl/ssl/quic/quic_channel_local.h
@@ -501,6 +501,12 @@ struct quic_channel_st {
/* Title for qlog purposes. We own this copy. */
char *qlog_title;
+
+ /*
+ * RX stream quality parameter.
+ */
+ QUIC_RSTREAM_QPARM *rsqp;
+
/*
* number of path responses waiting to be dispatched
* from control frame queue (CFQ)
diff --git a/deps/openssl/openssl/ssl/quic/quic_engine.c b/deps/openssl/openssl/ssl/quic/quic_engine.c
index 370b9c3987f..135417b3a7f 100644
--- a/deps/openssl/openssl/ssl/quic/quic_engine.c
+++ b/deps/openssl/openssl/ssl/quic/quic_engine.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2026 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
@@ -136,8 +136,8 @@ void ossl_quic_engine_update_poll_descriptors(QUIC_ENGINE *qeng, int force)
* the engine level in future when we can have multiple ports. This is not
* important currently as the port list has a single entry.
*/
- OSSL_LIST_FOREACH(port, port, &qeng->port_list)
- ossl_quic_port_update_poll_descriptors(port, force);
+ OSSL_LIST_FOREACH (port, port, &qeng->port_list)
+ ossl_quic_port_update_poll_descriptors(port, force);
}
/*
@@ -185,8 +185,7 @@ static void qeng_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags)
return;
/* Iterate through all ports and service them. */
- OSSL_LIST_FOREACH(port, port, &qeng->port_list)
- {
+ OSSL_LIST_FOREACH (port, port, &qeng->port_list) {
QUIC_TICK_RESULT subr = { 0 };
ossl_quic_port_subtick(port, &subr, flags);
diff --git a/deps/openssl/openssl/ssl/quic/quic_fc.c b/deps/openssl/openssl/ssl/quic/quic_fc.c
index 1691d4d69ef..9ff79c0bad9 100644
--- a/deps/openssl/openssl/ssl/quic/quic_fc.c
+++ b/deps/openssl/openssl/ssl/quic/quic_fc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 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
@@ -393,8 +393,17 @@ int ossl_quic_rxfc_get_error(QUIC_RXFC *rxfc, int clear)
{
int r = rxfc->error_code;
- if (clear)
+ if (r == OSSL_QUIC_ERR_NO_ERROR && rxfc->parent != NULL)
+ r = rxfc->parent->error_code;
+
+ /*
+ * The clear argument is used for testing only.
+ */
+ if (clear) {
rxfc->error_code = 0;
+ if (rxfc->parent != NULL)
+ rxfc->parent->error_code = 0;
+ }
return r;
}
diff --git a/deps/openssl/openssl/ssl/quic/quic_fifd.c b/deps/openssl/openssl/ssl/quic/quic_fifd.c
index 8daaa472200..0d99a8748a7 100644
--- a/deps/openssl/openssl/ssl/quic/quic_fifd.c
+++ b/deps/openssl/openssl/ssl/quic/quic_fifd.c
@@ -78,17 +78,21 @@ static void on_acked(void *arg)
sstream = fifd->get_sstream_by_id(chunks[i].stream_id,
pkt->ackm_pkt.pkt_space,
fifd->get_sstream_by_id_arg);
- if (sstream == NULL)
- continue;
- if (chunks[i].end >= chunks[i].start)
- /* coverity[check_return]: Best effort - we cannot fail here. */
- ossl_quic_sstream_mark_acked(sstream,
- chunks[i].start, chunks[i].end);
+ if (sstream != NULL) {
+ if (chunks[i].end >= chunks[i].start)
+ /* coverity[check_return]: Best effort - we cannot fail here. */
+ ossl_quic_sstream_mark_acked(sstream,
+ chunks[i].start, chunks[i].end);
- if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX)
- ossl_quic_sstream_mark_acked_fin(sstream);
+ if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX)
+ ossl_quic_sstream_mark_acked_fin(sstream);
+ }
+ /*
+ * Resetting the send part frees the send stream, so these must be
+ * confirmed even when it is already gone.
+ */
if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX)
fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
chunks[i].stream_id, pkt,
@@ -99,7 +103,7 @@ static void on_acked(void *arg)
chunks[i].stream_id, pkt,
fifd->confirm_frame_arg);
- if (ossl_quic_sstream_is_totally_acked(sstream))
+ if (sstream != NULL && ossl_quic_sstream_is_totally_acked(sstream))
fifd->sstream_updated(chunks[i].stream_id, fifd->sstream_updated_arg);
}
diff --git a/deps/openssl/openssl/ssl/quic/quic_port.c b/deps/openssl/openssl/ssl/quic/quic_port.c
index aad9c3a5b3d..77e28c63fb0 100644
--- a/deps/openssl/openssl/ssl/quic/quic_port.c
+++ b/deps/openssl/openssl/ssl/quic/quic_port.c
@@ -439,8 +439,8 @@ int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio)
if (!port_update_poll_desc(port, net_wbio, /*for_write=*/1))
return 0;
- OSSL_LIST_FOREACH(ch, ch, &port->channel_list)
- ossl_qtx_set_bio(ch->qtx, net_wbio);
+ OSSL_LIST_FOREACH (ch, ch, &port->channel_list)
+ ossl_qtx_set_bio(ch->qtx, net_wbio);
port->net_wbio = net_wbio;
port_update_addressing_mode(port);
@@ -680,8 +680,7 @@ void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *res,
port_rx_pre(port);
/* Iterate through all channels and service them. */
- OSSL_LIST_FOREACH(ch, ch, &port->channel_list)
- {
+ OSSL_LIST_FOREACH (ch, ch, &port->channel_list) {
QUIC_TICK_RESULT subr = { 0 };
ossl_quic_channel_subtick(ch, &subr, flags);
@@ -1122,7 +1121,7 @@ static void port_send_retry(QUIC_PORT *port,
*/
unsigned char buffer[512];
unsigned char ct_buf[ENCRYPTED_TOKEN_MAX_LEN];
- WPACKET wpkt;
+ WPACKET wpkt = { 0 };
size_t written, token_buf_len, ct_len;
QUIC_PKT_HDR hdr = { 0 };
QUIC_VALIDATION_TOKEN token = { 0 };
@@ -1208,6 +1207,7 @@ static void port_send_retry(QUIC_PORT *port,
"port retry send failed due to network BIO I/O error");
err:
+ WPACKET_cleanup(&wpkt);
cleanup_validation_token(&token);
}
@@ -1274,21 +1274,21 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer,
if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, client_hdr->dst_conn_id.id_len,
&hdr, NULL))
- return;
+ goto err;
/*
* Add the array of supported versions to the end of the packet
*/
for (i = 0; i < OSSL_NELEM(supported_versions); i++) {
if (!WPACKET_put_bytes_u32(&wpkt, supported_versions[i]))
- return;
+ goto err;
}
if (!WPACKET_get_total_written(&wpkt, &msg[0].data_len))
- return;
+ goto err;
if (!WPACKET_finish(&wpkt))
- return;
+ goto err;
/*
* Send it back to the client attempting to connect
@@ -1298,6 +1298,10 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer,
if (!BIO_sendmmsg(port->net_wbio, msg, sizeof(BIO_MSG), 1, 0, &written))
ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR,
"port version negotiation send failed");
+ return;
+err:
+ WPACKET_cleanup(&wpkt);
+ return;
}
/**
@@ -1510,6 +1514,7 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg,
&& ossl_quic_lcidm_lookup(port->lcidm, dcid, NULL,
(void **)&ch)) {
assert(ch != NULL);
+ ossl_quic_tx_packetiser_add_unvalidated_credit(ch->txp, e->data_len);
ossl_quic_channel_inject(ch, e);
return;
}
@@ -1721,6 +1726,7 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg,
* Time to reinject packets from qrx to channel before
* qrx will be destroyed here.
*/
+ ossl_quic_tx_packetiser_add_unvalidated_credit(new_ch->txp, e->data_len);
while (ossl_qrx_read_pkt(qrx_src, &qrx_pkt) == 1)
ossl_quic_channel_inject_pkt(new_ch, qrx_pkt);
ossl_qrx_update_pn_space(qrx_src, new_ch->qrx);
@@ -1772,9 +1778,9 @@ void ossl_quic_port_raise_net_error(QUIC_PORT *port,
if (triggering_ch != NULL)
ossl_quic_channel_raise_net_error(triggering_ch);
- OSSL_LIST_FOREACH(ch, ch, &port->channel_list)
- if (ch != triggering_ch)
- ossl_quic_channel_raise_net_error(ch);
+ OSSL_LIST_FOREACH (ch, ch, &port->channel_list)
+ if (ch != triggering_ch)
+ ossl_quic_channel_raise_net_error(ch);
}
void ossl_quic_port_restore_err_state(const QUIC_PORT *port)
diff --git a/deps/openssl/openssl/ssl/quic/quic_rcidm.c b/deps/openssl/openssl/ssl/quic/quic_rcidm.c
index 0d5cb0337b2..9fd125f8024 100644
--- a/deps/openssl/openssl/ssl/quic/quic_rcidm.c
+++ b/deps/openssl/openssl/ssl/quic/quic_rcidm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2026 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
@@ -191,7 +191,7 @@ struct quic_rcidm_st {
uint64_t retire_prior_to;
/* (SORT BY seq_num ASC) -> (RCID *) */
- PRIORITY_QUEUE_OF(RCID) * rcids;
+ PRIORITY_QUEUE_OF(RCID) *rcids;
/*
* Current RCID object we are using. This may differ from the first item in
@@ -311,8 +311,8 @@ void ossl_quic_rcidm_free(QUIC_RCIDM *rcidm)
while ((rcid = ossl_pqueue_RCID_pop(rcidm->rcids)) != NULL)
OPENSSL_free(rcid);
- OSSL_LIST_FOREACH_DELSAFE(rcid, rnext, retiring, &rcidm->retiring_list)
- OPENSSL_free(rcid);
+ OSSL_LIST_FOREACH_DELSAFE (rcid, rnext, retiring, &rcidm->retiring_list)
+ OPENSSL_free(rcid);
ossl_pqueue_RCID_free(rcidm->rcids);
OPENSSL_free(rcidm);
diff --git a/deps/openssl/openssl/ssl/quic/quic_reactor_wait_ctx.c b/deps/openssl/openssl/ssl/quic/quic_reactor_wait_ctx.c
index ae3b7cb3efe..f84a7b82f66 100644
--- a/deps/openssl/openssl/ssl/quic/quic_reactor_wait_ctx.c
+++ b/deps/openssl/openssl/ssl/quic/quic_reactor_wait_ctx.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2024-2026 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
@@ -45,9 +45,9 @@ int ossl_quic_reactor_wait_ctx_enter(QUIC_REACTOR_WAIT_CTX *ctx,
{
QUIC_REACTOR_WAIT_SLOT *slot;
- OSSL_LIST_FOREACH(slot, quic_reactor_wait_slot, &ctx->slots)
- if (slot->rtor == rtor)
- break;
+ OSSL_LIST_FOREACH (slot, quic_reactor_wait_slot, &ctx->slots)
+ if (slot->rtor == rtor)
+ break;
if (slot == NULL) {
if ((slot = OPENSSL_zalloc(sizeof(QUIC_REACTOR_WAIT_SLOT))) == NULL)
@@ -66,9 +66,9 @@ void ossl_quic_reactor_wait_ctx_leave(QUIC_REACTOR_WAIT_CTX *ctx,
{
QUIC_REACTOR_WAIT_SLOT *slot;
- OSSL_LIST_FOREACH(slot, quic_reactor_wait_slot, &ctx->slots)
- if (slot->rtor == rtor)
- break;
+ OSSL_LIST_FOREACH (slot, quic_reactor_wait_slot, &ctx->slots)
+ if (slot->rtor == rtor)
+ break;
assert(slot != NULL);
slot_deactivate(slot);
@@ -78,8 +78,7 @@ void ossl_quic_reactor_wait_ctx_cleanup(QUIC_REACTOR_WAIT_CTX *ctx)
{
QUIC_REACTOR_WAIT_SLOT *slot, *nslot;
- OSSL_LIST_FOREACH_DELSAFE(slot, nslot, quic_reactor_wait_slot, &ctx->slots)
- {
+ OSSL_LIST_FOREACH_DELSAFE (slot, nslot, quic_reactor_wait_slot, &ctx->slots) {
assert(slot->blocking_count == 0);
OPENSSL_free(slot);
}
diff --git a/deps/openssl/openssl/ssl/quic/quic_record_rx.c b/deps/openssl/openssl/ssl/quic/quic_record_rx.c
index 0065f1c1e57..1f0b9b5c58e 100644
--- a/deps/openssl/openssl/ssl/quic/quic_record_rx.c
+++ b/deps/openssl/openssl/ssl/quic/quic_record_rx.c
@@ -10,6 +10,7 @@
#include <openssl/ssl.h>
#include "internal/quic_record_rx.h"
#include "quic_record_shared.h"
+#include "quic_record_rx_local.h"
#include "internal/common.h"
#include "internal/list.h"
#include "../ssl_local.h"
@@ -32,61 +33,6 @@ static ossl_inline int pkt_is_marked(const uint64_t *bitf, size_t pkt_idx)
return (*bitf & (((uint64_t)1) << pkt_idx)) != 0;
}
-/*
- * RXE
- * ===
- *
- * RX Entries (RXEs) store processed (i.e., decrypted) data received from the
- * network. One RXE is used per received QUIC packet.
- */
-typedef struct rxe_st RXE;
-
-struct rxe_st {
- OSSL_QRX_PKT pkt;
- OSSL_LIST_MEMBER(rxe, RXE);
- size_t data_len, alloc_len, refcount;
-
- /* Extra fields for per-packet information. */
- QUIC_PKT_HDR hdr; /* data/len are decrypted payload */
-
- /* Decoded packet number. */
- QUIC_PN pn;
-
- /* Addresses copied from URXE. */
- BIO_ADDR peer, local;
-
- /* Time we received the packet (not when we processed it). */
- OSSL_TIME time;
-
- /* Total length of the datagram which contained this packet. */
- size_t datagram_len;
-
- /*
- * The key epoch the packet was received with. Always 0 for non-1-RTT
- * packets.
- */
- uint64_t key_epoch;
-
- /*
- * Monotonically increases with each datagram received.
- * For diagnostic use only.
- */
- uint64_t datagram_id;
-
- /*
- * alloc_len allocated bytes (of which data_len bytes are valid) follow this
- * structure.
- */
-};
-
-DEFINE_LIST_OF(rxe, RXE);
-typedef OSSL_LIST(rxe) RXE_LIST;
-
-static ossl_inline unsigned char *rxe_data(const RXE *e)
-{
- return (unsigned char *)(e + 1);
-}
-
/*
* QRL
* ===
@@ -1048,6 +994,7 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe,
uint32_t pn_space, enc_level;
OSSL_QRL_ENC_LEVEL *el = NULL;
uint64_t rx_key_epoch = UINT64_MAX;
+ const unsigned char *token = NULL;
/*
* Get a free RXE. If we need to allocate a new one, use the packet length
@@ -1181,7 +1128,7 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe,
* Relocate token buffer and fix pointer.
*/
if (rxe->hdr.type == QUIC_PKT_TYPE_INITIAL) {
- const unsigned char *token = rxe->hdr.token;
+ token = rxe->hdr.token;
/*
* This may change the value of rxe and change the value of the token
@@ -1215,6 +1162,12 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe,
0, 0, &rxe->hdr, NULL, NULL)
!= 1)
goto malformed;
+ /*
+ * Restore the relocated token value here, since the above decode reset it
+ * to be within the packet
+ */
+ if (token != NULL)
+ rxe->hdr.token = token;
}
/* Validate header and decode PN. */
diff --git a/deps/openssl/openssl/ssl/quic/quic_record_rx_local.h b/deps/openssl/openssl/ssl/quic/quic_record_rx_local.h
new file mode 100644
index 00000000000..4a2fd8c0e1b
--- /dev/null
+++ b/deps/openssl/openssl/ssl/quic/quic_record_rx_local.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_QUIC_RECORD_RX_LOCAL_H
+#define OSSL_QUIC_RECORD_RX_LOCAL_H
+
+#include "internal/quic_record_rx.h"
+#include "internal/list.h"
+
+#ifndef OPENSSL_NO_QUIC
+
+/*
+ * RXE
+ * ===
+ *
+ * RX Entries (RXEs) store processed (i.e., decrypted) data received from the
+ * network. One RXE is used per received QUIC packet.
+ *
+ * The OSSL_QRX_PKT handed out to users of the QRX is the first member, so a
+ * packet pointer can be cast back to its RXE. It is intended that only the
+ * QRX implementation access this structure directly, tests which need to
+ * construct a packet without a QRX being the exception.
+ */
+typedef struct rxe_st RXE;
+
+struct rxe_st {
+ OSSL_QRX_PKT pkt;
+ OSSL_LIST_MEMBER(rxe, RXE);
+ size_t data_len, alloc_len, refcount;
+
+ /* Extra fields for per-packet information. */
+ QUIC_PKT_HDR hdr; /* data/len are decrypted payload */
+
+ /* Decoded packet number. */
+ QUIC_PN pn;
+
+ /* Addresses copied from URXE. */
+ BIO_ADDR peer, local;
+
+ /* Time we received the packet (not when we processed it). */
+ OSSL_TIME time;
+
+ /* Total length of the datagram which contained this packet. */
+ size_t datagram_len;
+
+ /*
+ * The key epoch the packet was received with. Always 0 for non-1-RTT
+ * packets.
+ */
+ uint64_t key_epoch;
+
+ /*
+ * Monotonically increases with each datagram received.
+ * For diagnostic use only.
+ */
+ uint64_t datagram_id;
+
+ /*
+ * alloc_len allocated bytes (of which data_len bytes are valid) follow this
+ * structure.
+ */
+};
+
+DEFINE_LIST_OF(rxe, RXE);
+typedef OSSL_LIST(rxe) RXE_LIST;
+
+static ossl_inline unsigned char *rxe_data(const RXE *e)
+{
+ return (unsigned char *)(e + 1);
+}
+
+#endif
+
+#endif
diff --git a/deps/openssl/openssl/ssl/quic/quic_rstream.c b/deps/openssl/openssl/ssl/quic/quic_rstream.c
index 2fe1cb2cdbe..0fdceb65009 100644
--- a/deps/openssl/openssl/ssl/quic/quic_rstream.c
+++ b/deps/openssl/openssl/ssl/quic/quic_rstream.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 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
@@ -10,32 +10,33 @@
#include "internal/common.h"
#include "internal/time.h"
#include "internal/quic_stream.h"
-#include "internal/quic_sf_list.h"
+#include "internal/quic_strm_reas.h"
#include "internal/ring_buf.h"
struct quic_rstream_st {
- SFRAME_LIST fl;
+ SFRAME_SET fs;
QUIC_RXFC *rxfc;
OSSL_STATM *statm;
UINT_RANGE head_range;
- struct ring_buf rbuf;
};
+/* ARGSUSED */
+#define STDERR NULL
+static void print_foo(void *f, ...)
+{
+}
+
+#define DEBUG_PRINT print_foo
+
QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
- OSSL_STATM *statm, size_t rbuf_size)
+ OSSL_STATM *statm, QUIC_RSTREAM_QPARM *rsqp)
{
QUIC_RSTREAM *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL)
return NULL;
- ring_buf_init(&ret->rbuf);
- if (!ring_buf_resize(&ret->rbuf, rbuf_size, 0)) {
- OPENSSL_free(ret);
- return NULL;
- }
-
- ossl_sframe_list_init(&ret->fl);
+ ossl_sframe_set_init(&ret->fs, rsqp);
ret->rxfc = rxfc;
ret->statm = statm;
return ret;
@@ -43,14 +44,10 @@ QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
void ossl_quic_rstream_free(QUIC_RSTREAM *qrs)
{
- int cleanse;
-
if (qrs == NULL)
return;
- cleanse = qrs->fl.cleanse;
- ossl_sframe_list_destroy(&qrs->fl);
- ring_buf_destroy(&qrs->rbuf, cleanse);
+ ossl_sframe_set_destroy_ranges(&qrs->fs);
OPENSSL_free(qrs);
}
@@ -70,7 +67,7 @@ int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT *pkt,
range.start = offset;
range.end = offset + data_len;
- return ossl_sframe_list_insert(&qrs->fl, &range, pkt, data, fin);
+ return ossl_sframe_set_insert(&qrs->fs, &range, pkt, data, fin);
}
static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
@@ -83,9 +80,11 @@ static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
size_t readbytes_ = 0;
int fin_ = 0, ret = 1;
- while (ossl_sframe_list_peek(&qrs->fl, &iter, &range, &data, &fin_)) {
+ DEBUG_PRINT(STDERR, "%s want: %zu\n", OPENSSL_FUNC, size);
+ while (ossl_sframe_set_peek(&qrs->fs, &iter, &range, &data, &fin_)) {
size_t l = (size_t)(range.end - range.start);
+ DEBUG_PRINT(STDERR, "\t[ %llu, %llu ]\n", range.start, range.end);
if (l > size) {
l = size;
fin_ = 0;
@@ -94,25 +93,6 @@ static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
if (l == 0)
break;
- if (data == NULL) {
- size_t max_len;
-
- data = ring_buf_get_ptr(&qrs->rbuf, range.start, &max_len);
- if (!ossl_assert(data != NULL))
- return 0;
- if (max_len < l) {
- memcpy(buf, data, max_len);
- size -= max_len;
- buf += max_len;
- readbytes_ += max_len;
- l -= max_len;
- data = ring_buf_get_ptr(&qrs->rbuf, range.start + max_len,
- &max_len);
- if (!ossl_assert(data != NULL) || !ossl_assert(max_len > l))
- return 0;
- }
- }
-
memcpy(buf, data, l);
size -= l;
buf += l;
@@ -121,14 +101,15 @@ static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
break;
}
- if (drop && offset != 0) {
- ret = ossl_sframe_list_drop_frames(&qrs->fl, offset);
- ring_buf_cpop_range(&qrs->rbuf, 0, offset - 1, qrs->fl.cleanse);
- }
+ if (drop && offset != 0)
+ ret = ossl_sframe_set_move_offset(&qrs->fs, offset);
if (ret) {
+ DEBUG_PRINT(STDERR, "%s got: %zu\n", OPENSSL_FUNC, readbytes_);
*readbytes = readbytes_;
*fin = fin_;
+ } else {
+ DEBUG_PRINT(STDERR, "%s got: nothing\n", OPENSSL_FUNC);
}
return ret;
@@ -172,13 +153,9 @@ int ossl_quic_rstream_peek(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
int ossl_quic_rstream_available(QUIC_RSTREAM *qrs, size_t *avail, int *fin)
{
- void *iter = NULL;
- UINT_RANGE range;
- const unsigned char *data;
uint64_t avail_ = 0;
- while (ossl_sframe_list_peek(&qrs->fl, &iter, &range, &data, fin))
- avail_ += range.end - range.start;
+ ossl_sframe_set_avail(&qrs->fs, &avail_, fin);
#if SIZE_MAX < UINT64_MAX
*avail = avail_ > SIZE_MAX ? SIZE_MAX : (size_t)avail_;
@@ -193,38 +170,32 @@ int ossl_quic_rstream_get_record(QUIC_RSTREAM *qrs,
int *fin)
{
const unsigned char *record_ = NULL;
- size_t rec_len_, max_len;
+ void *iterator = NULL;
+ size_t rec_len_;
+ int ok;
- if (!ossl_sframe_list_lock_head(&qrs->fl, &qrs->head_range, &record_, fin)) {
- /* No head frame to lock and return */
+ ok = ossl_sframe_set_peek(&qrs->fs, &iterator, &qrs->head_range, &record_,
+ fin);
+ if (ok == 0) {
*record = NULL;
*rec_len = 0;
return 1;
}
+ DEBUG_PRINT(STDERR, "%s head: [ %llu, %llu ]\n", OPENSSL_FUNC,
+ qrs->head_range.start, qrs->head_range.end);
/* if final empty frame, we drop it immediately */
if (qrs->head_range.end == qrs->head_range.start) {
if (!ossl_assert(*fin))
return 0;
- if (!ossl_sframe_list_drop_frames(&qrs->fl, qrs->head_range.end))
+ if (!ossl_sframe_set_move_offset(&qrs->fs, qrs->head_range.end))
return 0;
}
rec_len_ = (size_t)(qrs->head_range.end - qrs->head_range.start);
-
- if (record_ == NULL && rec_len_ != 0) {
- record_ = ring_buf_get_ptr(&qrs->rbuf, qrs->head_range.start,
- &max_len);
- if (!ossl_assert(record_ != NULL))
- return 0;
- if (max_len < rec_len_) {
- rec_len_ = max_len;
- qrs->head_range.end = qrs->head_range.start + max_len;
- }
- }
-
*rec_len = rec_len_;
*record = record_;
+
return 1;
}
@@ -232,9 +203,6 @@ int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len)
{
uint64_t offset;
- if (!ossl_sframe_list_is_head_locked(&qrs->fl))
- return 0;
-
if (read_len > qrs->head_range.end - qrs->head_range.start) {
if (read_len != SIZE_MAX)
return 0;
@@ -243,12 +211,9 @@ int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len)
offset = qrs->head_range.start + read_len;
}
- if (!ossl_sframe_list_drop_frames(&qrs->fl, offset))
+ if (!ossl_sframe_set_move_offset(&qrs->fs, offset))
return 0;
- if (offset > 0)
- ring_buf_cpop_range(&qrs->rbuf, 0, offset - 1, qrs->fl.cleanse);
-
if (qrs->rxfc != NULL) {
OSSL_TIME rtt = get_rtt(qrs);
@@ -259,36 +224,17 @@ int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len)
return 1;
}
-static int write_at_ring_buf_cb(uint64_t logical_offset,
- const unsigned char *buf,
- size_t buf_len,
- void *cb_arg)
-{
- struct ring_buf *rbuf = cb_arg;
-
- return ring_buf_write_at(rbuf, logical_offset, buf, buf_len);
-}
-
-int ossl_quic_rstream_move_to_rbuf(QUIC_RSTREAM *qrs)
+void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse)
{
- if (ring_buf_avail(&qrs->rbuf) == 0)
- return 0;
- return ossl_sframe_list_move_data(&qrs->fl,
- write_at_ring_buf_cb, &qrs->rbuf);
+ qrs->fs.cleanse = cleanse;
}
-int ossl_quic_rstream_resize_rbuf(QUIC_RSTREAM *qrs, size_t rbuf_size)
+size_t ossl_quic_rstream_get_chunk_count(QUIC_RSTREAM *qrs)
{
- if (ossl_sframe_list_is_head_locked(&qrs->fl))
- return 0;
-
- if (!ring_buf_resize(&qrs->rbuf, rbuf_size, qrs->fl.cleanse))
- return 0;
-
- return 1;
+ return qrs->fs.stream_chunks;
}
-void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse)
+size_t ossl_quic_rstream_get_range_count(QUIC_RSTREAM *qrs)
{
- qrs->fl.cleanse = cleanse;
+ return qrs->fs.stream_ranges;
}
diff --git a/deps/openssl/openssl/ssl/quic/quic_rx_depack.c b/deps/openssl/openssl/ssl/quic/quic_rx_depack.c
index 59d16b2f362..704ac4a4954 100644
--- a/deps/openssl/openssl/ssl/quic/quic_rx_depack.c
+++ b/deps/openssl/openssl/ssl/quic/quic_rx_depack.c
@@ -1462,7 +1462,6 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket)
PACKET pkt;
OSSL_ACKM_RX_PKT ackm_data;
uint32_t enc_level;
- size_t dgram_len = qpacket->datagram_len;
if (ch == NULL)
return 0;
@@ -1497,8 +1496,6 @@ int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket)
*/
if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE)
ossl_quic_tx_packetiser_set_validated(ch->txp);
- else
- ossl_quic_tx_packetiser_add_unvalidated_credit(ch->txp, dgram_len);
/* Now that special cases are out of the way, parse frames */
if (!PACKET_buf_init(&pkt, qpacket->hdr->data, qpacket->hdr->len)
diff --git a/deps/openssl/openssl/ssl/quic/quic_sf_list.c b/deps/openssl/openssl/ssl/quic/quic_sf_list.c
deleted file mode 100644
index 03bbbe6d356..00000000000
--- a/deps/openssl/openssl/ssl/quic/quic_sf_list.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include "internal/uint_set.h"
-#include "internal/common.h"
-#include "internal/quic_sf_list.h"
-
-struct stream_frame_st {
- struct stream_frame_st *prev, *next;
- UINT_RANGE range;
- OSSL_QRX_PKT *pkt;
- const unsigned char *data;
-};
-
-static void stream_frame_free(SFRAME_LIST *fl, STREAM_FRAME *sf)
-{
- if (fl->cleanse && sf->data != NULL)
- OPENSSL_cleanse((unsigned char *)sf->data,
- (size_t)(sf->range.end - sf->range.start));
- ossl_qrx_pkt_release(sf->pkt);
- OPENSSL_free(sf);
-}
-
-static STREAM_FRAME *stream_frame_new(UINT_RANGE *range, OSSL_QRX_PKT *pkt,
- const unsigned char *data)
-{
- STREAM_FRAME *sf = OPENSSL_zalloc(sizeof(*sf));
-
- if (sf == NULL)
- return NULL;
-
- if (pkt != NULL)
- ossl_qrx_pkt_up_ref(pkt);
-
- sf->range = *range;
- sf->pkt = pkt;
- sf->data = data;
-
- return sf;
-}
-
-void ossl_sframe_list_init(SFRAME_LIST *fl)
-{
- memset(fl, 0, sizeof(*fl));
-}
-
-void ossl_sframe_list_destroy(SFRAME_LIST *fl)
-{
- STREAM_FRAME *sf, *next_frame;
-
- for (sf = fl->head; sf != NULL; sf = next_frame) {
- next_frame = sf->next;
- stream_frame_free(fl, sf);
- }
-}
-
-static int append_frame(SFRAME_LIST *fl, UINT_RANGE *range,
- OSSL_QRX_PKT *pkt,
- const unsigned char *data)
-{
- STREAM_FRAME *new_frame;
-
- if ((new_frame = stream_frame_new(range, pkt, data)) == NULL)
- return 0;
- new_frame->prev = fl->tail;
- if (fl->tail != NULL)
- fl->tail->next = new_frame;
- fl->tail = new_frame;
- ++fl->num_frames;
- return 1;
-}
-
-int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range,
- OSSL_QRX_PKT *pkt,
- const unsigned char *data, int fin)
-{
- STREAM_FRAME *sf, *new_frame, *prev_frame, *next_frame;
-#ifndef NDEBUG
- uint64_t curr_end = fl->tail != NULL ? fl->tail->range.end
- : fl->offset;
-
- /* This check for FINAL_SIZE_ERROR is handled by QUIC FC already */
- assert((!fin || curr_end <= range->end)
- && (!fl->fin || curr_end >= range->end));
-#endif
-
- if (fl->offset >= range->end)
- goto end;
-
- /* nothing there yet */
- if (fl->tail == NULL) {
- fl->tail = fl->head = stream_frame_new(range, pkt, data);
- if (fl->tail == NULL)
- return 0;
-
- ++fl->num_frames;
- goto end;
- }
-
- /* optimize insertion at the end */
- if (fl->tail->range.start < range->start) {
- if (fl->tail->range.end >= range->end)
- goto end;
-
- if (!append_frame(fl, range, pkt, data))
- return 0;
- goto end;
- }
-
- prev_frame = NULL;
- for (sf = fl->head; sf != NULL && sf->range.start < range->start;
- sf = sf->next)
- prev_frame = sf;
-
- if (!ossl_assert(sf != NULL))
- /* frame list invariant broken */
- return 0;
-
- if (prev_frame != NULL && prev_frame->range.end >= range->end)
- goto end;
-
- /*
- * Now we must create a new frame although in the end we might drop it,
- * because we will be potentially dropping existing overlapping frames.
- */
- new_frame = stream_frame_new(range, pkt, data);
- if (new_frame == NULL)
- return 0;
-
- for (next_frame = sf;
- next_frame != NULL && next_frame->range.end <= range->end;) {
- STREAM_FRAME *drop_frame = next_frame;
-
- next_frame = next_frame->next;
- if (next_frame != NULL)
- next_frame->prev = drop_frame->prev;
- if (prev_frame != NULL)
- prev_frame->next = drop_frame->next;
- if (fl->head == drop_frame)
- fl->head = next_frame;
- if (fl->tail == drop_frame)
- fl->tail = prev_frame;
- --fl->num_frames;
- stream_frame_free(fl, drop_frame);
- }
-
- if (next_frame != NULL) {
- /* check whether the new_frame is redundant because there is no gap */
- if (prev_frame != NULL
- && next_frame->range.start <= prev_frame->range.end) {
- stream_frame_free(fl, new_frame);
- goto end;
- }
- next_frame->prev = new_frame;
- } else {
- fl->tail = new_frame;
- }
-
- new_frame->next = next_frame;
- new_frame->prev = prev_frame;
-
- if (prev_frame != NULL)
- prev_frame->next = new_frame;
- else
- fl->head = new_frame;
-
- ++fl->num_frames;
-
-end:
- fl->fin = fin || fl->fin;
-
- return 1;
-}
-
-int ossl_sframe_list_peek(const SFRAME_LIST *fl, void **iter,
- UINT_RANGE *range, const unsigned char **data,
- int *fin)
-{
- STREAM_FRAME *sf = *iter;
- uint64_t start;
-
- if (sf == NULL) {
- start = fl->offset;
- sf = fl->head;
- } else {
- start = sf->range.end;
- sf = sf->next;
- }
-
- range->start = start;
-
- if (sf == NULL || sf->range.start > start
- || !ossl_assert(start < sf->range.end)) {
- range->end = start;
- *data = NULL;
- *iter = NULL;
- /* set fin only if we are at the end */
- *fin = sf == NULL ? fl->fin : 0;
- return 0;
- }
-
- range->end = sf->range.end;
- if (sf->data != NULL)
- *data = sf->data + (start - sf->range.start);
- else
- *data = NULL;
- *fin = sf->next == NULL ? fl->fin : 0;
- *iter = sf;
- return 1;
-}
-
-int ossl_sframe_list_drop_frames(SFRAME_LIST *fl, uint64_t limit)
-{
- STREAM_FRAME *sf;
-
- /* offset cannot move back or past the data received */
- if (!ossl_assert(limit >= fl->offset)
- || !ossl_assert(fl->tail == NULL
- || limit <= fl->tail->range.end)
- || !ossl_assert(fl->tail != NULL
- || limit == fl->offset))
- return 0;
-
- fl->offset = limit;
-
- for (sf = fl->head; sf != NULL && sf->range.end <= limit;) {
- STREAM_FRAME *drop_frame = sf;
-
- sf = sf->next;
- --fl->num_frames;
- stream_frame_free(fl, drop_frame);
- }
- fl->head = sf;
-
- if (sf != NULL)
- sf->prev = NULL;
- else
- fl->tail = NULL;
-
- fl->head_locked = 0;
-
- return 1;
-}
-
-int ossl_sframe_list_lock_head(SFRAME_LIST *fl, UINT_RANGE *range,
- const unsigned char **data,
- int *fin)
-{
- int ret;
- void *iter = NULL;
-
- if (fl->head_locked)
- return 0;
-
- ret = ossl_sframe_list_peek(fl, &iter, range, data, fin);
- if (ret)
- fl->head_locked = 1;
- return ret;
-}
-
-int ossl_sframe_list_is_head_locked(SFRAME_LIST *fl)
-{
- return fl->head_locked;
-}
-
-int ossl_sframe_list_move_data(SFRAME_LIST *fl,
- sframe_list_write_at_cb *write_at_cb,
- void *cb_arg)
-{
- STREAM_FRAME *sf = fl->head, *prev_frame = NULL;
- uint64_t limit = fl->offset;
-
- if (sf == NULL)
- return 1;
-
- if (fl->head_locked)
- sf = sf->next;
-
- for (; sf != NULL; sf = sf->next) {
- size_t len;
- const unsigned char *data = sf->data;
-
- if (limit < sf->range.start)
- limit = sf->range.start;
-
- if (data != NULL) {
- if (limit > sf->range.start)
- data += (size_t)(limit - sf->range.start);
- len = (size_t)(sf->range.end - limit);
-
- if (!write_at_cb(limit, data, len, cb_arg))
- /* data did not fit */
- return 0;
-
- if (fl->cleanse)
- OPENSSL_cleanse((unsigned char *)sf->data,
- (size_t)(sf->range.end - sf->range.start));
-
- /* release the packet */
- sf->data = NULL;
- ossl_qrx_pkt_release(sf->pkt);
- sf->pkt = NULL;
- }
-
- limit = sf->range.end;
-
- /* merge contiguous frames */
- if (prev_frame != NULL
- && prev_frame->range.end >= sf->range.start) {
- prev_frame->range.end = sf->range.end;
- prev_frame->next = sf->next;
-
- if (sf->next != NULL)
- sf->next->prev = prev_frame;
- else
- fl->tail = prev_frame;
-
- --fl->num_frames;
- stream_frame_free(fl, sf);
- sf = prev_frame;
- continue;
- }
-
- prev_frame = sf;
- }
-
- return 1;
-}
diff --git a/deps/openssl/openssl/ssl/quic/quic_srtm.c b/deps/openssl/openssl/ssl/quic/quic_srtm.c
index 46f675cef23..19f6d7d60ac 100644
--- a/deps/openssl/openssl/ssl/quic/quic_srtm.c
+++ b/deps/openssl/openssl/ssl/quic/quic_srtm.c
@@ -485,8 +485,8 @@ static void check_mark(SRTM_ITEM *item, void *arg)
{
struct check_args *arg_ = arg;
uint32_t token = arg_->token;
- uint64_t prev_seq_num = 0;
- void *prev_opaque = NULL;
+ ossl_unused uint64_t prev_seq_num = 0;
+ ossl_unused void *prev_opaque = NULL;
int have_prev = 0;
assert(item != NULL);
@@ -514,7 +514,7 @@ static void check_mark(SRTM_ITEM *item, void *arg)
static void check_count(SRTM_ITEM *item, void *arg)
{
struct check_args *arg_ = arg;
- uint32_t token = arg_->token;
+ ossl_unused uint32_t token = arg_->token;
assert(item != NULL);
@@ -535,7 +535,8 @@ void ossl_quic_srtm_check(const QUIC_SRTM *srtm)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
struct check_args args = { 0 };
- size_t tokens_expected, tokens_expected_old;
+ size_t tokens_expected;
+ ossl_unused size_t tokens_expected_old;
args.token = token_next;
++token_next;
diff --git a/deps/openssl/openssl/ssl/quic/quic_stream_map.c b/deps/openssl/openssl/ssl/quic/quic_stream_map.c
index da53d4b8054..761b577d261 100644
--- a/deps/openssl/openssl/ssl/quic/quic_stream_map.c
+++ b/deps/openssl/openssl/ssl/quic/quic_stream_map.c
@@ -760,20 +760,27 @@ static QUIC_RXFC *qsm_get_max_streams_rxfc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s)
: qsm->max_streams_uni_rxfc;
}
-void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm,
+void ossl_quic_stream_map_retire_stream_credit(QUIC_STREAM_MAP *qsm,
QUIC_STREAM *s,
OSSL_TIME rtt)
{
QUIC_RXFC *max_streams_rxfc;
+ if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL)
+ (void)ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt);
+}
+
+void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm,
+ QUIC_STREAM *s,
+ OSSL_TIME rtt)
+{
list_remove(&qsm->accept_list, &s->accept_node);
if (ossl_quic_stream_is_bidi(s))
--qsm->num_accept_bidi;
else
--qsm->num_accept_uni;
- if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL)
- (void)ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt);
+ ossl_quic_stream_map_retire_stream_credit(qsm, s, rtt);
}
size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni)
diff --git a/deps/openssl/openssl/ssl/quic/quic_strm_reas.c b/deps/openssl/openssl/ssl/quic/quic_strm_reas.c
new file mode 100644
index 00000000000..e54fefe433f
--- /dev/null
+++ b/deps/openssl/openssl/ssl/quic/quic_strm_reas.c
@@ -0,0 +1,1345 @@
+/*
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/uint_set.h"
+#include "internal/common.h"
+#include "internal/quic_stream.h"
+#include "internal/quic_strm_reas.h"
+#include "internal/list.h"
+#include "internal/quic_channel.h"
+
+#define STDERR NULL
+/* ARGSUSED */
+static void print_foo(void *f, ...)
+{
+}
+
+#define DEBUG_PRINT print_foo
+
+#define DIRECT_STORAGE_SZ (2 * sizeof(void *))
+
+/*
+ * Maximal allocation overhead in packet buffers is ~64kB for
+ * connection. If ~64kB limit is exceeded, then the newly received
+ * chunks are moved from the packet to the stream buffer.
+ */
+#define PKT_BUFFER_OVERHEAD_TRESHOLD (65535)
+
+/*
+ * storage type indicates where stream data bytes
+ * are stored.
+ */
+enum {
+ ST_TYPE_DIRECT, /* in chunk structure itself (sc_dstorage) */
+ ST_TYPE_PKT, /* bytes are stored in attached pkt (sc_pkt) */
+ ST_TYPE_HEAP /* data are stored on memory heap buffer */
+};
+
+/*
+ * Stream chunk keeps stream bytes as received from QUIC STREAM_FRAME.
+ * Each chunk of stream data by [start, end).
+ */
+struct stream_chunk_t {
+ OSSL_LIST_MEMBER(sc, struct stream_chunk_t);
+ UINT_RANGE sc_range;
+ int sc_st; /* storage type */
+ union {
+ const unsigned char *u_data;
+ unsigned char *u_data_w;
+ } sc_data_u;
+ union {
+ OSSL_QRX_PKT *u_sc_pkt;
+ unsigned char *u_sc_buf;
+ unsigned char u_sc_dstorage[DIRECT_STORAGE_SZ];
+ } sc_storage_u;
+};
+
+struct quic_rstream_qparm_st {
+ size_t rsqp_pkt_overhead_treshold;
+ size_t rsqp_pkt_overhead_sz;
+ QUIC_CHANNEL *rsqp_ch;
+};
+
+#define sc_data sc_data_u.u_data
+#define sc_data_w sc_data_u.u_data_w
+
+#define sc_pkt sc_storage_u.u_sc_pkt
+#define sc_buf sc_storage_u.u_sc_buf
+#define sc_dstorage sc_storage_u.u_sc_dstorage
+
+DEFINE_LIST_OF(sc, struct stream_chunk_t);
+
+#define SCHUNK_SIZE(_sc) ((_sc)->sc_range.end - (_sc)->sc_range.start)
+#define SRANGE_SIZE(_sr) ((_sr)->sr_range.end - (_sr)->sr_range.start)
+#define SCHUNK_OVERHEAD(_pkt, _sc) ((_pkt)->datagram_len - SCHUNK_SIZE(_sc))
+
+/*
+ * Stream range keeps list of continuous stream chunks. The range
+ * is also defined by [start, end) interval. For every chunk
+ * in range this assertion must hold:
+ * sc->sc_range.end == sc->sc_next->sc_range.start
+ *
+ * If newly arriving stream chunk can not be inserted to existing
+ * stream range, then new range must be created.
+ */
+struct stream_range_t {
+ OSSL_LIST(sc)
+ sr_chunks;
+ OSSL_RBT_ENTRY(stream_range_t)
+ sr_rbe;
+ UINT_RANGE sr_range;
+ struct stream_chunk_t *sr_it_sc; /* iterator */
+};
+
+static int srange_cmp(const struct stream_range_t *, const struct stream_range_t *);
+
+OSSL_RBT_PROTOTYPE(srange, stream_range_t, sr_rbe, srange_cmp)
+
+OSSL_RBT_GENERATE(srange, stream_range_t, sr_rbe, srange_cmp);
+
+#define UINT64_TO_SIZE_T(_x) ((size_t)(((_x) > SIZE_MAX) ? SIZE_MAX : (_x)))
+
+static void rsqp_add_overhead(QUIC_RSTREAM_QPARM *rsqp, size_t sc_overhead)
+{
+ rsqp->rsqp_pkt_overhead_sz += sc_overhead;
+}
+
+static void rsqp_sub_overhead(QUIC_RSTREAM_QPARM *rsqp, size_t sc_overhead)
+{
+ rsqp->rsqp_pkt_overhead_sz -= sc_overhead;
+}
+
+/*
+ * Cleansing (SSL_OP_CLEANSE_PLAINTEXT) must write through the const
+ * data pointers received from ossl_sframe_set_insert(), which may
+ * point into a shared packet buffer. That is safe: each chunk
+ * references the disjoint payload slice of its own frame and a
+ * processed packet is kept alive only by the chunks stored on it,
+ * so nobody else reads the wiped bytes.
+ *
+ * The const should eventually be dropped from the prototypes
+ * instead; until then deconst() is used.
+ */
+static unsigned char *deconst(const unsigned char *data)
+{
+ union {
+ const unsigned char *u_data;
+ unsigned char *u_data_w;
+ } data_u;
+
+ data_u.u_data = data;
+
+ return data_u.u_data_w;
+}
+
+static void sc_data_trim_left(struct stream_chunk_t *sc, size_t trim_sz,
+ int cleanse)
+{
+ if (sc->sc_st == ST_TYPE_DIRECT) {
+ assert(SCHUNK_SIZE(sc) >= trim_sz);
+ memmove(sc->sc_data_w, &sc->sc_data[trim_sz],
+ UINT64_TO_SIZE_T((SCHUNK_SIZE(sc) - trim_sz)));
+ if (cleanse && trim_sz > 0) {
+ OPENSSL_cleanse(
+ sc->sc_data_w + UINT64_TO_SIZE_T(SCHUNK_SIZE(sc) - trim_sz),
+ UINT64_TO_SIZE_T(trim_sz));
+ }
+ } else {
+ if (cleanse && trim_sz > 0) {
+ OPENSSL_cleanse(sc->sc_data_w, trim_sz);
+ }
+ sc->sc_data += trim_sz;
+ }
+}
+
+static void sc_data_trim_right(struct stream_chunk_t *sc, size_t trim_sz,
+ int cleanse)
+{
+ unsigned char *data_realloc;
+ size_t w_offset;
+
+ assert(SCHUNK_SIZE(sc) >= trim_sz);
+
+ if (cleanse)
+ OPENSSL_cleanse(
+ &sc->sc_data_w[sc->sc_range.end - trim_sz - sc->sc_range.start],
+ trim_sz);
+
+ if (sc->sc_st == ST_TYPE_HEAP) {
+ /*
+ * this is a shrinking realloc() here, so it should not fail.
+ * even if it fails, we still don't care, the worst outcome
+ * of such failure is waste of memory.
+ */
+ assert(sc->sc_data_w >= sc->sc_buf);
+ w_offset = sc->sc_data_w - sc->sc_buf;
+ if (trim_sz > 0) {
+ assert(SCHUNK_SIZE(sc) > trim_sz);
+ data_realloc = OPENSSL_realloc(sc->sc_buf,
+ w_offset + UINT64_TO_SIZE_T(SCHUNK_SIZE(sc)) - trim_sz);
+ if (data_realloc != NULL) {
+ sc->sc_buf = data_realloc;
+ sc->sc_data_w = sc->sc_buf + w_offset;
+ }
+ }
+ }
+}
+
+static int srange_cmp(const struct stream_range_t *a_sr,
+ const struct stream_range_t *b_sr)
+{
+ assert(a_sr->sr_range.start < a_sr->sr_range.end);
+ assert(b_sr->sr_range.start < b_sr->sr_range.end);
+ /*
+ * no overlap, A precedes B
+ */
+ if (a_sr->sr_range.end < b_sr->sr_range.start)
+ return -1;
+
+ /*
+ * no overlap, A follows B
+ */
+ if (a_sr->sr_range.start > b_sr->sr_range.end)
+ return 1;
+
+ /*
+ * partial or full overlap or ranges are adjacent.
+ * the program needs to do close examination on
+ * how to add new chunk to existing stream range.
+ */
+ return 0;
+}
+
+static int keep_schunk_data_on_packet(SFRAME_SET *fs, OSSL_QRX_PKT *pkt,
+ size_t overhead)
+{
+ if ((fs->rsqp->rsqp_pkt_overhead_sz + overhead) >= fs->rsqp->rsqp_pkt_overhead_treshold)
+ return 0;
+
+ return 1;
+}
+
+static struct stream_chunk_t *new_schunk(SFRAME_SET *fs, OSSL_QRX_PKT *pkt,
+ UINT_RANGE *r, const unsigned char *data)
+{
+ struct stream_chunk_t *sc;
+ uint64_t rsize;
+ size_t overhead;
+
+ if (pkt == NULL)
+ return NULL;
+
+ sc = OPENSSL_zalloc(sizeof(*sc));
+ if (sc == NULL)
+ return NULL;
+
+ rsize = r->end - r->start;
+ assert(rsize <= pkt->datagram_len);
+ overhead = UINT64_TO_SIZE_T(pkt->datagram_len - rsize);
+
+ if (keep_schunk_data_on_packet(fs, pkt, overhead) == 1) {
+ sc->sc_st = ST_TYPE_PKT;
+ sc->sc_pkt = pkt;
+ ossl_qrx_pkt_up_ref(pkt);
+ rsqp_add_overhead(fs->rsqp, overhead);
+ sc->sc_data = data;
+ sc->sc_range = *r;
+ DEBUG_PRINT(STDERR,
+ "%s sc: %p sc overhead: %llu pkt_buf_overhead_sz: %llu -> %zu\n",
+ OPENSSL_FUNC, (void *)sc, SCHUNK_OVERHEAD(pkt, sc),
+ fs->rsqp->rsqp_pkt_overhead_sz - SCHUNK_OVERHEAD(pkt, sc),
+ fs->rsqp->rsqp_pkt_overhead_sz);
+ } else {
+ if (rsize <= DIRECT_STORAGE_SZ) {
+ DEBUG_PRINT(STDERR, "%s ST_TYPE_DIRECT sc: %p %llu\n", OPENSSL_FUNC,
+ (void *)sc, rsize);
+ sc->sc_st = ST_TYPE_DIRECT;
+ sc->sc_data_w = sc->sc_dstorage;
+ } else {
+ DEBUG_PRINT(STDERR, "%s ST_TYPE_HEAP sc: %p %llu\n", OPENSSL_FUNC,
+ (void *)sc, rsize);
+ sc->sc_st = ST_TYPE_HEAP;
+ sc->sc_buf = OPENSSL_malloc(UINT64_TO_SIZE_T(rsize));
+ if (sc->sc_buf == NULL) {
+ OPENSSL_free(sc);
+ return NULL;
+ }
+ sc->sc_data_w = sc->sc_buf;
+ }
+ sc->sc_range = *r;
+ memcpy(sc->sc_data_w, data, UINT64_TO_SIZE_T(rsize));
+
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(data), UINT64_TO_SIZE_T(rsize));
+ }
+
+ return sc;
+}
+
+static void destroy_schunk(SFRAME_SET *fs, struct stream_chunk_t *sc)
+{
+ if (sc == NULL)
+ return;
+
+ if (fs->cleanse)
+ OPENSSL_cleanse(sc->sc_data_w,
+ UINT64_TO_SIZE_T(sc->sc_st == ST_TYPE_DIRECT
+ ? DIRECT_STORAGE_SZ
+ : SCHUNK_SIZE(sc)));
+
+ switch (sc->sc_st) {
+ case ST_TYPE_PKT:
+ assert(fs->rsqp->rsqp_pkt_overhead_sz >= SCHUNK_OVERHEAD(sc->sc_pkt, sc));
+ DEBUG_PRINT(STDERR,
+ "%s sc: %p sc overhead: %llu pkt_buf_overhead_sz: %zu -> %llu\n",
+ OPENSSL_FUNC, (void *)sc, SCHUNK_OVERHEAD(sc->sc_pkt, sc),
+ fs->rsqp->rsqp_pkt_overhead_sz,
+ fs->rsqp->rsqp_pkt_overhead_sz - SCHUNK_OVERHEAD(sc->sc_pkt, sc));
+ rsqp_sub_overhead(fs->rsqp,
+ UINT64_TO_SIZE_T(SCHUNK_OVERHEAD(sc->sc_pkt, sc)));
+ ossl_qrx_pkt_release(sc->sc_pkt);
+ break;
+ case ST_TYPE_HEAP:
+ OPENSSL_free(sc->sc_buf);
+ break;
+ default:
+ assert(sc->sc_st == ST_TYPE_DIRECT);
+ }
+
+ OPENSSL_free(sc);
+}
+
+static struct stream_range_t *new_srange(void)
+{
+ struct stream_range_t *sr;
+
+ sr = OPENSSL_zalloc(sizeof(*sr));
+ if (sr != NULL) {
+ ossl_list_sc_init(&sr->sr_chunks);
+ }
+
+ return sr;
+}
+
+static void destroy_srange(SFRAME_SET *fs, struct stream_range_t *sr)
+{
+ struct stream_chunk_t *sc;
+
+ if (sr == NULL)
+ return;
+
+ assert(sr->sr_rbe.rb_parent == NULL);
+ assert(sr->sr_rbe.rb_left == NULL);
+ assert(sr->sr_rbe.rb_right == NULL);
+
+ while ((sc = ossl_list_sc_head(&sr->sr_chunks)) != NULL) {
+ ossl_list_sc_remove(&sr->sr_chunks, sc);
+ fs->stream_chunks--;
+ destroy_schunk(fs, sc);
+ }
+
+ OPENSSL_free(sr);
+}
+
+static struct stream_range_t *create_range(SFRAME_SET *fs,
+ struct stream_chunk_t *sc)
+{
+ struct stream_range_t *sr;
+
+ assert(sc != NULL);
+
+ sr = new_srange();
+ if (sr != NULL) {
+ ossl_list_sc_insert_head(&sr->sr_chunks, sc);
+ sr->sr_range = sc->sc_range;
+ fs->stream_chunks++;
+ }
+
+ return sr;
+}
+
+void ossl_sframe_set_init(SFRAME_SET *fs, QUIC_RSTREAM_QPARM *rsqp)
+{
+ assert(rsqp != NULL);
+
+ memset(fs, 0, sizeof(*fs));
+ OSSL_RBT_INIT(srange, &fs->ranges);
+ fs->rsqp = rsqp;
+}
+
+static uint64_t get_sc_dstorage_sz(struct stream_chunk_t *sc)
+{
+ uint64_t sz = 0;
+
+ if (sc->sc_st == ST_TYPE_DIRECT && SCHUNK_SIZE(sc) < DIRECT_STORAGE_SZ)
+ sz = DIRECT_STORAGE_SZ - SCHUNK_SIZE(sc);
+
+ return sz;
+}
+
+static int try_dstorage(SFRAME_SET *fs, OSSL_QRX_PKT *pkt,
+ struct stream_range_t *sr, UINT_RANGE *r, const unsigned char **data)
+{
+ struct stream_chunk_t *head_sc, *tail_sc, *new_sc;
+ uint64_t rsize;
+ uint64_t offset;
+ uint64_t dsize;
+
+ /*
+ * full overlap which spans over more range with more than 1 chunk,
+ * nothing to be done here, caller will handle that.
+ */
+ rsize = r->end - r->start;
+ if (r->start < sr->sr_range.start && r->end > sr->sr_range.end
+ && ossl_list_sc_num(&sr->sr_chunks) > 1)
+ return 0;
+
+ head_sc = ossl_list_sc_head(&sr->sr_chunks);
+ assert(head_sc != NULL);
+ tail_sc = ossl_list_sc_tail(&sr->sr_chunks);
+ assert(tail_sc != NULL);
+
+ /*
+ * full overlap of direct storage can be treated when range contains
+ * exactly one chunk.
+ */
+ if (head_sc == tail_sc
+ && head_sc->sc_range.start > r->start
+ && head_sc->sc_range.end < r->end) {
+ /*
+ * can deal with full overlap
+ */
+ if (head_sc->sc_st != ST_TYPE_DIRECT)
+ return 0;
+
+ DEBUG_PRINT(STDERR, "%s @in %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, *data, r->start, r->end);
+ rsize = r->end - r->start;
+ if (rsize <= DIRECT_STORAGE_SZ) {
+ /*
+ * update existing chunk
+ */
+ DEBUG_PRINT(STDERR,
+ "%s overwrite dstorage %p [ %llu, %llu ] -> [ %llu, %llu ] "
+ "sr: %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, (void *)head_sc,
+ head_sc->sc_range.start, head_sc->sc_range.end,
+ r->start, r->end,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+ memcpy(head_sc->sc_data_w, *data, UINT64_TO_SIZE_T(rsize));
+
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(*data), UINT64_TO_SIZE_T(rsize));
+
+ *data += rsize;
+ head_sc->sc_range.start = r->start;
+ head_sc->sc_range.end = r->end;
+ } else {
+ /*
+ * try to replace existing chunk
+ */
+ new_sc = new_schunk(fs, pkt, r, *data);
+ if (new_sc == NULL) {
+ DEBUG_PRINT(STDERR, "%s new_chunk() alloc failed\n",
+ OPENSSL_FUNC);
+ return -1;
+ }
+
+ DEBUG_PRINT(STDERR,
+ "%s replace chunk %p [ %llu, %llu ] -> %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC,
+ (void *)head_sc, head_sc->sc_range.start, head_sc->sc_range.end,
+ (void *)new_sc, new_sc->sc_range.start, new_sc->sc_range.end);
+ ossl_list_sc_remove(&sr->sr_chunks, head_sc);
+ ossl_list_sc_insert_head(&sr->sr_chunks, new_sc);
+ destroy_schunk(fs, head_sc);
+ }
+ DEBUG_PRINT(STDERR, "\trange: %p [ %llu, %llu ] -> [ %llu, %llu ]\n",
+ (void *)sr, sr->sr_range.start, sr->sr_range.end, r->start, r->end);
+ sr->sr_range.start = r->start;
+ sr->sr_range.end = r->end;
+ /*
+ * indicate that while range got consumed.
+ */
+ r->start = 0;
+ r->end = 0;
+ } else if (tail_sc->sc_range.end < r->end) {
+ /*
+ * append only
+ */
+ if (tail_sc->sc_st != ST_TYPE_DIRECT)
+ return 0;
+
+ dsize = get_sc_dstorage_sz(tail_sc);
+ if (dsize == 0)
+ return 0;
+
+ DEBUG_PRINT(STDERR, "%s append: @in %p [ %llu, %llu ] dsize: %llu "
+ "tail_sc: %p [ %llu, %llu] sr: %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, *data, r->start, r->end, dsize,
+ (void *)tail_sc, tail_sc->sc_range.start, tail_sc->sc_range.end,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+
+ if (r->start < tail_sc->sc_range.end) {
+ rsize = tail_sc->sc_range.end - r->start;
+
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(*data), UINT64_TO_SIZE_T(rsize));
+
+ *data += rsize;
+
+ r->start = tail_sc->sc_range.end;
+ }
+
+ rsize = r->end - r->start;
+ /*
+ * earlier check done in ossl_sframe_set_insert() ensures
+ * there is at least some data to append.
+ */
+ assert(rsize > 0);
+ rsize = (rsize < dsize) ? rsize : dsize;
+ offset = SCHUNK_SIZE(tail_sc);
+ memcpy(&tail_sc->sc_data_w[offset], *data, UINT64_TO_SIZE_T(rsize));
+ DEBUG_PRINT(STDERR, "%s append tail_sc: %p [ %llu, %llu ] -> ",
+ OPENSSL_FUNC, (void *)tail_sc,
+ tail_sc->sc_range.start, tail_sc->sc_range.end);
+ tail_sc->sc_range.end += rsize;
+ DEBUG_PRINT(STDERR, "[ %llu, %llu ]\n",
+ tail_sc->sc_range.start, tail_sc->sc_range.end);
+ assert(SCHUNK_SIZE(tail_sc) <= DIRECT_STORAGE_SZ);
+ DEBUG_PRINT(STDERR, "\trange: %p [ %llu, %llu ] -> ",
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+ sr->sr_range.end = tail_sc->sc_range.end;
+ DEBUG_PRINT(STDERR, "[ %llu, %llu ]\n",
+ sr->sr_range.start, sr->sr_range.end);
+
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(*data), UINT64_TO_SIZE_T(rsize));
+
+ *data += rsize;
+ r->start = tail_sc->sc_range.end;
+ } else if (head_sc->sc_range.start > r->start) {
+ const unsigned char *data_buf;
+ /*
+ * prepend only
+ */
+ if (head_sc->sc_st != ST_TYPE_DIRECT)
+ return 0;
+
+ dsize = get_sc_dstorage_sz(head_sc);
+ if (dsize == 0)
+ return 0;
+
+ DEBUG_PRINT(STDERR, "%s prepend: @in %p [ %llu, %llu ] dsize: %llu "
+ "sr: %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, *data, r->start, r->end, dsize,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+
+ if (r->end > head_sc->sc_range.start) {
+ if (fs->cleanse)
+ OPENSSL_cleanse(
+ deconst(*data + (head_sc->sc_range.start - r->start)),
+ UINT64_TO_SIZE_T(r->end - head_sc->sc_range.start));
+ r->end = head_sc->sc_range.start;
+ }
+
+ rsize = r->end - r->start;
+ /*
+ * earlier check done in ossl_sframe_set_insert() ensures
+ * there is at least some data to append.
+ */
+ assert(rsize > 0);
+ rsize = (rsize < dsize) ? rsize : dsize;
+ memmove(&head_sc->sc_data_w[rsize], head_sc->sc_data,
+ UINT64_TO_SIZE_T(SCHUNK_SIZE(head_sc)));
+ offset = r->end - rsize - r->start;
+ assert(offset < r->end - r->start);
+ data_buf = *data;
+ memcpy(head_sc->sc_data_w, &data_buf[offset], UINT64_TO_SIZE_T(rsize));
+ DEBUG_PRINT(STDERR, "%s prepend head_sc: %p [ %llu, %llu ] -> ",
+ OPENSSL_FUNC, (void *)head_sc,
+ head_sc->sc_range.start, head_sc->sc_range.end);
+ head_sc->sc_range.start -= rsize;
+ DEBUG_PRINT(STDERR, "[ %llu, %llu ]\n",
+ head_sc->sc_range.start, head_sc->sc_range.end);
+ assert(SCHUNK_SIZE(head_sc) <= DIRECT_STORAGE_SZ);
+ DEBUG_PRINT(STDERR, "\trange: %p [ %llu, %llu ] -> ",
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+ sr->sr_range.start = head_sc->sc_range.start;
+ DEBUG_PRINT(STDERR, "[ %llu, %llu ]\n",
+ sr->sr_range.start, sr->sr_range.end);
+ assert(r->end - r->start >= rsize);
+
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(&data_buf[offset]),
+ UINT64_TO_SIZE_T(rsize));
+
+ r->end -= rsize;
+ } else {
+ assert(0);
+ return -1;
+ }
+
+ /*
+ * returns 1 if all data were consumed
+ */
+ assert(r->end >= r->start);
+ DEBUG_PRINT(STDERR, "%s @out %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, *data, r->start, r->end);
+
+ return ((r->end - r->start) == 0) ? 1 : 0;
+}
+
+/*
+ * If there is partial overlap between newly received data `r` and
+ * existing stream range `sr`, then this function trims overlapping
+ * bytes from `r`.
+ * sr - pointer to stream range
+ * r - pointer to range of bytes received in stream frame
+ * data - pointer to data bytes delivered in stream frame
+ * function updates r so there is no partial overlap between and sr
+ * after function returns. Function returns pointer to the first
+ * data byte in stream after `r` is adjusted. Function returns `data`
+ * when no trimming happened.
+ */
+static const unsigned char *trim_partial_overlap(SFRAME_SET *fs,
+ struct stream_range_t *sr, UINT_RANGE *r, const unsigned char *data)
+{
+ uint64_t unused_sz;
+
+ if (!(r->start < sr->sr_range.start && r->end > sr->sr_range.end)) {
+ if (r->end > sr->sr_range.end && r->start < sr->sr_range.end) {
+ unused_sz = sr->sr_range.end - r->start;
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(data), UINT64_TO_SIZE_T(unused_sz));
+
+ DEBUG_PRINT(STDERR, "%s right overlap %p [ %llu, %llu ]:\n\t"
+ "r: [ %llu, %llu ] -> [ %llu, %llu ]\n",
+ OPENSSL_FUNC,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end,
+ r->start, r->end,
+ sr->sr_range.end, r->end);
+
+ data += unused_sz;
+ r->start = sr->sr_range.end;
+ } else if (r->start < sr->sr_range.start
+ && r->end > sr->sr_range.start) {
+ unused_sz = r->end - sr->sr_range.start;
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(data
+ + (sr->sr_range.start - r->start)),
+ UINT64_TO_SIZE_T(unused_sz));
+
+ DEBUG_PRINT(STDERR, "%s left overlap %p [ %llu, %llu]:\n\t"
+ "r: [ %llu, %llu ] -> [ %llu, %llu ]\n",
+ OPENSSL_FUNC,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end,
+ r->start, r->end,
+ r->start, sr->sr_range.start);
+ r->end = sr->sr_range.start;
+ }
+ }
+
+ return data;
+}
+
+/*
+ * Inserts a newly received chunk to the head of the chunk list.
+ */
+static void prepend_chunk(SFRAME_SET *fs, struct stream_range_t *sr,
+ struct stream_chunk_t *sc)
+{
+ DEBUG_PRINT(STDERR, "%s %p [ %llu, %llu ] add to head %p [ %llu, %llu ] "
+ "-> [ %llu, %llu ]\n",
+ OPENSSL_FUNC,
+ (void *)sc, sc->sc_range.start, sc->sc_range.end,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end,
+ sc->sc_range.start, sr->sr_range.end);
+
+ /*
+ * the new chunk must not be empty
+ */
+ assert(sc->sc_range.end > sc->sc_range.start);
+ /*
+ * and must not overlap range.
+ */
+ assert(sc->sc_range.end == sr->sr_range.start);
+
+ ossl_list_sc_insert_head(&sr->sr_chunks, sc);
+ sr->sr_range.start = sc->sc_range.start;
+ fs->stream_chunks++;
+}
+
+/*
+ * Inserts a newly received chunk to the tail of the chunk list.
+ */
+static void append_chunk(SFRAME_SET *fs, struct stream_range_t *sr,
+ struct stream_chunk_t *sc)
+{
+ DEBUG_PRINT(STDERR, "%s %p [ %llu, %llu ] add to tail %p [ %llu, %llu ] "
+ "-> [ %llu, %llu ]\n",
+ OPENSSL_FUNC,
+ (void *)sc, sc->sc_range.start, sc->sc_range.end,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end,
+ sr->sr_range.start, sc->sc_range.end);
+
+ /*
+ * the new chunk must not be empty
+ */
+ assert(sc->sc_range.end > sc->sc_range.start);
+ /*
+ * and must not overlap range
+ */
+ assert(sc->sc_range.start == sr->sr_range.end);
+
+ ossl_list_sc_insert_tail(&sr->sr_chunks, sc);
+ sr->sr_range.end = sc->sc_range.end;
+ fs->stream_chunks++;
+}
+
+static void replace_chunks_in_range(SFRAME_SET *fs, struct stream_range_t *sr,
+ struct stream_chunk_t *sc)
+{
+ struct stream_chunk_t *destroy_sc;
+
+ while ((destroy_sc = ossl_list_sc_head(&sr->sr_chunks)) != NULL) {
+ ossl_list_sc_remove(&sr->sr_chunks, destroy_sc);
+ fs->stream_chunks--;
+ destroy_schunk(fs, destroy_sc);
+ }
+
+ ossl_list_sc_insert_head(&sr->sr_chunks, sc);
+ fs->stream_chunks++;
+ DEBUG_PRINT(STDERR, "%s range: %p [ %llu, %llu ] -> [ %llu, %llu ]\n",
+ OPENSSL_FUNC, (void *)sr, sr->sr_range.start, sr->sr_range.end,
+ sc->sc_range.start, sc->sc_range.end);
+ sr->sr_range.start = sc->sc_range.start;
+ sr->sr_range.end = sc->sc_range.end;
+}
+
+static struct stream_range_t *find_range(SFRAME_SET *fs,
+ struct stream_range_t *key)
+{
+ struct stream_range_t *sr = NULL;
+
+ if (!OSSL_RBT_EMPTY(srange, &fs->ranges))
+ sr = OSSL_RBT_FIND(srange, &fs->ranges, key);
+
+ return sr;
+}
+
+/*
+ * This function help us to merge two ranges (list of chunks)
+ * into single range. Function moves the end of the range
+ * towards start. It effectively chops n last chunks until
+ * new_end is found.
+ */
+static int chop_range(SFRAME_SET *fs, struct stream_range_t *sr,
+ uint64_t new_end)
+{
+ struct stream_chunk_t *sc;
+ size_t unused_sz;
+
+ assert(sr->sr_range.end >= new_end);
+
+ while ((sc = ossl_list_sc_tail(&sr->sr_chunks)) != NULL) {
+ if (sc->sc_range.start >= new_end) {
+ ossl_list_sc_remove(&sr->sr_chunks, sc);
+ fs->stream_chunks--;
+ destroy_schunk(fs, sc);
+ } else {
+ break;
+ }
+ }
+
+ if (sc == NULL)
+ return 0;
+
+ assert(new_end <= sc->sc_range.end);
+ assert(sc->sc_range.start < new_end);
+
+ unused_sz = UINT64_TO_SIZE_T(sc->sc_range.end - new_end);
+ if (unused_sz == 0) {
+ sr->sr_range.end = new_end;
+ return 1;
+ }
+
+ sc_data_trim_right(sc, unused_sz, fs->cleanse);
+ sc->sc_range.end = new_end;
+ sr->sr_range.end = new_end;
+
+ if (sc->sc_st == ST_TYPE_PKT) {
+ rsqp_add_overhead(fs->rsqp, unused_sz);
+ DEBUG_PRINT(STDERR, "%s sc: %p unused_sz: %zu %zu -> %zu\n",
+ OPENSSL_FUNC, (void *)sc, unused_sz,
+ fs->rsqp->rsqp_pkt_overhead_sz - unused_sz,
+ fs->rsqp->rsqp_pkt_overhead_sz);
+ }
+
+ return 1;
+}
+
+/*
+ * function merges two with full overlap. The super_sr range
+ * contains the whole sub_sr range. The function destroys
+ * sub_sr and returns super_sr.
+ */
+static struct stream_range_t *merge_ranges(SFRAME_SET *fs,
+ struct stream_range_t *super_sr, struct stream_range_t *sub_sr)
+{
+ /*
+ * both ranges must not be empty
+ */
+ assert(super_sr->sr_range.start < super_sr->sr_range.end);
+ assert(sub_sr->sr_range.start < sub_sr->sr_range.end);
+ /*
+ * sub_sr and super_sr are equal ranges (sets) super_sr
+ * sub_sr is subset of super_sr (super_sr includes sub_sr).
+ */
+ assert(super_sr->sr_range.start <= sub_sr->sr_range.start
+ && super_sr->sr_range.end >= sub_sr->sr_range.end);
+
+ DEBUG_PRINT(STDERR, "%s super: %p [ %llu, %llu ], sub: %p [ %llu, %llu]\n",
+ OPENSSL_FUNC, (void *)super_sr, super_sr->sr_range.start,
+ super_sr->sr_range.end, (void *)sub_sr, sub_sr->sr_range.start,
+ sub_sr->sr_range.end);
+ destroy_srange(fs, sub_sr);
+
+ return super_sr;
+}
+
+/*
+ * The ranges are either adjacent
+ * (left_sr->sr_range.end == right_sr->sr_range.end) or there
+ * is partial overlap between left_sr and right_sr(
+ * (left_sr->sr_range.end >= right_sr->sr_range.start).
+ * If there is partial overlap, then the left range is chopped
+ * so its end is aligned with start of right_sr.
+ */
+static struct stream_range_t *append_range(SFRAME_SET *fs,
+ struct stream_range_t *left_sr, struct stream_range_t *right_sr)
+{
+ /*
+ * both ranges must not be empty
+ */
+ assert(left_sr->sr_range.start < left_sr->sr_range.end);
+ assert(right_sr->sr_range.start < right_sr->sr_range.end);
+ /*
+ * right range follows left range (left < right)
+ */
+ assert(left_sr->sr_range.end >= right_sr->sr_range.start);
+
+ DEBUG_PRINT(STDERR, "%s %p [ %llu, %llu ] + %p [ %llu, %llu ] = %p "
+ "[ %llu, %llu ]\n",
+ OPENSSL_FUNC, (void *)left_sr, left_sr->sr_range.start,
+ left_sr->sr_range.end, (void *)right_sr, right_sr->sr_range.start,
+ right_sr->sr_range.end, (void *)left_sr,
+ left_sr->sr_range.start, right_sr->sr_range.end);
+
+ /*
+ * make sure there is no overlap between ranges
+ * (right_sr->sr_range.start == left_sr->sr_range.end)
+ */
+ if (chop_range(fs, left_sr, right_sr->sr_range.start) == 0)
+ return NULL;
+
+ ossl_list_sc_join(&left_sr->sr_chunks, &right_sr->sr_chunks);
+ left_sr->sr_range.end = right_sr->sr_range.end;
+
+ destroy_srange(fs, right_sr);
+
+ return left_sr;
+}
+
+/*
+ * receives a chunk of data from stream frame.
+ * note there is a tri-state return value:
+ */
+int ossl_sframe_set_insert(SFRAME_SET *fs, UINT_RANGE *r, OSSL_QRX_PKT *pkt,
+ const unsigned char *data, int fin)
+{
+ struct stream_range_t *sr = NULL;
+ struct stream_range_t *adjacent_sr = NULL;
+ struct stream_range_t *joined_sr = NULL;
+ struct stream_chunk_t *sc = NULL;
+ struct stream_range_t key_sr = { 0 };
+
+ assert(r->start <= r->end);
+
+ /*
+ * receive the FIN frame. If FIN was not seen yet, then record
+ * FIN's offset (r->end). If FIN was received then verify FIN's
+ * offset match, error out on mismatch.
+ */
+ if (fin != 0) {
+ if (fs->fin == 0) {
+ sr = OSSL_RBT_MAX(srange, &fs->ranges);
+ if (r->end < fs->offset
+ || (sr != NULL && sr->sr_range.end > r->end)) {
+ ossl_quic_channel_raise_protocol_error(fs->rsqp->rsqp_ch,
+ OSSL_QUIC_ERR_FINAL_SIZE_ERROR,
+ OSSL_QUIC_FRAME_TYPE_STREAM_FIN,
+ "stream final size error");
+ return 0;
+ }
+ fs->fin = 1;
+ fs->fin_off = r->end;
+ } else if (fs->fin_off != r->end) {
+ ossl_quic_channel_raise_protocol_error(fs->rsqp->rsqp_ch,
+ OSSL_QUIC_ERR_FINAL_SIZE_ERROR,
+ OSSL_QUIC_FRAME_TYPE_STREAM_FIN,
+ "stream final size error");
+ return 0;
+ }
+ }
+
+ /*
+ * reject any data at or past the FIN offset (if FIN offset is set).
+ */
+ if (fs->fin != 0) {
+ if (fs->fin_off < r->end) {
+ ossl_quic_channel_raise_protocol_error(fs->rsqp->rsqp_ch,
+ OSSL_QUIC_ERR_FINAL_SIZE_ERROR,
+ (fin == 0) ? OSSL_QUIC_FRAME_TYPE_STREAM
+ : OSSL_QUIC_FRAME_TYPE_STREAM_FIN,
+ "stream final size error");
+ return 0;
+ }
+ }
+
+ if (r->end <= fs->offset) {
+ /*
+ * retransmitted range got consumed already.
+ */
+ DEBUG_PRINT(STDERR, "%s [ %llu, %llu ] <= %llu\n", OPENSSL_FUNC,
+ r->start, r->end, fs->offset);
+ if (fs->cleanse && data != NULL)
+ OPENSSL_cleanse(deconst(data), UINT64_TO_SIZE_T(r->end - r->start));
+ return 1;
+ }
+
+ if (r->start < fs->offset) {
+ /*
+ * Make sure retransmitted chunk does not reintroduce
+ * bytes which were consumed already.
+ * Make sure retransmitted chunk does not reintroduce
+ * bytes which were consumed already.
+ */
+ DEBUG_PRINT(STDERR, "%s [ %llu, %llu ] -> [ %llu, %llu ]\n", OPENSSL_FUNC,
+ r->start, r->end, fs->offset, r->end);
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(data),
+ UINT64_TO_SIZE_T(fs->offset - r->start));
+ data += fs->offset - r->start;
+ r->start = fs->offset;
+ }
+
+ key_sr.sr_range = *r;
+
+ /*
+ * Empty, 0 size chunk can carry the FIN bit only,
+ * and that has been just handled above.
+ */
+ if (r->start == r->end)
+ return 1;
+
+ assert(r->start < r->end);
+
+ if ((sr = find_range(fs, &key_sr)) == NULL) {
+ sc = new_schunk(fs, pkt, r, data);
+ if (sc == NULL)
+ goto err;
+
+ sr = create_range(fs, sc);
+ if (sr == NULL)
+ goto err;
+ DEBUG_PRINT(STDERR, "%s chunk: %p [ %llu, %llu ] new range: %p\n",
+ OPENSSL_FUNC, (void *)sc, sc->sc_range.start, sc->sc_range.end,
+ (void *)sr);
+ sc = NULL;
+ OSSL_RBT_INSERT(srange, &fs->ranges, sr);
+ fs->stream_ranges++;
+ } else {
+ /*
+ * retransmission, the whole chunk is found in existing range already
+ */
+ if (r->start >= sr->sr_range.start && r->end <= sr->sr_range.end) {
+ DEBUG_PRINT(STDERR,
+ "%s [ %llu, %llu ] found in %p [ %llu, %llu ]\n", OPENSSL_FUNC,
+ r->start, r->end, (void *)sr, sr->sr_range.start,
+ sr->sr_range.end);
+ if (fs->cleanse)
+ OPENSSL_cleanse(deconst(data),
+ UINT64_TO_SIZE_T(r->end - r->start));
+ goto done; /* Range is present already. */
+ }
+
+ switch (try_dstorage(fs, pkt, sr, r, &data)) {
+ case 0:
+ break;
+ case 1:
+ /*
+ * all data were consumed, range is updated.
+ */
+ goto range_updated;
+ default:
+ /*
+ * malloc error. forget the range we found.
+ */
+ sr = NULL;
+ goto err;
+ }
+
+ /*
+ * full overlap between sr and r is handled by replace_chunks_in_range()
+ * we call after we allocate stream chunk sc for newly received range r.
+ */
+ data = trim_partial_overlap(fs, sr, r, data);
+
+ sc = new_schunk(fs, pkt, r, data);
+ if (sc == NULL) {
+ sr = NULL;
+ goto err;
+ }
+ DEBUG_PRINT(STDERR, "%s %p [ %llu, %llu ] -> %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, (void *)sc, sc->sc_range.start, sc->sc_range.end,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+
+ /*
+ * Following calls can still be improved to handle
+ * chunks with direct storage better, but I don't think it's
+ * worth the effort. out of order short data chunks (less
+ * than DIRECT_STORAGE_SZ) should be considered exceptional.
+ */
+ if (sc->sc_range.start < sr->sr_range.start
+ && sc->sc_range.end > sr->sr_range.end) {
+ /* new chunk includes the whole range */
+ replace_chunks_in_range(fs, sr, sc);
+ sc = NULL; /* chunk got consumed */
+ } else if (sc->sc_range.end > sr->sr_range.end
+ && sc->sc_range.start <= sr->sr_range.end) {
+ append_chunk(fs, sr, sc);
+ sc = NULL; /* chunk got consumed */
+ } else if (sc->sc_range.start < sr->sr_range.start
+ && sc->sc_range.end >= sr->sr_range.start) {
+ prepend_chunk(fs, sr, sc);
+ sc = NULL; /* chunk got consumed */
+ } else {
+ assert(NULL); /* unreachable */
+ sr = NULL;
+ goto err;
+ }
+
+ range_updated:
+ /*
+ * Range got updated we may need to join updated range with
+ * another ranges which exist in tree. The current range
+ * is removed here and used as a search key. If nothing is found
+ * range is inserted back to tree.
+ *
+ * If another range is found the ranges are merged to single
+ * range. The process repeats (merging ranges may be cascade effect,
+ * where more ranges collapse to single range). The merge result is
+ * removed from tree and used as a search key to find another range.
+ * If nothing is found then update is done. otherwise the ranges
+ * are merged again.
+ */
+ OSSL_RBT_REMOVE(srange, &fs->ranges, sr);
+ fs->stream_ranges--;
+ /*
+ * _INSERT() returns range where sr needs to be joined
+ */
+ adjacent_sr = OSSL_RBT_INSERT(srange, &fs->ranges, sr);
+
+ while (adjacent_sr != NULL) {
+ OSSL_RBT_REMOVE(srange, &fs->ranges, adjacent_sr);
+ DEBUG_PRINT(STDERR, "%s %p [ %llu, %llu ] >< %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, (void *)sr, sr->sr_range.start, sr->sr_range.end,
+ (void *)adjacent_sr, adjacent_sr->sr_range.start,
+ adjacent_sr->sr_range.end);
+ fs->stream_ranges--;
+
+ if (sr->sr_range.start <= adjacent_sr->sr_range.start
+ && sr->sr_range.end >= adjacent_sr->sr_range.end) {
+ /*
+ * adjacent_sr subset of sr
+ */
+ joined_sr = merge_ranges(fs, sr, adjacent_sr);
+ } else if (sr->sr_range.start >= adjacent_sr->sr_range.start
+ && sr->sr_range.end <= adjacent_sr->sr_range.end) {
+ /*
+ * sr subset of adjacent_sr
+ */
+ joined_sr = merge_ranges(fs, adjacent_sr, sr);
+ } else if (sr->sr_range.start < adjacent_sr->sr_range.start
+ && sr->sr_range.end >= adjacent_sr->sr_range.start) {
+ /*
+ * adjacent_sr follows sr
+ */
+ assert(sr->sr_range.end < adjacent_sr->sr_range.end);
+ joined_sr = append_range(fs, sr, adjacent_sr);
+ } else if (sr->sr_range.start <= adjacent_sr->sr_range.end
+ && sr->sr_range.end > adjacent_sr->sr_range.end) {
+ /*
+ * sr follows adjacent_sr
+ */
+ assert(sr->sr_range.end > adjacent_sr->sr_range.end);
+ joined_sr = append_range(fs, adjacent_sr, sr);
+ } else {
+ assert(NULL); /* never happens */
+ joined_sr = NULL;
+ }
+ if (joined_sr == NULL)
+ goto err;
+
+ sr = joined_sr;
+ adjacent_sr = OSSL_RBT_INSERT(srange, &fs->ranges, sr);
+ }
+ fs->stream_ranges++;
+ }
+
+done:
+ return 1;
+
+err:
+ destroy_schunk(fs, sc);
+ destroy_srange(fs, sr);
+ destroy_srange(fs, adjacent_sr);
+ /*
+ * not enough memory (or another serious error) has occurred,
+ * any error here is fatal as some stream chunks could be ACKed
+ * already (RFC 9000, 31.1 Packet processing). At least stream
+ * needs to be reset. Preferred action is to close connection.
+ */
+
+ return 0;
+}
+
+/*
+ * peeks over the continuous range which is ready to
+ * read. ready to read means the fs->offset must be
+ * found in range. Also fs->offset can not reach past
+ * the first gap in stream data received so far, thus
+ * the only range we can use for peek operation is
+ * OSSL_RBT_MIN(&fs->ranges).
+ *
+ * NOTE: it is unsafe to carry more _peek() operations
+ * over single SFRMAE_SET.
+ */
+int ossl_sframe_set_peek(SFRAME_SET *fs, void **iterator,
+ UINT_RANGE *range, const unsigned char **data,
+ int *fin)
+{
+ uint64_t start;
+ struct stream_range_t *sr = (struct stream_range_t *)*iterator;
+ struct stream_chunk_t *sc = NULL;
+
+ if (sr == NULL) {
+ sr = OSSL_RBT_MIN(srange, &fs->ranges);
+ start = fs->offset;
+ if (sr != NULL) {
+ sc = ossl_list_sc_head(&sr->sr_chunks);
+ sr->sr_it_sc = NULL;
+ assert(sc->sc_range.start == sr->sr_range.start);
+ }
+ /*
+ * no chunks are ready to be consumed, if there is a gap.
+ */
+ if (sc != NULL && sc->sc_range.start > start) {
+ DEBUG_PRINT(STDERR, "%s sc: %p sr: %p sc->start %llu, fs->offset: %llu\n",
+ OPENSSL_FUNC, (void *)sc, (void *)sr, sc->sc_range.start, start);
+ sc = NULL;
+ }
+ } else if (sr == OSSL_RBT_MIN(srange, &fs->ranges) && sr->sr_it_sc != NULL) {
+ /*
+ * sr == _RB_MIN(), revalidates iterator in case the range we
+ * work with disappears because it's got joined with other range
+ * after new chunk arrival. perhaps not issue now as those operations
+ * are mutually exclusive now.
+ *
+ * sr->sr_it_sc becomes NULL on _move() or _flatten() operation.
+ *
+ * We may need to revisit iterator implementation as current
+ * iterator supports one caller only.
+ */
+ start = sr->sr_it_sc->sc_range.end;
+ sc = ossl_list_sc_next(sr->sr_it_sc);
+ assert(sc == NULL || sc->sc_range.start == start);
+ assert(sc == NULL || sc->sc_range.start < sc->sc_range.end);
+ } else {
+ /* iterator got invalidated by move/flatten operation on range */
+ DEBUG_PRINT(STDERR, "%s iterator got invalidated\n", OPENSSL_FUNC);
+ return 0;
+ }
+
+ range->start = start;
+
+ if (sc == NULL) {
+ range->end = start;
+ *data = NULL;
+ *iterator = NULL;
+
+ /*
+ * set fin only if we are at the end of the stream and application
+ * can read from the stream. In other words: there must be no gap
+ * between FIN offset and offset where application reads from stream.
+ */
+ if (fs->fin && start == fs->fin_off)
+ *fin = fs->fin;
+ else
+ *fin = 0;
+
+ DEBUG_PRINT(STDERR, "%s no more chunks\n", OPENSSL_FUNC);
+
+ return 0;
+ }
+
+ range->end = sc->sc_range.end;
+ /* chunk keeps data always attached, data dies with chunk */
+ assert(sc->sc_data != NULL);
+ assert(sc->sc_range.start <= start);
+ *data = sc->sc_data + (start - sc->sc_range.start);
+ *fin = fs->fin && sc->sc_range.end == fs->fin_off;
+
+ if (sr->sr_it_sc != NULL)
+ DEBUG_PRINT(STDERR, "%s %p [ %llu, %llu ] %p [ %llu, %llu ]\n",
+ OPENSSL_FUNC, (void *)sr->sr_it_sc,
+ sr->sr_it_sc->sc_range.start, sr->sr_it_sc->sc_range.end,
+ (void *)sc, sc->sc_range.start, sc->sc_range.end);
+
+ sr->sr_it_sc = sc;
+ *iterator = sr;
+
+ /*
+ * peek operation indicates error if there are no data to read
+ * in range.
+ */
+ DEBUG_PRINT(STDERR,
+ "%s peek range: [ %llu, %llu ] range: %p [ %llu, %llu ]\n", OPENSSL_FUNC,
+ range->start, range->end, (void *)sr, sr->sr_range.start,
+ sr->sr_range.end);
+
+ return (range->start == range->end) ? 0 : 1;
+}
+
+void ossl_sframe_set_destroy_ranges(SFRAME_SET *fs)
+{
+ struct stream_range_t *sr, *save_sr;
+
+ OSSL_RBT_FOREACH_SAFE (sr, srange, &fs->ranges, save_sr) {
+ OSSL_RBT_REMOVE(srange, &fs->ranges, sr);
+ fs->stream_ranges--;
+ destroy_srange(fs, sr);
+ }
+}
+
+/*
+ * moves the read offset, freeing all chunks which end offset
+ * is less than new_offset
+ * sc->sc_range.end < new_offset
+ */
+int ossl_sframe_set_move_offset(SFRAME_SET *fs, uint64_t new_offset)
+{
+ struct stream_range_t *sr = OSSL_RBT_MIN(srange, &fs->ranges);
+ struct stream_chunk_t *sc, *save_sc;
+ size_t unused_sz;
+
+ if (new_offset == fs->offset)
+ return 1;
+
+ /*
+ * Offset can move forward within the continuous head range only.
+ * It can not move backward, into a gap or past the head range end.
+ */
+ if (sr == NULL || new_offset < fs->offset
+ || new_offset < sr->sr_range.start || new_offset > sr->sr_range.end)
+ return 0;
+
+ fs->offset = new_offset;
+
+ OSSL_LIST_FOREACH_DELSAFE (sc, save_sc, sc, &sr->sr_chunks) {
+ if (new_offset >= sc->sc_range.end) {
+ ossl_list_sc_remove(&sr->sr_chunks, sc);
+ fs->stream_chunks--;
+ if (sr->sr_it_sc == sc)
+ sr->sr_it_sc = NULL; /* invalidate iterator chunk */
+ destroy_schunk(fs, sc);
+ } else {
+ break;
+ }
+ }
+
+ DEBUG_PRINT(STDERR, "%s offset: %llu -> %llu range: %p [ %llu, %llu ] -> ",
+ OPENSSL_FUNC, fs->offset - new_offset, new_offset,
+ (void *)sr, sr->sr_range.start, sr->sr_range.end);
+
+ if (sc == NULL) {
+ /*
+ * the whole range was consumed.
+ * this step invalidates iterator we use in ossl_sframe_peek()
+ */
+ OSSL_RBT_REMOVE(srange, &fs->ranges, sr);
+ destroy_srange(fs, sr);
+ fs->stream_ranges--;
+ DEBUG_PRINT(STDERR, "[ NULL ]\n");
+ } else {
+ unused_sz = UINT64_TO_SIZE_T(new_offset - sc->sc_range.start);
+ sc_data_trim_left(sc, unused_sz, fs->cleanse);
+ sc->sc_range.start = new_offset;
+ sr->sr_range.start = new_offset;
+ DEBUG_PRINT(STDERR, "[ %lli, %llu ]\n",
+ sr->sr_range.start, sr->sr_range.end);
+
+ if (sc->sc_st == ST_TYPE_PKT) {
+ rsqp_add_overhead(fs->rsqp, unused_sz);
+ DEBUG_PRINT(STDERR, "%s sc: %p unused_sz: %zu %zu -> %zu\n",
+ OPENSSL_FUNC, (void *)sc, unused_sz,
+ fs->rsqp->rsqp_pkt_overhead_sz - unused_sz,
+ fs->rsqp->rsqp_pkt_overhead_sz);
+ }
+ }
+
+ return 1;
+}
+
+/* Contiguous bytes available from fs->offset, in O(log n): the first range. */
+int ossl_sframe_set_avail(SFRAME_SET *fs, uint64_t *avail, int *fin)
+{
+ struct stream_range_t *sr = OSSL_RBT_MIN(srange, &fs->ranges);
+
+ if (sr != NULL && sr->sr_range.start <= fs->offset
+ && sr->sr_range.end > fs->offset)
+ *avail = sr->sr_range.end - fs->offset;
+ else
+ *avail = 0;
+ *fin = (fs->fin && fs->offset + *avail == fs->fin_off) ? 1 : 0;
+ return 1;
+}
+
+QUIC_RSTREAM_QPARM *ossl_quic_rstream_qparm_new(QUIC_CHANNEL *ch)
+{
+ QUIC_RSTREAM_QPARM *rsqp;
+
+ rsqp = OPENSSL_malloc(sizeof(QUIC_RSTREAM_QPARM));
+ if (rsqp != NULL) {
+ rsqp->rsqp_pkt_overhead_treshold = PKT_BUFFER_OVERHEAD_TRESHOLD;
+ rsqp->rsqp_pkt_overhead_sz = 0;
+ rsqp->rsqp_ch = ch;
+ }
+
+ return rsqp;
+}
+
+void ossl_quic_rstream_qparm_destroy(QUIC_RSTREAM_QPARM *rsqp)
+{
+ if (rsqp != NULL) {
+ assert(rsqp->rsqp_pkt_overhead_sz == 0);
+ OPENSSL_free(rsqp);
+ }
+}
diff --git a/deps/openssl/openssl/ssl/record/methods/tls1_meth.c b/deps/openssl/openssl/ssl/record/methods/tls1_meth.c
index ed4a436dffc..10f4d241133 100644
--- a/deps/openssl/openssl/ssl/record/methods/tls1_meth.c
+++ b/deps/openssl/openssl/ssl/record/methods/tls1_meth.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 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
@@ -261,6 +261,14 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
!= 0) {
unsigned char *seq;
+ /*
+ * Publicly invalid: the record is shorter than the mandatory
+ * AEAD overhead. Leave alert handling to the caller so TLS
+ * reports bad_record_mac and DTLS silently discards the record.
+ */
+ if (!sending && reclen[ctr] < rl->eivlen + rl->taglen)
+ return 0;
+
seq = rl->sequence;
if (rl->isdtls) {
diff --git a/deps/openssl/openssl/ssl/ssl_lib.c b/deps/openssl/openssl/ssl/ssl_lib.c
index ba494f5fc0d..b1b36c80a82 100644
--- a/deps/openssl/openssl/ssl/ssl_lib.c
+++ b/deps/openssl/openssl/ssl/ssl_lib.c
@@ -5485,6 +5485,7 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
{
CERT *new_cert;
+ uint32_t *new_valid_flags = NULL;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
/* TODO(QUIC FUTURE): Add support for QUIC */
@@ -5509,6 +5510,34 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
*/
if (!ossl_assert(sc->sid_ctx_length <= sizeof(sc->sid_ctx)))
goto err;
+
+ /*
+ * |valid_flags| is sized from the number of signature algorithm slots of
+ * the SSL_CTX the connection was created from, so it must be resized for
+ * the replacement context.
+ *
+ * The built-in slots are indexed by the fixed SSL_PKEY_* constants and so
+ * mean the same thing in either context. They are preserved because they
+ * may already hold peer signature algorithm state which does not depend
+ * on the SSL_CTX. A provider slot index is instead a position in one
+ * context's provider list, so the same index denotes a different
+ * algorithm here and the old value cannot be carried over. They are reset
+ * rather than recomputed: recomputing them means recomputing the shared
+ * signature algorithms against the replacement context, which would let
+ * its preferences take effect on an established connection.
+ */
+ if (sc->s3.tmp.valid_flags != NULL) {
+ /* Should never happen: ssl_cert_new() enforces this */
+ if (!ossl_assert(new_cert->ssl_pkey_num >= SSL_PKEY_NUM))
+ goto err;
+ new_valid_flags = OPENSSL_zalloc(new_cert->ssl_pkey_num
+ * sizeof(*new_valid_flags));
+ if (new_valid_flags == NULL)
+ goto err;
+ memcpy(new_valid_flags, sc->s3.tmp.valid_flags,
+ SSL_PKEY_NUM * sizeof(*new_valid_flags));
+ }
+
if (!SSL_CTX_up_ref(ctx))
goto err;
@@ -5525,12 +5554,18 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
ssl_cert_free(sc->cert);
sc->cert = new_cert;
+ sc->ssl_pkey_num = new_cert->ssl_pkey_num;
+ if (new_valid_flags != NULL) {
+ OPENSSL_free(sc->s3.tmp.valid_flags);
+ sc->s3.tmp.valid_flags = new_valid_flags;
+ }
SSL_CTX_free(ssl->ctx); /* decrement reference count */
ssl->ctx = ctx;
return ssl->ctx;
err:
+ OPENSSL_free(new_valid_flags);
ssl_cert_free(new_cert);
return NULL;
}
@@ -7005,8 +7040,10 @@ static int nss_keylog_int(const char *prefix,
*/
prefix_len = strlen(prefix);
out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3;
- if ((out = cursor = OPENSSL_malloc(out_len)) == NULL)
+ if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) {
+ SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
return 0;
+ }
memcpy(cursor, prefix, prefix_len);
cursor += prefix_len;
diff --git a/deps/openssl/openssl/ssl/statem/statem_clnt.c b/deps/openssl/openssl/ssl/statem/statem_clnt.c
index 0279a62abd2..bdf99cd35fd 100644
--- a/deps/openssl/openssl/ssl/statem/statem_clnt.c
+++ b/deps/openssl/openssl/ssl/statem/statem_clnt.c
@@ -2819,7 +2819,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s,
* tickets for longer than 7 days.
*/
if (ticket_lifetime_hint > 604800) {
- ticket_lifetime_hint = 604800;
+ s->session->ext.tick_lifetime_hint = 604800;
}
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
diff --git a/deps/openssl/openssl/ssl/statem/statem_dtls.c b/deps/openssl/openssl/ssl/statem/statem_dtls.c
index f62b757721f..96ea03ab73c 100644
--- a/deps/openssl/openssl/ssl/statem/statem_dtls.c
+++ b/deps/openssl/openssl/ssl/statem/statem_dtls.c
@@ -1218,6 +1218,8 @@ int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found)
memcpy(s->init_buf->data, frag->fragment,
frag->msg_header.msg_len + header_length);
s->init_num = frag->msg_header.msg_len + header_length;
+ /* Always retransmit from the start, not wherever init_off was left */
+ s->init_off = 0;
dtls1_set_message_header_int(s, frag->msg_header.type,
frag->msg_header.msg_len,
diff --git a/deps/openssl/openssl/util/missingcrypto-internal.txt b/deps/openssl/openssl/util/missingcrypto-internal.txt
index 54e1bc9ba7d..41115bbec3b 100644
--- a/deps/openssl/openssl/util/missingcrypto-internal.txt
+++ b/deps/openssl/openssl/util/missingcrypto-internal.txt
@@ -6,3 +6,4 @@ ossl_do_PVK_header(3)
ossl_do_blob_header(3)
ossl_b2i(3)
ossl_b2i_bio(3)
+ossl_rbtree(3)
diff --git a/deps/openssl/openssl/util/missingcrypto.txt b/deps/openssl/openssl/util/missingcrypto.txt
index ad0f165fa6b..2059b9414ab 100644
--- a/deps/openssl/openssl/util/missingcrypto.txt
+++ b/deps/openssl/openssl/util/missingcrypto.txt
@@ -1035,8 +1035,6 @@ X509V3_EXT_conf(3)
X509V3_EXT_conf_nid(3)
X509V3_EXT_get(3)
X509V3_EXT_get_nid(3)
-X509V3_EXT_nconf(3)
-X509V3_EXT_nconf_nid(3)
X509V3_EXT_val_prn(3)
X509V3_NAME_from_section(3)
X509V3_add_standard_extensions(3)
diff --git a/deps/openssl/openssl/util/perl/OpenSSL/Test.pm b/deps/openssl/openssl/util/perl/OpenSSL/Test.pm
index 3123c1d3ec2..3381369875f 100644
--- a/deps/openssl/openssl/util/perl/OpenSSL/Test.pm
+++ b/deps/openssl/openssl/util/perl/OpenSSL/Test.pm
@@ -1,4 +1,4 @@
-# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2026 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
@@ -1288,11 +1288,13 @@ sub __decorate_cmd {
my $display_cmd = "$cmdstr$stdin$stdout$stderr";
- # VMS program output escapes TAP::Parser
- if ($^O eq 'VMS') {
- $stderr=" 2> ".$null
- unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};
- }
+ # Under a non-verbose harness nothing drains the command's stderr, so a
+ # chatty command can fill the pipe buffer and then block forever waiting
+ # for a reader that never comes. Send it to the null device unless the
+ # recipe asked for a specific redirection. On VMS this also keeps
+ # program output from escaping TAP::Parser.
+ $stderr=" 2> ".$null
+ unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE};
$cmdstr .= "$stdin$stdout$stderr";
diff --git a/deps/openssl/openssl/util/perl/OpenSSL/paramnames.pm b/deps/openssl/openssl/util/perl/OpenSSL/paramnames.pm
index 262c184ca2d..0920931fd96 100644
--- a/deps/openssl/openssl/util/perl/OpenSSL/paramnames.pm
+++ b/deps/openssl/openssl/util/perl/OpenSSL/paramnames.pm
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2023-2026 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
@@ -169,6 +169,7 @@ my %params = (
'DIGEST_PARAM_SIZE' => "size", # size_t
'DIGEST_PARAM_XOF' => "xof", # int, 0 or 1
'DIGEST_PARAM_ALGID_ABSENT' => "algid-absent", # int, 0 or 1
+ 'DIGEST_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
# MAC parameters
'MAC_PARAM_KEY' => "key", # octet string