--- /dev/null
+From e645016abc803dafc75e4b8f6e4118f088900ffb Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Mon, 18 Sep 2017 11:36:45 -0700
+Subject: KEYS: fix writing past end of user-supplied buffer in keyring_read()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit e645016abc803dafc75e4b8f6e4118f088900ffb upstream.
+
+Userspace can call keyctl_read() on a keyring to get the list of IDs of
+keys in the keyring. But if the user-supplied buffer is too small, the
+kernel would write the full list anyway --- which will corrupt whatever
+userspace memory happened to be past the end of the buffer. Fix it by
+only filling the space that is available.
+
+Fixes: b2a4df200d57 ("KEYS: Expand the capacity of a keyring")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/keyring.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+--- a/security/keys/keyring.c
++++ b/security/keys/keyring.c
+@@ -423,7 +423,7 @@ static void keyring_describe(const struc
+ }
+
+ struct keyring_read_iterator_context {
+- size_t qty;
++ size_t buflen;
+ size_t count;
+ key_serial_t __user *buffer;
+ };
+@@ -435,9 +435,9 @@ static int keyring_read_iterator(const v
+ int ret;
+
+ kenter("{%s,%d},,{%zu/%zu}",
+- key->type->name, key->serial, ctx->count, ctx->qty);
++ key->type->name, key->serial, ctx->count, ctx->buflen);
+
+- if (ctx->count >= ctx->qty)
++ if (ctx->count >= ctx->buflen)
+ return 1;
+
+ ret = put_user(key->serial, ctx->buffer);
+@@ -472,16 +472,12 @@ static long keyring_read(const struct ke
+ return 0;
+
+ /* Calculate how much data we could return */
+- ctx.qty = nr_keys * sizeof(key_serial_t);
+-
+ if (!buffer || !buflen)
+- return ctx.qty;
+-
+- if (buflen > ctx.qty)
+- ctx.qty = buflen;
++ return nr_keys * sizeof(key_serial_t);
+
+ /* Copy the IDs of the subscribed keys into the buffer */
+ ctx.buffer = (key_serial_t __user *)buffer;
++ ctx.buflen = buflen;
+ ctx.count = 0;
+ ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx);
+ if (ret < 0) {
--- /dev/null
+From 237bbd29f7a049d310d907f4b2716a7feef9abf3 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Mon, 18 Sep 2017 11:37:03 -0700
+Subject: KEYS: prevent creating a different user's keyrings
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 237bbd29f7a049d310d907f4b2716a7feef9abf3 upstream.
+
+It was possible for an unprivileged user to create the user and user
+session keyrings for another user. For example:
+
+ sudo -u '#3000' sh -c 'keyctl add keyring _uid.4000 "" @u
+ keyctl add keyring _uid_ses.4000 "" @u
+ sleep 15' &
+ sleep 1
+ sudo -u '#4000' keyctl describe @u
+ sudo -u '#4000' keyctl describe @us
+
+This is problematic because these "fake" keyrings won't have the right
+permissions. In particular, the user who created them first will own
+them and will have full access to them via the possessor permissions,
+which can be used to compromise the security of a user's keys:
+
+ -4: alswrv-----v------------ 3000 0 keyring: _uid.4000
+ -5: alswrv-----v------------ 3000 0 keyring: _uid_ses.4000
+
+Fix it by marking user and user session keyrings with a flag
+KEY_FLAG_UID_KEYRING. Then, when searching for a user or user session
+keyring by name, skip all keyrings that don't have the flag set.
+
+Fixes: 69664cf16af4 ("keys: don't generate user and user session keyrings unless they're accessed")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/key.h | 2 ++
+ security/keys/internal.h | 2 +-
+ security/keys/key.c | 2 ++
+ security/keys/keyring.c | 23 ++++++++++++++---------
+ security/keys/process_keys.c | 6 ++++--
+ 5 files changed, 23 insertions(+), 12 deletions(-)
+
+--- a/include/linux/key.h
++++ b/include/linux/key.h
+@@ -187,6 +187,7 @@ struct key {
+ #define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */
+ #define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */
+ #define KEY_FLAG_KEEP 10 /* set if key should not be removed */
++#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */
+
+ /* the key type and key description string
+ * - the desc is used to match a key against search criteria
+@@ -243,6 +244,7 @@ extern struct key *key_alloc(struct key_
+ #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
+ #define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */
+ #define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */
++#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */
+
+ extern void key_revoke(struct key *key);
+ extern void key_invalidate(struct key *key);
+--- a/security/keys/internal.h
++++ b/security/keys/internal.h
+@@ -141,7 +141,7 @@ extern key_ref_t keyring_search_aux(key_
+ extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx);
+ extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx);
+
+-extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
++extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
+
+ extern int install_user_keyrings(void);
+ extern int install_thread_keyring_to_cred(struct cred *);
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -302,6 +302,8 @@ struct key *key_alloc(struct key_type *t
+ key->flags |= 1 << KEY_FLAG_IN_QUOTA;
+ if (flags & KEY_ALLOC_BUILT_IN)
+ key->flags |= 1 << KEY_FLAG_BUILTIN;
++ if (flags & KEY_ALLOC_UID_KEYRING)
++ key->flags |= 1 << KEY_FLAG_UID_KEYRING;
+
+ #ifdef KEY_DEBUGGING
+ key->magic = KEY_DEBUG_MAGIC;
+--- a/security/keys/keyring.c
++++ b/security/keys/keyring.c
+@@ -1097,15 +1097,15 @@ found:
+ /*
+ * Find a keyring with the specified name.
+ *
+- * All named keyrings in the current user namespace are searched, provided they
+- * grant Search permission directly to the caller (unless this check is
+- * skipped). Keyrings whose usage points have reached zero or who have been
+- * revoked are skipped.
++ * Only keyrings that have nonzero refcount, are not revoked, and are owned by a
++ * user in the current user namespace are considered. If @uid_keyring is %true,
++ * the keyring additionally must have been allocated as a user or user session
++ * keyring; otherwise, it must grant Search permission directly to the caller.
+ *
+ * Returns a pointer to the keyring with the keyring's refcount having being
+ * incremented on success. -ENOKEY is returned if a key could not be found.
+ */
+-struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
++struct key *find_keyring_by_name(const char *name, bool uid_keyring)
+ {
+ struct key *keyring;
+ int bucket;
+@@ -1133,10 +1133,15 @@ struct key *find_keyring_by_name(const c
+ if (strcmp(keyring->description, name) != 0)
+ continue;
+
+- if (!skip_perm_check &&
+- key_permission(make_key_ref(keyring, 0),
+- KEY_NEED_SEARCH) < 0)
+- continue;
++ if (uid_keyring) {
++ if (!test_bit(KEY_FLAG_UID_KEYRING,
++ &keyring->flags))
++ continue;
++ } else {
++ if (key_permission(make_key_ref(keyring, 0),
++ KEY_NEED_SEARCH) < 0)
++ continue;
++ }
+
+ /* we've got a match but we might end up racing with
+ * key_cleanup() if the keyring is currently 'dead'
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -77,7 +77,8 @@ int install_user_keyrings(void)
+ if (IS_ERR(uid_keyring)) {
+ uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
+ cred, user_keyring_perm,
+- KEY_ALLOC_IN_QUOTA,
++ KEY_ALLOC_UID_KEYRING |
++ KEY_ALLOC_IN_QUOTA,
+ NULL, NULL);
+ if (IS_ERR(uid_keyring)) {
+ ret = PTR_ERR(uid_keyring);
+@@ -94,7 +95,8 @@ int install_user_keyrings(void)
+ session_keyring =
+ keyring_alloc(buf, user->uid, INVALID_GID,
+ cred, user_keyring_perm,
+- KEY_ALLOC_IN_QUOTA,
++ KEY_ALLOC_UID_KEYRING |
++ KEY_ALLOC_IN_QUOTA,
+ NULL, NULL);
+ if (IS_ERR(session_keyring)) {
+ ret = PTR_ERR(session_keyring);
--- /dev/null
+From 910801809b2e40a4baedd080ef5d80b4a180e70e Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Wed, 20 Sep 2017 16:58:38 +0200
+Subject: security/keys: properly zero out sensitive key material in big_key
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+commit 910801809b2e40a4baedd080ef5d80b4a180e70e upstream.
+
+Error paths forgot to zero out sensitive material, so this patch changes
+some kfrees into a kzfrees.
+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Eric Biggers <ebiggers3@gmail.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Kirill Marinushkin <k.marinushkin@gmail.com>
+Cc: security@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/big_key.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/security/keys/big_key.c
++++ b/security/keys/big_key.c
+@@ -194,7 +194,7 @@ int big_key_preparse(struct key_preparse
+ *path = file->f_path;
+ path_get(path);
+ fput(file);
+- kfree(data);
++ kzfree(data);
+ } else {
+ /* Just store the data in a buffer */
+ void *data = kmalloc(datalen, GFP_KERNEL);
+@@ -210,9 +210,9 @@ int big_key_preparse(struct key_preparse
+ err_fput:
+ fput(file);
+ err_enckey:
+- kfree(enckey);
++ kzfree(enckey);
+ error:
+- kfree(data);
++ kzfree(data);
+ return ret;
+ }
+
+@@ -226,7 +226,7 @@ void big_key_free_preparse(struct key_pr
+
+ path_put(path);
+ }
+- kfree(prep->payload.data[big_key_data]);
++ kzfree(prep->payload.data[big_key_data]);
+ }
+
+ /*
+@@ -258,7 +258,7 @@ void big_key_destroy(struct key *key)
+ path->mnt = NULL;
+ path->dentry = NULL;
+ }
+- kfree(key->payload.data[big_key_data]);
++ kzfree(key->payload.data[big_key_data]);
+ key->payload.data[big_key_data] = NULL;
+ }
+
+@@ -326,7 +326,7 @@ long big_key_read(const struct key *key,
+ err_fput:
+ fput(file);
+ error:
+- kfree(data);
++ kzfree(data);
+ } else {
+ ret = datalen;
+ if (copy_to_user(buffer, key->payload.data[big_key_data],
--- /dev/null
+From 428490e38b2e352812e0b765d8bceafab0ec441d Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Wed, 20 Sep 2017 16:58:39 +0200
+Subject: security/keys: rewrite all of big_key crypto
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+commit 428490e38b2e352812e0b765d8bceafab0ec441d upstream.
+
+This started out as just replacing the use of crypto/rng with
+get_random_bytes_wait, so that we wouldn't use bad randomness at boot
+time. But, upon looking further, it appears that there were even deeper
+underlying cryptographic problems, and that this seems to have been
+committed with very little crypto review. So, I rewrote the whole thing,
+trying to keep to the conventions introduced by the previous author, to
+fix these cryptographic flaws.
+
+It makes no sense to seed crypto/rng at boot time and then keep
+using it like this, when in fact there's already get_random_bytes_wait,
+which can ensure there's enough entropy and be a much more standard way
+of generating keys. Since this sensitive material is being stored
+untrusted, using ECB and no authentication is simply not okay at all. I
+find it surprising and a bit horrifying that this code even made it past
+basic crypto review, which perhaps points to some larger issues. This
+patch moves from using AES-ECB to using AES-GCM. Since keys are uniquely
+generated each time, we can set the nonce to zero. There was also a race
+condition in which the same key would be reused at the same time in
+different threads. A mutex fixes this issue now.
+
+So, to summarize, this commit fixes the following vulnerabilities:
+
+ * Low entropy key generation, allowing an attacker to potentially
+ guess or predict keys.
+ * Unauthenticated encryption, allowing an attacker to modify the
+ cipher text in particular ways in order to manipulate the plaintext,
+ which is is even more frightening considering the next point.
+ * Use of ECB mode, allowing an attacker to trivially swap blocks or
+ compare identical plaintext blocks.
+ * Key re-use.
+ * Faulty memory zeroing.
+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Reviewed-by: Eric Biggers <ebiggers3@gmail.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Kirill Marinushkin <k.marinushkin@gmail.com>
+Cc: security@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/Kconfig | 4 -
+ security/keys/big_key.c | 124 ++++++++++++++++++++++--------------------------
+ 2 files changed, 59 insertions(+), 69 deletions(-)
+
+--- a/security/keys/Kconfig
++++ b/security/keys/Kconfig
+@@ -45,10 +45,8 @@ config BIG_KEYS
+ bool "Large payload keys"
+ depends on KEYS
+ depends on TMPFS
+- depends on (CRYPTO_ANSI_CPRNG = y || CRYPTO_DRBG = y)
+ select CRYPTO_AES
+- select CRYPTO_ECB
+- select CRYPTO_RNG
++ select CRYPTO_GCM
+ help
+ This option provides support for holding large keys within the kernel
+ (for example Kerberos ticket caches). The data may be stored out to
+--- a/security/keys/big_key.c
++++ b/security/keys/big_key.c
+@@ -1,5 +1,6 @@
+ /* Large capacity key type
+ *
++ * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+@@ -16,10 +17,10 @@
+ #include <linux/shmem_fs.h>
+ #include <linux/err.h>
+ #include <linux/scatterlist.h>
++#include <linux/random.h>
+ #include <keys/user-type.h>
+ #include <keys/big_key-type.h>
+-#include <crypto/rng.h>
+-#include <crypto/skcipher.h>
++#include <crypto/aead.h>
+
+ /*
+ * Layout of key payload words.
+@@ -49,7 +50,12 @@ enum big_key_op {
+ /*
+ * Key size for big_key data encryption
+ */
+-#define ENC_KEY_SIZE 16
++#define ENC_KEY_SIZE 32
++
++/*
++ * Authentication tag length
++ */
++#define ENC_AUTHTAG_SIZE 16
+
+ /*
+ * big_key defined keys take an arbitrary string as the description and an
+@@ -64,57 +70,62 @@ struct key_type key_type_big_key = {
+ .destroy = big_key_destroy,
+ .describe = big_key_describe,
+ .read = big_key_read,
++ /* no ->update(); don't add it without changing big_key_crypt() nonce */
+ };
+
+ /*
+- * Crypto names for big_key data encryption
++ * Crypto names for big_key data authenticated encryption
+ */
+-static const char big_key_rng_name[] = "stdrng";
+-static const char big_key_alg_name[] = "ecb(aes)";
++static const char big_key_alg_name[] = "gcm(aes)";
+
+ /*
+- * Crypto algorithms for big_key data encryption
++ * Crypto algorithms for big_key data authenticated encryption
+ */
+-static struct crypto_rng *big_key_rng;
+-static struct crypto_skcipher *big_key_skcipher;
++static struct crypto_aead *big_key_aead;
+
+ /*
+- * Generate random key to encrypt big_key data
++ * Since changing the key affects the entire object, we need a mutex.
+ */
+-static inline int big_key_gen_enckey(u8 *key)
+-{
+- return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE);
+-}
++static DEFINE_MUTEX(big_key_aead_lock);
+
+ /*
+ * Encrypt/decrypt big_key data
+ */
+ static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
+ {
+- int ret = -EINVAL;
++ int ret;
+ struct scatterlist sgio;
+- SKCIPHER_REQUEST_ON_STACK(req, big_key_skcipher);
++ struct aead_request *aead_req;
++ /* We always use a zero nonce. The reason we can get away with this is
++ * because we're using a different randomly generated key for every
++ * different encryption. Notably, too, key_type_big_key doesn't define
++ * an .update function, so there's no chance we'll wind up reusing the
++ * key to encrypt updated data. Simply put: one key, one encryption.
++ */
++ u8 zero_nonce[crypto_aead_ivsize(big_key_aead)];
++
++ aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL);
++ if (!aead_req)
++ return -ENOMEM;
++
++ memset(zero_nonce, 0, sizeof(zero_nonce));
++ sg_init_one(&sgio, data, datalen + (op == BIG_KEY_ENC ? ENC_AUTHTAG_SIZE : 0));
++ aead_request_set_crypt(aead_req, &sgio, &sgio, datalen, zero_nonce);
++ aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
++ aead_request_set_ad(aead_req, 0);
+
+- if (crypto_skcipher_setkey(big_key_skcipher, key, ENC_KEY_SIZE)) {
++ mutex_lock(&big_key_aead_lock);
++ if (crypto_aead_setkey(big_key_aead, key, ENC_KEY_SIZE)) {
+ ret = -EAGAIN;
+ goto error;
+ }
+-
+- skcipher_request_set_tfm(req, big_key_skcipher);
+- skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
+- NULL, NULL);
+-
+- sg_init_one(&sgio, data, datalen);
+- skcipher_request_set_crypt(req, &sgio, &sgio, datalen, NULL);
+-
+ if (op == BIG_KEY_ENC)
+- ret = crypto_skcipher_encrypt(req);
++ ret = crypto_aead_encrypt(aead_req);
+ else
+- ret = crypto_skcipher_decrypt(req);
+-
+- skcipher_request_zero(req);
+-
++ ret = crypto_aead_decrypt(aead_req);
+ error:
++ mutex_unlock(&big_key_aead_lock);
++ aead_request_free(aead_req);
+ return ret;
+ }
+
+@@ -146,15 +157,13 @@ int big_key_preparse(struct key_preparse
+ *
+ * File content is stored encrypted with randomly generated key.
+ */
+- size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher));
++ size_t enclen = datalen + ENC_AUTHTAG_SIZE;
+
+- /* prepare aligned data to encrypt */
+ data = kmalloc(enclen, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ memcpy(data, prep->data, datalen);
+- memset(data + datalen, 0x00, enclen - datalen);
+
+ /* generate random key */
+ enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
+@@ -162,13 +171,12 @@ int big_key_preparse(struct key_preparse
+ ret = -ENOMEM;
+ goto error;
+ }
+-
+- ret = big_key_gen_enckey(enckey);
+- if (ret)
++ ret = get_random_bytes_wait(enckey, ENC_KEY_SIZE);
++ if (unlikely(ret))
+ goto err_enckey;
+
+ /* encrypt aligned data */
+- ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey);
++ ret = big_key_crypt(BIG_KEY_ENC, data, datalen, enckey);
+ if (ret)
+ goto err_enckey;
+
+@@ -294,7 +302,7 @@ long big_key_read(const struct key *key,
+ struct file *file;
+ u8 *data;
+ u8 *enckey = (u8 *)key->payload.data[big_key_data];
+- size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher));
++ size_t enclen = datalen + ENC_AUTHTAG_SIZE;
+
+ data = kmalloc(enclen, GFP_KERNEL);
+ if (!data)
+@@ -342,47 +350,31 @@ error:
+ */
+ static int __init big_key_init(void)
+ {
+- struct crypto_skcipher *cipher;
+- struct crypto_rng *rng;
+ int ret;
+
+- rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
+- if (IS_ERR(rng)) {
+- pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng));
+- return PTR_ERR(rng);
+- }
+-
+- big_key_rng = rng;
+-
+- /* seed RNG */
+- ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
+- if (ret) {
+- pr_err("Can't reset rng: %d\n", ret);
+- goto error_rng;
+- }
+-
+ /* init block cipher */
+- cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
+- if (IS_ERR(cipher)) {
+- ret = PTR_ERR(cipher);
++ big_key_aead = crypto_alloc_aead(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR(big_key_aead)) {
++ ret = PTR_ERR(big_key_aead);
+ pr_err("Can't alloc crypto: %d\n", ret);
+- goto error_rng;
++ return ret;
++ }
++ ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE);
++ if (ret < 0) {
++ pr_err("Can't set crypto auth tag len: %d\n", ret);
++ goto free_aead;
+ }
+-
+- big_key_skcipher = cipher;
+
+ ret = register_key_type(&key_type_big_key);
+ if (ret < 0) {
+ pr_err("Can't register type: %d\n", ret);
+- goto error_cipher;
++ goto free_aead;
+ }
+
+ return 0;
+
+-error_cipher:
+- crypto_free_skcipher(big_key_skcipher);
+-error_rng:
+- crypto_free_rng(big_key_rng);
++free_aead:
++ crypto_free_aead(big_key_aead);
+ return ret;
+ }
+
crypto-talitos-don-t-provide-setkey-for-non-hmac-hashing-algs.patch
crypto-talitos-fix-sha224.patch
crypto-talitos-fix-hashing.patch
+security-keys-properly-zero-out-sensitive-key-material-in-big_key.patch
+security-keys-rewrite-all-of-big_key-crypto.patch
+keys-fix-writing-past-end-of-user-supplied-buffer-in-keyring_read.patch
+keys-prevent-creating-a-different-user-s-keyrings.patch
crypto-af_alg-remove-sgl-terminator-indicator-when-chaining.patch