|
|
Message-ID: <20200501230913.GB915@sol.localdomain>
Date: Fri, 1 May 2020 16:09:13 -0700
From: Eric Biggers <ebiggers@...nel.org>
To: "Jason A. Donenfeld" <Jason@...c4.com>
Cc: dhowells@...hat.com, keyrings@...r.kernel.org,
Andy Lutomirski <luto@...nel.org>,
Greg KH <gregkh@...uxfoundation.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
kernel-hardening@...ts.openwall.com
Subject: Re: [PATCH] security/keys: rewrite big_key crypto to use Zinc
On Fri, May 01, 2020 at 04:23:57PM -0600, Jason A. Donenfeld wrote:
> A while back, I noticed that the crypto and crypto API usage in big_keys
> were entirely broken in multiple ways, so I rewrote it. Now, I'm
> rewriting it again, but this time using Zinc's ChaCha20Poly1305
> function. This makes the file considerably more simple; the diffstat
> alone should justify this commit. It also should be faster, since it no
> longer requires a mutex around the "aead api object" (nor allocations),
> allowing us to encrypt multiple items in parallel. We also benefit from
> being able to pass any type of pointer, so we can get rid of the
> ridiculously complex custom page allocator that big_key really doesn't
> need.
>
> Cc: David Howells <dhowells@...hat.com>
> Cc: Andy Lutomirski <luto@...nel.org>
> Cc: Greg KH <gregkh@...uxfoundation.org>
> Cc: Linus Torvalds <torvalds@...ux-foundation.org>
> Cc: kernel-hardening@...ts.openwall.com
> Signed-off-by: Jason A. Donenfeld <Jason@...c4.com>
> ---
> I finally got around to updating this patch from the mailing list posts
> back in 2017-2018, using the library interface that we eventually merged
> in 2019. I haven't retested this for functionality, but nothing much has
> changed, so I suspect things should still be good to go.
>
> security/keys/Kconfig | 4 +-
> security/keys/big_key.c | 230 +++++-----------------------------------
> 2 files changed, 28 insertions(+), 206 deletions(-)
>
> diff --git a/security/keys/Kconfig b/security/keys/Kconfig
> index 47c041563d41..5aa442490d52 100644
> --- a/security/keys/Kconfig
> +++ b/security/keys/Kconfig
> @@ -60,9 +60,7 @@ config BIG_KEYS
> bool "Large payload keys"
> depends on KEYS
> depends on TMPFS
> - select CRYPTO
> - select CRYPTO_AES
> - select CRYPTO_GCM
> + select CRYPTO_LIB_CHACHA20POLY1305
> help
> This option provides support for holding large keys within the kernel
> (for example Kerberos ticket caches). The data may be stored out to
The 'select CRYPTO' is actually still needed because CRYPTO_LIB_CHACHA20POLY1305
is under the CRYPTO menuconfig:
make allnoconfig
cat >> .config << EOF
CONFIG_SHMEM=y
CONFIG_TMPFS=y
CONFIG_KEYS=y
CONFIG_BIG_KEYS=y
EOF
make olddefconfig
WARNING: unmet direct dependencies detected for CRYPTO_LIB_CHACHA20POLY1305
Depends on [n]: CRYPTO [=n] && (CRYPTO_ARCH_HAVE_LIB_CHACHA [=n] || !CRYPTO_ARCH_HAVE_LIB_CHACHA [=n]) && (CRYPTO_ARCH_HAVE_LIB_POLY1305 [=n] || !CRYPTO_ARCH_HAVE_LIB_POLY1305 [=n])
Selected by [y]:
- BIG_KEYS [=y] && KEYS [=y] && TMPFS [=y]
Maybe the 'source "lib/crypto/Kconfig"' in crypto/Kconfig should be moved to
lib/Kconfig so that it's under "Library routines" and the crypto library options
can be selected without the full CRYPTO framework?
But lib/crypto/libchacha.c uses crypto_xor_cpy(), and
lib/crypto/chacha20poly1305.c uses crypto_memneq(). So those functions would
first need to be pulled into lib/crypto/ too.
> @@ -265,7 +121,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
> *path = file->f_path;
> path_get(path);
> fput(file);
> - big_key_free_buffer(buf);
> + kvfree(buf);
> } else {
> /* Just store the data in a buffer */
> void *data = kmalloc(datalen, GFP_KERNEL);
> @@ -283,7 +139,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
> err_enckey:
> kzfree(enckey);
> error:
> - big_key_free_buffer(buf);
> + kvfree(buf);
> return ret;
> }
There should be a 'memzero_explicit(buf, enclen);' before the above two calls to
kvfree().
Or even better these should use kvfree_sensitive(), but that hasn't been merged
yet. It was under discussion last month:
https://lkml.kernel.org/lkml/20200407200318.11711-1-longman@redhat.com/
>
> - ret = big_key_crypt(BIG_KEY_DEC, buf, enclen, enckey);
> - if (ret)
> + ret = chacha20poly1305_decrypt(buf, buf, enclen, NULL, 0, 0,
> + enckey) ? 0 : -EINVAL;
> + if (unlikely(ret))
> goto err_fput;
-EINVAL is often unclear, since everyone uses it for everything. How about
using -EBADMSG, which is what was used before via crypto_aead_decrypt()?
>
> ret = datalen;
>
> /* copy out decrypted data */
> - memcpy(buffer, buf->virt, datalen);
> + memcpy(buffer, buf, datalen);
>
> err_fput:
> fput(file);
> error:
> - big_key_free_buffer(buf);
> + kvfree(buf);
Likewise, the buffer should be zeroed before freeing here.
- Eric
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.