Fix CVE-2025-9820, CVE-2025-14831, drop unused patches

- Fix PKCS#11 token initialization label overflow (CVE-2025-9820)
- Fix name constraint processing performance issue (CVE-2025-14831)
- Drop unused patches

Resolves: RHEL-147830
This commit is contained in:
Alexander Sosedkin 2025-09-01 18:10:54 +02:00
parent 3f09b2839a
commit 0eebef3b64
17 changed files with 2048 additions and 6770 deletions

View File

@ -1,29 +0,0 @@
From b6c6e699ec79820bc949db3c71992ce277eef141 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 15 Aug 2024 09:37:55 +0900
Subject: [PATCH] gnutls-3.7.3-fips-dsa-post.patch
Signed-off-by: rpm-build <rpm-build>
---
lib/fips.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/lib/fips.c b/lib/fips.c
index 1611200..8a9824a 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -611,11 +611,6 @@ int _gnutls_fips_perform_self_checks2(void)
}
}
- ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA);
- if (ret < 0) {
- return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
- }
-
ret = gnutls_pk_self_test(0, GNUTLS_PK_EC);
if (ret < 0) {
return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
--
2.46.0

View File

@ -1,107 +0,0 @@
From 115c0edc929a3f09b0a252507112c0de70026b5e Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 10 Feb 2025 11:43:51 +0900
Subject: [PATCH] gnutls-3.7.6-fips-sha1-sigver.patch
Signed-off-by: rpm-build <rpm-build>
---
lib/nettle/pk.c | 11 ++++-------
lib/pubkey.c | 3 ---
tests/fips-test.c | 8 ++++----
3 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index 91eaffd..0b4788a 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -2784,10 +2784,7 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
if (hash_len > vdata->size)
hash_len = vdata->size;
- /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy
- * mode */
switch (DIG_TO_MAC(sign_params->dsa_dig)) {
- case GNUTLS_MAC_SHA1:
case GNUTLS_MAC_SHA256:
case GNUTLS_MAC_SHA384:
case GNUTLS_MAC_SHA512:
@@ -2857,7 +2854,7 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
bits = mpz_sizeinbase(pub.n, 2);
/* In FIPS 140-3, RSA key size should be larger than 2048-bit.
- * In addition to this, only SHA-1 and SHA-2 are allowed
+ * In addition to this, only SHA-2 is allowed
* for SigVer; it is checked in _pkcs1_rsa_verify_sig in
* lib/pubkey.c.
*/
@@ -2903,9 +2900,9 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
}
/* RSA modulus size should be 2048-bit or larger in FIPS
- * 140-3. In addition to this, only SHA-1 and SHA-2 are
- * allowed for SigVer, while Nettle only supports
- * SHA256, SHA384, and SHA512 for RSA-PSS (see
+ * 140-3. In addition to this, only SHA-2 is allowed
+ * for SigVer, while Nettle only supports SHA256,
+ * SHA384, and SHA512 for RSA-PSS (see
* _rsa_pss_verify_digest in this file for the details).
*/
if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
diff --git a/lib/pubkey.c b/lib/pubkey.c
index 1e5ecf3..811e531 100644
--- a/lib/pubkey.c
+++ b/lib/pubkey.c
@@ -2516,10 +2516,7 @@ static int _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
d.size = digest_size;
if (pk == GNUTLS_PK_RSA) {
- /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy
- * mode */
switch (me->id) {
- case GNUTLS_MAC_SHA1:
case GNUTLS_MAC_SHA256:
case GNUTLS_MAC_SHA384:
case GNUTLS_MAC_SHA512:
diff --git a/tests/fips-test.c b/tests/fips-test.c
index 3af4df7..c024427 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -596,7 +596,7 @@ void doit(void)
}
FIPS_POP_CONTEXT(NOT_APPROVED);
- /* Verify a signature created with 2432-bit RSA and SHA-1; approved */
+ /* Verify a signature created with 2432-bit RSA and SHA-1; not approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1,
GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1,
@@ -604,7 +604,7 @@ void doit(void)
if (ret < 0) {
fail("gnutls_pubkey_verify_data2 failed\n");
}
- FIPS_POP_CONTEXT(APPROVED);
+ FIPS_POP_CONTEXT(NOT_APPROVED);
gnutls_free(signature.data);
gnutls_pubkey_deinit(pubkey);
gnutls_privkey_deinit(privkey);
@@ -707,7 +707,7 @@ void doit(void)
}
FIPS_POP_CONTEXT(NOT_APPROVED);
- /* Verify a signature created with ECDSA and SHA-1; approved */
+ /* Verify a signature created with ECDSA and SHA-1; not approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA1,
GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1,
@@ -715,7 +715,7 @@ void doit(void)
if (ret < 0) {
fail("gnutls_pubkey_verify_data2 failed\n");
}
- FIPS_POP_CONTEXT(APPROVED);
+ FIPS_POP_CONTEXT(NOT_APPROVED);
gnutls_free(signature.data);
/* Create a signature with ECDSA and SHA-1 (old API); not approved */
--
2.48.1

View File

@ -1,25 +0,0 @@
From 18c555b4d2461ad202996398609552b9c4ecd43b Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 22 Nov 2023 15:21:49 +0900
Subject: [PATCH] gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch
Signed-off-by: rpm-build <rpm-build>
---
tests/gnutls_ktls.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c
index ccbe566..049c888 100644
--- a/tests/gnutls_ktls.c
+++ b/tests/gnutls_ktls.c
@@ -347,7 +347,6 @@ void doit(void)
{
run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-GCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-256-GCM");
- run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+CHACHA20-POLY1305");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+CHACHA20-POLY1305");
--
2.41.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,411 @@
From f23de850c8f37bd498bbdb1adc491ee05614ca11 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Fri, 6 Feb 2026 15:43:54 +0100
Subject: [PATCH 1/2] tests/pkcs11/pkcs11-mock4: add, modified for 3.8.10
---
tests/Makefile.am | 6 ++
tests/pkcs11/pkcs11-mock4.c | 125 ++++++++++++++++++++++++++++++++++++
2 files changed, 131 insertions(+)
create mode 100644 tests/pkcs11/pkcs11-mock4.c
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9e5c7de84..62c4ec2f9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -358,6 +358,11 @@ libpkcs11mock3_la_SOURCES = pkcs11/pkcs11-mock3.c
libpkcs11mock3_la_LDFLAGS = -shared -rpath $(pkglibdir) -module -no-undefined -avoid-version
libpkcs11mock3_la_LIBADD = ../gl/libgnu.la
+noinst_LTLIBRARIES += libpkcs11mock4.la
+libpkcs11mock4_la_SOURCES = pkcs11/pkcs11-mock4.c
+libpkcs11mock4_la_LDFLAGS = -shared -rpath $(pkglibdir) -module -no-undefined -avoid-version
+libpkcs11mock4_la_LIBADD = ../gl/libgnu.la
+
pkcs11_cert_import_url_exts_SOURCES = pkcs11/pkcs11-cert-import-url-exts.c
pkcs11_cert_import_url_exts_DEPENDENCIES = libpkcs11mock1.la libutils.la
@@ -655,6 +660,7 @@ TESTS_ENVIRONMENT += \
P11MOCKLIB1=$(abs_builddir)/.libs/libpkcs11mock1.so \
P11MOCKLIB2=$(abs_builddir)/.libs/libpkcs11mock2.so \
P11MOCKLIB3=$(abs_builddir)/.libs/libpkcs11mock3.so \
+ P11MOCKLIB4=$(abs_builddir)/.libs/libpkcs11mock4.so \
PKCS12_MANY_CERTS_FILE=$(srcdir)/cert-tests/data/pkcs12_5certs.p12 \
PKCS12FILE=$(srcdir)/cert-tests/data/client.p12 \
PKCS12PASSWORD=foobar \
diff --git a/tests/pkcs11/pkcs11-mock4.c b/tests/pkcs11/pkcs11-mock4.c
new file mode 100644
index 000000000..a6dd21cdd
--- /dev/null
+++ b/tests/pkcs11/pkcs11-mock4.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2025 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dlfcn.h>
+#include <p11-kit/pkcs11.h>
+#include <p11-kit/pkcs11x.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "softhsm.h"
+
+/* This provides a mock PKCS #11 module that delegates all the
+ * operations to SoftHSM except that it returns CKR_CANT_LOCK upon
+ * C_Initialize if CKF_OS_LOCKING_OK is set.
+ */
+
+static void *dl;
+static CK_C_Initialize base_C_Initialize;
+static CK_FUNCTION_LIST override_funcs;
+
+#ifdef __sun
+#pragma fini(mock_deinit)
+#pragma init(mock_init)
+#define _CONSTRUCTOR
+#define _DESTRUCTOR
+#else
+#define _CONSTRUCTOR __attribute__((constructor))
+#define _DESTRUCTOR __attribute__((destructor))
+#endif
+
+#define LOCK_FLAGS (CKF_LIBRARY_CANT_CREATE_OS_THREADS | CKF_OS_LOCKING_OK)
+
+static CK_RV override_C_Initialize(void *args)
+{
+ CK_C_INITIALIZE_ARGS *init_args = args;
+ static bool first = true;
+
+ // we don't have threadsafe initialization/fallback in 3.8.10...
+ /*
+ if (first) {
+ assert(init_args &&
+ (init_args->flags & LOCK_FLAGS) == LOCK_FLAGS);
+ first = false;
+ return CKR_CANT_LOCK;
+ } else {
+ assert(!init_args ||
+ (init_args->flags & LOCK_FLAGS) != LOCK_FLAGS);
+ }
+ */
+ // ... so we expect 3.8.10 behaviour
+ assert(first);
+ assert(init_args);
+ assert(!(init_args->flags & LOCK_FLAGS) != LOCK_FLAGS);
+ first = false;
+
+ return base_C_Initialize(args);
+}
+
+CK_RV C_GetFunctionList(CK_FUNCTION_LIST **function_list)
+{
+ CK_C_GetFunctionList func;
+ CK_FUNCTION_LIST *funcs;
+
+ assert(dl);
+
+ func = dlsym(dl, "C_GetFunctionList");
+ if (func == NULL) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ func(&funcs);
+
+ base_C_Initialize = funcs->C_Initialize;
+
+ memcpy(&override_funcs, funcs, sizeof(CK_FUNCTION_LIST));
+ override_funcs.C_Initialize = override_C_Initialize;
+ *function_list = &override_funcs;
+
+ return CKR_OK;
+}
+
+static _CONSTRUCTOR void mock_init(void)
+{
+ const char *lib;
+
+ /* suppress compiler warning */
+ (void)set_softhsm_conf;
+
+ lib = softhsm_lib();
+
+ dl = dlopen(lib, RTLD_NOW);
+ if (dl == NULL)
+ exit(77);
+}
+
+static _DESTRUCTOR void mock_deinit(void)
+{
+ dlclose(dl);
+}
--
2.52.0
From 87fc01fb853911e412e0fe238b069a68376ad8de Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 18 Nov 2025 13:17:55 +0900
Subject: [PATCH 2/2] pkcs11: avoid stack overwrite when initializing a token
If gnutls_pkcs11_token_init is called with label longer than 32
characters, the internal storage used to blank-fill it would
overflow. This adds a guard to prevent that.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/pkcs11_write.c | 5 +-
tests/Makefile.am | 4 +-
tests/pkcs11/long-label.c | 164 ++++++++++++++++++++++++++++++++++++++
3 files changed, 170 insertions(+), 3 deletions(-)
create mode 100644 tests/pkcs11/long-label.c
diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c
index f5e9058e0..64b85a2df 100644
--- a/lib/pkcs11_write.c
+++ b/lib/pkcs11_write.c
@@ -28,6 +28,7 @@
#include "pkcs11x.h"
#include "x509/common.h"
#include "pk.h"
+#include "minmax.h"
static const ck_bool_t tval = 1;
static const ck_bool_t fval = 0;
@@ -1172,7 +1173,7 @@ int gnutls_pkcs11_delete_url(const char *object_url, unsigned int flags)
* gnutls_pkcs11_token_init:
* @token_url: A PKCS #11 URL specifying a token
* @so_pin: Security Officer's PIN
- * @label: A name to be used for the token
+ * @label: A name to be used for the token, at most 32 characters
*
* This function will initialize (format) a token. If the token is
* at a factory defaults state the security officer's PIN given will be
@@ -1210,7 +1211,7 @@ int gnutls_pkcs11_token_init(const char *token_url, const char *so_pin,
/* so it seems memset has other uses than zeroing! */
memset(flabel, ' ', sizeof(flabel));
if (label != NULL)
- memcpy(flabel, label, strlen(label));
+ memcpy(flabel, label, MIN(sizeof(flabel), strlen(label)));
rv = pkcs11_init_token(module, slot, (uint8_t *)so_pin, strlen(so_pin),
(uint8_t *)flabel);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 62c4ec2f9..0e4d04342 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -508,13 +508,15 @@ pathbuf_CPPFLAGS = $(AM_CPPFLAGS) \
if ENABLE_PKCS11
if !WINDOWS
ctests += tls13/post-handshake-with-cert-pkcs11 pkcs11/tls-neg-pkcs11-no-key \
- global-init-override pkcs11/distrust-after
+ global-init-override pkcs11/distrust-after pkcs11/long-label
tls13_post_handshake_with_cert_pkcs11_DEPENDENCIES = libpkcs11mock2.la libutils.la
tls13_post_handshake_with_cert_pkcs11_LDADD = $(LDADD) $(LIBDL)
pkcs11_tls_neg_pkcs11_no_key_DEPENDENCIES = libpkcs11mock2.la libutils.la
pkcs11_tls_neg_pkcs11_no_key_LDADD = $(LDADD) $(LIBDL)
pkcs11_distrust_after_DEPENDENCIES = libpkcs11mock3.la libutils.la
pkcs11_distrust_after_LDADD = $(LDADD) $(LIBDL)
+pkcs11_long_label_DEPENDENCIES = libpkcs11mock4.la libutils.la
+pkcs11_long_label_LDADD = $(LDADD) $(LIBDL)
endif
endif
diff --git a/tests/pkcs11/long-label.c b/tests/pkcs11/long-label.c
new file mode 100644
index 000000000..a70bc9728
--- /dev/null
+++ b/tests/pkcs11/long-label.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2025 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32)
+
+int main(void)
+{
+ exit(77);
+}
+
+#else
+
+#include <string.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+
+#include "cert-common.h"
+#include "pkcs11/softhsm.h"
+#include "utils.h"
+
+/* This program tests that a token can be initialized with
+ * a label longer than 32 characters.
+ */
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "server|<%d>| %s", level, str);
+}
+
+#define PIN "1234"
+
+#define CONFIG_NAME "softhsm-long-label"
+#define CONFIG CONFIG_NAME ".config"
+
+static int pin_func(void *userdata, int attempt, const char *url,
+ const char *label, unsigned flags, char *pin,
+ size_t pin_max)
+{
+ if (attempt == 0) {
+ strcpy(pin, PIN);
+ return 0;
+ }
+ return -1;
+}
+
+static void test(const char *provider)
+{
+ int ret;
+ size_t i;
+
+ gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+
+ success("test with %s\n", provider);
+
+ if (debug) {
+ gnutls_global_set_log_function(tls_log_func);
+ gnutls_global_set_log_level(4711);
+ }
+
+ /* point to SoftHSM token that libpkcs11mock4.so internally uses */
+ setenv(SOFTHSM_ENV, CONFIG, 1);
+
+ gnutls_pkcs11_set_pin_function(pin_func, NULL);
+
+ ret = gnutls_pkcs11_add_provider(provider, "trusted");
+ if (ret != 0) {
+ fail("gnutls_pkcs11_add_provider: %s\n", gnutls_strerror(ret));
+ }
+
+ /* initialize softhsm token */
+ ret = gnutls_pkcs11_token_init(
+ SOFTHSM_URL, PIN,
+ "this is a very long label whose length exceeds 32");
+ if (ret < 0) {
+ fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
+ }
+
+ for (i = 0;; i++) {
+ char *url = NULL;
+
+ ret = gnutls_pkcs11_token_get_url(i, 0, &url);
+ if (ret < 0)
+ break;
+ if (strstr(url,
+ "token=this%20is%20a%20very%20long%20label%20whose"))
+ break;
+ }
+ if (ret < 0)
+ fail("gnutls_pkcs11_token_get_url: %s\n", gnutls_strerror(ret));
+
+ gnutls_pkcs11_deinit();
+}
+
+void doit(void)
+{
+ const char *bin;
+ const char *lib;
+ char buf[128];
+
+ if (gnutls_fips140_mode_enabled())
+ exit(77);
+
+ /* this must be called once in the program */
+ global_init();
+
+ /* we call gnutls_pkcs11_init manually */
+ gnutls_pkcs11_deinit();
+
+ /* check if softhsm module is loadable */
+ lib = softhsm_lib();
+
+ /* initialize SoftHSM token that libpkcs11mock4.so internally uses */
+ bin = softhsm_bin();
+
+ set_softhsm_conf(CONFIG);
+ snprintf(buf, sizeof(buf),
+ "%s --init-token --slot 0 --label test --so-pin " PIN
+ " --pin " PIN,
+ bin);
+ system(buf);
+
+ test(lib);
+
+ lib = getenv("P11MOCKLIB4");
+ if (lib == NULL) {
+ fail("P11MOCKLIB4 is not set\n");
+ }
+
+ set_softhsm_conf(CONFIG);
+ snprintf(buf, sizeof(buf),
+ "%s --init-token --slot 0 --label test --so-pin " PIN
+ " --pin " PIN,
+ bin);
+ system(buf);
+
+ test(lib);
+}
+#endif /* _WIN32 */
--
2.52.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
From a9800309197fe5aef913944b2fc77164946f0689 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 23 Jul 2024 16:04:56 +0900
Subject: [PATCH] build: link against libhogweed when checking
nettle_rsa_oaep_*
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index fb0aefe1f4..8b55808bd7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -795,7 +795,7 @@ AM_CONDITIONAL([NEED_SIV_GCM], [test "$ac_cv_func_nettle_siv_gcm_encrypt_message
# Check for RSA-OAEP
save_LIBS=$LIBS
-LIBS="$LIBS $NETTLE_LIBS"
+LIBS="$LIBS $HOGWEED_LIBS $NETTLE_LIBS $GMP_LIBS"
AC_CHECK_FUNCS(nettle_rsa_oaep_sha256_encrypt)
LIBS=$save_LIBS
AM_CONDITIONAL([NEED_RSA_OAEP], [test "$ac_cv_func_nettle_rsa_oaep_sha256_encrypt" != yes])
--
2.45.2

View File

@ -1,13 +0,0 @@
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0e89fdf..5179858 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -269,7 +269,7 @@ thirdparty_libadd += $(LIBTASN1_LIBS)
endif
if ENABLE_NETTLE
-thirdparty_libadd += $(NETTLE_LIBS) $(HOGWEED_LIBS) $(GMP_LIBS)
+thirdparty_libadd += $(HOGWEED_LIBS) $(NETTLE_LIBS) $(GMP_LIBS)
libgnutls_la_LIBADD += nettle/libcrypto.la
endif

View File

@ -1,165 +0,0 @@
From 558cf23853f6ad0537daff4613d316265857b7fd Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Wed, 21 Aug 2024 14:50:54 +0900
Subject: [PATCH] fips: skip HMAC checks of nettle libraries when statically
linked
Since commit b6e9b10347ed577a9a37b7b28e1a039c5f6ccb16, it is possible
to link Nettle libraries statically. In that case, FIPS integrity
checks against the Nettle shared libraries should be skipped as they
are not used by GnuTLS.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/fips.c | 32 ++++++++++++++++++++++++--------
lib/fipshmac.c | 12 ++++--------
2 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/lib/fips.c b/lib/fips.c
index e5fce6b1b9..dc86a44354 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -157,14 +157,6 @@ void _gnutls_fips_mode_reset_zombie(void)
#define GNUTLS_LIBRARY_SONAME "none"
#endif
-#ifndef NETTLE_LIBRARY_SONAME
-#define NETTLE_LIBRARY_SONAME "none"
-#endif
-
-#ifndef HOGWEED_LIBRARY_SONAME
-#define HOGWEED_LIBRARY_SONAME "none"
-#endif
-
#define HMAC_SIZE 32
#define HMAC_ALGO GNUTLS_MAC_SHA256
#define HMAC_FORMAT_VERSION 1
@@ -177,8 +169,12 @@ struct hmac_entry {
struct hmac_file {
int version;
struct hmac_entry gnutls;
+#ifdef NETTLE_LIBRARY_SONAME
struct hmac_entry nettle;
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
struct hmac_entry hogweed;
+#endif
#ifdef GMP_LIBRARY_SONAME
struct hmac_entry gmp;
#endif
@@ -186,8 +182,12 @@ struct hmac_file {
struct lib_paths {
char gnutls[GNUTLS_PATH_MAX];
+#ifdef NETTLE_LIBRARY_SONAME
char nettle[GNUTLS_PATH_MAX];
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
char hogweed[GNUTLS_PATH_MAX];
+#endif
#ifdef GMP_LIBRARY_SONAME
char gmp[GNUTLS_PATH_MAX];
#endif
@@ -250,10 +250,14 @@ static int handler(void *user, const char *section, const char *name,
}
} else if (!strcmp(section, GNUTLS_LIBRARY_SONAME)) {
return lib_handler(&p->gnutls, section, name, value);
+#ifdef NETTLE_LIBRARY_SONAME
} else if (!strcmp(section, NETTLE_LIBRARY_SONAME)) {
return lib_handler(&p->nettle, section, name, value);
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
} else if (!strcmp(section, HOGWEED_LIBRARY_SONAME)) {
return lib_handler(&p->hogweed, section, name, value);
+#endif
#ifdef GMP_LIBRARY_SONAME
} else if (!strcmp(section, GMP_LIBRARY_SONAME)) {
return lib_handler(&p->gmp, section, name, value);
@@ -403,10 +407,14 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
if (!strcmp(soname, GNUTLS_LIBRARY_SONAME))
_gnutls_str_cpy(paths->gnutls, GNUTLS_PATH_MAX, path);
+#ifdef NETTLE_LIBRARY_SONAME
else if (!strcmp(soname, NETTLE_LIBRARY_SONAME))
_gnutls_str_cpy(paths->nettle, GNUTLS_PATH_MAX, path);
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
else if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
_gnutls_str_cpy(paths->hogweed, GNUTLS_PATH_MAX, path);
+#endif
#ifdef GMP_LIBRARY_SONAME
else if (!strcmp(soname, GMP_LIBRARY_SONAME))
_gnutls_str_cpy(paths->gmp, GNUTLS_PATH_MAX, path);
@@ -423,14 +431,18 @@ static int load_lib_paths(struct lib_paths *paths)
_gnutls_debug_log("Gnutls library path was not found\n");
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
}
+#ifdef NETTLE_LIBRARY_SONAME
if (paths->nettle[0] == '\0') {
_gnutls_debug_log("Nettle library path was not found\n");
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
}
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
if (paths->hogweed[0] == '\0') {
_gnutls_debug_log("Hogweed library path was not found\n");
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
}
+#endif
#ifdef GMP_LIBRARY_SONAME
if (paths->gmp[0] == '\0') {
_gnutls_debug_log("Gmp library path was not found\n");
@@ -483,12 +495,16 @@ static int check_binary_integrity(void)
ret = check_lib_hmac(&hmac.gnutls, paths.gnutls);
if (ret < 0)
return ret;
+#ifdef NETTLE_LIBRARY_SONAME
ret = check_lib_hmac(&hmac.nettle, paths.nettle);
if (ret < 0)
return ret;
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
ret = check_lib_hmac(&hmac.hogweed, paths.hogweed);
if (ret < 0)
return ret;
+#endif
#ifdef GMP_LIBRARY_SONAME
ret = check_lib_hmac(&hmac.gmp, paths.gmp);
if (ret < 0)
diff --git a/lib/fipshmac.c b/lib/fipshmac.c
index d3561b4c47..5c3202c561 100644
--- a/lib/fipshmac.c
+++ b/lib/fipshmac.c
@@ -40,14 +40,6 @@
#define GNUTLS_LIBRARY_SONAME "none"
#endif
-#ifndef NETTLE_LIBRARY_SONAME
-#define NETTLE_LIBRARY_SONAME "none"
-#endif
-
-#ifndef HOGWEED_LIBRARY_SONAME
-#define HOGWEED_LIBRARY_SONAME "none"
-#endif
-
#define HMAC_SIZE 32
#define HMAC_ALGO GNUTLS_MAC_SHA256
#define HMAC_STR_SIZE (2 * HMAC_SIZE + 1)
@@ -117,10 +109,14 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
if (!strcmp(soname, GNUTLS_LIBRARY_SONAME))
return print_lib(data ? data : path, soname);
+#ifdef NETTLE_LIBRARY_SONAME
if (!strcmp(soname, NETTLE_LIBRARY_SONAME))
return print_lib(path, soname);
+#endif
+#ifdef HOGWEED_LIBRARY_SONAME
if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
return print_lib(path, soname);
+#endif
#ifdef GMP_LIBRARY_SONAME
if (!strcmp(soname, GMP_LIBRARY_SONAME))
return print_lib(path, soname);
--
2.46.0

View File

@ -1,170 +0,0 @@
From 292f96f26d7ce80e4a165c903c4fd569b85c1c1f Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 16 Aug 2024 09:42:15 +0900
Subject: [PATCH 1/2] build: fix setting AM_CONDITIONAL for brotli and zstd
As the with_{libbrotli,libzsttd} variables are unset if configured
with --without-{brotli,zstd}, check the unequality to "no" doesn't
work; use explicit matching with "yes" instead.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
configure.ac | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 95ec4c1515..a476176800 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1158,7 +1158,7 @@ if test x$ac_brotli != xno; then
else
AC_MSG_RESULT(no)
fi
-AM_CONDITIONAL(HAVE_LIBBROTLI, test "$with_libbrotlienc" != "no" && test "$with_libbrotlidec" != "no")
+AM_CONDITIONAL(HAVE_LIBBROTLI, test "$with_libbrotlienc" = yes && test "$with_libbrotlidec" = yes)
AS_IF([test "$ac_cv_dlopen_soname_works" = yes], [
save_CFLAGS=$CFLAGS
@@ -1203,7 +1203,7 @@ if test x$ac_zstd != xno; then
else
AC_MSG_RESULT(no)
fi
-AM_CONDITIONAL(HAVE_LIBZSTD, test "$with_libzstd" != "no")
+AM_CONDITIONAL(HAVE_LIBZSTD, test "$with_libzstd" = yes)
AS_IF([test "$ac_cv_dlopen_soname_works" = yes], [
save_CFLAGS=$CFLAGS
--
2.46.0
From 546153198d2fb8fc4902f23de6254bb7988de534 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 16 Aug 2024 09:48:31 +0900
Subject: [PATCH 2/2] build: don't emit Requires.private for dlopened libraries
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
configure.ac | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index a476176800..f3e7a3aeae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1100,11 +1100,6 @@ if test x$ac_zlib != xno; then
PKG_CHECK_EXISTS(zlib, ZLIB_HAS_PKGCONFIG=y, ZLIB_HAS_PKGCONFIG=n)
if test "$ZLIB_HAS_PKGCONFIG" = "y" ; then
PKG_CHECK_MODULES(ZLIB, [zlib])
- if test "x$GNUTLS_REQUIRES_PRIVATE" = x; then
- GNUTLS_REQUIRES_PRIVATE="Requires.private: zlib"
- else
- GNUTLS_REQUIRES_PRIVATE="$GNUTLS_REQUIRES_PRIVATE, zlib"
- fi
ac_zlib=yes
else
AC_LIB_HAVE_LINKFLAGS(z,, [#include <zlib.h>], [compress (0, 0, 0, 0);])
@@ -1134,6 +1129,13 @@ AS_IF([test "$ac_cv_dlopen_soname_works" = yes], [
compress (0, 0, 0, 0);])])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
+],
+ [test "$ZLIB_HAS_PKGCONFIG" = y && test "$ac_zlib" = yes], [
+ if test "x$GNUTLS_REQUIRES_PRIVATE" = x; then
+ GNUTLS_REQUIRES_PRIVATE="Requires.private: zlib"
+ else
+ GNUTLS_REQUIRES_PRIVATE="$GNUTLS_REQUIRES_PRIVATE, zlib"
+ fi
])
AC_ARG_WITH(brotli,
@@ -1146,11 +1148,6 @@ if test x$ac_brotli != xno; then
PKG_CHECK_MODULES(LIBBROTLIDEC, [libbrotlidec >= 1.0.0], [with_libbrotlidec=yes], [with_libbrotlidec=no])
if test "${with_libbrotlienc}" = "yes" && test "${with_libbrotlidec}" = "yes"; then
AC_DEFINE([HAVE_LIBBROTLI], 1, [Define if BROTLI compression is enabled.])
- if test "x$GNUTLS_REQUIRES_PRIVATE" = "x"; then
- GNUTLS_REQUIRES_PRIVATE="Requires.private: libbrotlienc, libbrotlidec"
- else
- GNUTLS_REQUIRES_PRIVATE="${GNUTLS_REQUIRES_PRIVATE}, libbrotlienc, libbrotlidec"
- fi
need_ltlibdl=yes
else
AC_MSG_WARN(*** LIBBROTLI was not found. You will not be able to use BROTLI compression.)
@@ -1180,6 +1177,13 @@ AS_IF([test "$ac_cv_dlopen_soname_works" = yes], [
BrotliDecoderVersion();])])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
+],
+ [test "$with_libbrotlienc" = yes && test "$with_libbrotlidec" = yes], [
+ if test "x$GNUTLS_REQUIRES_PRIVATE" = "x"; then
+ GNUTLS_REQUIRES_PRIVATE="Requires.private: libbrotlienc, libbrotlidec"
+ else
+ GNUTLS_REQUIRES_PRIVATE="${GNUTLS_REQUIRES_PRIVATE}, libbrotlienc, libbrotlidec"
+ fi
])
AC_ARG_WITH(zstd,
@@ -1191,11 +1195,6 @@ if test x$ac_zstd != xno; then
PKG_CHECK_MODULES(LIBZSTD, [libzstd >= 1.3.0], [with_libzstd=yes], [with_libzstd=no])
if test "${with_libzstd}" = "yes"; then
AC_DEFINE([HAVE_LIBZSTD], 1, [Define if ZSTD compression is enabled.])
- if test "x$GNUTLS_REQUIRES_PRIVATE" = "x"; then
- GNUTLS_REQUIRES_PRIVATE="Requires.private: libzstd"
- else
- GNUTLS_REQUIRES_PRIVATE="${GNUTLS_REQUIRES_PRIVATE}, libzstd"
- fi
need_ltlibdl=yes
else
AC_MSG_WARN(*** LIBZSTD was not found. You will not be able to use ZSTD compression.)
@@ -1215,6 +1214,13 @@ AS_IF([test "$ac_cv_dlopen_soname_works" = yes], [
ZSTD_versionNumber();])])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
+],
+ [test "$with_libzstd" = yes], [
+ if test "x$GNUTLS_REQUIRES_PRIVATE" = "x"; then
+ GNUTLS_REQUIRES_PRIVATE="Requires.private: libzstd"
+ else
+ GNUTLS_REQUIRES_PRIVATE="${GNUTLS_REQUIRES_PRIVATE}, libzstd"
+ fi
])
AC_ARG_WITH(liboqs,
--
2.46.0
From 8d0ec0ccdfeaae0d56426169d4c7b490e3b07826 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 16 Aug 2024 13:35:47 +0900
Subject: [PATCH] build: add liboqs in Requires.private in gnutls.pc if needed
When --with-liboqs is specified and liboqs cannot be dlopen'ed, it
will be linked at build time. In that case gnutls.pc should indicate
that through Requires.private.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
configure.ac | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/configure.ac b/configure.ac
index f3e7a3aeae..93ba723323 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1256,6 +1256,13 @@ AS_IF([test "$ac_cv_dlopen_soname_works" = yes], [
OQS_version ();])])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
+],
+ [test "$have_liboqs" = yes], [
+ if test "x$GNUTLS_REQUIRES_PRIVATE" = x; then
+ GNUTLS_REQUIRES_PRIVATE="Requires.private: liboqs"
+ else
+ GNUTLS_REQUIRES_PRIVATE="$GNUTLS_REQUIRES_PRIVATE, liboqs"
+ fi
])
AM_CONDITIONAL(NEED_LTLIBDL, test "$need_ltlibdl" = yes)
--
2.46.0

View File

@ -1,196 +0,0 @@
From 54c06a9cd7bcf8f245cf5f9da760f91939259f69 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Sun, 16 Feb 2025 09:02:46 +0900
Subject: [PATCH 1/3] serv: fix detection of early data reception
Upon success, gnutls_record_recv_early_data returns the amount of data
received, so the application should treat positive numbers as an
indication of early data reception.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
src/serv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/serv.c b/src/serv.c
index 17db12c5ca..86008c9523 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -1690,7 +1690,7 @@ static void tcp_server(const char *name, int port, int timeout)
GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
j->earlydata_eof = 1;
}
- if (r == 0) {
+ if (r >= 0) {
earlydata_read = 1;
}
}
--
2.49.0
From 8c488288ea05a759977dccd4ee4d61610da4dc38 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 17 Mar 2025 09:00:44 +0900
Subject: [PATCH 2/3] cli: send early data only after session data is set
Now that max_early_data_size is recorded as part of the stored
resumption data, this needs to be read before attempting to send early
data.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
src/socket.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/socket.c b/src/socket.c
index 48784b67fa..f32910c239 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -580,6 +580,11 @@ void socket_open_int(socket_st *hd, const char *hostname, const char *service,
}
if (hd->session) {
+ if (hd->rdata.data) {
+ gnutls_session_set_data(hd->session,
+ hd->rdata.data,
+ hd->rdata.size);
+ }
if (hd->edata.data) {
ret = gnutls_record_send_early_data(
hd->session, hd->edata.data,
@@ -591,11 +596,6 @@ void socket_open_int(socket_st *hd, const char *hostname, const char *service,
exit(1);
}
}
- if (hd->rdata.data) {
- gnutls_session_set_data(hd->session,
- hd->rdata.data,
- hd->rdata.size);
- }
if (client_trace || server_trace) {
hd->server_trace = server_trace;
--
2.49.0
From 56fa5e1901fe40a97553cf3141a4d205c4286702 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Sun, 16 Feb 2025 09:04:50 +0900
Subject: [PATCH 3/3] tests: add basic tests for 0-RTT with gnutls-serv and
gnutls-cli
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
tests/Makefile.am | 2 +-
tests/gnutls-cli-earlydata.sh | 84 +++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 1 deletion(-)
create mode 100755 tests/gnutls-cli-earlydata.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ec8fd982c5..72926e9da4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -546,7 +546,7 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start
sni-resume.sh ocsp-tests/ocsptool.sh cert-reencoding.sh pkcs7-cat.sh long-crl.sh \
serv-udp.sh logfile-option.sh gnutls-cli-resume.sh profile-tests.sh \
server-weak-keys.sh ocsp-tests/ocsp-signer-verify.sh cfg-test.sh \
- sanity-lib.sh
+ sanity-lib.sh gnutls-cli-earlydata.sh
if !DISABLE_SYSTEM_CONFIG
dist_check_SCRIPTS += system-override-sig.sh system-override-hash.sh \
diff --git a/tests/gnutls-cli-earlydata.sh b/tests/gnutls-cli-earlydata.sh
new file mode 100755
index 0000000000..72763f029f
--- /dev/null
+++ b/tests/gnutls-cli-earlydata.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+# Copyright (C) 2025 Red Hat, Inc.
+#
+# Author: Daiki Ueno
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>
+#
+
+: ${srcdir=.}
+: ${SERV=../src/gnutls-serv${EXEEXT}}
+: ${CLI=../src/gnutls-cli${EXEEXT}}
+unset RETCODE
+
+if ! test -x "$SERV"; then
+ exit 77
+fi
+
+if ! test -x "$CLI"; then
+ exit 77
+fi
+
+if test "$WINDIR" != ""; then
+ exit 77
+fi
+
+if test -n "$VALGRIND"; then
+ VALGRIND="${LIBTOOL:-libtool} --mode=execute $VALGRIND --error-exitcode=1"
+fi
+
+SERV="$SERV -q"
+
+. "$srcdir/scripts/common.sh"
+
+: ${ac_cv_sizeof_time_t=8}
+if test "$ac_cv_sizeof_time_t" -ge 8; then
+ ATTIME_VALID="2038-10-12" # almost the pregenerated cert expiration
+else
+ ATTIME_VALID="2030-12-17" # end of epoch 2590 days of validity
+fi
+
+testdir=`create_testdir earlydata`
+KEY="$srcdir/../doc/credentials/x509/key-ecc.pem"
+CERT="$srcdir/../doc/credentials/x509/cert-ecc.pem"
+CACERT="$srcdir/../doc/credentials/x509/ca.pem"
+
+eval "$GETPORT"
+launch_server --echo --x509keyfile "$KEY" --x509certfile "$CERT" --disable-client-cert --earlydata --maxearlydata 1000
+PID=$!
+wait_server "$PID"
+
+echo "This is a test message" > "$testdir/earlydata.txt"
+
+$VALGRIND "$CLI" --attime="$ATTIME_VALID" -p "$PORT" localhost --logfile="$testdir/cli.log" --priority="NORMAL:-VERS-ALL:+VERS-TLS1.3" --x509cafile "$CACERT" --resume --waitresumption --earlydata="$testdir/earlydata.txt" </dev/null >"$testdir/cli.out"
+if test $? -ne 0; then
+ cat "$testdir/cli.log"
+ fail "$PID" "failed to communicate with the server"
+fi
+
+if ! grep "This is a resumed session" "$testdir/cli.log" > /dev/null; then
+ fail "$PID" "session is not resumed"
+fi
+
+if ! cmp "$testdir/earlydata.txt" "$testdir/cli.out" > /dev/null; then
+ fail "$PID" "early data has not been sent back"
+fi
+
+kill "$PID"
+wait
+
+exit 0
--
2.49.0

View File

@ -1,43 +0,0 @@
From b33c2f1f372f0f985be5c398021aad8a5532855e Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Wed, 19 Mar 2025 18:29:55 +0900
Subject: [PATCH] global: call lc_init at startup
When leancrypto is statically linked, their constructor will not be
called and which prevents some low-level algorithms being
functional. This adds a manual initialization with lc_init() at the
startup of the GnuTLS library.
Suggested-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/global.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/global.c b/lib/global.c
index 42d90ee9d5..dc80e6302d 100644
--- a/lib/global.c
+++ b/lib/global.c
@@ -42,6 +42,9 @@
#include "str.h"
#include "global.h"
#include "liboqs/liboqs.h"
+#ifdef HAVE_LEANCRYPTO
+#include <leancrypto.h>
+#endif
/* Minimum library versions we accept. */
#define GNUTLS_MIN_LIBTASN1_VERSION "0.3.4"
@@ -366,6 +369,9 @@ static int _gnutls_global_init(unsigned constructor)
_gnutls_register_accel_crypto();
_gnutls_cryptodev_init();
_gnutls_afalg_init();
+#ifdef HAVE_LEANCRYPTO
+ lc_init(0);
+#endif
#ifdef ENABLE_FIPS140
/* These self tests are performed on the overridden algorithms
--
2.49.0

View File

@ -1,213 +0,0 @@
From dc5ee80c3a28577e9de0f82fb08164e4c02b96af Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Sun, 9 Feb 2025 10:31:20 +0900
Subject: [PATCH] handshake: only shuffle extensions in the first Client Hello
RFC 8446 section 4.1.2 states that the second Client Hello after HRR
should preserve the same content as the first Client Hello with
limited exceptions. Since GnuTLS 3.8.5, however, the library started
shuffling the order of extensions for privacy reasons and that didn't
comply with the RFC, leading to a connectivity issue against the
server configuration with a stricter check on that.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/gnutls_int.h | 4 +++
lib/hello_ext.c | 41 ++++++++++++++++---------
lib/state.c | 2 ++
tests/tls13/hello_retry_request.c | 51 ++++++++++++++++++++++++++++---
4 files changed, 79 insertions(+), 19 deletions(-)
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index d10a028b59..572de5aba3 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1666,6 +1666,10 @@ typedef struct {
/* Compression method for certificate compression */
gnutls_compression_method_t compress_certificate_method;
+ /* To shuffle extension sending order */
+ extensions_t client_hello_exts[MAX_EXT_TYPES];
+ bool client_hello_exts_set;
+
/* If you add anything here, check _gnutls_handshake_internal_state_clear().
*/
} internals_st;
diff --git a/lib/hello_ext.c b/lib/hello_ext.c
index 40af8c2b10..d677addd75 100644
--- a/lib/hello_ext.c
+++ b/lib/hello_ext.c
@@ -438,8 +438,6 @@ int _gnutls_gen_hello_extensions(gnutls_session_t session,
int pos, ret;
size_t i;
hello_ext_ctx_st ctx;
- /* To shuffle extension sending order */
- extensions_t indices[MAX_EXT_TYPES];
msg &= GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK;
@@ -469,26 +467,39 @@ int _gnutls_gen_hello_extensions(gnutls_session_t session,
ret - 4);
}
- /* Initializing extensions array */
- for (i = 0; i < MAX_EXT_TYPES; i++) {
- indices[i] = i;
- }
+ if (msg & GNUTLS_EXT_FLAG_CLIENT_HELLO &&
+ !session->internals.client_hello_exts_set) {
+ /* Initializing extensions array */
+ for (i = 0; i < MAX_EXT_TYPES; i++) {
+ session->internals.client_hello_exts[i] = i;
+ }
- if (!session->internals.priorities->no_shuffle_extensions) {
- /* Ordering padding and pre_shared_key as last extensions */
- swap_exts(indices, MAX_EXT_TYPES - 2, GNUTLS_EXTENSION_DUMBFW);
- swap_exts(indices, MAX_EXT_TYPES - 1,
- GNUTLS_EXTENSION_PRE_SHARED_KEY);
+ if (!session->internals.priorities->no_shuffle_extensions) {
+ /* Ordering padding and pre_shared_key as last extensions */
+ swap_exts(session->internals.client_hello_exts,
+ MAX_EXT_TYPES - 2, GNUTLS_EXTENSION_DUMBFW);
+ swap_exts(session->internals.client_hello_exts,
+ MAX_EXT_TYPES - 1,
+ GNUTLS_EXTENSION_PRE_SHARED_KEY);
- ret = shuffle_exts(indices, MAX_EXT_TYPES - 2);
- if (ret < 0)
- return gnutls_assert_val(ret);
+ ret = shuffle_exts(session->internals.client_hello_exts,
+ MAX_EXT_TYPES - 2);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
+ session->internals.client_hello_exts_set = true;
}
/* hello_ext_send() ensures we don't send duplicates, in case
* of overridden extensions */
for (i = 0; i < MAX_EXT_TYPES; i++) {
- size_t ii = indices[i];
+ size_t ii;
+
+ if (msg & GNUTLS_EXT_FLAG_CLIENT_HELLO)
+ ii = session->internals.client_hello_exts[i];
+ else
+ ii = i;
+
if (!extfunc[ii])
continue;
diff --git a/lib/state.c b/lib/state.c
index 9d3ece7570..43e961cfa2 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -516,6 +516,8 @@ static void handshake_internal_state_clear1(gnutls_session_t session)
session->internals.hrr_cs[0] = CS_INVALID_MAJOR;
session->internals.hrr_cs[1] = CS_INVALID_MINOR;
+
+ session->internals.client_hello_exts_set = false;
}
/* This function will clear all the variables in internals
diff --git a/tests/tls13/hello_retry_request.c b/tests/tls13/hello_retry_request.c
index f407b64234..6c5f698f01 100644
--- a/tests/tls13/hello_retry_request.c
+++ b/tests/tls13/hello_retry_request.c
@@ -51,14 +51,37 @@ static void tls_log_func(int level, const char *str)
}
#define HANDSHAKE_SESSION_ID_POS 34
+#define MAX_EXT_TYPES 64
struct ctx_st {
unsigned hrr_seen;
unsigned hello_counter;
uint8_t session_id[32];
size_t session_id_len;
+ unsigned extensions[MAX_EXT_TYPES];
+ size_t extensions_size1;
+ size_t extensions_size2;
};
+static int ext_callback(void *_ctx, unsigned tls_id, const unsigned char *data,
+ unsigned size)
+{
+ struct ctx_st *ctx = _ctx;
+ if (ctx->hello_counter == 0) {
+ assert(ctx->extensions_size1 < MAX_EXT_TYPES);
+ ctx->extensions[ctx->extensions_size1++] = tls_id;
+ } else {
+ assert(ctx->extensions_size2 < MAX_EXT_TYPES);
+ if (tls_id != ctx->extensions[ctx->extensions_size2]) {
+ fail("extension doesn't match at position %zu, %u != %u\n",
+ ctx->extensions_size2, tls_id,
+ ctx->extensions[ctx->extensions_size2]);
+ }
+ ctx->extensions_size2++;
+ }
+ return 0;
+}
+
static int hello_callback(gnutls_session_t session, unsigned int htype,
unsigned post, unsigned int incoming,
const gnutls_datum_t *msg)
@@ -73,15 +96,25 @@ static int hello_callback(gnutls_session_t session, unsigned int htype,
post == GNUTLS_HOOK_POST) {
size_t session_id_len;
uint8_t *session_id;
+ unsigned pos = HANDSHAKE_SESSION_ID_POS;
+ gnutls_datum_t mmsg;
+ int ret;
- assert(msg->size > HANDSHAKE_SESSION_ID_POS + 1);
- session_id_len = msg->data[HANDSHAKE_SESSION_ID_POS];
- session_id = &msg->data[HANDSHAKE_SESSION_ID_POS + 1];
+ assert(msg->size > pos + 1);
+ session_id_len = msg->data[pos];
+ session_id = &msg->data[pos + 1];
+
+ SKIP8(pos, msg->size);
+ SKIP16(pos, msg->size);
+ SKIP8(pos, msg->size);
+
+ mmsg.data = &msg->data[pos];
+ mmsg.size = msg->size - pos;
if (ctx->hello_counter > 0) {
assert(msg->size > 4);
if (msg->data[0] != 0x03 || msg->data[1] != 0x03) {
- fail("version is %d.%d expected 3,3\n",
+ fail("version is %d.%d expected 3.3\n",
(int)msg->data[0], (int)msg->data[1]);
}
@@ -95,6 +128,12 @@ static int hello_callback(gnutls_session_t session, unsigned int htype,
ctx->session_id_len = session_id_len;
memcpy(ctx->session_id, session_id, session_id_len);
+ ret = gnutls_ext_raw_parse(ctx, ext_callback, &mmsg, 0);
+ if (ret < 0) {
+ fail("unable to parse extensions: %s\n",
+ gnutls_strerror(ret));
+ }
+
ctx->hello_counter++;
}
@@ -164,6 +203,10 @@ void doit(void)
myfail("group doesn't match the expected: %s\n",
gnutls_group_get_name(gnutls_group_get(server)));
+ if (ctx.extensions_size1 != ctx.extensions_size2)
+ myfail("the number of extensions don't match in second Client Hello: %zu != %zu\n",
+ ctx.extensions_size1, ctx.extensions_size2);
+
gnutls_bye(client, GNUTLS_SHUT_WR);
gnutls_bye(server, GNUTLS_SHUT_WR);
--
2.48.1

View File

@ -1,59 +0,0 @@
From 54a42b44522986b8fab2081c2f18026b44f3c0b1 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Thu, 13 Feb 2025 16:23:07 +0900
Subject: [PATCH] tests: make pqc-hybrid-kx.sh work when system time set beyond
2038
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
tests/pqc-hybrid-kx.sh | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/tests/pqc-hybrid-kx.sh b/tests/pqc-hybrid-kx.sh
index f67b07c45b..9174a3d5bc 100644
--- a/tests/pqc-hybrid-kx.sh
+++ b/tests/pqc-hybrid-kx.sh
@@ -33,6 +33,13 @@ fi
. "${srcdir}/scripts/common.sh"
+: ${ac_cv_sizeof_time_t=8}
+if test "${ac_cv_sizeof_time_t}" -ge 8; then
+ ATTIME_VALID="2038-10-12" # almost the pregenerated cert expiration
+else
+ ATTIME_VALID="2030-12-17" # end of epoch 2590 days of validity
+fi
+
# First check any mismatch in the gnutls-cli --list
if ! "${CLI}" --list | grep '^Groups: .*GROUP-X25519-KYBER768.*' >/dev/null; then
if "${CLI}" --list | grep '^Public Key Systems: .*KYBER768.*' >/dev/null; then
@@ -93,7 +100,7 @@ for group in X25519-KYBER768 SECP256R1-MLKEM768 SECP384R1-MLKEM1024 X25519-MLKEM
PID=$!
wait_server ${PID}
- ${VALGRIND} "${CLI}" -p "${PORT}" localhost --priority "NORMAL:-GROUP-ALL:+GROUP-$group" --x509cafile="$CACERT" --logfile="$testdir/cli.log" </dev/null
+ ${VALGRIND} "${CLI}" --attime "${ATTIME_VALID}" -p "${PORT}" localhost --priority "NORMAL:-GROUP-ALL:+GROUP-$group" --x509cafile="$CACERT" --logfile="$testdir/cli.log" </dev/null
kill ${PID}
wait
@@ -112,7 +119,7 @@ for group in KYBER768 MLKEM768 MLKEM1024; do
PID=$!
wait_server ${PID}
- ${VALGRIND} "${CLI}" -p "${PORT}" localhost --priority "NORMAL:-GROUP-ALL:+GROUP-$group" --x509cafile="$CACERT" --logfile="$testdir/cli.log" </dev/null
+ ${VALGRIND} "${CLI}" --attime "${ATTIME_VALID}" -p "${PORT}" localhost --priority "NORMAL:-GROUP-ALL:+GROUP-$group" --x509cafile="$CACERT" --logfile="$testdir/cli.log" </dev/null
rc=$?
kill ${PID}
wait
@@ -140,7 +147,7 @@ for group in X25519-KYBER768 SECP256R1-MLKEM768 SECP384R1-MLKEM1024 X25519-MLKEM
PID=$!
wait_server ${PID}
- ${VALGRIND} "${CLI}" -p "${PORT}" localhost --priority "NORMAL:-GROUP-ALL:+GROUP-$group" --x509cafile="$CACERT" --logfile="$testdir/cli.log" </dev/null
+ ${VALGRIND} "${CLI}" --attime "${ATTIME_VALID}" -p "${PORT}" localhost --priority "NORMAL:-GROUP-ALL:+GROUP-$group" --x509cafile="$CACERT" --logfile="$testdir/cli.log" </dev/null
rc=$?
kill ${PID}
wait
--
2.49.0

View File

@ -35,6 +35,13 @@ Patch: gnutls-3.8.10-tests-mldsa.patch
# not yet upstreamed: https://gitlab.com/gnutls/gnutls/-/merge_requests/1990/diffs?commit_id=993a8055c03b60c95fc65962ed82adc80b049a9a
Patch: gnutls-3.8.10-keyupdate.patch
# upstreamed: https://gitlab.com/gnutls/gnutls/-/merge_requests/2041
Patch: gnutls-3.8.10-CVE-2025-9820.patch
# upstreamed: https://gitlab.com/gnutls/gnutls/-/merge_requests/2062
Patch: gnutls-3.8.10-CVE-2025-14831.patch
# intentionally omitted: CVE-2026-1584, since 3.8.10 is not vulnerable
%bcond_without bootstrap
%bcond_without dane
%bcond_without fips

View File

@ -1,346 +0,0 @@
From 3c32c1afe3e4653fd4093ed77090c36223bce7a0 Mon Sep 17 00:00:00 2001
From: Stephan Mueller <smueller@chronox.de>
Date: Thu, 8 May 2025 12:34:21 +0200
Subject: [PATCH] ARMv8: properly save/restore SIMD register v8 through v15
Those registers are used by ML-DSA and ML-KEM.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
internal/api/armv8_helper.h | 67 ++++++++++++
ml-dsa/src/armv8/dilithium_signature_armv8.c | 101 +++++++++++++++++--
ml-kem/src/armv8/kyber_indcpa_armv8.c | 13 +++
4 files changed, 173 insertions(+), 10 deletions(-)
create mode 100644 internal/api/armv8_helper.h
diff --git a/internal/api/armv8_helper.h b/internal/api/armv8_helper.h
new file mode 100644
index 00000000..456f3239
--- /dev/null
+++ b/internal/api/armv8_helper.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2025, Stephan Mueller <smueller@chronox.de>
+ *
+ * License: see LICENSE file in root directory
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#ifndef ARMV8_HELPER_H
+#define ARMV8_HELPER_H
+
+#include "ext_headers.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The ARMv8 Kyber implementation uses the SIMD registers v8 through v15 which
+ * must be preserved by the callee.
+ *
+ * Store only the lower 64 bits of the FP registers v8 through v15 according to
+ * https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#612simd-and-floating-point-registers
+ */
+static inline void store_fp_regs(uint64_t tmp[8])
+{
+ __asm__ volatile("mov %0, v8.d[0]" : "=r"(tmp[0]) : : "memory" );
+ __asm__ volatile("mov %0, v9.d[0]" : "=r"(tmp[1]) : : "memory" );
+ __asm__ volatile("mov %0, v10.d[0]" : "=r"(tmp[2]) : : "memory" );
+ __asm__ volatile("mov %0, v11.d[0]" : "=r"(tmp[3]) : : "memory" );
+ __asm__ volatile("mov %0, v12.d[0]" : "=r"(tmp[4]) : : "memory" );
+ __asm__ volatile("mov %0, v13.d[0]" : "=r"(tmp[5]) : : "memory" );
+ __asm__ volatile("mov %0, v14.d[0]" : "=r"(tmp[6]) : : "memory" );
+ __asm__ volatile("mov %0, v15.d[0]" : "=r"(tmp[7]) : : "memory" );
+}
+
+/*
+ * Reload the stored register content into the SIMD registers
+ */
+static inline void reload_fp_regs(uint64_t tmp[8])
+{
+ __asm__ volatile("mov v8.d[0], %0" : : "r"(tmp[0]) : "memory" );
+ __asm__ volatile("mov v9.d[0], %0" : : "r"(tmp[1]) : "memory" );
+ __asm__ volatile("mov v10.d[0], %0" : : "r"(tmp[2]) : "memory" );
+ __asm__ volatile("mov v11.d[0], %0" : : "r"(tmp[3]) : "memory" );
+ __asm__ volatile("mov v12.d[0], %0" : : "r"(tmp[4]) : "memory" );
+ __asm__ volatile("mov v13.d[0], %0" : : "r"(tmp[5]) : "memory" );
+ __asm__ volatile("mov v14.d[0], %0" : : "r"(tmp[6]) : "memory" );
+ __asm__ volatile("mov v15.d[0], %0" : : "r"(tmp[7]) : "memory" );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ARMV8_HELPER_H */
diff --git a/ml-dsa/src/armv8/dilithium_signature_armv8.c b/ml-dsa/src/armv8/dilithium_signature_armv8.c
index a661ffe9..5bc64387 100644
--- a/ml-dsa/src/armv8/dilithium_signature_armv8.c
+++ b/ml-dsa/src/armv8/dilithium_signature_armv8.c
@@ -17,6 +17,7 @@
* DAMAGE.
*/
+#include "armv8_helper.h"
#include "dilithium_type.h"
#include "dilithium_signature_armv8.h"
#include "visibility.h"
@@ -36,14 +37,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_keypair_from_seed_armv8,
struct lc_dilithium_pk *pk, struct lc_dilithium_sk *sk,
const uint8_t *seed, size_t seedlen)
{
- return lc_dilithium_keypair_from_seed_impl(pk, sk, seed, seedlen);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_keypair_from_seed_impl(pk, sk, seed, seedlen);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_keypair_armv8,
struct lc_dilithium_pk *pk, struct lc_dilithium_sk *sk,
struct lc_rng_ctx *rng_ctx)
{
- return lc_dilithium_keypair_impl(pk, sk, rng_ctx);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_keypair_impl(pk, sk, rng_ctx);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_armv8,
@@ -51,7 +68,15 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_armv8,
size_t mlen, const struct lc_dilithium_sk *sk,
struct lc_rng_ctx *rng_ctx)
{
- return lc_dilithium_sign_impl(sig, m, mlen, sk, rng_ctx);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_sign_impl(sig, m, mlen, sk, rng_ctx);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_ctx_armv8,
@@ -60,14 +85,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_ctx_armv8,
size_t mlen, const struct lc_dilithium_sk *sk,
struct lc_rng_ctx *rng_ctx)
{
- return lc_dilithium_sign_ctx_impl(sig, ctx, m, mlen, sk, rng_ctx);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_sign_ctx_impl(sig, ctx, m, mlen, sk, rng_ctx);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_init_armv8,
struct lc_dilithium_ctx *ctx,
const struct lc_dilithium_sk *sk)
{
- return lc_dilithium_sign_init_impl(ctx, sk);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_sign_init_impl(ctx, sk);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_update_armv8,
@@ -83,14 +124,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_final_armv8,
const struct lc_dilithium_sk *sk,
struct lc_rng_ctx *rng_ctx)
{
- return lc_dilithium_sign_final_impl(sig, ctx, sk, rng_ctx);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_sign_final_impl(sig, ctx, sk, rng_ctx);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_armv8,
const struct lc_dilithium_sig *sig, const uint8_t *m,
size_t mlen, const struct lc_dilithium_pk *pk)
{
- return lc_dilithium_verify_impl(sig, m, mlen, pk);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_verify_impl(sig, m, mlen, pk);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_ctx_armv8,
@@ -98,14 +155,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_ctx_armv8,
struct lc_dilithium_ctx *ctx, const uint8_t *m,
size_t mlen, const struct lc_dilithium_pk *pk)
{
- return lc_dilithium_verify_ctx_impl(sig, ctx, m, mlen, pk);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_verify_ctx_impl(sig, ctx, m, mlen, pk);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_init_armv8,
struct lc_dilithium_ctx *ctx,
const struct lc_dilithium_pk *pk)
{
- return lc_dilithium_verify_init_impl(ctx, pk);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_verify_init_impl(ctx, pk);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_update_armv8,
@@ -120,5 +193,13 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_final_armv8,
struct lc_dilithium_ctx *ctx,
const struct lc_dilithium_pk *pk)
{
- return lc_dilithium_verify_final_impl(sig, ctx, pk);
+ uint64_t saved_regs[8];
+ int ret;
+
+ store_fp_regs(saved_regs);
+ ret = lc_dilithium_verify_final_impl(sig, ctx, pk);
+ reload_fp_regs(saved_regs);
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
+
+ return ret;
}
diff --git a/ml-kem/src/armv8/kyber_indcpa_armv8.c b/ml-kem/src/armv8/kyber_indcpa_armv8.c
index 26b797d8..d6289d73 100644
--- a/ml-kem/src/armv8/kyber_indcpa_armv8.c
+++ b/ml-kem/src/armv8/kyber_indcpa_armv8.c
@@ -23,6 +23,7 @@
* That code is released under MIT license.
*/
+#include "armv8_helper.h"
#include "build_bug_on.h"
#include "kyber_indcpa_armv8.h"
#include "kyber_poly_armv8.h"
@@ -229,6 +230,7 @@ int indcpa_keypair_armv8(uint8_t pk[LC_KYBER_INDCPA_PUBLICKEYBYTES],
uint8_t buf[2 * LC_KYBER_SYMBYTES];
uint8_t poly_getnoise_eta1_buf[POLY_GETNOISE_ETA1_BUFSIZE];
polyvec a[LC_KYBER_K], e, pkpv, skpv;
+ uint64_t saved_regs[8];
};
static const uint8_t kval = LC_KYBER_K;
unsigned int i;
@@ -239,6 +241,8 @@ int indcpa_keypair_armv8(uint8_t pk[LC_KYBER_INDCPA_PUBLICKEYBYTES],
LC_HASH_CTX_ON_STACK(sha3_512_ctx, lc_sha3_512);
LC_DECLARE_MEM(ws, struct workspace, 32);
+ store_fp_regs(ws->saved_regs);
+
buf = ws->buf;
publicseed = ws->buf;
noiseseed = ws->buf + LC_KYBER_SYMBYTES;
@@ -282,6 +286,7 @@ int indcpa_keypair_armv8(uint8_t pk[LC_KYBER_INDCPA_PUBLICKEYBYTES],
unpoison(pk, LC_KYBER_INDCPA_PUBLICKEYBYTES);
out:
+ reload_fp_regs(ws->saved_regs);
LC_RELEASE_MEM(ws);
return ret;
}
@@ -299,12 +304,15 @@ int indcpa_enc_armv8(uint8_t c[LC_KYBER_INDCPA_BYTES],
//uint8_t poly_getnoise_eta2_buf[POLY_GETNOISE_ETA2_BUFSIZE];
polyvec sp, pkpv, ep, at[LC_KYBER_K], b;
poly v, k, epp;
+ uint64_t saved_regs[8];
};
unsigned int i;
uint8_t nonce = 0, nonce2 = LC_KYBER_K;
int ret;
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
+ store_fp_regs(ws->saved_regs);
+
/*
* Use the poly_getnoise_eta1_buf for this operation as seed is smaller
* than poly_getnoise_eta1_buf and has the same alignment.
@@ -354,6 +362,7 @@ int indcpa_enc_armv8(uint8_t c[LC_KYBER_INDCPA_BYTES],
pack_ciphertext(c, &ws->b, &ws->v);
out:
+ reload_fp_regs(ws->saved_regs);
LC_RELEASE_MEM(ws);
return ret;
}
@@ -365,9 +374,12 @@ int indcpa_dec_armv8(uint8_t m[LC_KYBER_INDCPA_MSGBYTES],
struct workspace {
polyvec b, skpv;
poly v, mp;
+ uint64_t saved_regs[8];
};
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
+ store_fp_regs(ws->saved_regs);
+
unpack_sk(&ws->skpv, sk);
/* Validate input */
@@ -386,6 +398,7 @@ int indcpa_dec_armv8(uint8_t m[LC_KYBER_INDCPA_MSGBYTES],
poly_tomsg(m, &ws->mp);
+ reload_fp_regs(ws->saved_regs);
LC_RELEASE_MEM(ws);
return 0;
}