]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Make XTS key check failure not fatal
authorZoltan Fridrich <zfridric@redhat.com>
Thu, 29 Sep 2022 13:31:28 +0000 (15:31 +0200)
committerZoltan Fridrich <zfridric@redhat.com>
Mon, 3 Oct 2022 08:47:59 +0000 (10:47 +0200)
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
.gitignore
lib/accelerated/x86/aes-xts-x86-aesni.c
lib/nettle/cipher.c
tests/Makefile.am
tests/xts-key-check.c [new file with mode: 0644]

index 4225452b8d5ad689c7f04dd4d41b00affcdabb2e..18d091e21d84f2133aa3b5e54ee89d664372acdc 100644 (file)
@@ -929,6 +929,7 @@ tests/x509sign-verify-gost
 tests/x509sign-verify-rsa
 tests/x509sign-verify2
 tests/x509signself
+tests/xts-key-check
 tests/gnutls_ktls
 tests/record-sendfile
 *.tmp
index 0588d0bd55f407c040f45141932453fad9179d0e..d6936a688dc3c571289c66a8028195f92d6b28c1 100644 (file)
@@ -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);
                }
        }
index c9c59fb0baf79eea9ffba562d4cf3ea593a9f259..9c2ce19e7e72219e47dc21b3edcf88ddd04641a7 100644 (file)
@@ -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
index 3e126f0046b02a354f385e3db9a02b1e7bca984e..1122886b31f73219c15e48e0b82d2307f6ef88c9 100644 (file)
@@ -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 (file)
index 0000000..a3bea5a
--- /dev/null
@@ -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);
+}