Compare commits

...

No commits in common. 'c9' and 'i10c-beta' have entirely different histories.

5
.gitignore vendored

@ -1,3 +1,4 @@
SOURCES/gmp-6.2.1.tar.xz
SOURCES/gnutls-3.8.3.tar.xz
SOURCES/gnutls-3.8.3.tar.xz.sig
SOURCES/gnutls-3.8.7.1.tar.xz
SOURCES/gnutls-3.8.7.1.tar.xz.sig
SOURCES/nettle-3.10-hobbled.tar.xz

@ -1,3 +1,4 @@
0578d48607ec0e272177d175fd1807c30b00fdf2 SOURCES/gmp-6.2.1.tar.xz
806156ac9563caab642d6274496b9cc5b2117612 SOURCES/gnutls-3.8.3.tar.xz
dd7822b360953108a86dc3dbc7d07214563cc678 SOURCES/gnutls-3.8.3.tar.xz.sig
d66729d963c7a5fb170e4b3afeb63702a9ccd265 SOURCES/gnutls-3.8.7.1.tar.xz
d4c1e07e58e09279687542c10d4463c62d12e3ce SOURCES/gnutls-3.8.7.1.tar.xz.sig
762cc3c0a8cf735353927607a147d7bb802b5aad SOURCES/nettle-3.10-hobbled.tar.xz

@ -1,19 +1,19 @@
From 0a29639ad24072afbd79b2ceede9976e51b9e2af Mon Sep 17 00:00:00 2001
From b6c6e699ec79820bc949db3c71992ce277eef141 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Fri, 1 Jul 2022 16:46:07 +0900
Subject: [PATCH] fips: don't run POST for DSA
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>>
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 656d43e..c776690 100644
index 1611200..8a9824a 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -523,11 +523,6 @@ int _gnutls_fips_perform_self_checks2(void)
return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
@@ -611,11 +611,6 @@ int _gnutls_fips_perform_self_checks2(void)
}
}
- ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA);
@ -25,5 +25,5 @@ index 656d43e..c776690 100644
if (ret < 0) {
return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
--
2.36.1
2.46.0

@ -1,189 +0,0 @@
From 3c931abeb7e9bbf744cde83fbaaf3bb011107834 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 19 Aug 2022 12:32:27 +0900
Subject: [PATCH] build: allow GMP to be statically linked
Even though we set the custom allocator[1] to zeroize sensitive data,
it can be easily invalidated if the application sets its own custom
allocator. An approach to prevent that is to link against a static
library of GMP, so the use of GMP is privatized and the custom
allocator configuration is not shared with other applications.
This patch allows libgnutls to be linked with the static library of
GMP. Note that, to this work libgmp.a needs to be compiled with -fPIC
and libhogweed in Nettle is also linked to the static library of GMP.
1. https://gitlab.com/gnutls/gnutls/-/merge_requests/1554
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
configure.ac | 14 +++++++++++++-
lib/fips.c | 18 +++++++++++++++++-
lib/fipshmac.c | 2 ++
lib/global.c | 2 ++
4 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index f81d93edc0..b38583c554 100644
--- a/configure.ac
+++ b/configure.ac
@@ -786,6 +786,8 @@ LIBS=$save_LIBS
AM_CONDITIONAL([NEED_SIV_GCM], [test "$ac_cv_func_nettle_siv_gcm_encrypt_message" != yes])
# Check sonames of the linked libraries needed for FIPS selftests.
+save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS $GMP_CFLAGS"
save_LIBS=$LIBS
LIBS="$LIBS $GMP_LIBS"
AC_MSG_CHECKING([gmp soname])
@@ -799,9 +801,14 @@ if test -z "$gmp_so"; then
gmp_so=none
fi
AC_MSG_RESULT($gmp_so)
-AC_DEFINE_UNQUOTED([GMP_LIBRARY_SONAME], ["$gmp_so"], [The soname of gmp library])
+if test "$gmp_so" != none; then
+ AC_DEFINE_UNQUOTED([GMP_LIBRARY_SONAME], ["$gmp_so"], [The soname of gmp library])
+fi
LIBS=$save_LIBS
+CFLAGS=$save_CFLAGS
+save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS $NETTLE_CFLAGS"
save_LIBS=$LIBS
LIBS="$LIBS $NETTLE_LIBS"
AC_MSG_CHECKING([nettle soname])
@@ -817,7 +824,11 @@ fi
AC_MSG_RESULT($nettle_so)
AC_DEFINE_UNQUOTED([NETTLE_LIBRARY_SONAME], ["$nettle_so"], [The soname of nettle library])
LIBS=$save_LIBS
+CFLAGS=$save_CFLAGS
+save_CFLAGS=$CFLAGS
+# <nettle/bignum.h> includes <gmp.h>
+CFLAGS="$CFLAGS $HOGWEED_CFLAGS $GMP_CFLAGS"
save_LIBS=$LIBS
LIBS="$LIBS $HOGWEED_LIBS"
AC_MSG_CHECKING([hogweed soname])
@@ -833,6 +844,7 @@ fi
AC_MSG_RESULT($hogweed_so)
AC_DEFINE_UNQUOTED([HOGWEED_LIBRARY_SONAME], ["$hogweed_so"], [The soname of hogweed library])
LIBS=$save_LIBS
+CFLAGS=$save_CFLAGS
gnutls_so=libgnutls.so.`expr "$LT_CURRENT" - "$LT_AGE"`
AC_DEFINE_UNQUOTED([GNUTLS_LIBRARY_SONAME], ["$gnutls_so"], [The soname of gnutls library])
diff --git a/lib/fips.c b/lib/fips.c
index e337221267..c1859709da 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -157,7 +157,11 @@ void _gnutls_fips_mode_reset_zombie(void)
#define GNUTLS_LIBRARY_NAME GNUTLS_LIBRARY_SONAME
#define NETTLE_LIBRARY_NAME NETTLE_LIBRARY_SONAME
#define HOGWEED_LIBRARY_NAME HOGWEED_LIBRARY_SONAME
+
+/* GMP can be statically linked. */
+#ifdef GMP_LIBRARY_SONAME
#define GMP_LIBRARY_NAME GMP_LIBRARY_SONAME
+#endif
#define HMAC_SIZE 32
#define HMAC_ALGO GNUTLS_MAC_SHA256
@@ -173,14 +177,18 @@ struct hmac_file {
struct hmac_entry gnutls;
struct hmac_entry nettle;
struct hmac_entry hogweed;
+#ifdef GMP_LIBRARY_SONAME
struct hmac_entry gmp;
+#endif
};
struct lib_paths {
char gnutls[GNUTLS_PATH_MAX];
char nettle[GNUTLS_PATH_MAX];
char hogweed[GNUTLS_PATH_MAX];
+#ifdef GMP_LIBRARY_SONAME
char gmp[GNUTLS_PATH_MAX];
+#endif
};
/*
@@ -244,8 +252,10 @@ static int handler(void *user, const char *section, const char *name,
return lib_handler(&p->nettle, section, name, value);
} else if (!strcmp(section, HOGWEED_LIBRARY_NAME)) {
return lib_handler(&p->hogweed, section, name, value);
+#ifdef GMP_LIBRARY_SONAME
} else if (!strcmp(section, GMP_LIBRARY_NAME)) {
return lib_handler(&p->gmp, section, name, value);
+#endif
} else {
return 0;
}
@@ -393,8 +403,10 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
_gnutls_str_cpy(paths->nettle, GNUTLS_PATH_MAX, path);
else if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
_gnutls_str_cpy(paths->hogweed, GNUTLS_PATH_MAX, path);
+#ifdef GMP_LIBRARY_SONAME
else if (!strcmp(soname, GMP_LIBRARY_SONAME))
_gnutls_str_cpy(paths->gmp, GNUTLS_PATH_MAX, path);
+#endif
return 0;
}
@@ -415,10 +427,12 @@ static int load_lib_paths(struct lib_paths *paths)
_gnutls_debug_log("Hogweed library path was not found\n");
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
}
+#ifdef GMP_LIBRARY_SONAME
if (paths->gmp[0] == '\0') {
_gnutls_debug_log("Gmp library path was not found\n");
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
}
+#endif
return GNUTLS_E_SUCCESS;
}
@@ -471,9 +485,11 @@ static int check_binary_integrity(void)
ret = check_lib_hmac(&hmac.hogweed, paths.hogweed);
if (ret < 0)
return ret;
- ret = check_lib_hmac(&hmac.gmp, paths.gmp);
+#ifdef GMP_LIBRARY_SONAME
+ ret = check_lib_hmac(&file.gmp, GMP_LIBRARY_NAME, "__gmpz_init");
if (ret < 0)
return ret;
+#endif
return 0;
}
diff --git a/lib/fipshmac.c b/lib/fipshmac.c
index 51f38f18e5..6a4883a131 100644
--- a/lib/fipshmac.c
+++ b/lib/fipshmac.c
@@ -107,8 +107,10 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
return print_lib(path, soname);
if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
return print_lib(path, soname);
+#ifdef GMP_LIBRARY_SONAME
if (!strcmp(soname, GMP_LIBRARY_SONAME))
return print_lib(path, soname);
+#endif
return 0;
}
diff --git a/lib/global.c b/lib/global.c
index 924ec945de..c197fd0e5f 100644
--- a/lib/global.c
+++ b/lib/global.c
@@ -564,7 +564,9 @@ static const struct gnutls_library_config_st _gnutls_library_config[] = {
{ "libgnutls-soname", GNUTLS_LIBRARY_SONAME },
{ "libnettle-soname", NETTLE_LIBRARY_SONAME },
{ "libhogweed-soname", HOGWEED_LIBRARY_SONAME },
+#ifdef GMP_LIBRARY_SONAME
{ "libgmp-soname", GMP_LIBRARY_SONAME },
+#endif
{ "hardware-features", HW_FEATURES },
{ "tls-features", TLS_FEATURES },
{ "default-system-config", SYSTEM_PRIORITY_FILE },
--
2.41.0

@ -1,27 +1,25 @@
From 7d98e7768f3e4e1f981f76e27338ae7118ee2c39 Mon Sep 17 00:00:00 2001
From 18c555b4d2461ad202996398609552b9c4ecd43b Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 22 Jan 2024 15:17:04 +0900
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 | 2 --
1 file changed, 2 deletions(-)
tests/gnutls_ktls.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c
index ccbe566..8b8992d 100644
index ccbe566..049c888 100644
--- a/tests/gnutls_ktls.c
+++ b/tests/gnutls_ktls.c
@@ -347,10 +347,8 @@ void doit(void)
@@ -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");
#if defined(__linux__)
run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-CCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-CCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+CHACHA20-POLY1305");
--
2.43.0
2.41.0

@ -1,418 +0,0 @@
From 1c4701ffc342259fc5965d5a0de90d87f780e3e5 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 12 Jan 2024 17:56:58 +0900
Subject: [PATCH] nettle: avoid normalization of mpz_t in deterministic ECDSA
This removes function calls that potentially leak bit-length of a
private key used to calculate a nonce in deterministic ECDSA. Namely:
- _gnutls_dsa_compute_k has been rewritten to work on always
zero-padded mp_limb_t arrays instead of mpz_t
- rnd_mpz_func has been replaced with rnd_datum_func, which is backed
by a byte array instead of an mpz_t value
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/nettle/int/dsa-compute-k.c | 70 +++++++++++++++++++++----------
lib/nettle/int/dsa-compute-k.h | 23 +++++++++-
lib/nettle/int/ecdsa-compute-k.c | 28 +++----------
lib/nettle/int/ecdsa-compute-k.h | 4 +-
lib/nettle/pk.c | 65 +++++++++++++++++++++-------
tests/sign-verify-deterministic.c | 2 +-
6 files changed, 127 insertions(+), 65 deletions(-)
diff --git a/lib/nettle/int/dsa-compute-k.c b/lib/nettle/int/dsa-compute-k.c
index 8ff5739c2b..2fcb2bb80e 100644
--- a/lib/nettle/int/dsa-compute-k.c
+++ b/lib/nettle/int/dsa-compute-k.c
@@ -31,19 +31,30 @@
#include "mpn-base256.h"
#include <string.h>
-#define BITS_TO_LIMBS(bits) (((bits) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
+/* For mini-gmp */
+#ifndef GMP_LIMB_BITS
+#define GMP_LIMB_BITS GMP_NUMB_BITS
+#endif
-/* The maximum size of q, chosen from the fact that we support
- * 521-bit elliptic curve generator and 512-bit DSA subgroup at
- * maximum. */
-#define MAX_Q_BITS 521
-#define MAX_Q_SIZE ((MAX_Q_BITS + 7) / 8)
-#define MAX_Q_LIMBS BITS_TO_LIMBS(MAX_Q_BITS)
+static inline int is_zero_limb(mp_limb_t x)
+{
+ x |= (x << 1);
+ return ((x >> 1) - 1) >> (GMP_LIMB_BITS - 1);
+}
+
+static int sec_zero_p(const mp_limb_t *ap, mp_size_t n)
+{
+ volatile mp_limb_t w;
+ mp_size_t i;
-#define MAX_HASH_BITS (MAX_HASH_SIZE * 8)
-#define MAX_HASH_LIMBS BITS_TO_LIMBS(MAX_HASH_BITS)
+ for (i = 0, w = 0; i < n; i++)
+ w |= ap[i];
-int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
+ return is_zero_limb(w);
+}
+
+int _gnutls_dsa_compute_k(mp_limb_t *h, const mp_limb_t *q, const mp_limb_t *x,
+ mp_size_t qn, mp_bitcnt_t q_bits,
gnutls_mac_algorithm_t mac, const uint8_t *digest,
size_t length)
{
@@ -51,9 +62,6 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
uint8_t K[MAX_HASH_SIZE];
uint8_t xp[MAX_Q_SIZE];
uint8_t tp[MAX_Q_SIZE];
- mp_limb_t h[MAX(MAX_Q_LIMBS, MAX_HASH_LIMBS)];
- mp_bitcnt_t q_bits = mpz_sizeinbase(q, 2);
- mp_size_t qn = mpz_size(q);
mp_bitcnt_t h_bits = length * 8;
mp_size_t hn = BITS_TO_LIMBS(h_bits);
size_t nbytes = (q_bits + 7) / 8;
@@ -62,6 +70,7 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
mp_limb_t cy;
gnutls_hmac_hd_t hd;
int ret = 0;
+ mp_limb_t scratch[MAX_Q_LIMBS];
if (unlikely(q_bits > MAX_Q_BITS))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
@@ -69,7 +78,7 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
/* int2octets(x) */
- mpn_get_base256(xp, nbytes, mpz_limbs_read(x), qn);
+ mpn_get_base256(xp, nbytes, x, qn);
/* bits2octets(h) */
mpn_set_base256(h, hn, digest, length);
@@ -93,12 +102,12 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
mpn_rshift(h, h, hn, shift % GMP_NUMB_BITS);
}
- cy = mpn_sub_n(h, h, mpz_limbs_read(q), qn);
+ cy = mpn_sub_n(h, h, q, qn);
/* Fall back to addmul_1, if nettle is linked with mini-gmp. */
#ifdef mpn_cnd_add_n
- mpn_cnd_add_n(cy, h, h, mpz_limbs_read(q), qn);
+ mpn_cnd_add_n(cy, h, h, q, qn);
#else
- mpn_addmul_1(h, mpz_limbs_read(q), qn, cy != 0);
+ mpn_addmul_1(h, q, qn, cy != 0);
#endif
mpn_get_base256(tp, nbytes, h, qn);
@@ -174,12 +183,8 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
if (tlen * 8 > q_bits)
mpn_rshift(h, h, qn, tlen * 8 - q_bits);
/* Check if k is in [1,q-1] */
- if (!mpn_zero_p(h, qn) &&
- mpn_cmp(h, mpz_limbs_read(q), qn) < 0) {
- mpn_copyi(mpz_limbs_write(k, qn), h, qn);
- mpz_limbs_finish(k, qn);
+ if (!sec_zero_p(h, qn) && mpn_sub_n(scratch, h, q, qn))
break;
- }
ret = gnutls_hmac_init(&hd, mac, K, length);
if (ret < 0)
@@ -203,3 +208,24 @@ out:
return ret;
}
+
+/* cancel-out dsa_sign's addition of 1 to random data */
+void _gnutls_dsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h,
+ mp_size_t n)
+{
+ /* Fall back to sub_1, if nettle is linked with mini-gmp. */
+#ifdef mpn_sec_sub_1
+ mp_limb_t t[MAX_Q_LIMBS];
+
+ mpn_sec_sub_1(h, h, n, 1, t);
+#else
+ mpn_sub_1(h, h, n, 1);
+#endif
+ mpn_get_base256(k, nbytes, h, n);
+}
+
+void _gnutls_ecdsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h,
+ mp_size_t n)
+{
+ mpn_get_base256(k, nbytes, h, n);
+}
diff --git a/lib/nettle/int/dsa-compute-k.h b/lib/nettle/int/dsa-compute-k.h
index 49d243acb4..2f0667a01e 100644
--- a/lib/nettle/int/dsa-compute-k.h
+++ b/lib/nettle/int/dsa-compute-k.h
@@ -26,8 +26,29 @@
#include <gnutls/gnutls.h>
#include <nettle/bignum.h> /* includes gmp.h */
-int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
+#define BITS_TO_LIMBS(bits) (((bits) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
+
+/* The maximum size of q, chosen from the fact that we support
+ * 521-bit elliptic curve generator and 512-bit DSA subgroup at
+ * maximum. */
+#define MAX_Q_BITS 521
+#define MAX_Q_SIZE ((MAX_Q_BITS + 7) / 8)
+#define MAX_Q_LIMBS BITS_TO_LIMBS(MAX_Q_BITS)
+
+#define MAX_HASH_BITS (MAX_HASH_SIZE * 8)
+#define MAX_HASH_LIMBS BITS_TO_LIMBS(MAX_HASH_BITS)
+
+#define DSA_COMPUTE_K_ITCH MAX(MAX_Q_LIMBS, MAX_HASH_LIMBS)
+
+int _gnutls_dsa_compute_k(mp_limb_t *h, const mp_limb_t *q, const mp_limb_t *x,
+ mp_size_t qn, mp_bitcnt_t q_bits,
gnutls_mac_algorithm_t mac, const uint8_t *digest,
size_t length);
+void _gnutls_dsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h,
+ mp_size_t n);
+
+void _gnutls_ecdsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h,
+ mp_size_t n);
+
#endif /* GNUTLS_LIB_NETTLE_INT_DSA_COMPUTE_K_H */
diff --git a/lib/nettle/int/ecdsa-compute-k.c b/lib/nettle/int/ecdsa-compute-k.c
index 3b7f886160..4e25235c40 100644
--- a/lib/nettle/int/ecdsa-compute-k.c
+++ b/lib/nettle/int/ecdsa-compute-k.c
@@ -29,38 +29,38 @@
#include "dsa-compute-k.h"
#include "gnutls_int.h"
-static inline int _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve)
+int _gnutls_ecc_curve_to_dsa_q(mpz_t q, gnutls_ecc_curve_t curve)
{
switch (curve) {
#ifdef ENABLE_NON_SUITEB_CURVES
case GNUTLS_ECC_CURVE_SECP192R1:
- mpz_init_set_str(*q,
+ mpz_init_set_str(q,
"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836"
"146BC9B1B4D22831",
16);
return 0;
case GNUTLS_ECC_CURVE_SECP224R1:
- mpz_init_set_str(*q,
+ mpz_init_set_str(q,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2"
"E0B8F03E13DD29455C5C2A3D",
16);
return 0;
#endif
case GNUTLS_ECC_CURVE_SECP256R1:
- mpz_init_set_str(*q,
+ mpz_init_set_str(q,
"FFFFFFFF00000000FFFFFFFFFFFFFFFF"
"BCE6FAADA7179E84F3B9CAC2FC632551",
16);
return 0;
case GNUTLS_ECC_CURVE_SECP384R1:
- mpz_init_set_str(*q,
+ mpz_init_set_str(q,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFC7634D81F4372DDF"
"581A0DB248B0A77AECEC196ACCC52973",
16);
return 0;
case GNUTLS_ECC_CURVE_SECP521R1:
- mpz_init_set_str(*q,
+ mpz_init_set_str(q,
"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFA51868783BF2F966B7FCC0148F709A"
@@ -73,19 +73,3 @@ static inline int _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve)
GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
}
}
-
-int _gnutls_ecdsa_compute_k(mpz_t k, gnutls_ecc_curve_t curve, const mpz_t x,
- gnutls_mac_algorithm_t mac, const uint8_t *digest,
- size_t length)
-{
- mpz_t q;
- int ret;
-
- ret = _gnutls_ecc_curve_to_dsa_q(&q, curve);
- if (ret < 0)
- return gnutls_assert_val(ret);
-
- ret = _gnutls_dsa_compute_k(k, q, x, mac, digest, length);
- mpz_clear(q);
- return ret;
-}
diff --git a/lib/nettle/int/ecdsa-compute-k.h b/lib/nettle/int/ecdsa-compute-k.h
index be8beddb5d..207685763f 100644
--- a/lib/nettle/int/ecdsa-compute-k.h
+++ b/lib/nettle/int/ecdsa-compute-k.h
@@ -26,8 +26,6 @@
#include <gnutls/gnutls.h>
#include <nettle/bignum.h> /* includes gmp.h */
-int _gnutls_ecdsa_compute_k(mpz_t k, gnutls_ecc_curve_t curve, const mpz_t x,
- gnutls_mac_algorithm_t mac, const uint8_t *digest,
- size_t length);
+int _gnutls_ecc_curve_to_dsa_q(mpz_t q, gnutls_ecc_curve_t curve);
#endif /* GNUTLS_LIB_NETTLE_INT_ECDSA_COMPUTE_K_H */
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index 305548f4d1..dd6b9936a8 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -103,10 +103,16 @@ static void rnd_nonce_func(void *_ctx, size_t length, uint8_t *data)
}
}
-static void rnd_mpz_func(void *_ctx, size_t length, uint8_t *data)
+static void rnd_datum_func(void *ctx, size_t length, uint8_t *data)
{
- mpz_t *k = _ctx;
- nettle_mpz_get_str_256(length, data, *k);
+ gnutls_datum_t *d = ctx;
+
+ if (length > d->size) {
+ memset(data, 0, length - d->size);
+ memcpy(data + (length - d->size), d->data, d->size);
+ } else {
+ memcpy(data, d->data, length);
+ }
}
static void rnd_nonce_func_fallback(void *_ctx, size_t length, uint8_t *data)
@@ -1403,7 +1409,10 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_signature sig;
int curve_id = pk_params->curve;
const struct ecc_curve *curve;
- mpz_t k;
+ mpz_t q;
+ /* 521-bit elliptic curve generator at maximum */
+ uint8_t buf[(521 + 7) / 8];
+ gnutls_datum_t k = { NULL, 0 };
void *random_ctx;
nettle_random_func *random_func;
@@ -1447,17 +1456,32 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
not_approved = true;
}
- mpz_init(k);
+ mpz_init(q);
+
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
- ret = _gnutls_ecdsa_compute_k(
- k, curve_id, pk_params->params[ECC_K],
+ mp_limb_t h[DSA_COMPUTE_K_ITCH];
+
+ ret = _gnutls_ecc_curve_to_dsa_q(q, curve_id);
+ if (ret < 0)
+ goto ecdsa_cleanup;
+
+ ret = _gnutls_dsa_compute_k(
+ h, mpz_limbs_read(q), priv.p,
+ ecc_size(priv.ecc), ecc_bit_size(priv.ecc),
DIG_TO_MAC(sign_params->dsa_dig), vdata->data,
vdata->size);
if (ret < 0)
goto ecdsa_cleanup;
+
+ k.data = buf;
+ k.size = (ecc_bit_size(priv.ecc) + 7) / 8;
+
+ _gnutls_ecdsa_compute_k_finish(k.data, k.size, h,
+ ecc_size(priv.ecc));
+
random_ctx = &k;
- random_func = rnd_mpz_func;
+ random_func = rnd_datum_func;
} else {
random_ctx = NULL;
random_func = rnd_nonce_func;
@@ -1476,7 +1500,7 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
ecdsa_cleanup:
dsa_signature_clear(&sig);
ecc_scalar_zclear(&priv);
- mpz_clear(k);
+ mpz_clear(q);
if (ret < 0) {
gnutls_assert();
@@ -1488,7 +1512,9 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_params pub;
bigint_t priv;
struct dsa_signature sig;
- mpz_t k;
+ /* 512-bit DSA subgroup at maximum */
+ uint8_t buf[(512 + 7) / 8];
+ gnutls_datum_t k = { NULL, 0 };
void *random_ctx;
nettle_random_func *random_func;
@@ -1515,19 +1541,27 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
hash_len = vdata->size;
}
- mpz_init(k);
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
+ mp_limb_t h[DSA_COMPUTE_K_ITCH];
+
ret = _gnutls_dsa_compute_k(
- k, pub.q, TOMPZ(priv),
+ h, mpz_limbs_read(pub.q),
+ mpz_limbs_read(TOMPZ(priv)), mpz_size(pub.q),
+ mpz_sizeinbase(pub.q, 2),
DIG_TO_MAC(sign_params->dsa_dig), vdata->data,
vdata->size);
if (ret < 0)
goto dsa_fail;
- /* cancel-out dsa_sign's addition of 1 to random data */
- mpz_sub_ui(k, k, 1);
+
+ k.data = buf;
+ k.size = (mpz_sizeinbase(pub.q, 2) + 7) / 8;
+
+ _gnutls_dsa_compute_k_finish(k.data, k.size, h,
+ mpz_size(pub.q));
+
random_ctx = &k;
- random_func = rnd_mpz_func;
+ random_func = rnd_datum_func;
} else {
random_ctx = NULL;
random_func = rnd_nonce_func;
@@ -1544,7 +1578,6 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
dsa_fail:
dsa_signature_clear(&sig);
- mpz_clear(k);
if (ret < 0) {
gnutls_assert();
diff --git a/tests/sign-verify-deterministic.c b/tests/sign-verify-deterministic.c
index 6969b57a11..bdd5a49c7d 100644
--- a/tests/sign-verify-deterministic.c
+++ b/tests/sign-verify-deterministic.c
@@ -198,7 +198,7 @@ void doit(void)
&tests[i].msg, &signature);
if (ret < 0)
testfail("gnutls_pubkey_verify_data2\n");
- success(" - pass");
+ success(" - pass\n");
next:
gnutls_free(signature.data);
--
2.44.0

@ -1,36 +0,0 @@
From 945c2f10eeda441f32404d1328761e311915add0 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 23 Jan 2024 11:54:32 +0900
Subject: [PATCH] ktls: fix kernel version checking using utsname
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/system/ktls.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/system/ktls.c b/lib/system/ktls.c
index 8efb913cda..432c70c5a2 100644
--- a/lib/system/ktls.c
+++ b/lib/system/ktls.c
@@ -482,7 +482,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session,
return GNUTLS_E_INTERNAL_ERROR;
}
- if (strcmp(utsname.sysname, "Linux") == 0) {
+ if (strcmp(utsname.sysname, "Linux") != 0) {
return GNUTLS_E_INTERNAL_ERROR;
}
@@ -495,6 +495,9 @@ int _gnutls_ktls_set_keys(gnutls_session_t session,
return GNUTLS_E_INTERNAL_ERROR;
}
+ _gnutls_debug_log("Linux kernel version %lu.%lu has been detected\n",
+ major, minor);
+
/* setsockopt(SOL_TLS, TLS_RX) support added in 5.10 */
if (major < 5 || (major == 5 && minor < 10)) {
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
--
2.43.0

@ -1,410 +0,0 @@
From e369e67a62f44561d417cb233acc566cc696d82d Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 29 Jan 2024 13:52:46 +0900
Subject: [PATCH] gnutls_x509_trust_list_verify_crt2: remove length limit of
input
Previously, if cert_list_size exceeded DEFAULT_MAX_VERIFY_DEPTH, the
chain verification logic crashed with assertion failure. This patch
removes the restriction while keeping the maximum number of
retrieved certificates being DEFAULT_MAX_VERIFY_DEPTH.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/gnutls_int.h | 5 +-
lib/x509/common.c | 10 +-
lib/x509/verify-high.c | 51 ++++++----
tests/test-chains.h | 211 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 258 insertions(+), 19 deletions(-)
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index d8561ebe3a..8cf9a87157 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -232,7 +232,10 @@ typedef enum record_send_state_t {
#define MAX_PK_PARAM_SIZE 2048
-/* defaults for verification functions
+/* Defaults for verification functions.
+ *
+ * update many_icas in tests/test-chains.h when increasing
+ * DEFAULT_MAX_VERIFY_DEPTH.
*/
#define DEFAULT_MAX_VERIFY_DEPTH 16
#define DEFAULT_MAX_VERIFY_BITS (MAX_PK_PARAM_SIZE * 8)
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 2cc83c9155..705aa868bc 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1725,7 +1725,15 @@ unsigned int _gnutls_sort_clist(gnutls_x509_crt_t *clist,
bool insorted[DEFAULT_MAX_VERIFY_DEPTH]; /* non zero if clist[i] used in sorted list */
gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
- assert(clist_size <= DEFAULT_MAX_VERIFY_DEPTH);
+ /* Limit the number of certificates in the chain, to avoid DoS
+ * because of the O(n^2) sorting below. FIXME: Switch to a
+ * topological sort algorithm which should be linear to the
+ * number of certificates and subject-issuer relationships.
+ */
+ if (clist_size > DEFAULT_MAX_VERIFY_DEPTH) {
+ _gnutls_debug_log("too many certificates; skipping sorting\n");
+ return 1;
+ }
for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
issuer[i] = -1;
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 4e7361eb63..aacc24a7d8 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -25,7 +25,7 @@
#include "errors.h"
#include <libtasn1.h>
#include "global.h"
-#include "num.h" /* MAX */
+#include "num.h" /* MIN */
#include "tls-sig.h"
#include "str.h"
#include "datum.h"
@@ -1361,7 +1361,8 @@ int gnutls_x509_trust_list_verify_crt2(
int ret = 0;
unsigned int i;
size_t hash;
- gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
+ gnutls_x509_crt_t *cert_list_copy = NULL;
+ unsigned int cert_list_max_size = 0;
gnutls_x509_crt_t retrieved[DEFAULT_MAX_VERIFY_DEPTH];
unsigned int retrieved_size = 0;
const char *hostname = NULL, *purpose = NULL, *email = NULL;
@@ -1421,16 +1422,28 @@ int gnutls_x509_trust_list_verify_crt2(
}
}
- memcpy(sorted, cert_list, cert_list_size * sizeof(gnutls_x509_crt_t));
- cert_list = sorted;
+ /* Allocate extra for retrieved certificates. */
+ if (!INT_ADD_OK(cert_list_size, DEFAULT_MAX_VERIFY_DEPTH,
+ &cert_list_max_size))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ cert_list_copy = _gnutls_reallocarray(NULL, cert_list_max_size,
+ sizeof(gnutls_x509_crt_t));
+ if (!cert_list_copy)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ memcpy(cert_list_copy, cert_list,
+ cert_list_size * sizeof(gnutls_x509_crt_t));
+ cert_list = cert_list_copy;
records = gl_list_nx_create_empty(GL_LINKEDHASH_LIST, cert_eq,
cert_hashcode, NULL, false);
- if (records == NULL)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ if (records == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto cleanup;
+ }
- for (i = 0; i < cert_list_size &&
- cert_list_size <= DEFAULT_MAX_VERIFY_DEPTH;) {
+ for (i = 0; i < cert_list_size;) {
unsigned int sorted_size = 1;
unsigned int j, k;
gnutls_x509_crt_t issuer;
@@ -1442,8 +1455,7 @@ int gnutls_x509_trust_list_verify_crt2(
assert(sorted_size > 0);
- /* Remove duplicates. Start with index 1, as the first element
- * may be re-checked after issuer retrieval. */
+ /* Remove duplicates. */
for (j = 0; j < sorted_size; j++) {
if (gl_list_search(records, cert_list[i + j])) {
if (i + j < cert_list_size - 1) {
@@ -1495,13 +1507,15 @@ int gnutls_x509_trust_list_verify_crt2(
ret = retrieve_issuers(
list, cert_list[i - 1], &retrieved[retrieved_size],
- DEFAULT_MAX_VERIFY_DEPTH -
- MAX(retrieved_size, cert_list_size));
+ MIN(DEFAULT_MAX_VERIFY_DEPTH - retrieved_size,
+ cert_list_max_size - cert_list_size));
if (ret < 0) {
break;
} else if (ret > 0) {
assert((unsigned int)ret <=
- DEFAULT_MAX_VERIFY_DEPTH - cert_list_size);
+ DEFAULT_MAX_VERIFY_DEPTH - retrieved_size);
+ assert((unsigned int)ret <=
+ cert_list_max_size - cert_list_size);
memmove(&cert_list[i + ret], &cert_list[i],
(cert_list_size - i) *
sizeof(gnutls_x509_crt_t));
@@ -1517,8 +1531,10 @@ int gnutls_x509_trust_list_verify_crt2(
}
cert_list_size = shorten_clist(list, cert_list, cert_list_size);
- if (cert_list_size <= 0)
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ if (cert_list_size <= 0) {
+ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ goto cleanup;
+ }
hash = hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.data,
cert_list[cert_list_size - 1]->raw_issuer_dn.size);
@@ -1661,10 +1677,13 @@ int gnutls_x509_trust_list_verify_crt2(
}
cleanup:
+ gnutls_free(cert_list_copy);
for (i = 0; i < retrieved_size; i++) {
gnutls_x509_crt_deinit(retrieved[i]);
}
- gl_list_free(records);
+ if (records) {
+ gl_list_free(records);
+ }
return ret;
}
diff --git a/tests/test-chains.h b/tests/test-chains.h
index 3e559fecd5..a7fe1cdecc 100644
--- a/tests/test-chains.h
+++ b/tests/test-chains.h
@@ -23,7 +23,7 @@
#ifndef GNUTLS_TESTS_TEST_CHAINS_H
#define GNUTLS_TESTS_TEST_CHAINS_H
-#define MAX_CHAIN 10
+#define MAX_CHAIN 17
static const char *chain_with_no_subject_id_in_ca_ok[] = {
"-----BEGIN CERTIFICATE-----\n"
@@ -4383,6 +4383,213 @@ static const char *cross_signed_ca[] = {
NULL
};
+/* This assumes DEFAULT_MAX_VERIFY_DEPTH to be 16 */
+static const char *many_icas[] = {
+ /* Server */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBqzCCAV2gAwIBAgIUIK3+SD3GmqJlRLZ/ESyhTzkSDL8wBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowNzEbMBkGA1UEChMSR251VExTIHRlc3Qgc2VydmVyMRgwFgYD\n"
+ "VQQDEw90ZXN0LmdudXRscy5vcmcwKjAFBgMrZXADIQAWGjx45NIJiKFsNBxxRRjm\n"
+ "NxUT5KYK7xXr5HPVywwgLaOBkjCBjzAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGC\n"
+ "D3Rlc3QuZ251dGxzLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8E\n"
+ "BAMCB4AwHQYDVR0OBBYEFKgNAQWZPx76/vXqQOdIi5mTftsaMB8GA1UdIwQYMBaA\n"
+ "FDaPsY6WAGuRtrhYJE6Gk/bg5qbdMAUGAytlcANBAMIDh8aGcIIFDTUrzfV7tnkX\n"
+ "hHrxyFKBH/cApf6xcJQTfDXm23po627Ibp+WgLaWMY08Fn9Y2V6Ev8ADfqXNbQ8=\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA16 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUSnE0PKdm/dsnZSWBh5Ct4pS6DcwwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAxq9SI8vp0QH1dDBBuZW+t+bLLROppQbjSQ4O1BEonDOjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQ2j7GOlgBrkba4\n"
+ "WCROhpP24Oam3TAfBgNVHSMEGDAWgBRvdUKX0aw3nfUIdvivXGSfRO7zyjAFBgMr\n"
+ "ZXADQQBsI2Hc7X5hXoHTvk01qMc5a1I27QHAFRARJnvIQ15wxNS2LVLzGk+AUmwr\n"
+ "sOhBKAcVfS55uWtYdjoWQ80h238H\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA15 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUQk4XkgQVImnp6OPZas7ctwgBza4wBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAs3yVKLJd3sKbNVmj6Bxy2j1x025rksyQpZZWnCx5a+CjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRvdUKX0aw3nfUI\n"
+ "dvivXGSfRO7zyjAfBgNVHSMEGDAWgBRhGfUXYPh4YQsdtTWYUozLphGgfzAFBgMr\n"
+ "ZXADQQBXTtm56x6/pHXdW8dTvZLc/8RufNQrMlc23TCgX0apUnrZdTsNAb7OE4Uu\n"
+ "9PBuxK+CC9NL/BL2hXsKvAT+NWME\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA14 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUKfwz7UUYRvYlvqwmnLJlTOS9o1AwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAXbUetQ08t+F4+IcKL++HpeclqTxXZ7cG4mwqvHmTUEWjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRhGfUXYPh4YQsd\n"
+ "tTWYUozLphGgfzAfBgNVHSMEGDAWgBQYRQqO+V1kefF7QvNnFU1fX5H9+jAFBgMr\n"
+ "ZXADQQAiSHNMTLPFP3oa6q13Dj8jSxF9trQDJGM1ArWffFcPZUt2U4/ODHdcMTHx\n"
+ "kGwhIj+ghBlu6ykgu6J2wewCUooC\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA13 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUUKOs59gyCPAZzoC7zMZQSh6AnQgwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAmvqhj5GYqsXIpsr1BXBfD+2mTP/m/TEpKIYSZHM62dijYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQYRQqO+V1kefF7\n"
+ "QvNnFU1fX5H9+jAfBgNVHSMEGDAWgBQ27HzvP5hl2xR+LOzRcPfmY5ndXjAFBgMr\n"
+ "ZXADQQBrB3NkrYC7EQ74qgeesVOE71rW012dPOOKPAV0laR+JLEgsv9sfus+AdBF\n"
+ "WBNwR3KeYBTi/MFDuecxBHU2m5gD\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA12 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUUQooGfH21+sR7/pSgCWm13gg2H4wBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAK2of/B4wMpk6k/KdugC5dMS+jo2fseUM7/PvXkE6HASjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQ27HzvP5hl2xR+\n"
+ "LOzRcPfmY5ndXjAfBgNVHSMEGDAWgBSJDHU0Mj1Xr0e8ErCnRK24w7XwTTAFBgMr\n"
+ "ZXADQQDY8d2bAZpj7oGhdl2dBsCE48jEWj49da0PbgN12koAj3gf4hjMPd8G7p5z\n"
+ "8RsURAwQmCkE8ShvdNw/Qr2tDL0E\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA11 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUW9Dw0hU2pfjXhb5Stip+mk9SndIwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAn5ISjLVV6RBWsnxDWHDicpye7SjFwGOTwzF01/psiJ2jYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSJDHU0Mj1Xr0e8\n"
+ "ErCnRK24w7XwTTAfBgNVHSMEGDAWgBSR9UU27RI0XohiEgHDxNo/9HP4djAFBgMr\n"
+ "ZXADQQCfQg6MDHk71vhyrEo4/5PcLb2Li5F/FKURyux7snv2TbkSdInloAqca9UR\n"
+ "DtqHSLCNLXCNdSPr5QwIt5p29rsE\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA10 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUR4uTedG8e6MibKViQ3eX7QzXG1swBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAnslX04kSVOL5LAf1e+Ze3ggNnDJcEAxLDk8I/IhyjTyjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSR9UU27RI0Xohi\n"
+ "EgHDxNo/9HP4djAfBgNVHSMEGDAWgBRC7US5gJYnvd5F7EN+C4anMgd2NzAFBgMr\n"
+ "ZXADQQDo+jHt07Tvz3T5Lbz6apBrSln8xKYfJk2W1wP85XAnf7sZT9apM1bS4EyD\n"
+ "Kckw+KG+9x7myOZz6AXJgZB5OGAO\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA9 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUSIIIRjrNpE+kEPkiJMOqaNAazvQwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAZKy7p1Gn4W/reRxKJN99+QkHt2q9aELktCKe5PqrX5ejYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRC7US5gJYnvd5F\n"
+ "7EN+C4anMgd2NzAfBgNVHSMEGDAWgBSOhR7Ornis2x8g0J+bvTTwMnW60zAFBgMr\n"
+ "ZXADQQA0MEcC4FgKZEAfalVpApU2to0G158MVz/WTNcSc7fnl8ifJ/g56dVHL1jr\n"
+ "REvC/S28dn/CGAlbVXUAgxnHAbgE\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA8 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUGGFSgD95vOTSj7iFxfXA5vq6vsYwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAg3W/bTdW0fR32NeZEVMXICpa30d7rSdddLOYDvqqUO+jYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSOhR7Ornis2x8g\n"
+ "0J+bvTTwMnW60zAfBgNVHSMEGDAWgBT3zK8Hbn9aVTAOOFY6RSxJ2o5x2jAFBgMr\n"
+ "ZXADQQBl4gnzE463iMFg57gPvjHdVzA39sJBpiu0kUGfRcLnoRI/VOaLcx7WnJ9+\n"
+ "c3KxPZBec76EdIoQDkTmI6m2FIAM\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA7 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUGktMGXhNuaMhKyAlecymmLD+/GIwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEA/Z1oc76hOQ0Hi+2hePaGIntnMIDqBlb7RDMjRpYONP2jYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBT3zK8Hbn9aVTAO\n"
+ "OFY6RSxJ2o5x2jAfBgNVHSMEGDAWgBSPae3JUN3jP0NgUJqDV3eYxcaM3DAFBgMr\n"
+ "ZXADQQBMkwKaUZlvG/hax8rv3nnDv8kJOr6KVHBnxSx3hZ+8HIBT7GFm1+YDeYOB\n"
+ "jhNg66kyeFPGXXBCe+mvNQFFjCEE\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA6 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUKn3gz5lAUpKqWlHKLKYDbOJ4rygwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAZ/eD4eTe91ddvHusm7YlLPxU4ByGFc6suAmlP1CxXkWjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSPae3JUN3jP0Ng\n"
+ "UJqDV3eYxcaM3DAfBgNVHSMEGDAWgBT9f/qSI/jhxvGI7aMtkpraDcjBnjAFBgMr\n"
+ "ZXADQQAMRnkmRhnLGdmJaY8B42gfyaAsqCMyds/Tw4OHYy+N48XuAxRjKkhf3szC\n"
+ "0lY71oU043mNP1yx/dzAuCTrVSgI\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA5 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUEgEYbBXXEyGv3vOq10JQv1SBiUUwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAs2xEDPw8RVal53nX9GVwUd1blq1wjtVFC8S1V7up7MWjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBT9f/qSI/jhxvGI\n"
+ "7aMtkpraDcjBnjAfBgNVHSMEGDAWgBRBVkLu9BmCKz7HNI8md4vPpoE/7jAFBgMr\n"
+ "ZXADQQCCufAyLijtzzmeCuO3K50rBSbGvB3FQfep7g6kVsQKM3bw/olWK5/Ji0dD\n"
+ "ubJ0cFl1FmfAda7aVxLBtJOvO6MI\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA4 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIULj8GkaHw+92HuOTnXnXlxCy3VrEwBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAiedxh4dvtwDellMAHc/pZH0MAOXobRenTUgF1yj5l12jYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRBVkLu9BmCKz7H\n"
+ "NI8md4vPpoE/7jAfBgNVHSMEGDAWgBSDtNRgQ36KwW/ASaMyr6WeDt0STDAFBgMr\n"
+ "ZXADQQDL8U2ckzur7CktdrVUNvfLhVCOz33d/62F28vQFHUa8h/4h+Mi1MMbXOKT\n"
+ "1bL2TvpFpU7Fx/vcIPXDielVqr4C\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA3 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUQXl74TDDw6MQRMbQUSPa6Qrvba8wBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEA7l0jQ0f4fJRw7Qja/Hz2qn8y91SI7CokxhSf+FT+9M6jYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSDtNRgQ36KwW/A\n"
+ "SaMyr6WeDt0STDAfBgNVHSMEGDAWgBQ2inEK4KH6ATftmybxKE1dZUzOozAFBgMr\n"
+ "ZXADQQCnP7Oqx1epGnFnO7TrTJwcUukXDEYsINve2GeUsi8HEIeKKlMcLZ2Cnaj7\n"
+ "5v9NGuWh3QJpmmSGpEemiv8dJc4A\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA2 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBYTCCAROgAwIBAgIUP7Nmof8H2F1LyDkjqlYIUpGdXE8wBQYDK2VwMB0xGzAZ\n"
+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n"
+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n"
+ "K2VwAyEAkW9Rod3CXAnha6nlaHkDbCOegq94lgmjqclA9sOIt3yjYzBhMA8GA1Ud\n"
+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQ2inEK4KH6ATft\n"
+ "mybxKE1dZUzOozAfBgNVHSMEGDAWgBRPq/CQlK/zuXkjZvTCibu+vejD+jAFBgMr\n"
+ "ZXADQQBU+A+uF0yrtO/yv9cRUdCoL3Y1NKM35INg8BQDnkv724cW9zk1x0q9Fuou\n"
+ "zvfSVb8S3vT8fF5ZDOxarQs6ZH0C\n"
+ "-----END CERTIFICATE-----\n",
+ /* ICA1 */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBXTCCAQ+gAwIBAgIUfUWP+AQHpdFTRKTf21mMzjaJsp0wBQYDK2VwMBkxFzAV\n"
+ "BgNVBAMTDkdudVRMUyB0ZXN0IENBMCAXDTI0MDMxMjIyNTMzOVoYDzk5OTkxMjMx\n"
+ "MjM1OTU5WjAdMRswGQYDVQQDDBJHbnVUTFMgdGVzdCBJQ0EgJGkwKjAFBgMrZXAD\n"
+ "IQAVmfBAvLbT+pTD24pQrr6S0jEIFIV/qOv93yYvAUzpzKNjMGEwDwYDVR0TAQH/\n"
+ "BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFE+r8JCUr/O5eSNm9MKJ\n"
+ "u7696MP6MB8GA1UdIwQYMBaAFAFpt5wrFsqCtHc4PpluPDvwcxQLMAUGAytlcANB\n"
+ "AC6+XZnthjlUD0TbBKRF3qT5if3Pp29Bgvutw8859unzUZW8FkHg5KeDBj9ncgJc\n"
+ "O2tFnNH2hV6LDPJzU0rtLQc=\n"
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
+static const char *many_icas_ca[] = {
+ /* CA (self-signed) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBNzCB6qADAgECAhRjaokcQwcrtW8tjuVFz3A33F8POjAFBgMrZXAwGTEXMBUG\n"
+ "A1UEAxMOR251VExTIHRlc3QgQ0EwIBcNMjQwMzEyMjI1MzM5WhgPOTk5OTEyMzEy\n"
+ "MzU5NTlaMBkxFzAVBgNVBAMTDkdudVRMUyB0ZXN0IENBMCowBQYDK2VwAyEAvoxP\n"
+ "TNdbWktxA8qQNNH+25Cx9rzP+DxLGeI/7ODwrQGjQjBAMA8GA1UdEwEB/wQFMAMB\n"
+ "Af8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQBabecKxbKgrR3OD6Zbjw78HMU\n"
+ "CzAFBgMrZXADQQCP5IUD74M7WrUx20uqzrzuj+s2jnBVmLQfWf/Ucetx+oTRFeq4\n"
+ "xZB/adWhycSeJUAB1zKqYUV9hgT8FWHbnHII\n"
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
@@ -4696,6 +4903,8 @@ static struct {
1620118136, 1 },
{ "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0,
1704955300 },
+ { "many intermediates - ok", many_icas, many_icas_ca, 0, 0, 0,
+ 1710284400 },
{ NULL, NULL, NULL, 0, 0 }
};
--
2.44.0

@ -0,0 +1,165 @@
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

@ -0,0 +1,170 @@
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

@ -0,0 +1,334 @@
From 24a4cb910a51f35dff89842e8cce27f88e8e78c3 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Wed, 24 Aug 2022 17:19:57 +0900
Subject: [PATCH] Clear any intermediate data allocate on stack
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
cbc.c | 3 +++
cfb.c | 13 +++++++++++++
ctr.c | 4 ++++
ctr16.c | 2 ++
ecc-random.c | 3 +++
ecdsa-keygen.c | 2 ++
ecdsa-sign.c | 2 ++
ed25519-sha512-sign.c | 2 ++
ed448-shake256-sign.c | 2 ++
gostdsa-sign.c | 2 ++
hmac.c | 10 +++++++---
nettle-internal.h | 5 +++++
pbkdf2.c | 5 ++++-
pss-mgf1.c | 5 ++++-
pss.c | 4 ++++
15 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/cbc.c b/cbc.c
index 76b6492d..b9da3aa0 100644
--- a/cbc.c
+++ b/cbc.c
@@ -128,6 +128,9 @@ cbc_decrypt(const void *ctx, nettle_cipher_func *f,
length - block_size);
/* Writes first block. */
memxor3(dst, buffer, initial_iv, block_size);
+
+ TMP_CLEAR(buffer, buffer_size);
+ TMP_CLEAR(initial_iv, block_size);
}
}
diff --git a/cfb.c b/cfb.c
index b9da3159..b1b01b9e 100644
--- a/cfb.c
+++ b/cfb.c
@@ -83,6 +83,8 @@ cfb_encrypt(const void *ctx, nettle_cipher_func *f,
/* We do not care about updating IV here. This is the last call in
* message sequence and one has to set IV afterwards anyway */
}
+
+ TMP_CLEAR(buffer, block_size);
}
/* Don't allocate any more space than this on the stack */
@@ -115,6 +117,8 @@ cfb_decrypt(const void *ctx, nettle_cipher_func *f,
f(ctx, block_size, buffer, iv);
memxor3(dst + length, src + length, buffer, left);
+
+ TMP_CLEAR(buffer, block_size);
}
}
else
@@ -160,6 +164,9 @@ cfb_decrypt(const void *ctx, nettle_cipher_func *f,
f(ctx, block_size, buffer, iv);
memxor(dst, buffer, left);
}
+
+ TMP_CLEAR(buffer, buffer_size);
+ TMP_CLEAR(initial_iv, block_size);
}
}
@@ -196,6 +203,9 @@ cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
pos ++;
}
memcpy(iv, buffer + pos, block_size);
+
+ TMP_CLEAR(buffer, block_size * 2);
+ TMP_CLEAR(outbuf, block_size);
}
void
@@ -235,4 +245,7 @@ cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
}
memcpy(iv, buffer + i, block_size);
+
+ TMP_CLEAR(buffer, block_size * 2);
+ TMP_CLEAR(outbuf, block_size * 2);
}
diff --git a/ctr.c b/ctr.c
index 8c6b4626..217d1abb 100644
--- a/ctr.c
+++ b/ctr.c
@@ -137,6 +137,8 @@ ctr_crypt(const void *ctx, nettle_cipher_func *f,
f(ctx, block_size, block, ctr);
INCREMENT(block_size, ctr);
memxor3(dst + filled, src + filled, block, length - filled);
+
+ TMP_CLEAR(block, block_size);
}
}
else
@@ -173,5 +175,7 @@ ctr_crypt(const void *ctx, nettle_cipher_func *f,
INCREMENT(block_size, ctr);
memxor(dst, buffer, length);
}
+
+ TMP_CLEAR(buffer, buffer_size);
}
}
diff --git a/ctr16.c b/ctr16.c
index d744d2a9..ec0abd72 100644
--- a/ctr16.c
+++ b/ctr16.c
@@ -102,5 +102,7 @@ _nettle_ctr_crypt16(const void *ctx, nettle_cipher_func *f,
done:
memxor3 (dst + i, src + i, buffer->b, length - i);
}
+
+ TMP_CLEAR(buffer, MIN(blocks, CTR_BUFFER_LIMIT / 16));
}
}
diff --git a/ecc-random.c b/ecc-random.c
index a7b48d6a..676f5933 100644
--- a/ecc-random.c
+++ b/ecc-random.c
@@ -36,6 +36,7 @@
#endif
#include <assert.h>
+#include <string.h>
#include "ecc.h"
#include "ecc-internal.h"
@@ -79,4 +80,6 @@ ecc_scalar_random (struct ecc_scalar *x,
TMP_ALLOC (scratch, ECC_MOD_RANDOM_ITCH (x->ecc->q.size));
ecc_mod_random (&x->ecc->q, x->p, random_ctx, random, scratch);
+
+ TMP_CLEAR (scratch, ECC_MOD_RANDOM_ITCH (x->ecc->q.size));
}
diff --git a/ecdsa-keygen.c b/ecdsa-keygen.c
index 870282b0..05dd827a 100644
--- a/ecdsa-keygen.c
+++ b/ecdsa-keygen.c
@@ -59,4 +59,6 @@ ecdsa_generate_keypair (struct ecc_point *pub,
ecc_mod_random (&ecc->q, key->p, random_ctx, random, p);
ecc->mul_g (ecc, p, key->p, p + 3*ecc->p.size);
ecc->h_to_a (ecc, 0, pub->p, p, p + 3*ecc->p.size);
+
+ TMP_CLEAR (p, itch);
}
diff --git a/ecdsa-sign.c b/ecdsa-sign.c
index e6fb3287..e6b960bf 100644
--- a/ecdsa-sign.c
+++ b/ecdsa-sign.c
@@ -68,4 +68,6 @@ ecdsa_sign (const struct ecc_scalar *key,
mpz_limbs_finish (signature->s, size);
}
while (mpz_sgn (signature->r) == 0 || mpz_sgn (signature->s) == 0);
+
+ TMP_CLEAR (k, size + ECC_ECDSA_SIGN_ITCH (size));
}
diff --git a/ed25519-sha512-sign.c b/ed25519-sha512-sign.c
index 389a157e..52a46ea5 100644
--- a/ed25519-sha512-sign.c
+++ b/ed25519-sha512-sign.c
@@ -38,6 +38,7 @@
#include "ecc-internal.h"
#include "sha2.h"
+#include <string.h>
void
ed25519_sha512_sign (const uint8_t *pub,
@@ -61,6 +62,7 @@ ed25519_sha512_sign (const uint8_t *pub,
length, msg, signature, scratch_out);
gmp_free_limbs (scratch, itch);
+ explicit_bzero (digest, sizeof(digest));
#undef k1
#undef k2
#undef scratch_out
diff --git a/ed448-shake256-sign.c b/ed448-shake256-sign.c
index c524593d..01abf457 100644
--- a/ed448-shake256-sign.c
+++ b/ed448-shake256-sign.c
@@ -39,6 +39,7 @@
#include "ecc-internal.h"
#include "eddsa-internal.h"
#include "sha3.h"
+#include <string.h>
void
ed448_shake256_sign (const uint8_t *pub,
@@ -63,6 +64,7 @@ ed448_shake256_sign (const uint8_t *pub,
length, msg, signature, scratch_out);
gmp_free_limbs (scratch, itch);
+ explicit_bzero (digest, sizeof(digest));
#undef k1
#undef k2
#undef scratch_out
diff --git a/gostdsa-sign.c b/gostdsa-sign.c
index 892c0742..a7e0c21d 100644
--- a/gostdsa-sign.c
+++ b/gostdsa-sign.c
@@ -71,4 +71,6 @@ gostdsa_sign (const struct ecc_scalar *key,
mpz_limbs_finish (signature->s, size);
}
while (mpz_sgn (signature->r) == 0 || mpz_sgn (signature->s) == 0);
+
+ TMP_CLEAR (k, size + ECC_GOSTDSA_SIGN_ITCH (size));
}
diff --git a/hmac.c b/hmac.c
index ea356970..6a55551b 100644
--- a/hmac.c
+++ b/hmac.c
@@ -53,6 +53,8 @@ hmac_set_key(void *outer, void *inner, void *state,
{
TMP_DECL(pad, uint8_t, NETTLE_MAX_HASH_BLOCK_SIZE);
TMP_ALLOC(pad, hash->block_size);
+ TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
+ TMP_ALLOC(digest, hash->digest_size);
hash->init(outer);
hash->init(inner);
@@ -62,9 +64,6 @@ hmac_set_key(void *outer, void *inner, void *state,
/* Reduce key to the algorithm's hash size. Use the area pointed
* to by state for the temporary state. */
- TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
- TMP_ALLOC(digest, hash->digest_size);
-
hash->init(state);
hash->update(state, key_length, key);
hash->digest(state, hash->digest_size, digest);
@@ -86,6 +85,9 @@ hmac_set_key(void *outer, void *inner, void *state,
hash->update(inner, hash->block_size, pad);
memcpy(state, inner, hash->context_size);
+
+ TMP_CLEAR(pad, hash->block_size);
+ TMP_CLEAR(digest, hash->digest_size);
}
void
@@ -112,4 +114,6 @@ hmac_digest(const void *outer, const void *inner, void *state,
hash->digest(state, length, dst);
memcpy(state, inner, hash->context_size);
+
+ TMP_CLEAR(digest, hash->digest_size);
}
diff --git a/nettle-internal.h b/nettle-internal.h
index c41f3ee0..62b89e11 100644
--- a/nettle-internal.h
+++ b/nettle-internal.h
@@ -76,6 +76,11 @@
do { assert((size_t)(size) <= (sizeof(name))); } while (0)
#endif
+#include <string.h> /* explicit_bzero */
+
+#define TMP_CLEAR(name, size) (explicit_bzero (name, sizeof (*name) * (size)))
+#define TMP_CLEAR_ALIGN(name, size) (explicit_bzero (name, size))
+
/* Limits that apply to systems that don't have alloca */
#define NETTLE_MAX_HASH_BLOCK_SIZE 144 /* For sha3_224*/
#define NETTLE_MAX_HASH_DIGEST_SIZE 64
diff --git a/pbkdf2.c b/pbkdf2.c
index 291d138a..a8ecba5b 100644
--- a/pbkdf2.c
+++ b/pbkdf2.c
@@ -92,8 +92,11 @@ pbkdf2 (void *mac_ctx,
if (length <= digest_size)
{
memcpy (dst, T, length);
- return;
+ break;
}
memcpy (dst, T, digest_size);
}
+
+ TMP_CLEAR (U, digest_size);
+ TMP_CLEAR (T, digest_size);
}
diff --git a/pss-mgf1.c b/pss-mgf1.c
index 3f5e204b..3644c642 100644
--- a/pss-mgf1.c
+++ b/pss-mgf1.c
@@ -66,8 +66,11 @@ pss_mgf1(const void *seed, const struct nettle_hash *hash,
if (length <= hash->digest_size)
{
hash->digest(state, length, mask);
- return;
+ break;
}
hash->digest(state, hash->digest_size, mask);
}
+
+ TMP_CLEAR(h, hash->digest_size);
+ TMP_CLEAR_ALIGN(state, hash->context_size);
}
diff --git a/pss.c b/pss.c
index d28e7b13..8106ebf2 100644
--- a/pss.c
+++ b/pss.c
@@ -77,6 +77,7 @@ pss_encode_mgf1(mpz_t m, size_t bits,
if (key_size < hash->digest_size + salt_length + 2)
{
TMP_GMP_FREE(em);
+ TMP_CLEAR_ALIGN(state, hash->context_size);
return 0;
}
@@ -111,6 +112,7 @@ pss_encode_mgf1(mpz_t m, size_t bits,
nettle_mpz_set_str_256_u(m, key_size, em);
TMP_GMP_FREE(em);
+ TMP_CLEAR_ALIGN(state, hash->context_size);
return 1;
}
@@ -194,5 +196,7 @@ pss_verify_mgf1(const mpz_t m, size_t bits,
ret = 1;
cleanup:
TMP_GMP_FREE(em);
+ TMP_CLEAR(h2, hash->digest_size);
+ TMP_CLEAR_ALIGN(state, hash->context_size);
return ret;
}
--
2.41.0

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save