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