crypto/openssl: update to 3.5.8

This is a security bugfix release. Please see the related merge commit
for more details.

Maintainer note:	`quic_ackm.h`'s conflict was resolved by taking
			the upstream version of the file verbatim.

Conflicts:
	crypto/openssl/include/internal/quic_ackm.h

MFC after:	3 days
Merge commit '248da023ae5ea7292930ac5d715d88b87e2e6f46'
This commit is contained in:
Enji Cooper committed 2026-08-28 18:28:12 -07:00
commit 78e936b2d0
259 files changed
+7387 -81985

No files matched your search

+258
View File
@@ -28,6 +28,237 @@ OpenSSL Releases
OpenSSL 3.5
-----------
### Changes between 3.5.7 and 3.5.8 [25 Aug 2026]
* Fixed QUIC server being able to trigger double free when processing `INITIAL`
packet.
Severity: Moderate
Issue summary: QUIC server may double free QRX (QUIC record layer RX) object
when channel creation fails for initial packet.
Impact summary: Double free leads to heap corruption, which typically results
in termination of QUIC server process, leading to a Denial of Service.
There is so far no evidence that this double free is exploitable for remote
code execution, thus it is considered highly improbable.
Reported by: Fuzz0x (ZKSC Institute of Security Research), Emilio Galle,
and Feng Xue (ThreatBoon).
([CVE-2026-18798])
*Alexandr Nedvědický*
* Fixed heap buffer overflow in CMS key unwrapping.
Severity: Moderate
Issue summary: OpenSSL CMS decryption sizes the key-unwrap output buffer
based on querying the unwrapped key size, but the AES-WRAP-PAD unwrap
primitive can write and cleanse more bytes than that query reports, causing
an 8-byte out-of-bounds heap write.
Impact summary: An attacker who supplies a crafted CMS message can trigger
a deterministic 8-byte out-of-bounds heap write when the victim decrypts it
with `CMS_decrypt()`, corrupting the heap and typically resulting in a Denial
of Service.
Reported by: Bhabani Sankar Das and Filipe Casal (Trail of Bits).
([CVE-2026-63072])
*Daniel Kubec*
* Fixed invalid pointer dereference in CMP server via crafted `protectionAlg`.
Severity: Moderate
Issue Summary: The OpenSSL Certificate Management Protocol (CMP)
password-based protection verification only checks whether
the `protectionAlg` parameter was not NULL and not its ASN.1 type,
before treating it as a `PBMParameter`. A crafted message can contain
a parameter of a different type, which is then dereferenced as an invalid
pointer.
Impact summary: A remote, unauthenticated attacker can crash an application
acting as a CMP server that accepts PBM-protected messages, or a CMP client
talking to a malicious or intercepted CMP server, resulting in a Denial
of Service.
Reported by: Ying Dong and Bhabani Sankar Das.
([CVE-2026-63076])
*Daniel Kubec*
* Fixed unbounded memory growth in QUIC server incoming channel queue.
Severity: Low
Issue summary: When an OpenSSL QUIC server (Listener SSL object) processes
valid QUIC Initial packets for unknown destination connection IDs, it can
allocate and queue new incoming channels without enforcing any limit.
Impact summary: A remote peer that can make many `INITIAL` packets reach
the server listener faster than the application accepts connections can
cause the memory allocated to store the per-channel state to grow
without any limits, potentially making the QUIC listener unavailable
and causing a Denial of Service.
Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI.
([CVE-2026-14456])
<!-- https://github.com/openssl/openssl/pull/32052 -->
*Filipe Casal*
* Fixed RPK server signature algorithm selection being able to dereference
a missing certificate.
Severity: Low
Issue summary: In a server or client configuration with [RFC 7250] Raw Public
Keys (RPKs) enabled, and only the private key (with no associated
certificate) configured locally, a NULL pointer dereference may occur
when the remote peer solicits raw public keys and also sends the typically
omitted `signature_algorithms_cert` TLS extension.
Impact summary: The impact is limited to a possible Denial of Service
as a result of an application abort, no data disclosure or remote command
execution are possible.
Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI.
([CVE-2026-14457])
*Viktor Dukhovni*
* Fixed excessive memory use buffering DTLS records for a future epoch.
Severity: Low
Issue summary: Receiving a DTLS record for a future epoch while a handshake
is in progress causes OpenSSL to buffer far more memory than the record
itself requires.
Impact summary: A peer can use a small amount of network traffic to make
an OpenSSL DTLS endpoint retain a disproportionately large amount of memory,
which may lead to a Denial of Service.
Reported by: Amazon Web Services.
([CVE-2026-54874])
*Matt Caswell*
* Fixed untrusted Sender DN being used as a format string in CMP response
validation.
Severity: Low
Issue Summary: The OpenSSL Certificate Management Protocol (CMP) response
validation passed an unexpected response sender distinguished name directly
as the format string to `ERR_raise_data()`.
Impact summary: A malicious or intercepted CMP endpoint can crash a CMP
client that enforces an expected sender or uses a pinned server certificate
whose subject becomes the default expected sender.
Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI,
Brandon Luo, and TrendAI Zero Day Initiative.
([CVE-2026-63073])
*Filipe Casal*
* Fixed CMP indefinite cache growth of `extraCerts`.
Severity: Low
Issue Summary: The OpenSSL Certificate Management Protocol (CMP) caches
additional certificates (`extraCerts`) sent in a CMP message, but never
expunges them (for instance, if they are invalid). If a server reuses
an `OSSL_CMP_CTX` object frequently, this cache of `extraCerts` may grow
unboundedly, and a malicious client may flood a CMP server with requests
driving this growth.
Impact Summary: Users utilizing a CMP server that reuses a single
`OSSL_CMP_CTX` object for the lifetime of a server process may observe
unbounded memory growth in the event a malicious client repeatedly sends
requests containing unique extra certificates, which may lead to OOM
conditions.
Reported by: Pavol Zacik (Red Hat).
([CVE-2026-63074])
*Neil Horman*
* Fixed QUIC ACK-only packet retention being able to cause memory exhaustion.
Severity: Low
Issue Summary: When OpenSSL processes QUIC traffic from a peer
that repeatedly sends ACK-eliciting packets while not acknowledging ACK-only
responses, the QUIC stack can retain ACK-only packet metadata
for the lifetime of the connection.
Impact Summary: A remote peer that can complete a QUIC handshake can cause
connection-scoped memory growth, which may lead to a Denial of Service
through memory exhaustion, especially with sustained traffic or many
concurrent QUIC connections.
Reported by: Opal Wright (Trail of Bits).
([CVE-2026-63075])
*Neil Horman*
* Fixed possibility of AEAD forgeries with empty ciphertext when using
`EVP_Cipher()`.
Severity: Low
Issue summary: ChaCha20-Poly1305 and AES-OCB decryption with an empty
ciphertext can report success without verifying the supplied authentication
tag when the operation is finalized by calling the `EVP_Cipher()` function.
Impact summary: Applications calling `EVP_Cipher()` on an empty ciphertext
and expecting the call to check the AEAD tag may accept forged messages.
Reported by: Billy Brumley (Rochester Institute of Technology).
([CVE-2026-75803])
<!-- https://github.com/openssl/openssl/pull/32416 -->
*Billy Bob Brumley*
* Added `OPENSSL_armcap(3)` documentation page.
<!-- https://github.com/openssl/openssl/pull/31749 -->
*Paul Elliott*
* Added support for selecting assembly code paths for LLVM-based Intel's `icx`
compiler.
<!-- https://github.com/openssl/openssl/pull/31572 -->
*Wolfgang Beck*
* Updated compliance with TLS 1.3 session ticket lifetime requirements.
TLS 1.3 clients now cap `ticket_lifetime_hint` to 7 days (604800 seconds)
when processing new session ticket messages, in accordance
with [RFC 8446 Section 4.6.1].
<!-- https://github.com/openssl/openssl/pull/31174 -->
*Abel Thomas*
* Fixed checking of authentication tags for empty ciphertexts for AEAD ciphers
in CCM cipher mode.
<!-- https://github.com/openssl/openssl/pull/32427 -->
*Mounir IDRASSI*
### Changes between 3.5.6 and 3.5.7 [9 Jun 2026]
* Fixed heap use-after-free in `PKCS7_verify()`.
@@ -306,6 +537,21 @@ OpenSSL 3.5
*Dmitry Belyavskiy (Red Hat)*
* Fixed excessive allocation of the handshake message buffer (aka HollowByte).
Previously, we would allocate a buffer large enough to hold the full size of
an incoming handshake message as advertised by the peer. This could be quite
large (although it is bounded, e.g. for ClientHello this is approximately
128 KiB). If the peer then fails to send the full handshake message, then the
endpoint is left waiting for the remainder of the message to arrive and the
memory is still allocated (i.e. a Slowloris attack). To prevent this, we
incrementally grow the buffer as we receive the data.
This issue was reported by Okta Red Team.
<!-- https://github.com/openssl/openssl/pull/30793 -->
*Matt Caswell*
* Fixed TLS 1.3 server not sending `NewSessionTicket` message
after ciphersuite mismatch.
<!-- https://github.com/openssl/openssl/pull/30626 -->
@@ -22260,6 +22506,9 @@ ndif
[CVE-2026-2673]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-2673
[CVE-2026-7383]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-7383
[CVE-2026-9076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-9076
[CVE-2026-14456]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14456
[CVE-2026-14457]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14457
[CVE-2026-18798]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-18798
[CVE-2026-22795]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22795
[CVE-2026-22796]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22796
[CVE-2026-28387]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28387
@@ -22281,9 +22530,18 @@ ndif
[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-54874]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54874
[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-75803]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75803
[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
[RFC 5297]: https://datatracker.ietf.org/doc/html/rfc5297
[RFC 7250]: https://datatracker.ietf.org/doc/html/rfc7250
[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
+37 -7
View File
@@ -70,7 +70,37 @@ guidelines:
git push -f [<repository> [<branch>]]
```
2. All source files should start with the following text (with
2. Similarly, if a non-trivial portion of a contribution was created
using an AI tool, you must declare which agent and model were used.
This is done by adding `Assisted-by: {agent}:{model}` below the commit
message:
```
One-line summary of change with AI-generated portions
Assisted-by: Claude:claude-sonnet-4-6
```
Multiple Assisted-by trailers can be included if multiple tools were used:
```
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: ChatGPT:gpt-4o
Assisted-by: GitHub Copilot:gpt-4.1
```
You will need to have signed a v1.1 or later CLA in order to
include AI-generated content in your contribution. CLAs signed
after June 2026 will have the requisite clauses.
Consult the [OpenSSL AI Code and Documentation Contribution
Policy] if an AI model assisted with the creation of your
contribution.
[OpenSSL AI Code and Documentation Contribution
Policy]: <https://openssl-library.org/policies/general/ai-policy/>
3. All source files should start with the following text (with
appropriate comment characters at the start of each line and the
year(s) updated):
@@ -83,11 +113,11 @@ guidelines:
https://www.openssl.org/source/license.html
```
3. Patches should be as current as possible; expect to have to rebase
4. Patches should be as current as possible; expect to have to rebase
often. We do not accept merge commits, you will have to remove them
(usually by rebasing) before it will be acceptable.
4. Code provided should follow our [coding style] and [documentation policy]
5. Code provided should follow our [coding style] and [documentation policy]
and compile without warnings.
There is a [Perl tool](util/check-format.pl) that helps
finding code formatting mistakes and other coding style nits.
@@ -100,16 +130,16 @@ guidelines:
[coding style]: https://openssl-library.org/policies/technical/coding-style/
[documentation policy]: https://openssl-library.org/policies/technical/documentation-policy/
5. When at all possible, code contributions should include tests. These can
6. When at all possible, code contributions should include tests. These can
either be added to an existing test, or completely new. Please see
[test/README.md](test/README.md) for information on the test framework.
6. New features or changed functionality must include
7. New features or changed functionality must include
documentation. Please look at the `.pod` files in `doc/man[1357]` for
examples of our style. Run `make doc-nits` to make sure that your
documentation changes are clean.
7. For user visible changes (API changes, behaviour changes, ...),
8. For user visible changes (API changes, behaviour changes, ...),
consider adding a note in [CHANGES.md](CHANGES.md).
This could be a summarising description of the change, and could
explain the grander details.
@@ -120,5 +150,5 @@ guidelines:
with a specific release without having to sift through the higher
noise ratio in git-log.
8. Guidelines on how to integrate error output of new crypto library modules
9. Guidelines on how to integrate error output of new crypto library modules
can be found in [crypto/err/README.md](crypto/err/README.md).
+56
View File
@@ -23,6 +23,50 @@ OpenSSL Releases
OpenSSL 3.5
-----------
### 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
in this release is Moderate.
This release incorporates the following bug fixes and mitigations:
* Fixed QUIC server being able to trigger double free when processing
`INITIAL` packet.
([CVE-2026-18798])
* Fixed heap buffer overflow in CMS key unwrapping.
([CVE-2026-63072])
* Fixed invalid pointer dereference in CMP server via crafted `protectionAlg`.
([CVE-2026-63076])
* Fixed unbounded memory growth in QUIC server incoming channel queue.
([CVE-2026-14456])
* Fixed RPK server signature algorithm selection being able to dereference
a missing certificate.
([CVE-2026-14457])
* Fixed excessive memory use buffering DTLS records for a future epoch.
([CVE-2026-54874])
* Fixed untrusted Sender DN being used as a format string in CMP response
validation.
([CVE-2026-63073])
* Fixed CMP indefinite cache growth of `extraCerts`.
([CVE-2026-63074])
* Fixed QUIC ACK-only packet retention being able to cause memory exhaustion.
([CVE-2026-63075])
* Fixed possibility of AEAD forgeries with empty ciphertext when using
`EVP_Cipher()`.
([CVE-2026-75803])
* Fixed checking of authentication tags for empty ciphertexts for AEAD ciphers
in CCM cipher mode.
### Major changes between OpenSSL 3.5.6 and OpenSSL 3.5.7 [9 Jun 2026]
OpenSSL 3.5.7 is a security patch release. The most severe CVE fixed
@@ -78,6 +122,8 @@ This release incorporates the following bug fixes and mitigations:
and AES-SIV modes.
([CVE-2026-45446])
* Fixed excessive allocation of the handshake message buffer (aka HollowByte).
### Major changes between OpenSSL 3.5.5 and OpenSSL 3.5.6 [7 Apr 2026]
OpenSSL 3.5.6 is a security patch release. The most severe CVE fixed in this
@@ -2267,6 +2313,9 @@ OpenSSL 0.9.x
[CVE-2026-2673]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-2673
[CVE-2026-7383]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-7383
[CVE-2026-9076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-9076
[CVE-2026-14456]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14456
[CVE-2026-14457]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14457
[CVE-2026-18798]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-18798
[CVE-2026-22795]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22795
[CVE-2026-22796]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22796
[CVE-2026-28387]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28387
@@ -2288,6 +2337,13 @@ OpenSSL 0.9.x
[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-54874]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54874
[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-75803]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75803
[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
+8 -4
View File
@@ -32,11 +32,15 @@ Installing the FIPS provider
============================
In order to be FIPS compliant you must only use FIPS validated source code.
Refer to <https://www.openssl.org/source/> for information related to
Refer to <https://openssl-library.org/source/> for information related to
which versions are FIPS validated. The instructions given below build OpenSSL
just using the FIPS validated source code. Any FIPS validated version may be
used with any other openssl library. Please see <https://www.openssl.org/source/>
To determine which FIPS validated library version may be appropriate for you.
just using the FIPS validated source code. A FIPS provider built from any
validated version may be used together with an OpenSSL library built from any
supported release from OpenSSL 3.0 onwards; provider compatibility is
maintained backward and forward across these releases, including future major
release series, for as long as the module remains supported. Please see
<https://openssl-library.org/source/>
to determine which FIPS validated library version may be appropriate for you.
If you want to use a validated FIPS provider, but also want to use the latest
OpenSSL release to build everything else, then refer to the next section.
+2 -2
View File
@@ -1,7 +1,7 @@
MAJOR=3
MINOR=5
PATCH=7
PATCH=8
PRE_RELEASE_TAG=
BUILD_METADATA=
RELEASE_DATE="9 Jun 2026"
RELEASE_DATE="25 Aug 2026"
SHLIB_VERSION=3
+19 -6
View File
@@ -1688,11 +1688,18 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
goto err;
#ifndef OPENSSL_NO_POSIX_IO
BIO_get_fp(in, &dbfp);
if (fstat(fileno(dbfp), &dbst) == -1) {
ERR_raise_data(ERR_LIB_SYS, errno,
"calling fstat(%s)", dbfile);
goto err;
if (BIO_get_fp(in, &dbfp) > 0 && dbfp != NULL) {
if (fstat(fileno(dbfp), &dbst) == -1) {
ERR_raise_data(ERR_LIB_SYS, errno,
"calling fstat(%s)", dbfile);
goto err;
}
} else {
if (stat(dbfile, &dbst) == -1) {
ERR_raise_data(ERR_LIB_SYS, errno,
"calling stat(%s)", dbfile);
goto err;
}
}
#endif
@@ -1722,8 +1729,14 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
}
retdb->dbfname = OPENSSL_strdup(dbfile);
if (retdb->dbfname == NULL)
if (retdb->dbfname == NULL) {
TXT_DB_free(retdb->db);
retdb->db = NULL;
OPENSSL_free(retdb);
retdb = NULL;
ERR_raise_data(ERR_LIB_SYS, errno, "Out of memory while copying filename: %s", dbfile);
goto err;
}
#ifndef OPENSSL_NO_POSIX_IO
retdb->dbst = dbst;
+1 -5
View File
@@ -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
@@ -1461,10 +1461,7 @@ static STRINT_PAIR callback_types[] = {
{ "Signature Algorithm mask", SSL_SECOP_SIGALG_MASK },
{ "Certificate chain EE key", SSL_SECOP_EE_KEY },
{ "Certificate chain CA key", SSL_SECOP_CA_KEY },
{ "Peer Chain EE key", SSL_SECOP_PEER_EE_KEY },
{ "Peer Chain CA key", SSL_SECOP_PEER_CA_KEY },
{ "Certificate chain CA digest", SSL_SECOP_CA_MD },
{ "Peer chain CA digest", SSL_SECOP_PEER_CA_MD },
{ "SSL compression", SSL_SECOP_COMPRESSION },
{ "Session ticket", SSL_SECOP_TICKET },
{ NULL }
@@ -1498,7 +1495,6 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx,
show_nm = 0;
break;
case SSL_SECOP_CA_MD:
case SSL_SECOP_PEER_CA_MD:
cert_md = 1;
break;
case SSL_SECOP_SIGALG_SUPPORTED:
+3 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016 VMS Software, Inc. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -230,6 +230,7 @@ int TerminalSocket(int FunctionCode, int *ReturnSocket)
LogMessage("TerminalSocket: SYS$QIO () - %08X", status);
close(TerminalSocketPair[0]);
close(TerminalSocketPair[1]);
sys$dassgn(TerminalDeviceChan);
return TERM_SOCK_FAILURE;
}
@@ -248,6 +249,7 @@ int TerminalSocket(int FunctionCode, int *ReturnSocket)
LogMessage("TerminalSocket: SYS$CANCEL () - %08X", status);
close(TerminalSocketPair[0]);
close(TerminalSocketPair[1]);
sys$dassgn(TerminalDeviceChan);
return TERM_SOCK_FAILURE;
}
+28 -27
View File
@@ -2846,11 +2846,9 @@ re_start:
}
/*
* According to RFC 5804 § 2.2, response codes are case-
* insensitive, make it uppercase but preserve the response.
* insensitive.
*/
strncpy(sbuf, mbuf, 2);
make_uppercase(sbuf);
if (!HAS_PREFIX(sbuf, "OK")) {
if (OPENSSL_strncasecmp(mbuf, "OK", 2) != 0) {
BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf);
goto shut;
}
@@ -3349,29 +3347,32 @@ shut:
print_stuff(bio_c_out, con, full_log);
do_ssl_shutdown(con);
/*
* If we ended with an alert being sent, but still with data in the
* network buffer to be read, then calling BIO_closesocket() will
* result in a TCP-RST being sent. On some platforms (notably
* Windows) then this will result in the peer immediately abandoning
* the connection including any buffered alert data before it has
* had a chance to be read. Shutting down the sending side first,
* and then closing the socket sends TCP-FIN first followed by
* TCP-RST. This seems to allow the peer to read the alert data.
*/
shutdown(SSL_get_fd(con), 1); /* SHUT_WR */
/*
* We just said we have nothing else to say, but it doesn't mean that
* the other side has nothing. It's even recommended to consume incoming
* data. [In testing context this ensures that alerts are passed on...]
*/
timeout.tv_sec = 0;
timeout.tv_usec = 500000; /* some extreme round-trip */
do {
FD_ZERO(&readfds);
openssl_fdset(sock, &readfds);
} while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
&& BIO_read(sbio, sbuf, BUFSIZZ) > 0);
/* The following half-close/drain workaround is TCP-specific. */
if (!isdtls && !isquic) {
/*
* If we ended with an alert being sent, but still with data in the
* network buffer to be read, then calling BIO_closesocket() will
* result in a TCP-RST being sent. On some platforms (notably
* Windows) then this will result in the peer immediately abandoning
* the connection including any buffered alert data before it has
* had a chance to be read. Shutting down the sending side first,
* and then closing the socket sends TCP-FIN first followed by
* TCP-RST. This seems to allow the peer to read the alert data.
*/
shutdown(SSL_get_fd(con), 1); /* SHUT_WR */
/*
* We just said we have nothing else to say, but it doesn't mean that
* the other side has nothing. It's even recommended to consume incoming
* data. [In testing context this ensures that alerts are passed on...]
*/
timeout.tv_sec = 0;
timeout.tv_usec = 500000; /* some extreme round-trip */
do {
FD_ZERO(&readfds);
openssl_fdset(sock, &readfds);
} while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
&& BIO_read(sbio, sbuf, BUFSIZZ) > 0);
}
BIO_closesocket(SSL_get_fd(con));
end:
-867
View File
@@ -1,867 +0,0 @@
/*
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/*
* This is experimental x86[_64] derivative. It assumes little-endian
* byte order and expects CPU to sustain unaligned memory references.
* It is used as playground for cache-time attack mitigations and
* serves as reference C implementation for x86[_64] as well as some
* other assembly modules.
*/
/**
* rijndael-alg-fst.c
*
* @version 3.0 (December 2000)
*
* Optimised ANSI C code for the Rijndael cipher (now AES)
*
* @author Vincent Rijmen
* @author Antoon Bosselaers
* @author Paulo Barreto
*
* This code is hereby placed in the public domain.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include <openssl/aes.h>
#include "aes_local.h"
/*
* These two parameters control which table, 256-byte or 2KB, is
* referenced in outer and respectively inner rounds.
*/
#define AES_COMPACT_IN_OUTER_ROUNDS
#ifdef AES_COMPACT_IN_OUTER_ROUNDS
/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
* adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
* by factor of ~2. */
#undef AES_COMPACT_IN_INNER_ROUNDS
#endif
#if 1
static void prefetch256(const void *table)
{
volatile unsigned long *t = (void *)table, ret;
unsigned long sum;
int i;
/* 32 is common least cache-line size */
for (sum = 0, i = 0; i < 256 / sizeof(t[0]); i += 32 / sizeof(t[0]))
sum ^= t[i];
ret = sum;
}
#else
#define prefetch256(t)
#endif
#undef GETU32
#define GETU32(p) (*((u32 *)(p)))
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
#define U64(C) C##UI64
#elif defined(__arch64__)
#define U64(C) C##UL
#else
#define U64(C) C##ULL
#endif
#undef ROTATE
#if defined(_MSC_VER)
#define ROTATE(a, n) _lrotl(a, n)
#elif defined(__ICC)
#define ROTATE(a, n) _rotl(a, n)
#elif defined(__GNUC__) && __GNUC__ >= 2
#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
#define ROTATE(a, n) ({ \
register unsigned int ret; \
asm( \
"roll %1,%0" \
: "=r"(ret) \
: "I"(n), "0"(a) \
: "cc"); \
ret; \
})
#endif
#endif
/*-
Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
Te0[x] = S [x].[02, 01, 01, 03];
Te1[x] = S [x].[03, 02, 01, 01];
Te2[x] = S [x].[01, 03, 02, 01];
Te3[x] = S [x].[01, 01, 03, 02];
*/
#define Te0 (u32)((u64 *)((u8 *)Te + 0))
#define Te1 (u32)((u64 *)((u8 *)Te + 3))
#define Te2 (u32)((u64 *)((u8 *)Te + 2))
#define Te3 (u32)((u64 *)((u8 *)Te + 1))
/*-
Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
Td0[x] = Si[x].[0e, 09, 0d, 0b];
Td1[x] = Si[x].[0b, 0e, 09, 0d];
Td2[x] = Si[x].[0d, 0b, 0e, 09];
Td3[x] = Si[x].[09, 0d, 0b, 0e];
Td4[x] = Si[x].[01];
*/
#define Td0 (u32)((u64 *)((u8 *)Td + 0))
#define Td1 (u32)((u64 *)((u8 *)Td + 3))
#define Td2 (u32)((u64 *)((u8 *)Td + 2))
#define Td3 (u32)((u64 *)((u8 *)Td + 1))
static const u64 Te[256] = {
U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
U64(0x5030306050303060), U64(0x0301010203010102),
U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
U64(0x5331316253313162), U64(0x3f15152a3f15152a),
U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
U64(0x2818183028181830), U64(0xa1969637a1969637),
U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
U64(0x0907070e0907070e), U64(0x3612122436121224),
U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
U64(0x0000000000000000), U64(0x2cededc12cededc1),
U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
U64(0x5533336655333366), U64(0x9485851194858511),
U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
U64(0x3010102030101020), U64(0x1affffe51affffe5),
U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
U64(0x3513132635131326), U64(0x2fececc32fececc3),
U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
U64(0xcc444488cc444488), U64(0x3917172e3917172e),
U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
U64(0x2b1919322b191932), U64(0x957373e6957373e6),
U64(0xa06060c0a06060c0), U64(0x9881811998818119),
U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
U64(0xab90903bab90903b), U64(0x8388880b8388880b),
U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
U64(0xa8919139a8919139), U64(0xa4959531a4959531),
U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
U64(0xd8484890d8484890), U64(0x0503030605030306),
U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
U64(0x9186861791868617), U64(0x58c1c19958c1c199),
U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
U64(0xb398982bb398982b), U64(0x3311112233111122),
U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
U64(0xc3414182c3414182), U64(0xb0999929b0999929),
U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
};
static const u8 Te4[256] = {
0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
};
static const u64 Td[256] = {
U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
U64(0x6033519760335197), U64(0x457f5362457f5362),
U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
U64(0x5868487058684870), U64(0x19fd458f19fd458f),
U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
U64(0x6fd406046fd40604), U64(0xff155060ff155060),
U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
U64(0xcc434089cc434089), U64(0x779ed967779ed967),
U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
U64(0x694b775a694b775a), U64(0x161a121c161a121c),
U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
U64(0x4022971340229713), U64(0x2011c6842011c684),
U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
U64(0xfa489411fa489411), U64(0x2264e9472264e947),
U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
U64(0x097826cd097826cd), U64(0xf418596ef418596e),
U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
};
static const u8 Td4[256] = {
0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
};
static const u32 rcon[] = {
0x00000001U,
0x00000002U,
0x00000004U,
0x00000008U,
0x00000010U,
0x00000020U,
0x00000040U,
0x00000080U,
0x0000001bU,
0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
};
/**
* Expand the cipher key into the encryption key schedule.
*/
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key)
{
u32 *rk;
int i = 0;
u32 temp;
if (!userKey || !key)
return -1;
if (bits != 128 && bits != 192 && bits != 256)
return -2;
rk = key->rd_key;
if (bits == 128)
key->rounds = 10;
else if (bits == 192)
key->rounds = 12;
else
key->rounds = 14;
rk[0] = GETU32(userKey);
rk[1] = GETU32(userKey + 4);
rk[2] = GETU32(userKey + 8);
rk[3] = GETU32(userKey + 12);
if (bits == 128) {
while (1) {
temp = rk[3];
rk[4] = rk[0] ^ ((u32)Te4[(temp >> 8) & 0xff]) ^ ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ ((u32)Te4[(temp >> 24)] << 16) ^ ((u32)Te4[(temp) & 0xff] << 24) ^ rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
return 0;
}
rk += 4;
}
}
rk[4] = GETU32(userKey + 16);
rk[5] = GETU32(userKey + 20);
if (bits == 192) {
while (1) {
temp = rk[5];
rk[6] = rk[0] ^ ((u32)Te4[(temp >> 8) & 0xff]) ^ ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ ((u32)Te4[(temp >> 24)] << 16) ^ ((u32)Te4[(temp) & 0xff] << 24) ^ rcon[i];
rk[7] = rk[1] ^ rk[6];
rk[8] = rk[2] ^ rk[7];
rk[9] = rk[3] ^ rk[8];
if (++i == 8) {
return 0;
}
rk[10] = rk[4] ^ rk[9];
rk[11] = rk[5] ^ rk[10];
rk += 6;
}
}
rk[6] = GETU32(userKey + 24);
rk[7] = GETU32(userKey + 28);
if (bits == 256) {
while (1) {
temp = rk[7];
rk[8] = rk[0] ^ ((u32)Te4[(temp >> 8) & 0xff]) ^ ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ ((u32)Te4[(temp >> 24)] << 16) ^ ((u32)Te4[(temp) & 0xff] << 24) ^ rcon[i];
rk[9] = rk[1] ^ rk[8];
rk[10] = rk[2] ^ rk[9];
rk[11] = rk[3] ^ rk[10];
if (++i == 7) {
return 0;
}
temp = rk[11];
rk[12] = rk[4] ^ ((u32)Te4[(temp) & 0xff]) ^ ((u32)Te4[(temp >> 8) & 0xff] << 8) ^ ((u32)Te4[(temp >> 16) & 0xff] << 16) ^ ((u32)Te4[(temp >> 24)] << 24);
rk[13] = rk[5] ^ rk[12];
rk[14] = rk[6] ^ rk[13];
rk[15] = rk[7] ^ rk[14];
rk += 8;
}
}
return 0;
}
/**
* Expand the cipher key into the decryption key schedule.
*/
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key)
{
u32 *rk;
int i, j, status;
u32 temp;
/* first, start with an encryption schedule */
status = AES_set_encrypt_key(userKey, bits, key);
if (status < 0)
return status;
rk = key->rd_key;
/* invert the order of the round keys: */
for (i = 0, j = 4 * (key->rounds); i < j; i += 4, j -= 4) {
temp = rk[i];
rk[i] = rk[j];
rk[j] = temp;
temp = rk[i + 1];
rk[i + 1] = rk[j + 1];
rk[j + 1] = temp;
temp = rk[i + 2];
rk[i + 2] = rk[j + 2];
rk[j + 2] = temp;
temp = rk[i + 3];
rk[i + 3] = rk[j + 3];
rk[j + 3] = temp;
}
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
for (i = 1; i < (key->rounds); i++) {
rk += 4;
#if 1
for (j = 0; j < 4; j++) {
u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
tp1 = rk[j];
m = tp1 & 0x80808080;
tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
m = tp2 & 0x80808080;
tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
m = tp4 & 0x80808080;
tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
tp9 = tp8 ^ tp1;
tpb = tp9 ^ tp2;
tpd = tp9 ^ tp4;
tpe = tp8 ^ tp4 ^ tp2;
#if defined(ROTATE)
rk[j] = tpe ^ ROTATE(tpd, 16) ^ ROTATE(tp9, 8) ^ ROTATE(tpb, 24);
#else
rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ (tp9 >> 24) ^ (tp9 << 8) ^ (tpb >> 8) ^ (tpb << 24);
#endif
}
#else
rk[0] = Td0[Te2[(rk[0]) & 0xff] & 0xff] ^ Td1[Te2[(rk[0] >> 8) & 0xff] & 0xff] ^ Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^ Td3[Te2[(rk[0] >> 24)] & 0xff];
rk[1] = Td0[Te2[(rk[1]) & 0xff] & 0xff] ^ Td1[Te2[(rk[1] >> 8) & 0xff] & 0xff] ^ Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^ Td3[Te2[(rk[1] >> 24)] & 0xff];
rk[2] = Td0[Te2[(rk[2]) & 0xff] & 0xff] ^ Td1[Te2[(rk[2] >> 8) & 0xff] & 0xff] ^ Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^ Td3[Te2[(rk[2] >> 24)] & 0xff];
rk[3] = Td0[Te2[(rk[3]) & 0xff] & 0xff] ^ Td1[Te2[(rk[3] >> 8) & 0xff] & 0xff] ^ Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^ Td3[Te2[(rk[3] >> 24)] & 0xff];
#endif
}
return 0;
}
/*
* Encrypt a single block
* in and out can overlap
*/
void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key)
{
const u32 *rk;
u32 s0, s1, s2, s3, t[4];
int r;
assert(in && out && key);
rk = key->rd_key;
/*
* map byte array block to cipher state
* and add initial round key:
*/
s0 = GETU32(in) ^ rk[0];
s1 = GETU32(in + 4) ^ rk[1];
s2 = GETU32(in + 8) ^ rk[2];
s3 = GETU32(in + 12) ^ rk[3];
#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
prefetch256(Te4);
t[0] = (u32)Te4[(s0) & 0xff] ^ (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ (u32)Te4[(s3 >> 24)] << 24;
t[1] = (u32)Te4[(s1) & 0xff] ^ (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ (u32)Te4[(s0 >> 24)] << 24;
t[2] = (u32)Te4[(s2) & 0xff] ^ (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ (u32)Te4[(s1 >> 24)] << 24;
t[3] = (u32)Te4[(s3) & 0xff] ^ (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ (u32)Te4[(s2 >> 24)] << 24;
/* now do the linear transform using words */
{
int i;
u32 r0, r1, r2;
for (i = 0; i < 4; i++) {
r0 = t[i];
r1 = r0 & 0x80808080;
r2 = ((r0 & 0x7f7f7f7f) << 1) ^ ((r1 - (r1 >> 7)) & 0x1b1b1b1b);
#if defined(ROTATE)
t[i] = r2 ^ ROTATE(r2, 24) ^ ROTATE(r0, 24) ^ ROTATE(r0, 16) ^ ROTATE(r0, 8);
#else
t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^ (r0 << 16) ^ (r0 >> 16) ^ (r0 << 8) ^ (r0 >> 24);
#endif
t[i] ^= rk[4 + i];
}
}
#else
t[0] = Te0[(s0) & 0xff] ^ Te1[(s1 >> 8) & 0xff] ^ Te2[(s2 >> 16) & 0xff] ^ Te3[(s3 >> 24)] ^ rk[4];
t[1] = Te0[(s1) & 0xff] ^ Te1[(s2 >> 8) & 0xff] ^ Te2[(s3 >> 16) & 0xff] ^ Te3[(s0 >> 24)] ^ rk[5];
t[2] = Te0[(s2) & 0xff] ^ Te1[(s3 >> 8) & 0xff] ^ Te2[(s0 >> 16) & 0xff] ^ Te3[(s1 >> 24)] ^ rk[6];
t[3] = Te0[(s3) & 0xff] ^ Te1[(s0 >> 8) & 0xff] ^ Te2[(s1 >> 16) & 0xff] ^ Te3[(s2 >> 24)] ^ rk[7];
#endif
s0 = t[0];
s1 = t[1];
s2 = t[2];
s3 = t[3];
/*
* Nr - 2 full rounds:
*/
for (rk += 8, r = key->rounds - 2; r > 0; rk += 4, r--) {
#if defined(AES_COMPACT_IN_INNER_ROUNDS)
t[0] = (u32)Te4[(s0) & 0xff] ^ (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ (u32)Te4[(s3 >> 24)] << 24;
t[1] = (u32)Te4[(s1) & 0xff] ^ (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ (u32)Te4[(s0 >> 24)] << 24;
t[2] = (u32)Te4[(s2) & 0xff] ^ (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ (u32)Te4[(s1 >> 24)] << 24;
t[3] = (u32)Te4[(s3) & 0xff] ^ (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ (u32)Te4[(s2 >> 24)] << 24;
/* now do the linear transform using words */
{
int i;
u32 r0, r1, r2;
for (i = 0; i < 4; i++) {
r0 = t[i];
r1 = r0 & 0x80808080;
r2 = ((r0 & 0x7f7f7f7f) << 1) ^ ((r1 - (r1 >> 7)) & 0x1b1b1b1b);
#if defined(ROTATE)
t[i] = r2 ^ ROTATE(r2, 24) ^ ROTATE(r0, 24) ^ ROTATE(r0, 16) ^ ROTATE(r0, 8);
#else
t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^ (r0 << 16) ^ (r0 >> 16) ^ (r0 << 8) ^ (r0 >> 24);
#endif
t[i] ^= rk[i];
}
}
#else
t[0] = Te0[(s0) & 0xff] ^ Te1[(s1 >> 8) & 0xff] ^ Te2[(s2 >> 16) & 0xff] ^ Te3[(s3 >> 24)] ^ rk[0];
t[1] = Te0[(s1) & 0xff] ^ Te1[(s2 >> 8) & 0xff] ^ Te2[(s3 >> 16) & 0xff] ^ Te3[(s0 >> 24)] ^ rk[1];
t[2] = Te0[(s2) & 0xff] ^ Te1[(s3 >> 8) & 0xff] ^ Te2[(s0 >> 16) & 0xff] ^ Te3[(s1 >> 24)] ^ rk[2];
t[3] = Te0[(s3) & 0xff] ^ Te1[(s0 >> 8) & 0xff] ^ Te2[(s1 >> 16) & 0xff] ^ Te3[(s2 >> 24)] ^ rk[3];
#endif
s0 = t[0];
s1 = t[1];
s2 = t[2];
s3 = t[3];
}
/*
* apply last round and
* map cipher state to byte array block:
*/
#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
prefetch256(Te4);
*(u32 *)(out + 0) = (u32)Te4[(s0) & 0xff] ^ (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ (u32)Te4[(s3 >> 24)] << 24 ^ rk[0];
*(u32 *)(out + 4) = (u32)Te4[(s1) & 0xff] ^ (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ (u32)Te4[(s0 >> 24)] << 24 ^ rk[1];
*(u32 *)(out + 8) = (u32)Te4[(s2) & 0xff] ^ (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ (u32)Te4[(s1 >> 24)] << 24 ^ rk[2];
*(u32 *)(out + 12) = (u32)Te4[(s3) & 0xff] ^ (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ (u32)Te4[(s2 >> 24)] << 24 ^ rk[3];
#else
*(u32 *)(out + 0) = (Te2[(s0) & 0xff] & 0x000000ffU) ^ (Te3[(s1 >> 8) & 0xff] & 0x0000ff00U) ^ (Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^ (Te1[(s3 >> 24)] & 0xff000000U) ^ rk[0];
*(u32 *)(out + 4) = (Te2[(s1) & 0xff] & 0x000000ffU) ^ (Te3[(s2 >> 8) & 0xff] & 0x0000ff00U) ^ (Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^ (Te1[(s0 >> 24)] & 0xff000000U) ^ rk[1];
*(u32 *)(out + 8) = (Te2[(s2) & 0xff] & 0x000000ffU) ^ (Te3[(s3 >> 8) & 0xff] & 0x0000ff00U) ^ (Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^ (Te1[(s1 >> 24)] & 0xff000000U) ^ rk[2];
*(u32 *)(out + 12) = (Te2[(s3) & 0xff] & 0x000000ffU) ^ (Te3[(s0 >> 8) & 0xff] & 0x0000ff00U) ^ (Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^ (Te1[(s2 >> 24)] & 0xff000000U) ^ rk[3];
#endif
}
/*
* Decrypt a single block
* in and out can overlap
*/
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key)
{
const u32 *rk;
u32 s0, s1, s2, s3, t[4];
int r;
assert(in && out && key);
rk = key->rd_key;
/*
* map byte array block to cipher state
* and add initial round key:
*/
s0 = GETU32(in) ^ rk[0];
s1 = GETU32(in + 4) ^ rk[1];
s2 = GETU32(in + 8) ^ rk[2];
s3 = GETU32(in + 12) ^ rk[3];
#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
prefetch256(Td4);
t[0] = (u32)Td4[(s0) & 0xff] ^ (u32)Td4[(s3 >> 8) & 0xff] << 8 ^ (u32)Td4[(s2 >> 16) & 0xff] << 16 ^ (u32)Td4[(s1 >> 24)] << 24;
t[1] = (u32)Td4[(s1) & 0xff] ^ (u32)Td4[(s0 >> 8) & 0xff] << 8 ^ (u32)Td4[(s3 >> 16) & 0xff] << 16 ^ (u32)Td4[(s2 >> 24)] << 24;
t[2] = (u32)Td4[(s2) & 0xff] ^ (u32)Td4[(s1 >> 8) & 0xff] << 8 ^ (u32)Td4[(s0 >> 16) & 0xff] << 16 ^ (u32)Td4[(s3 >> 24)] << 24;
t[3] = (u32)Td4[(s3) & 0xff] ^ (u32)Td4[(s2 >> 8) & 0xff] << 8 ^ (u32)Td4[(s1 >> 16) & 0xff] << 16 ^ (u32)Td4[(s0 >> 24)] << 24;
/* now do the linear transform using words */
{
int i;
u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
for (i = 0; i < 4; i++) {
tp1 = t[i];
m = tp1 & 0x80808080;
tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
m = tp2 & 0x80808080;
tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
m = tp4 & 0x80808080;
tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
tp9 = tp8 ^ tp1;
tpb = tp9 ^ tp2;
tpd = tp9 ^ tp4;
tpe = tp8 ^ tp4 ^ tp2;
#if defined(ROTATE)
t[i] = tpe ^ ROTATE(tpd, 16) ^ ROTATE(tp9, 8) ^ ROTATE(tpb, 24);
#else
t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ (tp9 >> 24) ^ (tp9 << 8) ^ (tpb >> 8) ^ (tpb << 24);
#endif
t[i] ^= rk[4 + i];
}
}
#else
t[0] = Td0[(s0) & 0xff] ^ Td1[(s3 >> 8) & 0xff] ^ Td2[(s2 >> 16) & 0xff] ^ Td3[(s1 >> 24)] ^ rk[4];
t[1] = Td0[(s1) & 0xff] ^ Td1[(s0 >> 8) & 0xff] ^ Td2[(s3 >> 16) & 0xff] ^ Td3[(s2 >> 24)] ^ rk[5];
t[2] = Td0[(s2) & 0xff] ^ Td1[(s1 >> 8) & 0xff] ^ Td2[(s0 >> 16) & 0xff] ^ Td3[(s3 >> 24)] ^ rk[6];
t[3] = Td0[(s3) & 0xff] ^ Td1[(s2 >> 8) & 0xff] ^ Td2[(s1 >> 16) & 0xff] ^ Td3[(s0 >> 24)] ^ rk[7];
#endif
s0 = t[0];
s1 = t[1];
s2 = t[2];
s3 = t[3];
/*
* Nr - 2 full rounds:
*/
for (rk += 8, r = key->rounds - 2; r > 0; rk += 4, r--) {
#if defined(AES_COMPACT_IN_INNER_ROUNDS)
t[0] = (u32)Td4[(s0) & 0xff] ^ (u32)Td4[(s3 >> 8) & 0xff] << 8 ^ (u32)Td4[(s2 >> 16) & 0xff] << 16 ^ (u32)Td4[(s1 >> 24)] << 24;
t[1] = (u32)Td4[(s1) & 0xff] ^ (u32)Td4[(s0 >> 8) & 0xff] << 8 ^ (u32)Td4[(s3 >> 16) & 0xff] << 16 ^ (u32)Td4[(s2 >> 24)] << 24;
t[2] = (u32)Td4[(s2) & 0xff] ^ (u32)Td4[(s1 >> 8) & 0xff] << 8 ^ (u32)Td4[(s0 >> 16) & 0xff] << 16 ^ (u32)Td4[(s3 >> 24)] << 24;
t[3] = (u32)Td4[(s3) & 0xff] ^ (u32)Td4[(s2 >> 8) & 0xff] << 8 ^ (u32)Td4[(s1 >> 16) & 0xff] << 16 ^ (u32)Td4[(s0 >> 24)] << 24;
/* now do the linear transform using words */
{
int i;
u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
for (i = 0; i < 4; i++) {
tp1 = t[i];
m = tp1 & 0x80808080;
tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
m = tp2 & 0x80808080;
tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
m = tp4 & 0x80808080;
tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ ((m - (m >> 7)) & 0x1b1b1b1b);
tp9 = tp8 ^ tp1;
tpb = tp9 ^ tp2;
tpd = tp9 ^ tp4;
tpe = tp8 ^ tp4 ^ tp2;
#if defined(ROTATE)
t[i] = tpe ^ ROTATE(tpd, 16) ^ ROTATE(tp9, 8) ^ ROTATE(tpb, 24);
#else
t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ (tp9 >> 24) ^ (tp9 << 8) ^ (tpb >> 8) ^ (tpb << 24);
#endif
t[i] ^= rk[i];
}
}
#else
t[0] = Td0[(s0) & 0xff] ^ Td1[(s3 >> 8) & 0xff] ^ Td2[(s2 >> 16) & 0xff] ^ Td3[(s1 >> 24)] ^ rk[0];
t[1] = Td0[(s1) & 0xff] ^ Td1[(s0 >> 8) & 0xff] ^ Td2[(s3 >> 16) & 0xff] ^ Td3[(s2 >> 24)] ^ rk[1];
t[2] = Td0[(s2) & 0xff] ^ Td1[(s1 >> 8) & 0xff] ^ Td2[(s0 >> 16) & 0xff] ^ Td3[(s3 >> 24)] ^ rk[2];
t[3] = Td0[(s3) & 0xff] ^ Td1[(s2 >> 8) & 0xff] ^ Td2[(s1 >> 16) & 0xff] ^ Td3[(s0 >> 24)] ^ rk[3];
#endif
s0 = t[0];
s1 = t[1];
s2 = t[2];
s3 = t[3];
}
/*
* apply last round and
* map cipher state to byte array block:
*/
prefetch256(Td4);
*(u32 *)(out + 0) = ((u32)Td4[(s0) & 0xff]) ^ ((u32)Td4[(s3 >> 8) & 0xff] << 8) ^ ((u32)Td4[(s2 >> 16) & 0xff] << 16) ^ ((u32)Td4[(s1 >> 24)] << 24) ^ rk[0];
*(u32 *)(out + 4) = ((u32)Td4[(s1) & 0xff]) ^ ((u32)Td4[(s0 >> 8) & 0xff] << 8) ^ ((u32)Td4[(s3 >> 16) & 0xff] << 16) ^ ((u32)Td4[(s2 >> 24)] << 24) ^ rk[1];
*(u32 *)(out + 8) = ((u32)Td4[(s2) & 0xff]) ^ ((u32)Td4[(s1 >> 8) & 0xff] << 8) ^ ((u32)Td4[(s0 >> 16) & 0xff] << 16) ^ ((u32)Td4[(s3 >> 24)] << 24) ^ rk[2];
*(u32 *)(out + 12) = ((u32)Td4[(s3) & 0xff]) ^ ((u32)Td4[(s2 >> 8) & 0xff] << 8) ^ ((u32)Td4[(s1 >> 16) & 0xff] << 16) ^ ((u32)Td4[(s0 >> 24)] << 24) ^ rk[3];
}
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-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
@@ -80,6 +80,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2011-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
@@ -111,6 +111,9 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
$1>=10);
$avx=1 if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0);
$avx=1 if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__` =~ /#define __clang_major__.([0-9]+)/ &&
$1>=11); #icx started with clang 11
$shaext=1; ### set to zero if compiling for 1.0.1
$stitched_decrypt=0;
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-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
@@ -75,6 +75,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
$shaext=$avx; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
@@ -59,6 +59,13 @@ if (!$avx512vaes && `$ENV{CC} -v 2>&1`
}
}
if (!$avx512vaes && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx512vaes = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
+30 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2011-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
@@ -408,14 +408,38 @@ void OPENSSL_cpuid_setup(void)
if (OPENSSL_armcap_P & ARMV8_CPUID)
OPENSSL_arm_midr = _armv8_cpuid_probe();
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)) && (OPENSSL_armcap_P & ARMV7_NEON)) {
if ((OPENSSL_armcap_P & ARMV7_NEON)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)))
OPENSSL_armv8_rsa_neonized = 1;
}
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_COBALT_100) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2) || MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE) && (OPENSSL_armcap_P & ARMV8_SHA3))
if ((OPENSSL_armcap_P & ARMV8_SHA3)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_COBALT_100)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)
|| MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE))
OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3;
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2) || MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE) && (OPENSSL_armcap_P & ARMV8_SHA3))
if ((OPENSSL_armcap_P & ARMV8_SHA3)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)
|| MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE))
OPENSSL_armcap_P |= ARMV8_UNROLL12_EOR3;
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)) && (OPENSSL_armcap_P & ARMV8_SHA3))
if ((OPENSSL_armcap_P & ARMV8_SHA3)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)))
OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING;
#endif
}
+14 -1
View File
@@ -139,7 +139,20 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
}
i = BIO_read(in, &(b->data[len]), want);
if (i <= 0) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA);
/*
* A read error (i < 0), an EOF in the middle of an object
* (diff != 0, some bytes already buffered), or an EOF while
* still inside an indefinite-length constructed value awaiting
* its end-of-contents octets (eos != 0) all mean the input is
* truncated. Only a clean EOF at a top-level object boundary
* (i == 0, diff == 0, eos == 0) is the normal end of input:
* fail without queuing an error so that callers looping over
* concatenated DER values (e.g. the libcrypto d2i_*_bio()
* consumers in CPython's ssl module) terminate cleanly instead
* of seeing a spurious ASN1_R_NOT_ENOUGH_DATA.
*/
if (i < 0 || diff != 0 || eos != 0)
ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0) {
+16 -4
View File
@@ -51,12 +51,24 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
unsigned char *p;
int nchar;
int (*cpyfunc)(unsigned long, void *) = NULL;
if (len == -1)
len = strlen((const char *)in);
if (len == -1) {
size_t len_s = strlen((const char *)in);
if (len_s >= INT_MAX) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
return -1;
}
len = (int)len_s;
}
if (!mask)
mask = DIRSTRING_TYPE;
if (len < 0)
if (len < 0) {
ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT);
return -1;
} else if (len >= INT_MAX) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
return -1;
}
/* First do a string check and work out the number of characters */
switch (inform) {
@@ -294,7 +306,7 @@ static int out_utf8(unsigned long value, void *arg)
return len;
}
outlen = arg;
if (*outlen > INT_MAX - len) {
if (*outlen >= INT_MAX - len) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
return -1;
}
+4 -1
View File
@@ -426,8 +426,11 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
depth + 1, perr);
if (!typ)
goto bad;
if (!sk_ASN1_TYPE_push(sk, typ))
if (!sk_ASN1_TYPE_push(sk, typ)) {
ASN1_TYPE_free(typ);
goto bad;
}
}
}
+7 -1
View File
@@ -312,7 +312,13 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
/* the ptr parameter is actually a FILE ** in this case. */
if (ptr != NULL) {
fpp = (FILE **)ptr;
*fpp = (FILE *)b->ptr;
if (BIO_FLAGS_UPLINK_INTERNAL == 0
|| b->flags & BIO_FLAGS_UPLINK_INTERNAL) {
*fpp = (FILE *)b->ptr;
} else { /* avoid returning internal FILE * to the app */
*fpp = NULL;
ret = 0;
}
}
break;
case BIO_CTRL_GET_CLOSE:
@@ -1,4 +1,4 @@
# Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2020, Intel Corporation. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -64,6 +64,13 @@ if (!$avx512ifma && `$ENV{CC} -v 2>&1`
}
}
if (!$avx512ifma && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx512ifma = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -39,6 +39,13 @@ if (!$avxifma && `$ENV{CC} -v 2>&1`
$avxifma = ($ver>=16.0);
}
if (!$avxifma && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avxifma = ($1>=16);
}
}
if ($win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(rc[0-9]+)?/) {
my $ver = $1 + $2/100.0 + $3/10000.0; # 3.1.0->3.01, 3.10.1->3.1001
@@ -1,4 +1,4 @@
# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2021, Intel Corporation. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -63,6 +63,13 @@ if (!$avx512ifma && `$ENV{CC} -v 2>&1`
}
}
if (!$avx512ifma && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx512ifma = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -38,6 +38,13 @@ if (!$avxifma && `$ENV{CC} -v 2>&1`
$avxifma = ($ver>=16.0);
}
if (!$avxifma && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avxifma = ($1>=16);
}
}
if ($win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?(rc[0-9]+)?/) {
$avxifma = ($1>2.16) + ($1==2.16 && ((!defined($2) && !defined($3)) || (defined($2))));
@@ -1,4 +1,4 @@
# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2021, Intel Corporation. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -63,6 +63,13 @@ if (!$avx512ifma && `$ENV{CC} -v 2>&1`
}
}
if (!$avx512ifma && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx512ifma = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -38,6 +38,13 @@ if (!$avxifma && `$ENV{CC} -v 2>&1`
$avxifma = ($ver>=16.0);
}
if (!$avxifma && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avxifma = ($1>=16);
}
}
if ($win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?(rc[0-9]+)?/) {
$avxifma = ($1>2.16) + ($1==2.16 && ((!defined($2) && !defined($3)) || (defined($2))));
+9 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2012, Intel Corporation. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -73,6 +73,14 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9
$addx = ($ver>=3.03);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$addx = ($1>=11); #icx started with clang 11
$avx = ($1>=11);
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT = *OUT;
+8 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2012, Intel Corporation. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -90,6 +90,13 @@ if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([
$addx = ($ver>=3.03);
}
if (!$addx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$addx = ($1>=11); #icx started with clang 11
}
}
($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp"); # common internal API
{
my ($out,$inp,$mod,$n0,$times) = ("%rdi","%rsi","%rdx","%rcx","%r8d");
+8 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2005-2020 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
@@ -82,6 +82,13 @@ if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([
$addx = ($ver>=3.03);
}
if (!$addx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$addx = ($1>=11); #icx started with clang 11
}
}
# int bn_mul_mont(
$rp="%rdi"; # BN_ULONG *rp,
$ap="%rsi"; # const BN_ULONG *ap,
+8 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2011-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
@@ -69,6 +69,13 @@ if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([
$addx = ($ver>=3.03);
}
if (!$addx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$addx = ($1>=11); #icx started with clang 11
}
}
# int bn_mul_mont_gather5(
$rp="%rdi"; # BN_ULONG *rp,
$ap="%rsi"; # const BN_ULONG *ap,
+8 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2020 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
@@ -97,6 +97,8 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
return 0;
r->top = max;
if (max == 0)
goto end;
ap = a->d;
bp = b->d;
@@ -116,6 +118,7 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
*rp = carry;
r->top += carry;
end:
r->neg = 0;
bn_check_top(r);
return 1;
@@ -143,6 +146,9 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
if (bn_wexpand(r, max) == NULL)
return 0;
if (max == 0)
goto end;
ap = a->d;
bp = b->d;
rp = r->d;
@@ -162,6 +168,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
while (max && *--rp == 0)
max--;
end:
r->top = max;
r->neg = 0;
bn_pollute(r);
+4 -3
View File
@@ -552,7 +552,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
BN_ULONG acc = 0;
for (j = 0; j < width; j++) {
acc |= table[j] & ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
acc |= table[j] & value_barrier_bn((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
}
b->d[i] = acc;
@@ -573,8 +573,9 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
BN_ULONG acc = 0;
for (j = 0; j < xstride; j++) {
acc |= ((table[j + 0 * xstride] & y0) | (table[j + 1 * xstride] & y1) | (table[j + 2 * xstride] & y2) | (table[j + 3 * xstride] & y3))
& ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
acc |= ((table[j + 0 * xstride] & value_barrier_bn(y0)) | (table[j + 1 * xstride] & value_barrier_bn(y1))
| (table[j + 2 * xstride] & value_barrier_bn(y2)) | (table[j + 3 * xstride] & value_barrier_bn(y3)))
& value_barrier_bn((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1));
}
b->d[i] = acc;
+25 -7
View File
@@ -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
@@ -707,19 +707,37 @@ int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
int i;
BN_ULONG t1, t2, *ap, *bp;
/*
* As it is a public API function, we should handle NULL parameters in
* some way. The function can’t return an error, so let’s define that NULL
* is less than any BIGNUM.
*/
if (!ossl_assert(a != NULL && b != NULL))
return (b == NULL) - (a == NULL);
ap = a->d;
bp = b->d;
if (BN_get_flags(a, BN_FLG_CONSTTIME)
&& a->top == b->top) {
|| BN_get_flags(b, BN_FLG_CONSTTIME)) {
int res = 0;
int min_top = a->top < b->top ? a->top : b->top;
for (i = 0; i < b->top; i++) {
for (i = 0; i < min_top; i++) {
res = constant_time_select_int(constant_time_lt_bn(ap[i], bp[i]),
-1, res);
res = constant_time_select_int(constant_time_lt_bn(bp[i], ap[i]),
1, res);
}
for (i = min_top; i < a->top; ++i)
res = constant_time_select_int((int)constant_time_is_zero_bn(ap[i]),
res, 1);
for (i = min_top; i < b->top; ++i)
res = constant_time_select_int((int)constant_time_is_zero_bn(bp[i]),
res, -1);
return res;
}
@@ -948,11 +966,11 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
condition = ((~condition & ((condition - 1))) >> (BN_BITS2 - 1)) - 1;
t = (a->top ^ b->top) & condition;
t = (a->top ^ b->top) & value_barrier_bn(condition);
a->top ^= t;
b->top ^= t;
t = (a->neg ^ b->neg) & condition;
t = (a->neg ^ b->neg) & value_barrier_bn(condition);
a->neg ^= t;
b->neg ^= t;
@@ -980,13 +998,13 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP)
t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition;
t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & value_barrier_bn(condition);
a->flags ^= t;
b->flags ^= t;
/* conditionally swap the data */
for (i = 0; i < nwords; i++) {
t = (a->d[i] ^ b->d[i]) & condition;
t = (a->d[i] ^ b->d[i]) & value_barrier_bn(condition);
a->d[i] ^= t;
b->d[i] ^= t;
}
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2016-2020 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
@@ -64,6 +64,10 @@ $ymm=1 if ($xmm && !$ymm &&
`$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ &&
$2>=3.0); # first version supporting AVX
$ymm=1 if ($xmm && !$ymm &&
`$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__` =~ /#define __clang_major__.([0-9]+)/ &&
$1>=11); #icx started with clang 11
$a="eax";
($b,$b_)=("ebx","ebp");
($c,$c_)=("ecx","esi");
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# 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
@@ -91,6 +91,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
+1 -1
View File
@@ -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
*
+12 -10
View File
@@ -64,8 +64,10 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx,
sig_err:
res = ossl_x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_SIGNATURE);
if (res)
ERR_add_error_mem_bio("\n", bio);
if (res) {
ERR_add_error_txt(NULL, "\n");
ERR_add_error_mem_bio(NULL, bio);
}
res = 0;
end:
@@ -387,7 +389,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
int i;
if (sk_X509_num(certs) <= 0) {
ossl_cmp_log1(WARN, ctx, "no %s", desc);
ossl_cmp_log1(INFO, ctx, "no %s", desc);
return 0;
}
@@ -407,7 +409,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs,
}
}
if (in_extraCerts && n_acceptable_certs == 0)
ossl_cmp_warn(ctx, "no acceptable cert in extraCerts");
ossl_cmp_log1(WARN, ctx, "no acceptable %s", desc);
return 0;
}
@@ -502,14 +504,14 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
ctx->log_cb = backup_log_cb;
if (res) {
/* discard any diagnostic information on trying to use certs */
(void)ERR_pop_to_mark();
ctx->log_cb = backup_log_cb; /* re-enable logging */
/* discard any previous diagnostic information on trying to use certs */
(void)ERR_pop_to_mark();
if (res)
goto end;
}
/* failed finding a sender cert that verifies the message signature */
(void)ERR_clear_last_mark();
sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0);
skid_str = skid == NULL ? NULL : i2s_ASN1_OCTET_STRING(NULL, skid);
+4 -4
View File
@@ -245,9 +245,9 @@ ASN1_NDEF_SEQUENCE(CMS_AuthEnvelopedData) = {
ASN1_IMP_OPT(CMS_AuthEnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
ASN1_SET_OF(CMS_AuthEnvelopedData, recipientInfos, CMS_RecipientInfo),
ASN1_SIMPLE(CMS_AuthEnvelopedData, authEncryptedContentInfo, CMS_EncryptedContentInfo),
ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, authAttrs, X509_ALGOR, 2),
ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, authAttrs, X509_ATTRIBUTE, 1),
ASN1_SIMPLE(CMS_AuthEnvelopedData, mac, ASN1_OCTET_STRING),
ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, unauthAttrs, X509_ALGOR, 3)
ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, unauthAttrs, X509_ATTRIBUTE, 2)
} ASN1_NDEF_SEQUENCE_END(CMS_AuthEnvelopedData)
ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
@@ -257,9 +257,9 @@ ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ATTRIBUTE, 2),
ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ATTRIBUTE, 3)
} static_ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
ASN1_NDEF_SEQUENCE(CMS_CompressedData)
+42 -4
View File
@@ -928,6 +928,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
CMS_EncryptedContentInfo *ec;
CMS_KEKRecipientInfo *kekri;
unsigned char *ukey = NULL;
size_t ukey_alloc_len = 0;
int ukeylen;
int r = 0, wrap_nid;
EVP_CIPHER *cipher = NULL;
@@ -965,7 +966,8 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
goto err;
}
ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
ukey_alloc_len = (size_t)kekri->encryptedKey->length - 8;
ukey = OPENSSL_malloc(ukey_alloc_len);
if (ukey == NULL)
goto err;
@@ -994,7 +996,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
err:
EVP_CIPHER_free(cipher);
if (!r)
OPENSSL_free(ukey);
OPENSSL_clear_free(ukey, ukey_alloc_len);
EVP_CIPHER_CTX_free(ctx);
return r;
@@ -1204,6 +1206,35 @@ BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
return cms_EnvelopedData_Decryption_init_bio(cms);
}
/* The DER encoding of authAttrs, with the universal SET OF tag, is the AAD */
static int cms_AuthEnvelopedData_set_aad(BIO *b,
STACK_OF(X509_ATTRIBUTE) *authAttrs)
{
EVP_CIPHER_CTX *ctx;
unsigned char *aad = NULL;
int aadlen, outl, ok = 0;
const ASN1_ITEM *item;
if (!BIO_get_cipher_ctx(b, &ctx))
return 0;
item = EVP_CIPHER_CTX_is_encrypting(ctx)
? ASN1_ITEM_rptr(CMS_Attributes_AadEncrypt)
: ASN1_ITEM_rptr(CMS_Attributes_AadDecrypt);
aadlen = ASN1_item_i2d((ASN1_VALUE *)authAttrs, &aad, item);
if (aadlen <= 0 || aad == NULL) {
ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
goto err;
}
if (EVP_CipherUpdate(ctx, NULL, &outl, aad, aadlen) <= 0) {
ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE);
goto err;
}
ok = 1;
err:
OPENSSL_free(aad);
return ok;
}
BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms)
{
CMS_EncryptedContentInfo *ec;
@@ -1220,9 +1251,16 @@ BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms)
ec->taglen = aenv->mac->length;
}
ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms), 1);
if (ret == NULL)
return NULL;
/* If error or no cipher end of processing */
if (ret == NULL || ec->cipher == NULL)
/* authAttrs, if present, are the AEAD associated data */
if (aenv->authAttrs != NULL
&& !cms_AuthEnvelopedData_set_aad(ret, aenv->authAttrs))
goto err;
/* If no cipher end of processing */
if (ec->cipher == NULL)
return ret;
/* Now encrypt content key according to each RecipientInfo type */
+5 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2013-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
@@ -216,6 +216,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
size_t keklen;
int rv = 0;
unsigned char *out = NULL;
size_t out_alloc_len = 0;
int outlen;
size_t outsize;
@@ -240,7 +241,8 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
out = OPENSSL_malloc(outsize);
if (out == NULL)
goto err;
if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen))
out_alloc_len = (size_t)outlen;
if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, (int)inlen))
goto err;
*pout = out;
*poutlen = (size_t)outlen;
@@ -249,7 +251,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
err:
OPENSSL_cleanse(kek, keklen);
if (!rv)
OPENSSL_free(out);
OPENSSL_clear_free(out, out_alloc_len);
EVP_CIPHER_CTX_reset(kari->ctx);
/* FIXME: WHY IS kari->pctx freed here? /RL */
EVP_PKEY_CTX_free(kari->pctx);
+3
View File
@@ -371,6 +371,9 @@ DECLARE_ASN1_ITEM(CMS_EncryptedContentInfo)
DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
/* The authAttrs AAD encoding matches the signed-attributes one */
#define CMS_Attributes_AadEncrypt_it CMS_Attributes_Sign_it
#define CMS_Attributes_AadDecrypt_it CMS_Attributes_Verify_it
DECLARE_ASN1_ITEM(CMS_RecipientInfo)
DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
+4 -1
View File
@@ -315,6 +315,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
EVP_CIPHER *kekcipher;
unsigned char *key = NULL;
size_t keylen;
size_t key_alloc_len = 0;
const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
ec = ossl_cms_get0_env_enc_content(cms);
@@ -391,6 +392,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
if (key == NULL)
goto err;
key_alloc_len = keylen;
if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
goto err;
@@ -400,6 +402,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
key = OPENSSL_malloc(pwri->encryptedKey->length);
if (key == NULL)
goto err;
key_alloc_len = (size_t)pwri->encryptedKey->length;
if (!kek_unwrap_key(key, &keylen,
pwri->encryptedKey->data,
pwri->encryptedKey->length, kekctx)) {
@@ -419,7 +422,7 @@ err:
EVP_CIPHER_CTX_free(kekctx);
if (!r)
OPENSSL_free(key);
OPENSSL_clear_free(key, key_alloc_len);
X509_ALGOR_free(kekalg);
return r;
+39
View File
@@ -36,6 +36,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
unsigned char buf[4096];
int r = 0, i;
BIO *tmpout;
BIO *aeadbuf = NULL;
tmpout = cms_get_text_bio(out, flags);
@@ -44,6 +45,33 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
goto err;
}
/*
* For AEAD content (AuthEnvelopedData) the integrity tag is only verified
* once all the ciphertext has been processed, by the
* BIO_get_cipher_status() call below. RFC 5083 requires that the plaintext
* is not released to the caller until that verification succeeds, so
* buffer it in memory and only forward it to the output BIO once the tag
* has been checked. When CMS_TEXT is set tmpout is already a memory BIO
* that is flushed only on success, so the extra buffering is not needed.
*/
if (tmpout == out && BIO_method_type(in) == BIO_TYPE_CIPHER) {
EVP_CIPHER_CTX *ctx = NULL;
if (BIO_get_cipher_ctx(in, &ctx) > 0 && ctx != NULL
&& (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
& EVP_CIPH_FLAG_AEAD_CIPHER)
!= 0) {
aeadbuf = BIO_new(BIO_s_mem());
if (aeadbuf == NULL) {
ERR_raise(ERR_LIB_CMS, ERR_R_BIO_LIB);
goto err;
}
/* Return 0 (EOF) rather than a retryable -1 once drained. */
BIO_set_mem_eof_return(aeadbuf, 0);
tmpout = aeadbuf;
}
}
/* Read all content through chain to process digest, decrypt etc */
for (;;) {
i = BIO_read(in, buf, sizeof(buf));
@@ -66,6 +94,17 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR);
goto err;
}
} else if (aeadbuf != NULL) {
/* Forward the AEAD BIO to out BIO as the tag has been verified. */
for (;;) {
i = BIO_read(aeadbuf, buf, sizeof(buf));
if (i < 0)
goto err;
if (i == 0)
break;
if (BIO_write(out, buf, i) != i)
goto err;
}
}
r = 1;
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* 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
@@ -84,7 +84,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
declen = ct_base64_decode(logid_base64, &dec);
if (declen < 0) {
ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR);
ERR_raise(ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR);
goto err;
}
if (!SCT_set0_log_id(sct, dec, declen))
@@ -93,7 +93,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
declen = ct_base64_decode(extensions_base64, &dec);
if (declen < 0) {
ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR);
ERR_raise(ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR);
goto err;
}
SCT_set0_extensions(sct, dec, declen);
@@ -101,7 +101,7 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
declen = ct_base64_decode(signature_base64, &dec);
if (declen < 0) {
ERR_raise(ERR_LIB_CT, X509_R_BASE64_DECODE_ERROR);
ERR_raise(ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR);
goto err;
}
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2017-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
@@ -226,7 +226,7 @@ static const unsigned short ctype_char_map[128] = {
#ifdef CHARSET_EBCDIC
int ossl_toascii(int c)
{
if (c < -128 || c > 256 || c == EOF)
if (c < -128 || c >= 256 || c == EOF)
return c;
/*
* Adjust negatively signed characters.
@@ -241,7 +241,7 @@ int ossl_toascii(int c)
int ossl_fromascii(int c)
{
if (c < -128 || c > 256 || c == EOF)
if (c < -128 || c >= 256 || c == EOF)
return c;
if (c < 0)
c += 256;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 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
@@ -232,7 +232,7 @@ DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
goto done;
decerr:
ERR_raise(ERR_LIB_DH, EVP_R_DECODE_ERROR);
ERR_raise(ERR_LIB_DH, DH_R_DECODE_ERROR);
dherr:
DH_free(dh);
dh = NULL;
+23 -1
View File
@@ -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
@@ -74,6 +74,14 @@ int DH_check_params(const DH *dh, int *ret)
BN_CTX *ctx = NULL;
*ret = 0;
/*
* A DH with no modulus or generator cannot be checked. Report
* the failure via |*ret| rather than dereferencing NULL below.
*/
if (dh->params.p == NULL || dh->params.g == NULL) {
*ret = DH_NOT_SUITABLE_GENERATOR | DH_CHECK_P_NOT_PRIME;
return 1;
}
ctx = BN_CTX_new_ex(dh->libctx);
if (ctx == NULL)
goto err;
@@ -150,6 +158,11 @@ int DH_check(const DH *dh, int *ret)
int nid = DH_get_nid((DH *)dh);
*ret = 0;
/* A DH with no modulus or generator cannot be checked. */
if (dh->params.p == NULL || dh->params.g == NULL) {
*ret = DH_NOT_SUITABLE_GENERATOR | DH_CHECK_P_NOT_PRIME;
return 1;
}
if (nid != NID_undef)
return 1;
@@ -250,6 +263,15 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key)
*/
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
{
*ret = 0;
/*
* Without a modulus we cannot check anything; signal failure via
* |*ret| rather than crashing in BN_num_bits below.
*/
if (dh->params.p == NULL) {
*ret = DH_CHECK_PUBKEY_INVALID;
return 1;
}
/* Don't do any checks at all with an excessively large modulus */
if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
+1 -2
View File
@@ -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
@@ -198,7 +198,6 @@ static int dsa_keygen(DSA *dsa)
ok = dsa_keygen_pairwise_test(dsa, cb, cbarg)
&& dsa_keygen_knownanswer_test(dsa, ctx, cb, cbarg);
if (!ok) {
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
BN_free(dsa->pub_key);
BN_clear_free(dsa->priv_key);
dsa->pub_key = NULL;
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2014-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2014, Intel Corporation. All Rights Reserved.
# Copyright (c) 2015 CloudFlare, Inc.
#
@@ -80,6 +80,14 @@ if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([
$addx = ($ver>=3.03);
}
if (!$addx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
$addx = ($1>=11);
}
}
$code.=<<___;
.text
.extern OPENSSL_ia32cap_P
@@ -1,5 +1,5 @@
#!/usr/bin/env perl
# Copyright 2018-2020 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
@@ -97,6 +97,13 @@ if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([
$addx = ($ver>=3.03);
}
if (!$addx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$addx = ($1>=11); #icx started with clang 11
}
}
$code.=<<___;
.text
+2 -54
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2002-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
@@ -236,56 +236,6 @@ int ossl_ec_key_gen(EC_KEY *eckey)
return ret;
}
/*
* Refer: FIPS 140-3 IG 10.3.A Additional Comment 1
* Perform a KAT by duplicating the public key generation.
*
* NOTE: This issue requires a background understanding, provided in a separate
* document; the current IG 10.3.A AC1 is insufficient regarding the PCT for
* the key agreement scenario.
*
* Currently IG 10.3.A requires PCT in the mode of use prior to use of the
* key pair, citing the PCT defined in the associated standard. For key
* agreement, the only PCT defined in SP 800-56A is that of Section 5.6.2.4:
* the comparison of the original public key to a newly calculated public key.
*/
static int ecdsa_keygen_knownanswer_test(EC_KEY *eckey, BN_CTX *ctx,
OSSL_CALLBACK *cb, void *cbarg)
{
int len, ret = 0;
OSSL_SELF_TEST *st = NULL;
unsigned char bytes[512] = { 0 };
EC_POINT *pub_key2 = NULL;
st = OSSL_SELF_TEST_new(cb, cbarg);
if (st == NULL)
return 0;
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT_KAT,
OSSL_SELF_TEST_DESC_PCT_ECDSA);
if ((pub_key2 = EC_POINT_new(eckey->group)) == NULL)
goto err;
/* pub_key = priv_key * G (where G is a point on the curve) */
if (!EC_POINT_mul(eckey->group, pub_key2, eckey->priv_key, NULL, NULL, ctx))
goto err;
if (BN_num_bytes(pub_key2->X) > (int)sizeof(bytes))
goto err;
len = BN_bn2bin(pub_key2->X, bytes);
if (OSSL_SELF_TEST_oncorrupt_byte(st, bytes)
&& BN_bin2bn(bytes, len, pub_key2->X) == NULL)
goto err;
ret = !EC_POINT_cmp(eckey->group, eckey->pub_key, pub_key2, ctx);
err:
OSSL_SELF_TEST_onend(st, ret);
OSSL_SELF_TEST_free(st);
EC_POINT_free(pub_key2);
return ret;
}
/*
* ECC Key generation.
* See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates"
@@ -382,13 +332,11 @@ static int ec_generate_key(EC_KEY *eckey, int pairwise_test)
void *cbarg = NULL;
OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg);
ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg)
&& ecdsa_keygen_knownanswer_test(eckey, ctx, cb, cbarg);
ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
}
err:
/* Step (9): If there is an error return an invalid keypair. */
if (!ok) {
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
BN_clear(eckey->priv_key);
if (eckey->pub_key != NULL)
EC_POINT_set_to_infinity(group, eckey->pub_key);
+1
View File
@@ -1861,6 +1861,7 @@ X509_R_CANT_CHECK_DH_KEY:114:can't check dh key
X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed
X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
X509_R_CRL_ALREADY_DELTA:127:crl already delta
X509_R_CRL_SIGNATURE_ALGORITHM_MISMATCH:147:crl signature algorithm mismatch
X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
X509_R_DUPLICATE_ATTRIBUTE:140:duplicate attribute
X509_R_ERROR_GETTING_MD_BY_NID:141:error getting md by nid
+3 -1
View File
@@ -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
@@ -287,7 +287,9 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
* iteration we're on.
*/
EVP_KEYEXCH_free(exchange);
exchange = NULL;
EVP_KEYMGMT_free(tmp_keymgmt);
tmp_keymgmt = NULL;
switch (iter) {
case 1:
@@ -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
@@ -77,6 +77,13 @@ static int ffc_validate_LN(size_t L, size_t N, int type, int verify)
ERR_raise(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS);
#endif
} else if (type == FFC_PARAM_TYPE_DSA) {
if (N > 512) {
#ifndef OPENSSL_NO_DSA
ERR_raise_data(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS,
"N is %zu, but the maximum supported N is 512", N);
#endif
return 0;
}
if (L >= 3072 && N >= 256)
return 128;
if (L >= 2048 && N >= 224)
+6 -4
View File
@@ -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
@@ -50,9 +50,11 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
return 0;
#ifdef OPENSSL_HMAC_S390X
rv = s390x_HMAC_init(ctx, key, len, impl);
if (rv >= 1)
return rv;
{
int ret = s390x_HMAC_init(ctx, key, len, impl);
if (ret != -1) /* -1 means SW fallback */
return ret;
}
#endif
if (key != NULL) {
+16 -11
View File
@@ -21,6 +21,7 @@
#define NI_MAXHOST 255
#endif
#include "crypto/ctype.h" /* for ossl_isspace() */
#define OSSL_URL_SCHEME_SUFFIX "://"
static void init_pstring(char **pstr)
{
@@ -79,16 +80,20 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
return 0;
}
/* check for optional prefix "<scheme>://" */
scheme = scheme_end = url;
p = strstr(url, "://");
if (p == NULL) {
p = url;
} else {
scheme_end = p;
if (scheme_end == scheme)
goto parse_err;
p += strlen("://");
/* check for optional prefix "<scheme>://" as per RFC 3986: */
scheme = scheme_end = p = url;
if (ossl_isalpha(*p)) {
while (*p != '\0'
&& (ossl_isalpha(*p)
|| ossl_isdigit(*p)
|| strchr("+-.", *p) != NULL))
p++;
if (HAS_PREFIX(p, OSSL_URL_SCHEME_SUFFIX)) {
scheme_end = p;
p += sizeof(OSSL_URL_SCHEME_SUFFIX) - 1;
} else {
p = url;
}
}
/* parse optional "userinfo@" */
@@ -105,7 +110,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
/* parse hostname/address as far as needed here */
if (host[0] == '[') {
/* IPv6 literal, which may include ':' */
host_end = strchr(host + 1, ']');
host_end = memchr(host + 1, ']', authority_end - host - 1);
if (host_end == NULL)
goto parse_err;
p = ++host_end;
@@ -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
@@ -932,6 +932,9 @@ int ossl_ml_dsa_sig_encode(const ML_DSA_SIG *sig, const ML_DSA_PARAMS *params,
ret = 1;
err:
WPACKET_finish(&pkt);
/* Erase any partial signature output on failure */
if (ret == 0)
OPENSSL_cleanse(out, params->sig_len);
return ret;
}
+10 -4
View File
@@ -346,10 +346,15 @@ static int public_from_private(const ML_DSA_KEY *key, EVP_MD_CTX *md_ctx,
/* Compress t */
vector_power2_round(&t, t1, t0);
/* Zeroize secret */
vector_zero(&s1_ntt);
ret = 1;
err:
/*
* The low bits of |t| are private and |s1_ntt| is secret, wipe both.
* The trailing |a_ntt| matrix is not wiped: per FIPS 204 section 3.6.3
* the matrix A is easily computed from the public key and does not
* require any special protections.
*/
OPENSSL_cleanse(polys, (k + l) * sizeof(*polys));
OPENSSL_free(polys);
return ret;
}
@@ -370,6 +375,7 @@ int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key)
&& shake_xof(md_ctx, key->shake256_md,
key->pub_encoding, key->params->pk_len,
key->tr, sizeof(key->tr));
vector_zero(&t0);
vector_free(&t0);
EVP_MD_CTX_free(md_ctx);
return ret;
@@ -401,7 +407,7 @@ int ossl_ml_dsa_key_pairwise_check(const ML_DSA_KEY *key)
ret = vector_equal(&t1, &key->t1) && vector_equal(&t0, &key->t0);
err:
EVP_MD_CTX_free(md_ctx);
OPENSSL_free(polys);
OPENSSL_clear_free(polys, 2 * k * sizeof(*polys));
return ret;
}
@@ -489,7 +495,7 @@ int ossl_ml_dsa_generate_key(ML_DSA_KEY *out)
"explicit %s private key does not match seed",
out->params->alg);
}
OPENSSL_free(sk);
OPENSSL_clear_free(sk, out->params->sk_len);
}
return ret;
}
+5 -3
View File
@@ -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
@@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/crypto.h>
#include "ml_dsa_local.h"
#include "ml_dsa_vector.h"
#include "ml_dsa_matrix.h"
@@ -25,15 +26,16 @@ void ossl_ml_dsa_matrix_mult_vector(const MATRIX *a, const VECTOR *s,
{
size_t i, j;
POLY *poly = a->m_poly;
POLY product;
vector_zero(t);
for (i = 0; i < a->k; i++) {
for (j = 0; j < a->l; j++) {
POLY product;
ossl_ml_dsa_poly_ntt_mult(poly++, &s->poly[j], &product);
poly_add(&product, &t->poly[i], &t->poly[i]);
}
}
OPENSSL_cleanse(&product, sizeof(product));
}
+35 -12
View File
@@ -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
@@ -8,6 +8,7 @@
*/
#include <openssl/byteorder.h>
#include <openssl/crypto.h>
#include "ml_dsa_local.h"
#include "ml_dsa_vector.h"
#include "ml_dsa_matrix.h"
@@ -159,13 +160,14 @@ static int rej_bounded_poly(EVP_MD_CTX *h_ctx, const EVP_MD *md,
COEFF_FROM_NIBBLE_FUNC *coef_from_nibble,
const uint8_t *seed, size_t seed_len, POLY *out)
{
int ret = 0;
int j = 0;
uint32_t z0, z1;
uint8_t blocks[SHAKE256_BLOCKSIZE], *b, *end = blocks + sizeof(blocks);
/* Instead of just squeezing 1 byte at a time, we grab a whole block */
if (!shake_xof(h_ctx, md, seed, seed_len, blocks, sizeof(blocks)))
return 0;
goto err;
while (1) {
for (b = blocks; b < end; b++) {
@@ -173,15 +175,22 @@ static int rej_bounded_poly(EVP_MD_CTX *h_ctx, const EVP_MD *md,
z1 = *b >> 4; /* high nibble of byte */
if (coef_from_nibble(z0, &out->coeff[j])
&& ++j >= ML_DSA_NUM_POLY_COEFFICIENTS)
return 1;
&& ++j >= ML_DSA_NUM_POLY_COEFFICIENTS) {
ret = 1;
goto err;
}
if (coef_from_nibble(z1, &out->coeff[j])
&& ++j >= ML_DSA_NUM_POLY_COEFFICIENTS)
return 1;
&& ++j >= ML_DSA_NUM_POLY_COEFFICIENTS) {
ret = 1;
goto err;
}
}
if (!EVP_DigestSqueeze(h_ctx, blocks, sizeof(blocks)))
return 0;
goto err;
}
err:
OPENSSL_cleanse(blocks, sizeof(blocks));
return ret;
}
/**
@@ -205,6 +214,13 @@ int ossl_ml_dsa_matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md,
uint8_t derived_seed[ML_DSA_RHO_BYTES + 2];
POLY *poly = out->m_poly;
/*
* The seeds derived below and the sampling buffers in rej_ntt_poly() are
* not cleansed: per FIPS 204 section 3.6.3 the matrix A is easily
* computed from the public key and does not require any special
* protections.
*/
/* The seed used for each matrix element is rho + column_index + row_index */
memcpy(derived_seed, rho, ML_DSA_RHO_BYTES);
@@ -274,6 +290,7 @@ int ossl_ml_dsa_vector_expand_S(EVP_MD_CTX *h_ctx, const EVP_MD *md, int eta,
}
ret = 1;
err:
OPENSSL_cleanse(derived_seed, sizeof(derived_seed));
return ret;
}
@@ -284,9 +301,11 @@ int ossl_ml_dsa_poly_expand_mask(POLY *out, const uint8_t *seed, size_t seed_len
{
uint8_t buf[32 * 20];
size_t buf_len = 32 * (gamma1 == ML_DSA_GAMMA1_TWO_POWER_19 ? 20 : 18);
return shake_xof(h_ctx, md, seed, seed_len, buf, buf_len)
int ret = shake_xof(h_ctx, md, seed, seed_len, buf, buf_len)
&& ossl_ml_dsa_poly_decode_expand_mask(out, buf, buf_len, gamma1);
OPENSSL_cleanse(buf, sizeof(buf));
return ret;
}
/*
@@ -311,13 +330,14 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l
uint64_t signs;
int offset = 8;
size_t end;
int ret = 0;
/*
* Rather than squeeze 8 bytes followed by lots of 1 byte squeezes
* the SHAKE blocksize is squeezed each time and buffered into 'block'.
*/
if (!shake_xof(h_ctx, md, seed, seed_len, block, sizeof(block)))
return 0;
goto err;
/*
* grab the first 64 bits - since tau < 64
@@ -336,7 +356,7 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l
if (offset == sizeof(block)) {
/* squeeze another block if the bytes from block have been used */
if (!EVP_DigestSqueeze(h_ctx, block, sizeof(block)))
return 0;
goto err;
offset = 0;
}
@@ -354,5 +374,8 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l
out_c->coeff[index] = mod_sub(1, 2 * (signs & 1));
signs >>= 1; /* grab the next random bit */
}
return 1;
ret = 1;
err:
OPENSSL_cleanse(block, sizeof(block));
return ret;
}
+16 -3
View File
@@ -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
@@ -197,6 +197,7 @@ err:
EVP_MD_CTX_free(md_ctx);
OPENSSL_clear_free(alloc, alloc_len);
OPENSSL_cleanse(rho_prime, sizeof(rho_prime));
OPENSSL_cleanse(c_tilde, sizeof(c_tilde));
return ret;
}
@@ -387,7 +388,13 @@ int ossl_ml_dsa_sign(const ML_DSA_KEY *priv, int msg_is_mu,
alloced_m = m;
}
ret = ml_dsa_sign_internal(priv, msg_is_mu, m, m_len, rand, rand_len, sig);
OPENSSL_free(alloced_m);
/* The encoded message may contain confidential message content */
if (m != msg) {
if (m != m_tmp)
OPENSSL_clear_free(alloced_m, m_len);
else
OPENSSL_cleanse(m_tmp, sizeof(m_tmp));
}
}
if (sig_len != NULL)
*sig_len = priv->params->sig_len;
@@ -424,6 +431,12 @@ int ossl_ml_dsa_verify(const ML_DSA_KEY *pub, int msg_is_mu,
}
ret = ml_dsa_verify_internal(pub, msg_is_mu, m, m_len, sig, sig_len);
OPENSSL_free(alloced_m);
/* The encoded message may contain confidential message content */
if (m != msg) {
if (m != m_tmp)
OPENSSL_clear_free(alloced_m, m_len);
else
OPENSSL_cleanse(m_tmp, sizeof(m_tmp));
}
return ret;
}
+3 -1
View File
@@ -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
@@ -8,6 +8,7 @@
*/
#include <assert.h>
#include <openssl/crypto.h>
#include "ml_dsa_poly.h"
struct vector_st {
@@ -153,6 +154,7 @@ vector_expand_mask(VECTOR *out, const uint8_t *rho_prime, size_t rho_prime_len,
poly_expand_mask(out->poly + i, derived_seed, sizeof(derived_seed),
gamma1, h_ctx, md);
}
OPENSSL_cleanse(derived_seed, sizeof(derived_seed));
}
/* Scale back previously rounded value */
+81 -26
View File
@@ -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
@@ -1310,6 +1310,12 @@ static __owur int matrix_expand(EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
int rank = key->vinfo->rank;
int i, j;
/*
* The seeds derived below and the sampling buffers in sample_scalar()
* are not cleansed: per FIPS 203 section 3.3 the matrix A is easily
* computed from the public encapsulation key and does not require any
* special protections.
*/
memcpy(input, key->rho, ML_KEM_RANDOM_BYTES);
for (i = 0; i < rank; i++) {
for (j = 0; j < rank; j++) {
@@ -1340,8 +1346,10 @@ static __owur int cbd_2(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
uint16_t value, mask;
uint8_t b;
if (!prf(randbuf, sizeof(randbuf), in, mdctx, key))
if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) {
OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
return 0;
}
do {
b = *r++;
@@ -1363,6 +1371,8 @@ static __owur int cbd_2(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
mask = constish_time_non_zero(value >> 15);
*curr++ = value + (kPrime & mask);
} while (curr < end);
OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
return 1;
}
@@ -1380,8 +1390,10 @@ static __owur int cbd_3(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
uint8_t b1, b2, b3;
uint16_t value, mask;
if (!prf(randbuf, sizeof(randbuf), in, mdctx, key))
if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) {
OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
return 0;
}
do {
b1 = *r++;
@@ -1415,6 +1427,8 @@ static __owur int cbd_3(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
mask = constish_time_non_zero(value >> 15);
*curr++ = value + (kPrime & mask);
} while (curr < end);
OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
return 1;
}
@@ -1427,14 +1441,19 @@ static __owur int gencbd_vector(scalar *out, CBD_FUNC cbd, uint8_t *counter,
EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
{
uint8_t input[ML_KEM_RANDOM_BYTES + 1];
int ret = 0;
memcpy(input, seed, ML_KEM_RANDOM_BYTES);
do {
input[ML_KEM_RANDOM_BYTES] = (*counter)++;
if (!cbd(out++, input, mdctx, key))
return 0;
goto end;
} while (--rank > 0);
return 1;
ret = 1;
end:
OPENSSL_cleanse((void *)input, sizeof(input));
return ret;
}
/*
@@ -1445,15 +1464,20 @@ static __owur int gencbd_vector_ntt(scalar *out, CBD_FUNC cbd, uint8_t *counter,
EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
{
uint8_t input[ML_KEM_RANDOM_BYTES + 1];
int ret = 0;
memcpy(input, seed, ML_KEM_RANDOM_BYTES);
do {
input[ML_KEM_RANDOM_BYTES] = (*counter)++;
if (!cbd(out, input, mdctx, key))
return 0;
goto end;
scalar_ntt(out++);
} while (--rank > 0);
return 1;
ret = 1;
end:
OPENSSL_cleanse((void *)input, sizeof(input));
return ret;
}
/* The |ETA1| value for ML-KEM-512 is 3, the rest and all ETA2 values are 2. */
@@ -1492,10 +1516,11 @@ static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
uint8_t counter = 0;
int du = vinfo->du;
int dv = vinfo->dv;
int ret = 0;
/* FIPS 203 "y" vector */
if (!gencbd_vector_ntt(y, cbd_1, &counter, r, rank, mdctx, key))
return 0;
goto end;
/* FIPS 203 "v" scalar */
inner_product(&v, key->t, y, rank);
scalar_inverse_ntt(&v);
@@ -1504,7 +1529,7 @@ static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
/* All done with |y|, now free to reuse tmp[0] for FIPS 203 |e1| */
if (!gencbd_vector(e1, cbd_2, &counter, r, rank, mdctx, key))
return 0;
goto end;
vector_add(u, e1, rank);
vector_compress(u, du, rank);
vector_encode(out, u, du, rank);
@@ -1513,14 +1538,19 @@ static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
memcpy(input, r, ML_KEM_RANDOM_BYTES);
input[ML_KEM_RANDOM_BYTES] = counter;
if (!cbd_2(e2, input, mdctx, key))
return 0;
goto end;
scalar_add(&v, e2);
/* Combine message with |v| */
scalar_decode_decompress_add(&v, message);
scalar_compress(&v, dv);
scalar_encode(out + vinfo->u_vector_bytes, &v, dv);
return 1;
ret = 1;
end:
OPENSSL_cleanse((void *)input, sizeof(input));
OPENSSL_cleanse((void *)&v, sizeof(v));
return ret;
}
/*
@@ -1544,6 +1574,9 @@ decrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
scalar_sub(&v, &mask);
scalar_compress(&v, 1);
scalar_encode_1(out, &v);
OPENSSL_cleanse((void *)&v, sizeof(v));
OPENSSL_cleanse((void *)&mask, sizeof(mask));
}
/*-
@@ -1737,8 +1770,8 @@ static __owur int genkey(const uint8_t seed[ML_KEM_SEED_BYTES],
ret = 1;
end:
OPENSSL_cleanse((void *)augmented_seed, ML_KEM_RANDOM_BYTES);
OPENSSL_cleanse((void *)sigma, ML_KEM_RANDOM_BYTES);
OPENSSL_cleanse((void *)augmented_seed, sizeof(augmented_seed));
OPENSSL_cleanse((void *)hashed, sizeof(hashed));
if (ret == 0) {
ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
"internal error while generating %s private key",
@@ -1776,6 +1809,7 @@ static int encap(uint8_t *ctext, uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
"internal error while performing %s encapsulation",
key->vinfo->algorithm_name);
OPENSSL_cleanse((void *)Kr, sizeof(Kr));
return ret;
}
@@ -1822,6 +1856,7 @@ static int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
"internal error while performing %s decapsulation",
vinfo->algorithm_name);
OPENSSL_cleanse(failure_key, sizeof(failure_key));
return 0;
}
decrypt_cpa(decrypted, ctext, tmp, key);
@@ -1830,6 +1865,8 @@ static int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
|| !encrypt_cpa(tmp_ctext, decrypted, r, tmp, mdctx, key)) {
memcpy(secret, failure_key, ML_KEM_SHARED_SECRET_BYTES);
OPENSSL_cleanse(decrypted, ML_KEM_SHARED_SECRET_BYTES);
OPENSSL_cleanse(Kr, sizeof(Kr));
OPENSSL_cleanse(failure_key, sizeof(failure_key));
return 1;
}
mask = constant_time_eq_int_8(0,
@@ -1838,6 +1875,7 @@ static int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
secret[i] = constant_time_select_8(mask, Kr[i], failure_key[i]);
OPENSSL_cleanse(decrypted, ML_KEM_SHARED_SECRET_BYTES);
OPENSSL_cleanse(Kr, sizeof(Kr));
OPENSSL_cleanse(failure_key, sizeof(failure_key));
return 1;
}
@@ -1845,7 +1883,7 @@ static int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
* After allocating storage for public or private key data, update the key
* component pointers to reference that storage.
*/
static __owur int add_storage(scalar *p, int private, ML_KEM_KEY *key)
static __owur int add_storage(scalar *p, int private, int dup, ML_KEM_KEY *key)
{
int rank = key->vinfo->rank;
@@ -1854,9 +1892,12 @@ static __owur int add_storage(scalar *p, int private, ML_KEM_KEY *key)
/*
* We're adding key material, the seed buffer will now hold |rho| and
* |pkhash|.
* |pkhash|. Zero the key hash when creating fresh keys; when
* duplicating, |key| was memdup'd from the source so |seedbuf|
* already carries the correct |rho|/|pkhash| bytes — preserve them.
*/
memset(key->seedbuf, 0, sizeof(key->seedbuf));
if (dup == 0)
memset(key->seedbuf, 0, sizeof(key->seedbuf));
key->rho = key->seedbuf;
key->pkhash = key->seedbuf + ML_KEM_RANDOM_BYTES;
key->d = key->z = NULL;
@@ -1980,18 +2021,18 @@ ML_KEM_KEY *ossl_ml_kem_key_dup(const ML_KEM_KEY *key, int selection)
selection = 0;
else if (!ossl_ml_kem_have_prvkey(key))
selection &= ~OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
else if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
selection &= ~OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
switch (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) {
case 0:
ok = 1;
break;
case OSSL_KEYMGMT_SELECT_PUBLIC_KEY:
ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->puballoc), 0, ret);
ret->rho = ret->seedbuf;
ret->pkhash = ret->rho + ML_KEM_RANDOM_BYTES;
ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->puballoc), 0, 1, ret);
break;
case OSSL_KEYMGMT_SELECT_PRIVATE_KEY:
ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->prvalloc), 1, ret);
ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->prvalloc), 1, 1, ret);
/* Duplicated keys retain |d|, if available */
if (key->d != NULL)
ret->d = ret->z + ML_KEM_RANDOM_BYTES;
@@ -2111,7 +2152,7 @@ int ossl_ml_kem_parse_public_key(const uint8_t *in, size_t len, ML_KEM_KEY *key)
|| (mdctx = EVP_MD_CTX_new()) == NULL)
return 0;
if (add_storage(OPENSSL_malloc(vinfo->puballoc), 0, key))
if (add_storage(OPENSSL_malloc(vinfo->puballoc), 0, 0, key))
ret = parse_pubkey(in, mdctx, key);
if (!ret)
@@ -2139,7 +2180,7 @@ int ossl_ml_kem_parse_private_key(const uint8_t *in, size_t len,
|| (mdctx = EVP_MD_CTX_new()) == NULL)
return 0;
if (add_storage(OPENSSL_malloc(vinfo->prvalloc), 1, key))
if (add_storage(OPENSSL_malloc(vinfo->prvalloc), 1, 0, key))
ret = parse_prvkey(in, mdctx, key);
if (!ret)
@@ -2187,7 +2228,7 @@ int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key)
*/
CONSTTIME_SECRET(seed, ML_KEM_SEED_BYTES);
if (add_storage(OPENSSL_malloc(vinfo->prvalloc), 1, key))
if (add_storage(OPENSSL_malloc(vinfo->prvalloc), 1, 0, key))
ret = genkey(seed, mdctx, pubenc, key);
OPENSSL_cleanse(seed, sizeof(seed));
@@ -2196,6 +2237,9 @@ int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key)
EVP_MD_CTX_free(mdctx);
if (!ret) {
/* Erase any partial public key output */
if (pubenc != NULL)
OPENSSL_cleanse(pubenc, vinfo->pubkey_bytes);
ossl_ml_kem_key_reset(key);
return 0;
}
@@ -2254,6 +2298,10 @@ int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen,
}
#undef case_encap_seed
/* Erase any partial ciphertext output on failure */
if (!ret)
OPENSSL_cleanse(ctext, clen);
/* Declassify secret inputs and derived outputs before returning control */
CONSTTIME_DECLASSIFY(entropy, elen);
CONSTTIME_DECLASSIFY(ctext, clen);
@@ -2268,6 +2316,7 @@ int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen,
const ML_KEM_KEY *key)
{
uint8_t r[ML_KEM_RANDOM_BYTES];
int ret;
if (key == NULL)
return 0;
@@ -2277,8 +2326,11 @@ int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen,
< 1)
return 0;
return ossl_ml_kem_encap_seed(ctext, clen, shared_secret, slen,
ret = ossl_ml_kem_encap_seed(ctext, clen, shared_secret, slen,
r, sizeof(r), key);
OPENSSL_cleanse((void *)r, sizeof(r));
return ret;
}
int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
@@ -2293,11 +2345,13 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
#endif
/* Need a private key here */
if (!ossl_ml_kem_have_prvkey(key))
if (!ossl_ml_kem_have_prvkey(key)
|| shared_secret == NULL
|| slen < ML_KEM_SHARED_SECRET_BYTES)
return 0;
vinfo = key->vinfo;
if (shared_secret == NULL || slen != ML_KEM_SHARED_SECRET_BYTES
if (slen != ML_KEM_SHARED_SECRET_BYTES
|| ctext == NULL || clen != vinfo->ctext_bytes
|| (mdctx = EVP_MD_CTX_new()) == NULL) {
(void)RAND_bytes_ex(key->libctx, shared_secret,
@@ -2326,6 +2380,7 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
\
ret = decap(shared_secret, ctext, cbuf, tmp, mdctx, key); \
OPENSSL_cleanse((void *)tmp, sizeof(tmp)); \
OPENSSL_cleanse((void *)cbuf, sizeof(cbuf)); \
break; \
}
switch (vinfo->evp_type) {
@@ -1,4 +1,4 @@
# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2021, Intel Corporation. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -72,6 +72,13 @@ if (!$avx512vaes && `$ENV{CC} -v 2>&1`
}
}
if (!$avx512vaes && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx512vaes = ($1>=11); #icx started with clang 11
}
}
open OUT, "| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT = *OUT;
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-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
@@ -73,6 +73,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2010-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2010-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
@@ -121,6 +121,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
+4 -4
View File
@@ -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
@@ -893,13 +893,13 @@ static void *do_PVK_body_key(const unsigned char **in,
(unsigned char *)psbuf, inlen, libctx, propq))
goto err;
p += saltlen;
/* Copy BLOBHEADER across, decrypt rest */
memcpy(enctmp, p, 8);
p += 8;
if (keylen < 8) {
ERR_raise(ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT);
goto err;
}
/* Copy BLOBHEADER across, decrypt rest */
memcpy(enctmp, p, 8);
p += 8;
inlen = keylen - 8;
q = enctmp + 8;
if ((rc4 = EVP_CIPHER_fetch(libctx, "RC4", propq)) == NULL)
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2024 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
@@ -222,6 +222,6 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
}
return p7s;
err:
sk_PKCS7_free(p7s);
sk_PKCS7_pop_free(p7s, PKCS7_free);
return NULL;
}
+3 -2
View File
@@ -55,7 +55,8 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
& EVP_CIPH_FLAG_CIPHER_WITH_MAC)
!= 0) {
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) {
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len)
<= 0) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -70,7 +71,7 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor,
inlen -= mac_len;
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
(int)mac_len, (unsigned char *)in + inlen)
< 0) {
<= 0) {
ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR);
goto err;
}
+2
View File
@@ -186,6 +186,8 @@ char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen)
/* string must contain an even number of bytes */
if (unilen & 1)
return NULL;
if (unilen < 0)
return NULL;
for (asclen = 0, i = 0; i < unilen;) {
j = bmp_to_utf8(NULL, uni + i, unilen - i);
+1 -1
View File
@@ -1200,7 +1200,7 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
rsk = p7->d.signed_and_enveloped->recipientinfo;
if (rsk == NULL)
return NULL;
if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
if (idx < 0 || sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
return NULL;
ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
return ri->issuer_and_serial;
+16 -2
View File
@@ -537,7 +537,7 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
}
ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
return 1;
return 0;
}
STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
@@ -727,6 +727,10 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
break;
case NID_pkcs7_signedAndEnveloped:
if (p7->d.signed_and_enveloped == NULL || p7->d.signed_and_enveloped->enc_data == NULL) {
ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
break;
}
os = p7->d.signed_and_enveloped->enc_data->enc_data;
if (os == NULL) {
os = ASN1_OCTET_STRING_new();
@@ -735,6 +739,10 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
break;
case NID_pkcs7_enveloped:
if (p7->d.enveloped == NULL || p7->d.enveloped->enc_data == NULL) {
ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
break;
}
os = p7->d.enveloped->enc_data->enc_data;
if (os == NULL) {
os = ASN1_OCTET_STRING_new();
@@ -747,7 +755,13 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
break;
}
os = p7->d.sign->contents->d.data;
if (!PKCS7_type_is_data(p7->d.sign->contents)) {
ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
break;
}
os = PKCS7_get_octet_string(p7->d.sign->contents);
break;
default:
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2016-2020 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
@@ -73,6 +73,13 @@ if ($sse2) {
if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) {
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
}
########################################################################
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# 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
@@ -95,6 +95,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
+9 -8
View File
@@ -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
@@ -674,7 +674,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
EVP_RAND_CTX *ctx;
OSSL_PARAM params[9], *p = params;
const OSSL_PARAM *settables;
const char *prov_name;
char *name, *cipher;
int use_df = 1;
@@ -686,7 +685,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
return NULL;
}
prov_name = ossl_provider_name(EVP_RAND_get0_provider(rand));
ctx = EVP_RAND_CTX_new(rand, parent);
EVP_RAND_free(rand);
if (ctx == NULL) {
@@ -704,9 +702,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
&& OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_DIGEST))
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST,
dgbl->rng_digest, 0);
if (prov_name != NULL)
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME,
(char *)prov_name, 0);
if (dgbl->rng_propq != NULL)
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES,
dgbl->rng_propq, 0);
@@ -864,7 +859,10 @@ static EVP_RAND_CTX *rand_get0_public(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
return NULL;
rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
SECONDARY_RESEED_TIME_INTERVAL);
CRYPTO_THREAD_set_local(&dgbl->public, rand);
if (!CRYPTO_THREAD_set_local(&dgbl->public, rand)) {
EVP_RAND_CTX_free(rand);
rand = NULL;
}
}
return rand;
}
@@ -903,7 +901,10 @@ static EVP_RAND_CTX *rand_get0_private(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
return NULL;
rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
SECONDARY_RESEED_TIME_INTERVAL);
CRYPTO_THREAD_set_local(&dgbl->private, rand);
if (!CRYPTO_THREAD_set_local(&dgbl->private, rand)) {
EVP_RAND_CTX_free(rand);
rand = NULL;
}
}
return rand;
}
+1 -2
View File
@@ -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
@@ -636,7 +636,6 @@ static int rsa_keygen(OSSL_LIB_CTX *libctx, RSA *rsa, int bits, int primes,
OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg);
if (!ok) {
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
/* Clear intermediate results */
BN_clear_free(rsa->d);
BN_clear_free(rsa->p);
+15 -1
View File
@@ -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
@@ -160,6 +160,14 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
* See SP800-56Br2, section 7.1.1.1
* RSAEP: 1 < f < (n – 1).
* (where f is the plaintext).
*
* This bound is somewhat overkill here. RSASVE.GENERATE (7.2.1.2)
* regenerates z until 1 < z < n-1, so on that path the plaintext is in
* range unconditionally. On the OAEP path the leading 0x00 octet of the
* encoding forces m < n-1 unconditionally, while m = 0 or 1 is only
* cryptographically negligible, not impossible. The check is kept to
* mirror the RSADP bound in rsa_ossl_private_decrypt() and to keep RSAEP
* faithful to 7.1.1 of the SP; nothing in the SP relies on it here.
*/
if (padding == RSA_NO_PADDING) {
BIGNUM *nminus1 = BN_CTX_get(ctx);
@@ -572,6 +580,12 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
* See SP800-56Br2, section 7.1.2.1
* RSADP: 1 < f < (n – 1)
* (where f is the ciphertext).
*
* Kept under FIPS_MODULE because SP 800-56B KTS-OAEP (section 9.2) also
* decrypts through RSADP and needs this bound in a FIPS build, and there
* is no KTS-OAEP-specific path to attach it to. The non-FIPS RSASVE path
* applies the same 1 < c < n-1 in rsasve_recover()
* (providers/implementations/kem/rsa_kem.c); keep the two in step.
*/
if (padding == RSA_NO_PADDING) {
BIGNUM *nminus1 = BN_CTX_get(ctx);
+4 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 1998-2020 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
@@ -146,6 +146,9 @@ $ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" &&
$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ &&
$2>=3.0); # first version supporting AVX
$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__` =~ /#define __clang_major__.([0-9]+)/ &&
$1>=11); #icx started with clang 11
$shaext=$xmm; ### set to zero if compiling for 1.0.1
&external_label("OPENSSL_ia32cap_P") if ($xmm);
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-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
@@ -76,6 +76,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
+8 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2006-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
@@ -124,6 +124,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
$shaext=1; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
+8 -1
View File
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2007-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
@@ -99,6 +99,13 @@ if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLV
$avx = ($2>=3.0) + ($2>3.0);
}
if ($xmm && !$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
$shaext=$xmm; ### set to zero if compiling for 1.0.1
$unroll_after = 64*4; # If pre-evicted from L1P cache first spin of
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved.
# Copyright 2013-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
@@ -77,6 +77,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
# Copyright 2005-2024 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
@@ -140,6 +140,13 @@ if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0
$avx = ($2>=3.0) + ($2>3.0);
}
if (!$avx && `$ENV{CC} -x c /dev/null -dM -E|grep __clang_major__`
=~ /#define __clang_major__.([0-9]+)/) {
if ($1) {
$avx = ($1>=11); #icx started with clang 11
}
}
$shaext=1; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2023 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
@@ -17,9 +17,9 @@
void sha256_block_data_order_zvkb_zvknha_or_zvknhb(void *ctx, const void *in,
size_t num);
void sha256_block_data_order_c(void *ctx, const void *in, size_t num);
void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
void sha256_block_data_order(void *ctx, const void *in, size_t num);
void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num)
void sha256_block_data_order(void *ctx, const void *in, size_t num)
{
if (RISCV_HAS_ZVKB() && (RISCV_HAS_ZVKNHA() || RISCV_HAS_ZVKNHB()) && riscv_vlen() >= 128) {
sha256_block_data_order_zvkb_zvknha_or_zvknhb(ctx, in, num);
@@ -30,9 +30,9 @@ void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num)
void sha512_block_data_order_zvkb_zvknhb(void *ctx, const void *in, size_t num);
void sha512_block_data_order_c(void *ctx, const void *in, size_t num);
void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
void sha512_block_data_order(void *ctx, const void *in, size_t num);
void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num)
void sha512_block_data_order(void *ctx, const void *in, size_t num)
{
if (RISCV_HAS_ZVKB_AND_ZVKNHB() && riscv_vlen() >= 128) {
sha512_block_data_order_zvkb_zvknhb(ctx, in, num);
+29 -8
View File
@@ -8,6 +8,7 @@
*/
#include <stddef.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/proverr.h>
#include "slh_dsa_local.h"
@@ -122,8 +123,13 @@ static int slh_sign_internal(SLH_DSA_HASH_CTX *hctx,
err:
if (!WPACKET_finish(wpkt))
ret = 0;
OPENSSL_cleanse(m_digest, sizeof(m_digest));
OPENSSL_cleanse(pk_fors, sizeof(pk_fors));
if (ret)
*sig_len = sig_len_expected;
else
/* Erase any partial signature output */
OPENSSL_cleanse(sig, sig_len_expected);
return ret;
}
@@ -148,6 +154,7 @@ static int slh_verify_internal(SLH_DSA_HASH_CTX *hctx,
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len)
{
int ret = 0;
const SLH_DSA_KEY *pub = hctx->key;
SLH_HASH_FUNC_DECLARE(pub, hashf);
SLH_ADRS_FUNC_DECLARE(pub, adrsf);
@@ -185,7 +192,7 @@ static int slh_verify_internal(SLH_DSA_HASH_CTX *hctx,
if (!hashf->H_MSG(hctx, r, pk_seed, pk_root, msg, msg_len,
m_digest, sizeof(m_digest)))
return 0;
goto err;
/*
* Get md (the first md_len bytes of m_digest to use in
@@ -195,16 +202,20 @@ static int slh_verify_internal(SLH_DSA_HASH_CTX *hctx,
if (!PACKET_buf_init(m_digest_rpkt, m_digest, sizeof(m_digest))
|| !PACKET_get_bytes(m_digest_rpkt, &md, md_len)
|| !get_tree_ids(m_digest_rpkt, params, &tree_id, &leaf_id))
return 0;
goto err;
adrsf->set_tree_address(adrs, tree_id);
adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_FORS_TREE);
adrsf->set_keypair_address(adrs, leaf_id);
return ossl_slh_fors_pk_from_sig(hctx, sig_rpkt, md, pk_seed, adrs,
pk_fors, sizeof(pk_fors))
ret = ossl_slh_fors_pk_from_sig(hctx, sig_rpkt, md, pk_seed, adrs,
pk_fors, sizeof(pk_fors))
&& ossl_slh_ht_verify(hctx, pk_fors, sig_rpkt, pk_seed,
tree_id, leaf_id, pk_root)
&& PACKET_remaining(sig_rpkt) == 0;
err:
OPENSSL_cleanse(m_digest, sizeof(m_digest));
OPENSSL_cleanse(pk_fors, sizeof(pk_fors));
return ret;
}
/**
@@ -292,8 +303,13 @@ int ossl_slh_dsa_sign(SLH_DSA_HASH_CTX *slh_ctx,
return 0;
}
ret = slh_sign_internal(slh_ctx, m, m_len, sig, siglen, sigsize, add_rand);
if (m != msg && m != m_tmp)
OPENSSL_free(m);
/* The encoded message may contain confidential message content */
if (m != msg) {
if (m != m_tmp)
OPENSSL_clear_free(m, m_len);
else
OPENSSL_cleanse(m_tmp, sizeof(m_tmp));
}
return ret;
}
@@ -317,8 +333,13 @@ int ossl_slh_dsa_verify(SLH_DSA_HASH_CTX *slh_ctx,
return 0;
ret = slh_verify_internal(slh_ctx, m, m_len, sig, sig_len);
if (m != msg && m != m_tmp)
OPENSSL_free(m);
/* The encoded message may contain confidential message content */
if (m != msg) {
if (m != m_tmp)
OPENSSL_clear_free(m, m_len);
else
OPENSSL_cleanse(m_tmp, sizeof(m_tmp));
}
return ret;
}
@@ -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
@@ -109,5 +109,6 @@ void ossl_slh_dsa_hash_ctx_free(SLH_DSA_HASH_CTX *ctx)
if (ctx->md_big_ctx != ctx->md_ctx)
EVP_MD_CTX_free(ctx->md_big_ctx);
EVP_MAC_CTX_free(ctx->hmac_ctx);
OPENSSL_free(ctx);
/* Erases the |scratch| hash intermediates */
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
@@ -313,6 +313,12 @@ int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM params[],
key->pub = p;
return 1;
err:
/*
* A private key of unexpected length may have been copied into |priv|
* before |has_priv| was set, in which case the reset below would not
* erase it, so cleanse unconditionally.
*/
OPENSSL_cleanse(key->priv, sizeof(key->priv));
ossl_slh_dsa_key_reset(key);
return 0;
}
+13 -1
View File
@@ -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,12 +45,24 @@
* NOTE: Any changes to this structure will need updating in
* ossl_slh_dsa_hash_ctx_dup().
*/
/* A SHA-512 digest plus two |n| byte node values */
#define SLH_DSA_HASH_SCRATCH_LEN (64 + 2 * SLH_MAX_N)
struct slh_dsa_hash_ctx_st {
const SLH_DSA_KEY *key; /* This key is not owned by this object */
EVP_MD_CTX *md_ctx; /* Either SHAKE OR SHA-256 */
EVP_MD_CTX *md_big_ctx; /* Either SHA-512 or points to |md_ctx| for SHA-256*/
EVP_MAC_CTX *hmac_ctx; /* required by SHA algorithms for PRFmsg() */
int hmac_digest_used; /* Used for lazy init of hmac_ctx digest */
/*
* Working storage for the SHA2 hash function intermediates, used in
* place of local stack copies, so that potentially sensitive
* intermediate data lives in one place and is erased when this object
* is freed (FIPS 205 section 3.1). The SHAKE hash functions write
* their output directly to the caller's buffer and need no scratch.
* Not used concurrently.
*/
uint8_t scratch[SLH_DSA_HASH_SCRATCH_LEN];
};
__owur int ossl_slh_wots_pk_gen(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed,
+29 -23
View File
@@ -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
@@ -17,8 +17,8 @@
/* a = 6, 8, 9, 12 or 14 - There are (2^a) merkle trees */
#define SLH_MAX_A 9
#define SLH_MAX_K_TIMES_A (SLH_MAX_A * SLH_MAX_K)
#define SLH_MAX_ROOTS (SLH_MAX_K_TIMES_A * SLH_MAX_N)
/* The FORS public key is computed from the roots of k Merkle trees */
#define SLH_MAX_ROOTS (SLH_MAX_K * SLH_MAX_N)
static void slh_base_2b(const uint8_t *in, uint32_t b, uint32_t *out, size_t out_len);
@@ -87,25 +87,25 @@ static int slh_fors_node(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed,
if (height == 0) {
/* Gets here for leaf nodes */
if (!slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id, sk, sizeof(sk)))
return 0;
adrsf->set_tree_height(adrs, 0);
adrsf->set_tree_index(adrs, node_id);
ret = key->hash_func->F(ctx, pk_seed, adrs, sk, n, node, node_len);
if (slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id, sk, sizeof(sk))) {
adrsf->set_tree_height(adrs, 0);
adrsf->set_tree_index(adrs, node_id);
ret = key->hash_func->F(ctx, pk_seed, adrs, sk, n, node, node_len);
}
OPENSSL_cleanse(sk, n);
return ret;
} else {
if (!slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id, height - 1,
lnode, sizeof(rnode))
|| !slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id + 1,
height - 1, rnode, sizeof(rnode)))
return 0;
adrsf->set_tree_height(adrs, height);
adrsf->set_tree_index(adrs, node_id);
if (!key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, node, node_len))
return 0;
if (slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id, height - 1,
lnode, sizeof(lnode))
&& slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id + 1,
height - 1, rnode, sizeof(rnode))) {
adrsf->set_tree_height(adrs, height);
adrsf->set_tree_index(adrs, node_id);
ret = key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, node, node_len);
}
OPENSSL_cleanse(lnode, sizeof(lnode));
OPENSSL_cleanse(rnode, sizeof(rnode));
}
return 1;
return ret;
}
/**
@@ -132,6 +132,7 @@ int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md,
const uint8_t *sk_seed, const uint8_t *pk_seed,
uint8_t *adrs, WPACKET *sig_wpkt)
{
int ret = 0;
const SLH_DSA_KEY *key = ctx->key;
uint32_t tree_id, layer, s, tree_offset;
uint32_t ids[SLH_MAX_K];
@@ -165,7 +166,7 @@ int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md,
if (!slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs,
node_id + tree_id_times_two_power_a, out, sizeof(out))
|| !WPACKET_memcpy(sig_wpkt, out, n))
return 0;
goto err;
/*
* Traverse from the bottom of the tree (layer = 0)
@@ -178,15 +179,18 @@ int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md,
s = node_id ^ 1; /* XOR gets the index of the other child in a binary tree */
if (!slh_fors_node(ctx, sk_seed, pk_seed, adrs,
s + tree_offset, layer, out, sizeof(out)))
return 0;
goto err;
node_id >>= 1; /* Get the parent node id */
tree_offset >>= 1; /* Each layer up has half as many nodes */
if (!WPACKET_memcpy(sig_wpkt, out, n))
return 0;
goto err;
}
tree_id_times_two_power_a += two_power_a;
}
return 1;
ret = 1;
err:
OPENSSL_cleanse(out, sizeof(out));
return ret;
}
/**
@@ -288,6 +292,8 @@ int ossl_slh_fors_pk_from_sig(SLH_DSA_HASH_CTX *ctx, PACKET *fors_sig_rpkt,
err:
if (!WPACKET_finish(wroot_pkt))
ret = 0;
/* At most one |n| byte root per tree was written */
OPENSSL_cleanse(roots, k * n);
return ret;
}
+26 -12
View File
@@ -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
@@ -92,12 +92,15 @@ slh_prf_msg_shake(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_prf,
const uint8_t *opt_rand, const uint8_t *msg, size_t msg_len,
WPACKET *pkt)
{
int ret;
unsigned char out[SLH_MAX_N];
const SLH_DSA_PARAMS *params = ctx->key->params;
size_t n = params->n;
return xof_digest_3(ctx->md_ctx, sk_prf, n, opt_rand, n, msg, msg_len, out, n)
ret = xof_digest_3(ctx->md_ctx, sk_prf, n, opt_rand, n, msg, msg_len, out, n)
&& WPACKET_memcpy(pkt, out, n);
OPENSSL_cleanse(out, sizeof(out));
return ret;
}
static int
@@ -151,6 +154,7 @@ slh_hmsg_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
const uint8_t *pk_root, const uint8_t *msg, size_t msg_len,
uint8_t *out, size_t out_len)
{
int ret;
const SLH_DSA_PARAMS *params = hctx->key->params;
size_t m = params->m;
size_t n = params->n;
@@ -163,9 +167,11 @@ slh_hmsg_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
memcpy(seed, r, n);
memcpy(seed + n, pk_seed, n);
return digest_4(hctx->md_big_ctx, r, n, pk_seed, n, pk_root, n, msg, msg_len,
seed + 2 * n)
ret = digest_4(hctx->md_big_ctx, r, n, pk_seed, n, pk_root, n, msg, msg_len,
seed + 2 * n)
&& (PKCS1_MGF1(out, m, seed, seed_len, hctx->key->md_big) == 0);
OPENSSL_cleanse(seed, sizeof(seed));
return ret;
}
static int
@@ -205,16 +211,23 @@ slh_prf_msg_sha2(SLH_DSA_HASH_CTX *hctx,
&& EVP_MAC_update(mctx, msg, msg_len) == 1
&& EVP_MAC_final(mctx, mac, NULL, sizeof(mac)) == 1
&& WPACKET_memcpy(pkt, mac, n); /* Truncate output to n bytes */
OPENSSL_cleanse(mac, sizeof(mac));
return ret;
}
/*
* The |digest| scratch storage in the hash context is used in place of a
* local stack buffer, and is erased when the hash context is freed
* (FIPS 205 section 3.1). On the PRF path it holds a derived chain secret.
*/
static ossl_inline int
do_hash(EVP_MD_CTX *ctx, size_t n, const uint8_t *pk_seed, const uint8_t *adrs,
do_hash(SLH_DSA_HASH_CTX *hctx, EVP_MD_CTX *ctx, size_t n,
const uint8_t *pk_seed, const uint8_t *adrs,
const uint8_t *m, size_t m_len, size_t b, uint8_t *out, size_t out_len)
{
int ret;
uint8_t zeros[128] = { 0 };
uint8_t digest[MAX_DIGEST_SIZE];
uint8_t *digest = hctx->scratch;
ret = digest_4(ctx, pk_seed, n, zeros, b - n, adrs, SLH_ADRSC_SIZE,
m, m_len, digest);
@@ -230,7 +243,7 @@ slh_prf_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed,
{
size_t n = hctx->key->params->n;
return do_hash(hctx->md_ctx, n, pk_seed, adrs, sk_seed, n,
return do_hash(hctx, hctx->md_ctx, n, pk_seed, adrs, sk_seed, n,
OSSL_SLH_DSA_SHA2_NUM_ZEROS_H_AND_T_BOUND1, out, out_len);
}
@@ -238,21 +251,22 @@ static int
slh_f_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
const uint8_t *m1, size_t m1_len, uint8_t *out, size_t out_len)
{
return do_hash(hctx->md_ctx, hctx->key->params->n, pk_seed, adrs, m1, m1_len,
OSSL_SLH_DSA_SHA2_NUM_ZEROS_H_AND_T_BOUND1, out, out_len);
return do_hash(hctx, hctx->md_ctx, hctx->key->params->n, pk_seed, adrs,
m1, m1_len, OSSL_SLH_DSA_SHA2_NUM_ZEROS_H_AND_T_BOUND1, out, out_len);
}
static int
slh_h_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len)
{
uint8_t m[SLH_MAX_N * 2];
/* The concatenated children go in the scratch after the digest */
uint8_t *m = hctx->scratch + MAX_DIGEST_SIZE;
const SLH_DSA_PARAMS *prms = hctx->key->params;
size_t n = prms->n;
memcpy(m, m1, n);
memcpy(m + n, m2, n);
return do_hash(hctx->md_big_ctx, n, pk_seed, adrs, m, 2 * n,
return do_hash(hctx, hctx->md_big_ctx, n, pk_seed, adrs, m, 2 * n,
prms->sha2_h_and_t_bound, out, out_len);
}
@@ -262,7 +276,7 @@ slh_t_sha2(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
{
const SLH_DSA_PARAMS *prms = hctx->key->params;
return do_hash(hctx->md_big_ctx, prms->n, pk_seed, adrs, ml, ml_len,
return do_hash(hctx, hctx->md_big_ctx, prms->n, pk_seed, adrs, ml, ml_len,
prms->sha2_h_and_t_bound, out, out_len);
}
+16 -7
View File
@@ -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
@@ -8,6 +8,7 @@
*/
#include <string.h>
#include <openssl/crypto.h>
#include "slh_dsa_local.h"
#include "slh_dsa_key.h"
@@ -33,6 +34,7 @@ int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx,
const uint8_t *pk_seed,
uint64_t tree_id, uint32_t leaf_id, WPACKET *sig_wpkt)
{
int ret = 0;
const SLH_DSA_KEY *key = ctx->key;
SLH_ADRS_FUNC_DECLARE(key, adrsf);
SLH_ADRS_DECLARE(adrs);
@@ -70,7 +72,7 @@ int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx,
psig = WPACKET_get_curr(sig_wpkt);
if (!ossl_slh_xmss_sign(ctx, root, sk_seed, leaf_id, pk_seed, adrs,
sig_wpkt))
return 0;
goto err;
/*
* On the last loop it skips getting the public key since it is not needed
* to calculate another signature. If this was called it should equal
@@ -79,15 +81,18 @@ int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx,
if (layer < d - 1) {
if (!PACKET_buf_init(xmss_sig_rpkt, psig,
WPACKET_get_curr(sig_wpkt) - psig))
return 0;
goto err;
if (!ossl_slh_xmss_pk_from_sig(ctx, leaf_id, xmss_sig_rpkt, root,
pk_seed, adrs, root, sizeof(root)))
return 0;
goto err;
leaf_id = tree_id & mask;
tree_id >>= hm;
}
}
return 1;
ret = 1;
err:
OPENSSL_cleanse(root, sizeof(root));
return ret;
}
/**
@@ -108,6 +113,7 @@ int ossl_slh_ht_verify(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, PACKET *sig_pk
const uint8_t *pk_seed, uint64_t tree_id, uint32_t leaf_id,
const uint8_t *pk_root)
{
int ret = 0;
const SLH_DSA_KEY *key = ctx->key;
SLH_ADRS_FUNC_DECLARE(key, adrsf);
SLH_ADRS_DECLARE(adrs);
@@ -127,9 +133,12 @@ int ossl_slh_ht_verify(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, PACKET *sig_pk
adrsf->set_tree_address(adrs, tree_id);
if (!ossl_slh_xmss_pk_from_sig(ctx, leaf_id, sig_pkt, node,
pk_seed, adrs, node, sizeof(node)))
return 0;
goto err;
leaf_id = tree_id & mask;
tree_id >>= tree_height;
}
return (memcmp(node, pk_root, n) == 0);
ret = (memcmp(node, pk_root, n) == 0);
err:
OPENSSL_cleanse(node, sizeof(node));
return ret;
}
+5 -1
View File
@@ -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
@@ -244,6 +244,8 @@ int ossl_slh_wots_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg,
}
ret = 1;
err:
OPENSSL_cleanse(sk, sizeof(sk));
OPENSSL_cleanse(msg_and_csum_nibbles, sizeof(msg_and_csum_nibbles));
return ret;
}
@@ -311,5 +313,7 @@ int ossl_slh_wots_pk_from_sig(SLH_DSA_HASH_CTX *ctx,
err:
if (!WPACKET_finish(tmp_pkt))
ret = 0;
OPENSSL_cleanse(tmp, sizeof(tmp));
OPENSSL_cleanse(msg_and_csum_nibbles, sizeof(msg_and_csum_nibbles));
return ret;
}
+16 -13
View File
@@ -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
@@ -8,6 +8,7 @@
*/
#include <string.h>
#include <openssl/crypto.h>
#include "slh_dsa_local.h"
#include "slh_dsa_key.h"
@@ -39,29 +40,31 @@ int ossl_slh_xmss_node(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed,
{
const SLH_DSA_KEY *key = ctx->key;
SLH_ADRS_FUNC_DECLARE(key, adrsf);
int ret = 0;
if (h == 0) {
/* For leaf nodes generate the public key */
adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_WOTS_HASH);
adrsf->set_keypair_address(adrs, node_id);
if (!ossl_slh_wots_pk_gen(ctx, sk_seed, pk_seed, adrs,
if (ossl_slh_wots_pk_gen(ctx, sk_seed, pk_seed, adrs,
pk_out, pk_out_len))
return 0;
ret = 1;
} else {
uint8_t lnode[SLH_MAX_N], rnode[SLH_MAX_N];
if (!ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id, h - 1, pk_seed, adrs,
if (ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id, h - 1, pk_seed, adrs,
lnode, sizeof(lnode))
|| !ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id + 1, h - 1,
pk_seed, adrs, rnode, sizeof(rnode)))
return 0;
adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_TREE);
adrsf->set_tree_height(adrs, h);
adrsf->set_tree_index(adrs, node_id);
if (!key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, pk_out, pk_out_len))
return 0;
&& ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id + 1, h - 1,
pk_seed, adrs, rnode, sizeof(rnode))) {
adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_TREE);
adrsf->set_tree_height(adrs, h);
adrsf->set_tree_index(adrs, node_id);
ret = key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, pk_out, pk_out_len);
}
OPENSSL_cleanse(lnode, sizeof(lnode));
OPENSSL_cleanse(rnode, sizeof(rnode));
}
return 1;
return ret;
}
/**
+14
View File
@@ -535,6 +535,20 @@ int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
if (result == ONCE_UNINITED) {
init();
/*
* On weakly ordered systems, it may happen that the write to *lock
* below completes prior to some writes in whatever the init()
* callback routine above may do. In this case, other threads
* entering here may see unsynchronized data in whatever the init
* routine initializes, leading to erroneous behavior.
*
* We should use InitOnceExecuteOnce here to implement this, but
* doing so requires that we modify the definition of the
* CRYPTO_ONCE type, which is an ABI breakage. So instead
* just insert a memory barrier here to ensure that any pending
* writes are flushed to memory prior to setting ONCE_DONE below
*/
MemoryBarrier();
*lock = ONCE_DONE;
return 1;
}
+24 -14
View File
@@ -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
@@ -228,7 +228,7 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
X509 st_x509;
X509_CRL crl;
} data;
int ok = 0;
int res, ok = 0;
int i, j, k;
unsigned long h;
BUF_MEM *b = NULL;
@@ -320,25 +320,35 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
}
#ifndef OPENSSL_NO_POSIX_IO
#ifdef _WIN32
#define lstat _stat
#define stat _stat
#endif
{
struct stat st;
if (stat(b->data, &st) < 0)
break;
if (lstat(b->data, &st) < 0)
break; /* file does not exist, not even a symlink */
#ifndef _WIN32
if (stat(b->data, &st) < 0) {
k++;
continue; /* symlink is broken: following it went wrong */
}
#endif
}
#endif
/* found one. */
if (type == X509_LU_X509) {
if ((X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx,
propq))
== 0)
break;
} else if (type == X509_LU_CRL) {
if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0)
break;
}
res = 0;
ERR_set_mark();
if (type == X509_LU_X509)
res = X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx, propq);
else if (type == X509_LU_CRL)
res = X509_load_crl_file(xl, b->data, ent->dir_type);
/* else case will caught higher up */
ERR_pop_to_mark();
/* unless OPENSSL_NO_POSIX_IO, gracefully skip found file if cert/CRL fails to load. */
#ifndef OPENSSL_NO_POSIX_IO
res = 1;
#endif
if (res == 0)
break;
k++;
}
+5 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2004-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
@@ -134,6 +134,7 @@ static int policy_cache_new(X509 *x)
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
POLICY_CONSTRAINTS_free(ext_pcons);
return 1;
}
@@ -141,8 +142,10 @@ static int policy_cache_new(X509 *x)
/* NB: ext_cpols freed by policy_cache_set_policies */
if (i <= 0)
if (i <= 0) {
POLICY_CONSTRAINTS_free(ext_pcons);
return i;
}
ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
+4 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2022 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
@@ -173,7 +173,9 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
&& !(same_issuer && !ss)) {
ikeyid = X509V3_EXT_d2i(ext);
if ((ikeyid = X509V3_EXT_d2i(ext)) == NULL)
goto err;
if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ {
ASN1_OCTET_STRING_free(ikeyid);
ikeyid = NULL;
+8 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2003-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
@@ -613,6 +613,12 @@ static int nc_dn(const X509_NAME *nm, const X509_NAME *base)
return X509_V_ERR_OUT_OF_MEM;
if (base->canon_enclen > nm->canon_enclen)
return X509_V_ERR_PERMITTED_VIOLATION;
/*
* An empty base Name has no canonical encoding (canon_enc == NULL) and is
* a prefix of every Name, so it matches unconditionally.
*/
if (base->canon_enclen == 0)
return X509_V_OK;
if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
return X509_V_ERR_PERMITTED_VIOLATION;
return X509_V_OK;
@@ -789,6 +795,7 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
if (scheme == NULL || *scheme == '\0') {
ERR_raise_data(ERR_LIB_X509V3, X509_V_ERR_UNSUPPORTED_NAME_SYNTAX,
"x509: missing scheme in URI: %s\n", uri_copy);
OPENSSL_free(scheme);
OPENSSL_free(uri_copy);
ret = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
goto end;
+3 -1
View File
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* 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
@@ -26,6 +26,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = {
{ ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE),
"cert already in hash table" },
{ ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta" },
{ ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_SIGNATURE_ALGORITHM_MISMATCH),
"crl signature algorithm mismatch" },
{ ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
"crl verify failure" },
{ ERR_PACK(ERR_LIB_X509, 0, X509_R_DUPLICATE_ATTRIBUTE),
+7 -2
View File
@@ -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
@@ -590,7 +590,12 @@ static X509_OBJECT *x509_object_dup(const X509_OBJECT *obj)
ret->type = obj->type;
ret->data = obj->data;
X509_OBJECT_up_ref_count(ret);
if (!X509_OBJECT_up_ref_count(ret)) {
OPENSSL_free(ret);
return NULL;
}
return ret;
}
+6 -3
View File
@@ -1364,6 +1364,12 @@ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
/* Invalid IDP cannot be processed */
if ((crl->idp_flags & IDP_INVALID) != 0)
return 0;
/*
* Reject delta CRLs unconditionally here. They are considered by
* get_delta_sk() after a base CRL is selected.
*/
if (crl->base_crl_number != NULL)
return 0;
/* Reason codes or indirect CRLs need extended CRL support */
if ((ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT) == 0) {
if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
@@ -1373,9 +1379,6 @@ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
if ((crl->idp_reasons & ~tmp_reasons) == 0)
return 0;
}
/* Don't process deltas at this stage */
else if (crl->base_crl_number != NULL)
return 0;
/* If issuer name doesn't match certificate need indirect CRL */
if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)) != 0) {
if ((crl->idp_flags & IDP_INDIRECT) == 0)
Loaded 100 of 259 files, more files were not shown because too many files have changed in this diff. Show more