gnutls/gnutls-Make-XTS-key-check-failure-not-fatal.patch
Pedro Monreal Gonzalez 443be2c653 Accepting request 1009758 from home:pmonrealgonzalez:branches:security:tls
- Update to 3.7.8:
  * libgnutls: In FIPS140 mode, RSA signature verification is an
    approved operation if the key has modulus with known sizes
    (1024, 1280, 1536, and 1792 bits), in addition to any modulus
    sizes larger than 2048 bits, according to SP800-131A rev2.
  * libgnutls: gnutls_session_channel_binding performs additional
    checks when GNUTLS_CB_TLS_EXPORTER is requested. According to
    RFC9622 4.2, the "tls-exporter" channel binding is only usable
    when the handshake is bound to a unique master secret (i.e.,
    either TLS 1.3 or extended master secret extension is
    negotiated). Otherwise the function now returns error.
  * libgnutls: usage of the following functions, which are designed
    to loosen restrictions imposed by allowlisting mode of
    configuration, has been additionally restricted. Invoking
    them is now only allowed if system-wide TLS priority string
    has not been initialized yet:
      - gnutls_digest_set_secure
      - gnutls_sign_set_secure
      - gnutls_sign_set_secure_for_certs
      - gnutls_protocol_set_enabled
  * Delete gnutls-3.6.6-set_guile_site_dir.patch and use the
    --with-guile-extension-dir configure option to properly
    handle the guile extension directory.
  * Rebase gnutls-Make-XTS-key-check-failure-not-fatal.patch
  * Update gnutls.keyring
  * Add a build depencency on gtk-doc required by autoreconf

OBS-URL: https://build.opensuse.org/request/show/1009758
OBS-URL: https://build.opensuse.org/package/show/security:tls/gnutls?expand=0&rev=77
2022-10-11 12:44:03 +00:00

243 lines
7.9 KiB
Diff

From 00fff0aad2b606801704046042aa3b2b24f07d63 Mon Sep 17 00:00:00 2001
From: Zoltan Fridrich <zfridric@redhat.com>
Date: Thu, 29 Sep 2022 15:31:28 +0200
Subject: [PATCH] Make XTS key check failure not fatal
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
---
lib/accelerated/x86/aes-xts-x86-aesni.c | 1 -
lib/nettle/cipher.c | 73 ++++++++---------------
tests/Makefile.am | 2 +-
tests/xts-key-check.c | 78 +++++++++++++++++++++++++
5 files changed, 103 insertions(+), 52 deletions(-)
create mode 100644 tests/xts-key-check.c
diff --git a/lib/accelerated/x86/aes-xts-x86-aesni.c b/lib/accelerated/x86/aes-xts-x86-aesni.c
index 0588d0bd55..d6936a688d 100644
--- a/lib/accelerated/x86/aes-xts-x86-aesni.c
+++ b/lib/accelerated/x86/aes-xts-x86-aesni.c
@@ -73,7 +73,6 @@ x86_aes_xts_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
/* Check key block according to FIPS-140-2 IG A.9 */
if (_gnutls_fips_mode_enabled()){
if (gnutls_memcmp(key, key + (keysize / 2), keysize / 2) == 0) {
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
}
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
index c9c59fb0ba..9c2ce19e7e 100644
--- a/lib/nettle/cipher.c
+++ b/lib/nettle/cipher.c
@@ -448,12 +448,14 @@ _gcm_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
length, dst, src);
}
-static void _des_set_key(struct des_ctx *ctx, const uint8_t *key)
+static void
+_des_set_key(struct des_ctx *ctx, const uint8_t *key)
{
des_set_key(ctx, key);
}
-static void _des3_set_key(struct des3_ctx *ctx, const uint8_t *key)
+static void
+_des3_set_key(struct des3_ctx *ctx, const uint8_t *key)
{
des3_set_key(ctx, key);
}
@@ -476,50 +478,6 @@ _cfb8_decrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
length, dst, src);
}
-static void
-_xts_aes128_set_encrypt_key(struct xts_aes128_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes128_set_encrypt_key(xts_key, key);
-}
-
-static void
-_xts_aes128_set_decrypt_key(struct xts_aes128_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes128_set_decrypt_key(xts_key, key);
-}
-
-static void
-_xts_aes256_set_encrypt_key(struct xts_aes256_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes256_set_encrypt_key(xts_key, key);
-}
-
-static void
-_xts_aes256_set_decrypt_key(struct xts_aes256_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes256_set_decrypt_key(xts_key, key);
-}
-
static void
_xts_aes128_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
const uint8_t * src)
@@ -1041,8 +999,8 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
.ctx_size = sizeof(struct xts_aes128_key),
.encrypt = _xts_aes128_encrypt,
.decrypt = _xts_aes128_decrypt,
- .set_encrypt_key = (nettle_set_key_func*)_xts_aes128_set_encrypt_key,
- .set_decrypt_key = (nettle_set_key_func*)_xts_aes128_set_decrypt_key,
+ .set_encrypt_key = (nettle_set_key_func*)xts_aes128_set_encrypt_key,
+ .set_decrypt_key = (nettle_set_key_func*)xts_aes128_set_decrypt_key,
.max_iv_size = AES_BLOCK_SIZE,
},
{ .algo = GNUTLS_CIPHER_AES_256_XTS,
@@ -1052,8 +1010,8 @@ static const struct nettle_cipher_st builtin_ciphers[] = {
.ctx_size = sizeof(struct xts_aes256_key),
.encrypt = _xts_aes256_encrypt,
.decrypt = _xts_aes256_decrypt,
- .set_encrypt_key = (nettle_set_key_func*)_xts_aes256_set_encrypt_key,
- .set_decrypt_key = (nettle_set_key_func*)_xts_aes256_set_decrypt_key,
+ .set_encrypt_key = (nettle_set_key_func*)xts_aes256_set_encrypt_key,
+ .set_decrypt_key = (nettle_set_key_func*)xts_aes256_set_decrypt_key,
.max_iv_size = AES_BLOCK_SIZE,
},
{ .algo = GNUTLS_CIPHER_AES_128_SIV,
@@ -1144,6 +1102,21 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize)
return 0;
}
+ switch (ctx->cipher->algo) {
+ case GNUTLS_CIPHER_AES_128_XTS:
+ if (_gnutls_fips_mode_enabled() &&
+ gnutls_memcmp(key, (char *)key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ break;
+ case GNUTLS_CIPHER_AES_256_XTS:
+ if (_gnutls_fips_mode_enabled() &&
+ gnutls_memcmp(key, (char *)key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ break;
+ default:
+ break;
+ }
+
if (ctx->enc)
ctx->cipher->set_encrypt_key(ctx->ctx_ptr, key);
else
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3e126f0046..1122886b31 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
tls13-without-timeout-func buffer status-request-revoked \
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
- x509-upnconstraint cipher-padding pkcs7-verify-double-free \
+ x509-upnconstraint xts-key-check cipher-padding pkcs7-verify-double-free \
fips-rsa-sizes
ctests += tls-channel-binding
diff --git a/tests/xts-key-check.c b/tests/xts-key-check.c
new file mode 100644
index 0000000000..a3bea5abca
--- /dev/null
+++ b/tests/xts-key-check.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * Author: Zoltan Fridrich
+ *
+ * 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 General Public License
+ * along with GnuTLS. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnutls/crypto.h>
+
+#include "utils.h"
+
+static void test_xts_check(gnutls_cipher_algorithm_t alg)
+{
+ int ret;
+ gnutls_cipher_hd_t ctx;
+ gnutls_datum_t key, iv;
+
+ iv.size = gnutls_cipher_get_iv_size(alg);
+ iv.data = gnutls_malloc(iv.size);
+ if (iv.data == NULL)
+ fail("Error: %s\n", gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
+ gnutls_memset(iv.data, 0xf0, iv.size);
+
+ key.size = gnutls_cipher_get_key_size(alg);
+ key.data = gnutls_malloc(key.size);
+ if (key.data == NULL) {
+ gnutls_free(iv.data);
+ fail("Error: %s\n", gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
+ }
+ gnutls_memset(key.data, 0xf0, key.size);
+
+ ret = gnutls_cipher_init(&ctx, alg, &key, &iv);
+ if (ret == GNUTLS_E_SUCCESS) {
+ gnutls_cipher_deinit(ctx);
+ gnutls_free(iv.data);
+ gnutls_free(key.data);
+ fail("cipher initialization should fail for key1 == key2\n");
+ }
+
+ key.data[0] = 0xff;
+
+ ret = gnutls_cipher_init(&ctx, alg, &key, &iv);
+ gnutls_free(iv.data);
+ gnutls_free(key.data);
+
+ if (ret == GNUTLS_E_SUCCESS)
+ gnutls_cipher_deinit(ctx);
+ else
+ fail("cipher initialization should succeed with key1 != key2"
+ "\n%s\n", gnutls_strerror(ret));
+}
+
+void doit(void)
+{
+ if (!gnutls_fips140_mode_enabled())
+ exit(77);
+
+ test_xts_check(GNUTLS_CIPHER_AES_128_XTS);
+ test_xts_check(GNUTLS_CIPHER_AES_256_XTS);
+}
--
GitLab