With certificates no longer rebound after decoding,
ossl_cms_resolve_libctx() and ossl_pkcs7_resolve_libctx() only point
the signer and recipient infos at their container's context. Name
them for that.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 26 19:04:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32690
The X509_PUBKEY in a request holds the library context and property
query it needs to decode the public key, and the X509_REQ carried a
copy, just as X509 did. Worse, X509_REQ_new_ex() created the request
with ASN1_item_new() rather than ASN1_item_new_ex(), so only the copy
got the context and the public key was decoded in the default one.
Drop the copy, create the request with ASN1_item_new_ex() so the
X509_PUBKEY is seeded, and take the context from it in
X509_REQ_sign(), X509_REQ_digest() and d2i_X509_REQ_bio(). Remove
ossl_x509_req_set0_libctx(), which had no other callers.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 26 19:04:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32690
The X509_PUBKEY inside a certificate has a library context and
property query because it needs them to decode the public key. The
X509 carried a second copy, which the ASN.1 decoder cannot reach: it
seeds the X509_PUBKEY with the context it is given, for X509_new_ex()
+ d2i_X509() as well as for certificates embedded in a CMS, PKCS#7 or
CMP structure, but not the X509. ossl_x509_set0_libctx() existed only
to patch the copy afterwards, on refcounted certificates others may
share, and left the public key in the old context.
Drop the copy. The functions that fetch algorithms for a certificate
take the context from its public key, which is the value they were
seeded with, so their behaviour is unchanged. Remove
ossl_x509_set0_libctx() and its callers. X509_PUBKEY_set() gives a
replacement key the context of the one it replaces, so
X509_set_pubkey() keeps it.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 26 19:04:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32690
OSSL_CMP_MSG_http_perform() decoded responses with a NULL library
context, so the certificates in them, and the public keys decoded
from those, belonged to the default context. Setting the CMP context
on newCert afterwards reached the X509 but not its public key.
Decode in the CMP context instead.
Add internal ossl_x509_digest_sig_ex() taking the library context
explicitly and use it with the CMP context's when hashing newCert
for certConf. X509_digest_sig() is unchanged.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 26 19:04:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32690
X509_STORE_CTX_new_ex(3) documents that algorithms fetched while
processing with the store context come from its library context and
property query. The verifier did not do that: X509_verify(),
X509_CRL_verify() and X509_get_signature_info() fetch from the
certificate's or CRL's own context, the one it was decoded in, so a
chain of certificates decoded in the default context and verified
through a store context created in a FIPS context had its signatures
checked by the default provider.
Add internal ossl_x509_verify_ex(), ossl_x509_crl_verify_ex() and
ossl_x509_get_signature_info_ex() that take the library context and
property query explicitly, and use them from the verifier with the
store context's. The public functions are unchanged and still use the
object's own context.
Add a test verifying certificates decoded in the default context
through a store context whose library context has no signature
algorithms; it must fail.
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 26 19:04:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32690
Add a new keyword 'cex_min_bits:<bits>' for the OPENSSL_s390xcap environment
variable to specify the minimum number of bits that the exponent must have
to offload the operation to the crypto card. Operations with smaller exponents
fall back to software calculation. Mod-expo operations with small exponents
are faster in software than via the crypto card.
The default minimum exponent size is 2048 bits, but this can be changed via
the OPENSSL_s390xcap environment variable.
For mod-expo operations the exponent is checked, and for RSA CRT operations
the modulus is checked to have the minimum bit size. RSA public key operations
usually have small exponents, so they are most likely always performed in
software.
Checking the bit size of a BIGNUM may or may not be constant-time, dependent
on the BN_FLG_CONSTTIME flag of the BIGNUM. For RSA CRT operations, the bit
size of the modulus is checked. The modulus is public information, so no
constant-time issue here. For mod-expo operations with the public exponent
it is also not a constant-time issue, because the public exponent is also
public information. For mod-expo operations with the private exponent, the
size of the private exponent is usually the same as the size of the modulus,
which is public information. For DH mod-expo operations with the private key,
the size of the private key is usually dependent on the DH group that is
used, and this is also public information. Nevertheless, private exponents
better have the BN_FLG_CONSTTIME flag set. For RSA this is the case, and for
DH it is also the case when flag DH_FLAG_CACHE_MONT_P is set, which is always
done (dh_init() sets the flag unconditionally). Furthermore, flag
BN_FLG_CONSTTIME is set for the private key in ossl_dh_generate_public_key().
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Neil Horman <nhorman@openssl.org>
MergeDate: Fri Oct 23 15:20:45 2026
(Merged from https://github.com/openssl/openssl/pull/31630)
SSL_poll() cleaned up QUIC reactor wait registrations in item-array
order. Leaving a reactor can block while its notifier is signalled, so
two callers spanning the same reactors could each wait on one reactor
while still registered on another. The translation abort path has the
same ordering problem.
Split QUIC leave into two phases: deregister from every QUIC reactor,
then wait for any notification cycles still pending. For QUIC-only poll
sets this removes every waiter registration before any notifier wait.
DTLS listener cleanup is unchanged. Guard the QUIC drain call for
no-quic builds.
Phase 2 also prevents an immediate re-registration from keeping the
notifier signalled. Capture notify_generation during deregistration so a
wait is bounded to the observed cycle. Apply the same generation bound
to the combined single-reactor leave operation.
Exercise real SSL_poll cleanup on two reactors in both the post-poll and
translation-abort paths, including repeated items sharing a reactor.
Check that a delayed phase-2 waiter completes while a later notification
cycle remains signalled.
Fixes#32130
Assisted-by: OpenCode:GLM-5.2
Assisted-by: Codex:gpt-5.6-sol
Assisted-by: Codex:gpt-6-astra
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Merge-date: Tue Oct 20 12:29:05 2026
Merged-from: https://github.com/openssl/openssl/pull/32137
The demux free list caches released URXEs so a receive burst can be
served without allocating, but nothing bounds it: a transient flood
raising the per-connection receive queues also raises the free list's
retained high-water mark for the remaining lifetime of the listener.
Add a per-demux limit, ossl_dgram_demux_set_max_free_urxe(), enforced
in ossl_dgram_demux_release_urxe(): a URXE released while the free list
is at its limit is freed instead of cached, so the bound is strict
and no later trim pass is needed. Freeing there honours the documented
contract that no reference may be made to a URXE or its buffer after
it is released, and no release caller touches the entry afterwards.
The DTLS listener sets the limit to DEMUX_MAX_FREE_URXE, two receive
batches, so one full batch can always be cached; QUIC keeps the default
unbounded behaviour.
Resolves: https://github.com/openssl/openssl/issues/33173
Assisted-by: Claude Code:moonshotai/kimi-k3
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Ryan Hooper <ryanh@openssl.foundation>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Merge-date: Wed Oct 14 10:54:56 2026
Merged-from: https://github.com/openssl/openssl/pull/33197
The DTLS listener queues datagrams from a known peer into a per-connection
list (DTLS_RX::urxe_pending) with no limit on count or bytes. A reachable
peer that completes the ordinary cookie exchange can grow one parked
connection's queue without bound as long as the application keeps
the shared demux pumped, moving datagrams into userspace past the bound
the kernel socket buffer would otherwise provide.
Cap the queue at OSSL_DTLS_RX_DEFAULT_MAX_QUEUED (128) datagrams
per connection - a datagram count, not a byte cap. Every queued URXE
holds a buffer of at least the listener's maximum datagram size whatever
the datagram's length, so a full queue costs about 295 KB per connection
at the default 2000-byte size, roughly one default kernel socket receive
buffer; across a full 256-connection listener budget that is about 75 MB.
The queue is consumed FIFO, so on overflow the oldest datagram is evicted
rather than the newest: a DTLS flight can span several datagrams,
and under overload keeping the newest biases the queue toward the flight
the peer just sent instead of stale fragments of an older one.
The evicted URXE is unhooked under rx->mutex and released to the demux
after dropping it, so demux->mutex is never taken while rx->mutex
is held.
References: https://github.com/openssl/openssl/issues/33173
Assisted-by: Claude Code:moonshotai/kimi-k3
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Ryan Hooper <ryanh@openssl.foundation>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Merge-date: Wed Oct 14 10:54:54 2026
Merged-from: https://github.com/openssl/openssl/pull/33197
There was no way to learn the length of an opaque EVP_SKEY without
exporting the raw key, which is impossible for non-exportable keys
(e.g. keys held in hardware).
Let EVP_SKEY_get0_raw_key() accept a NULL key pointer, in which case
only the length is returned. It is read from the
OSSL_SKEY_PARAM_KEY_LENGTH key parameter, exported with
OSSL_SKEYMGMT_SELECT_PARAMETERS, so the secret key is never exported.
The built-in generic and AES key managements now report that parameter.
Fixes: https://github.com/openssl/openssl/issues/32998
Assisted-by: Claude Code:claude-opus-5-5
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Merge-date: Mon Oct 5 10:28:09 2026
Merged-from: https://github.com/openssl/openssl/pull/33035
Despite its name, X509_OBJECT_up_ref_count() does not reference count the
X509_OBJECT itself. With X509_OBJECT being opaque there is nothing useful an
application can do with it.
Assisted-by: Claude:claude-fable-5-1
Fixes#21121
Reviewed-by: Frederik Wedel-Heinen <fwh.openssl@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Fri Oct 2 08:09:09 2026
Merged-from: https://github.com/openssl/openssl/pull/32823
Replaces the length arithmetic and per-byte snprintf hex loop.
id_len is asserted against QUIC_MAX_CONN_ID_LEN, which the wire
parser already enforces.
ossl_determine_dirsep was awkwardly a char, with only one caller
being this function - remove it from internal/common.h and make
it a static returning a string.
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Merge-date: Fri Oct 2 07:18:25 2026
Merged-from: https://github.com/openssl/openssl/pull/31550
After processing the client's Finished or a peer KeyUpdate, the read
record layer advanced to the new epoch and the old one was freed
immediately. If the ACK we sent for that message was lost, the peer's
retransmission arrived at the now-discarded epoch: it could not be
authenticated, so no replacement ACK was ever produced and the peer
exhausted its retransmission budget.
RFC9147 section 5.8.1 requires the finished peer to ACK retransmissions
of the other side's final flight, and section 8 requires receive keys
from before a KeyUpdate to be retained until decryption with the new
keys succeeds. Retain exactly one prior read epoch's record layer
instead of freeing it, add a record-layer dispatch hook so the DTLS
method can take ownership of it, and authenticate a record at that
epoch with its own retained keys and replay window when the current
epoch's epoch-bits check would otherwise just drop it. This isn't
limited to replacing lost ACKs: a previous *application* epoch (from
KeyUpdate recovery) can also legitimately supply application data that
arrives reordered relative to the epoch change.
Successful authentication with the retained keys doesn't by itself
prove a record is a retransmission, so let it reach the handshake
layer instead of deciding that here: the DTLS 1.2-only Finished
special case (retransmit our own flight) is skipped for DTLS 1.3, and
the existing out-of-sequence duplicate-ACK path is widened from
post-handshake epochs only to include the epoch a Finished is sent
at -- the sequence and epoch checks in that path are what actually
decide whether a retained-epoch record can be acknowledged.
Fixes: #32891
Assisted-by: Claude:claude-sonnet-5
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Fri Oct 2 06:36:27 2026
Merged-from: https://github.com/openssl/openssl/pull/32963
The vectorization is implemented using vector extensions (of gcc/clang)
and will work on any architecture with 128 bit vector registers that has
suitable builtins like `vec_mulh` for the high part of a multiplication.
We also optimize the multiplication in `F_{q^2}` using a twisted
Karatsuba multiplication.
Bob has only been used for writing the comments based on a formal
verification of the code, and for the extraction of the constants
at the beginning of `ml_kem_vec128.c`.
Enable this for s390x.
Signed-off-by: Timo Keller <tkeller@linux.ibm.com>
Assisted-by: IBM Bob:2.0.3
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Tue Sep 29 16:47:13 2026
Merged-from: https://github.com/openssl/openssl/pull/31929
These are derived just-in-time, during any actual CRL processing.
Fixes CVE-2026-35189
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Bob Beck <beck@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
Merge-date: Tue Sep 29 11:11:18 2026
When FIN stream frame is received at particular offset,
then the FIN's offset must be the largest offset kept
in stream reassembly buffer.
Receiving stream frame with offset larger than FIN frame
must be reported as protocol violation and connection
must be closed.
In order to report protocol violation error the stream
reassembly module must have a reference to QUIC_CHANNEL
object where particular stream belongs to. The refernce
to channel is part of QUIC_RSTREAM_QPARAM structure.
This change makes stream quality parameter mandatory.
Co-authored-by: Jakub Zelenka <bukka@php.net>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Merge-date: Sat Sep 26 11:35:33 2026
Merged-from: https://github.com/openssl/openssl/pull/32038
There is currently no limit on how many bytes of packet
buffers each stream can hold in memory. To monitor and limit
the size of packet buffers used by stream the change accounts
so called stream chunk overhead which is a delta between
actual datagram size of packet delivering the particular
stream chunk and chunk itself. As soon as the chunk overhead
exceeds ~64kB for all stream chunks kept in receive buffer,
the newly received chunks will be moved from packet buffer
to stream buffer.
The packet buffer overhead limit is held in newly introduced
structure QUIC_RSTREAM_QPARAM (RX stream quality parameter).
If new additional quality parameters are added, then those
should be part of QUIC_RSTREAM_QPARAM structure.
this changeset introduces QUIC_RSTREAM_QPARAM
the the rsqp (reead stream quality parameter) enables
channel to control quality of RX stream. quality currently
means the packet buffer overhead. more parameters
may be added later.
Fixes: CVE-2026-54873
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Merge-date: Sat Sep 26 11:35:32 2026
Merged-from: https://github.com/openssl/openssl/pull/32038
The new implementation makes clear distinction between stream chunk
and stream range.
The strem chunk is defined by its `start` and `end` offset with
respect to offset 0 (the start of the stream). The `start` < `end`.
The lenght of the stream chunk is `end - start`. The stream chunks
are delivered as QUIC stream frames.
The stream range is list of stream chunks which together create
one continuous range of stream. The range is also deined by
`start` and `end` offset. The ranges are kept in R/B tree.
The chunks which are arriving in order are kept in list which
forms one node of R/B tree. If newly arriving stream chunk
can not be inserted to existing stream range for example because
chunk.start > range.end (there is a gap between existing range and
new chunk), then the new range is created and inserted to R/B
tree.
If the newly arriving chunk closes the gap between two existing
ranges, the ranges are merged to single tree node. The join
proces uses list join operation with O(1) complexity to make
the new continuous range of stream chunks.
In a nutshell: stream reassembly process is R/B tree look up/insert
with tail/head insertion to list.
There is also a preparatory work that will allow us to deal with
memory hog issue. Currently the QUIC stack keeps all stream
frame data on packet buffers until data is moved to application.
On hone hand, this saves one copy opration between on the other
hand it may cause receiver to hold lot more memory than currently
needed. Consider situation where QUIC stack needs to hold reference
to whole packet buffer, just because of sinle 1byte stream chunk.
The 1byte stream chunk (at let's say offset 10) can not be moved
to application yet, because QUIC stack is waiting for data at
offset 0 - 9. Such buffer might be waiting in reassembly queue
for a long time holding a reference to whole packet.
To mitigate this we need to allow the QUIC stack to move data
from packet buffers to stream buffers. The logic which decides
when data should be moved from packet buffers is missing in this
change. Here we just bring the code that supports improved
buffer handling. The data for short stream frames/chunks (16B)
are kept inside the stream chunk structure itself (this is referred
as direct storage, or dstorage). The code coalesces data from adjacent
stream frames into dstorage until it fill up. Once dstorage is full the
new stream chunk is allocated and added to range.
Larger stream chunks (size > 16B) get buffer from the heap.
It is then linked to stream buffer.
This commit just brings the quic_strm_reas.c in. It is not currently
hooked to build.
Fixes: CVE-2026-42772
Co-authored-by: Tomáš Mráz <tm@t8m.info>
Co-authored-by: Jakub Zelenka <bukka@php.net>
Co-authored-by: Mounir IDRASSI <mounir.idrassi@amcrypto.jp>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Merge-date: Sat Sep 26 11:35:31 2026
Merged-from: https://github.com/openssl/openssl/pull/32038
Re-formatting was done using the following command:
for i in `git grep -l 'OSSL_LIST\|PRIORITY_QUEUE_OF\|SPARSE_ARRAY_OF' \
-- '*.c' '*.h' '*.c.in' '*.h.in'`; do \
clang-format-21 --style=file:.clang-format -i "$i"; \
done
Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Milan Broz <mbroz@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Sep 24 09:01:06 2026
Merged-from: https://github.com/openssl/openssl/pull/32304
Introduce PKCS12_PARSE_CTX opaque context for PKCS12_parse_ex(), replacing
the growing parameter list pattern. Add PKCS12_decrypt_secretbag() for
decrypting secret bags and PKCS12_SAFEBAG_get1_skey() for converting
decrypted PKCS8 data to EVP_SKEY, following the existing private key
pattern (PKCS12_decrypt_skey_ex + EVP_PKCS82PKEY_ex).
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Simo Sorce <simo@redhat.com>
MergeDate: Thu Sep 24 07:34:22 2026
(Merged from https://github.com/openssl/openssl/pull/30937)
MSVC 14.51 builds of the VAES-512 CTR kernel return a wrong keystream for
AES-192 and AES-256 whenever the block count leaves a 4-block (single-zmm)
step. The default CTR-DRBG runs on AES-256-CTR, so this also corrupts
random byte generation and makes unrelated tests fail.
The same code is correct on VAES hardware built with gcc, so keep the hook
enabled there and off for MSVC until the code generation issue is found.
AES-CBC decryption is unaffected and stays enabled.
Hosted runners rarely have AVX-512, so whether CI exercises this path at all
depends on which host a job lands on. Run evp_extra_test under Intel SDE as
well, where -icx always reports VAES.
Refs #32873
Reviewed-by: Milan Broz <mbroz@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Mon Sep 21 09:57:35 2026
Merged-from: https://github.com/openssl/openssl/pull/32883
Do not finish reading after a DTLS 1.3 ACK while sent records remain
unacknowledged. Finishing reading stops the retransmit timer and clears
the entire sent queue, even for an empty or partial ACK.
Restore the preceding handshake state when ACK processing continues.
This preserves application-data handling and allows the expected
post-handshake authentication response to follow an incomplete ACK.
Limit the ACK epoch restriction to the initial handshake. Subsequent
sending and receiving epochs can differ, and the old restriction
produced empty ACKs for repeated unilateral KeyUpdates. Those exchanges
previously depended on the receive-side coverage bug to complete.
Exercise empty, nonmatching, partial and duplicate ACKs on both peers,
followed by application data and complete acknowledgement. Correct two
existing KeyUpdate tests which relied on unrelated ACKs clearing the
sent queue.
The regression fails on the parent. All 15 selected DTLS and SSL recipes
pass with --strict-warnings, including the default and FIPS SSL API runs.
Fixes openssl#32853
Assisted-by: Codex:gpt-6-astra
Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Ryan Hooper <ryanh@openssl.foundation>
Merge-date: Mon Sep 21 09:48:30 2026
Merged-from: https://github.com/openssl/openssl/pull/32854
_InterlockedExchangeAdd() is prototyped as
LONG _InterlockedExchangeAdd(volatile LONG *, LONG)
but CRYPTO_REF_COUNT held a volatile int. The MSVC branch passed
&refcnt->val straight in, which does not compile:
refcount.h(189): note: 'LONG _InterlockedExchangeAdd(volatile LONG *,LONG)':
cannot convert argument 1 from 'volatile int *' to 'volatile LONG *'
refcount.h(189): note: Types pointed to are unrelated
Declare val as volatile long in both the __ICL/_WIN32 and the _MSC_VER
variants and drop the cast, so the object type matches what the
intrinsic operates on.
Fixes: https://github.com/openssl/openssl/issues/21080
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
Merge-date: Mon Sep 21 09:35:35 2026
Merged-from: https://github.com/openssl/openssl/pull/32754
Add ossl_asn1_string_set1_data() and ossl_asn1_string_set1_string(),
copies of the public setters that also write a NUL byte after the data,
and switch all libcrypto callers to them. The ecosystem still treats
ASN1_STRING data as C strings; this keeps it working while it is fixed.
Removing the terminator later is a one-argument change in one function.
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Reviewed-by: Milan Broz <mbroz@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Fri Sep 18 09:05:58 2026
Merged-from: https://github.com/openssl/openssl/pull/32829
The signature info was computed once by ossl_x509v3_cache_extensions()
and stored in X509::siginf. Its security bits depend on a digest fetch
under the certificate's libctx/propq, so the cached answer was frozen
to the context the certificate was parsed in.
Compute it in X509_get_signature_info() instead. The siginf field and
ossl_x509_init_sig_info() are removed.
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Sep 17 16:44:34 2026
Merged-from: https://github.com/openssl/openssl/pull/32686
X509::sha1_hash exists only so X509_cmp() can compare certificates by
identity, yet X509_digest() handed it to callers when asked for SHA-1,
and it was computed under the certificate's libctx/propq, tying an
internal value to the context the certificate was parsed in.
Compute it with the built-in SHA-1 over the DER encoding instead, via
the new ossl_x509_internal_fingerprint(), so it is the same in every
library context; the only remaining failure mode is an allocation
failure. Drop the X509_digest() shortcut so the cached value is never
visible to callers, and rename the field to fingerprint in X509 and
X509_CRL. The CRL side gets the same treatment in a following commit.
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Sep 17 16:44:33 2026
Merged-from: https://github.com/openssl/openssl/pull/32686
Add a VAES-512 accelerated AES-CTR encryption path built on the shared
512-bit primitives. Counter blocks are generated and encrypted 4/8/16 at
a time; the low 64-bit counter word is clamped so that a 64-bit carry is
handled by a scalar step before VAES resumes, and payloads below the
provider threshold fall back to the existing aesni CTR path.
The provider gains a CTR hook that routes eligible payloads to the VAES
implementation, and aes_platform.h exposes VAES_CTR_ELIGIBLE (aliased to
VAES512_ELIGIBLE) with the ossl_aes_ctr_vaes prototypes.
The existing CTR known-answer vectors were all below the provider threshold
that dispatches to the VAES path, so that code was never exercised. Add
NIST SP800-38A 64-byte CTR KATs (AES-128/192/256) and a parametrized C test
spanning 64B-5000B across all key sizes and counter-carry boundaries,
validated against an independent ECB-based CTR reference.
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Sep 17 16:26:00 2026
Merged-from: https://github.com/openssl/openssl/pull/30755
The VAES-512 AES implementation file will host more than one mode. Rename
it to a mode-neutral name ahead of adding the AES-CTR implementation and
factoring out the shared VAES-512 primitives. This commit is a pure rename
with no content change.
Refactor the VAES-512 CBC decryption code to sit on top of a small set of
shared 512-bit primitives so that additional AES modes can reuse them:
- portable compiler abstractions for ISA targeting and inlining,
- OSSL_VAES512_DEFINE_ROUNDS, a macro emitting the 1x/2x/4x parallel
512-bit AES round functions for any round count and direction,
- OSSL_VAES512_LOAD_ROUNDKEYS / OSSL_VAES512_CLEAR_ROUNDKEYS helpers,
- ossl_vaes512_cpu_capable(), a shared runtime capability check.
The generated machine code for CBC decryption is byte-identical to the
previous version. aes_platform.h grows a VAES512_ELIGIBLE base guard with
VAES_CBC_ELIGIBLE kept as an alias.
Rename the assembly cleanup helper and perlasm module from CBC-specific
names to shared aes-vaes symbols so additional modes can reuse the same
stack scrub routine.
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Merge-date: Thu Sep 17 16:25:59 2026
Merged-from: https://github.com/openssl/openssl/pull/30755
Integrate ASCON-AEAD128 authenticated encryption cipher into OpenSSL's
default provider and libcrypto. ASCON-AEAD128 is specified in NIST
SP 800-232 and provides authenticated encryption with associated data
(AEAD) using a 128-bit key and 128-bit nonce.
Implementation details:
- Add cleanroom crypto/ascon implementation
- Add provider cipher implementation following OpenSSL stream cipher
patterns with generated parameter dispatch tables
- Support standard AEAD operations including AAD handling, tag
generation/verification, and context reinitialization
Fixes: #28271
Co-authored-by: Billy Brumley <bbb@iki.fi>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Merge-date: Wed Sep 16 14:25:19 2026
Merged-from: https://github.com/openssl/openssl/pull/29934
Strict on-demand seed source construction can re-enter itself when the
configured RAND requests entropy or a nonce through provider upcalls.
This recursively constructs the same seed source until the process
exhausts its stack.
Track active construction by logical execution so true recursion fails
with a RAND error while independent ASYNC jobs on the same thread and
library context can proceed. Keep the guard active during provider
lookup, context creation, and instantiation.
Add regression coverage for clean strict failure, independent and
paused ASYNC jobs, non-strict error propagation, and no-err builds.
Fixes#32683
Assisted-by: Codex:gpt-5
Reviewed-by: Mounir Idrassi <mounir.idrassi@idrix.fr>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Wed Sep 16 14:15:40 2026
Merged-from: https://github.com/openssl/openssl/pull/32685
@ifanzki reported an asan issue with the quic_radix_test in:
https://github.com/openssl/openssl/issues/32420
And we've tried fixing it a few different ways, with varying amounts of
success
This commit represents an alternative approach which I think is more
general to the bio_dgram_pair bio type.
The problem:
We have a race condition as reported above in which freeing one side of
a BIO dgram pair results in a use after free
The root cause:
BIO_new_bio_dgram_pair creates 2 dgram BIOS, each with a reference count
of one (which is sensible, as each bio has a single owner). However,
after creating the bios, it calls BIO_make_bio_pair(), which links the
two together. Under the covers in the bio_dgram_pair implementation,
each bio stores the pointer of its peer bio _without_ taking an
additional reference on the bio. This means that, once the first bio is
freed, the second bio may be doing subsequent io, which requires
dereferencing of the peer bio , which is already release,
leading to the use after free case observed.
Nominally this isn't an issue, as most code that uses BIO_dgram_pairs
are single threaded, and freeing of the component bios only occurs after
any i/o is already terminated, avoiding the observed UAF. However, the
QUIC radix test exercises the thread assisted mode of the quic stack,
and in so doing passes each half of a bio dgram pair to a separate
thread.
The fix:
Nominally we could resolve this by increasing the reference count on
each of the peer bios, and dropping that ref count when each is freed,
so that only the last to free actually deallocates both instances, but
this creates a chicken and egg issue. Since the the stored reference to
each bio lives in the dgram pair implementation, upping the refcount of
the bios prevents either bio from ever reaching the implementation free
code (dgram_pair_free)
So instead I'm proposing the following in this commit:
1) Instead of having the internal bio data track the peer bio, instead
have the internal data track a shared bio_dgram_peer_st structure
which is reference counted
2) When creating a pair, the pair only uses the data (ring buffers,
locks, etc), from the shared data, as its guaranteed to live until
the last owner of the pair either frees itself BIO_free, or destroys
the pair vi BIO_dgram_destroy_pair
3) If either side of the pair disconnects via the calls in (3), the
shared data state is updated to reflect that, and the remaining peer
triggers on that to get BROKEN_PIPE return codes
Also added tests from @bukka, as they provide more coverage than the
test I had in mind.
Fixes#32420
Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
MergeDate: Fri Sep 11 20:50:58 2026
(Merged from https://github.com/openssl/openssl/pull/32498)
In include/internal/ktls.h, the variable/parameter lengthi is used
in Kernel TLS (KTLS) helper declarations and macros, whereas all
related functions across the codebase consistently use length.
This naming inconsistency triggers static analysis warnings
(including potential CWE-467 flags regarding parameter/pointer
evaluation in macro expansions) and creates confusion during maintenance.
The identifier lengthi appears to be an unintended typo introduced
during the original KTLS interface definition.
CLA: trivial
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Norbert Pocs <norbertp@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Merge-date: Mon Sep 7 18:42:31 2026
Merged-from: https://github.com/openssl/openssl/pull/32568
The first value is kept. This is done for compatibility with
old FIPS providers from <=4.0 branches. They export two point
format parameters with different values.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Mon Sep 7 18:14:55 2026
Merged-from: https://github.com/openssl/openssl/pull/32675