--- /dev/null
+From 841a3ff329713f796a63356fef6e2f72e4a3f6a3 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 3 Jan 2018 11:16:23 -0800
+Subject: crypto: cryptd - pass through absence of ->setkey()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 841a3ff329713f796a63356fef6e2f72e4a3f6a3 upstream.
+
+When the cryptd template is used to wrap an unkeyed hash algorithm,
+don't install a ->setkey() method to the cryptd instance. This change
+is necessary for cryptd to keep working with unkeyed hash algorithms
+once we start enforcing that ->setkey() is called when present.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/cryptd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -911,7 +911,8 @@ static int cryptd_create_hash(struct cry
+ inst->alg.finup = cryptd_hash_finup_enqueue;
+ inst->alg.export = cryptd_hash_export;
+ inst->alg.import = cryptd_hash_import;
+- inst->alg.setkey = cryptd_hash_setkey;
++ if (crypto_shash_alg_has_setkey(salg))
++ inst->alg.setkey = cryptd_hash_setkey;
+ inst->alg.digest = cryptd_hash_digest_enqueue;
+
+ err = ahash_register_instance(tmpl, inst);
--- /dev/null
+From a208fa8f33031b9e0aba44c7d1b7e68eb0cbd29e Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 3 Jan 2018 11:16:26 -0800
+Subject: crypto: hash - annotate algorithms taking optional key
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit a208fa8f33031b9e0aba44c7d1b7e68eb0cbd29e upstream.
+
+We need to consistently enforce that keyed hashes cannot be used without
+setting the key. To do this we need a reliable way to determine whether
+a given hash algorithm is keyed or not. AF_ALG currently does this by
+checking for the presence of a ->setkey() method. However, this is
+actually slightly broken because the CRC-32 algorithms implement
+->setkey() but can also be used without a key. (The CRC-32 "key" is not
+actually a cryptographic key but rather represents the initial state.
+If not overridden, then a default initial state is used.)
+
+Prepare to fix this by introducing a flag CRYPTO_ALG_OPTIONAL_KEY which
+indicates that the algorithm has a ->setkey() method, but it is not
+required to be called. Then set it on all the CRC-32 algorithms.
+
+The same also applies to the Adler-32 implementation in Lustre.
+
+Also, the cryptd and mcryptd templates have to pass through the flag
+from their underlying algorithm.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/crypto/crc32-ce-glue.c | 2 ++
+ arch/arm64/crypto/crc32-ce-glue.c | 2 ++
+ arch/powerpc/crypto/crc32c-vpmsum_glue.c | 1 +
+ arch/s390/crypto/crc32-vx.c | 3 +++
+ arch/sparc/crypto/crc32c_glue.c | 1 +
+ arch/x86/crypto/crc32-pclmul_glue.c | 1 +
+ arch/x86/crypto/crc32c-intel_glue.c | 1 +
+ crypto/crc32_generic.c | 1 +
+ crypto/crc32c_generic.c | 1 +
+ crypto/cryptd.c | 7 +++----
+ crypto/mcryptd.c | 7 +++----
+ drivers/crypto/bfin_crc.c | 3 ++-
+ drivers/crypto/stm32/stm32_crc32.c | 2 ++
+ drivers/staging/lustre/lnet/libcfs/linux/linux-crypto-adler.c | 1 +
+ include/linux/crypto.h | 6 ++++++
+ 15 files changed, 30 insertions(+), 9 deletions(-)
+
+--- a/arch/arm/crypto/crc32-ce-glue.c
++++ b/arch/arm/crypto/crc32-ce-glue.c
+@@ -188,6 +188,7 @@ static struct shash_alg crc32_pmull_algs
+ .base.cra_name = "crc32",
+ .base.cra_driver_name = "crc32-arm-ce",
+ .base.cra_priority = 200,
++ .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .base.cra_blocksize = 1,
+ .base.cra_module = THIS_MODULE,
+ }, {
+@@ -203,6 +204,7 @@ static struct shash_alg crc32_pmull_algs
+ .base.cra_name = "crc32c",
+ .base.cra_driver_name = "crc32c-arm-ce",
+ .base.cra_priority = 200,
++ .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .base.cra_blocksize = 1,
+ .base.cra_module = THIS_MODULE,
+ } };
+--- a/arch/arm64/crypto/crc32-ce-glue.c
++++ b/arch/arm64/crypto/crc32-ce-glue.c
+@@ -185,6 +185,7 @@ static struct shash_alg crc32_pmull_algs
+ .base.cra_name = "crc32",
+ .base.cra_driver_name = "crc32-arm64-ce",
+ .base.cra_priority = 200,
++ .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .base.cra_blocksize = 1,
+ .base.cra_module = THIS_MODULE,
+ }, {
+@@ -200,6 +201,7 @@ static struct shash_alg crc32_pmull_algs
+ .base.cra_name = "crc32c",
+ .base.cra_driver_name = "crc32c-arm64-ce",
+ .base.cra_priority = 200,
++ .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .base.cra_blocksize = 1,
+ .base.cra_module = THIS_MODULE,
+ } };
+--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c
++++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c
+@@ -141,6 +141,7 @@ static struct shash_alg alg = {
+ .cra_name = "crc32c",
+ .cra_driver_name = "crc32c-vpmsum",
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(u32),
+ .cra_module = THIS_MODULE,
+--- a/arch/s390/crypto/crc32-vx.c
++++ b/arch/s390/crypto/crc32-vx.c
+@@ -239,6 +239,7 @@ static struct shash_alg crc32_vx_algs[]
+ .cra_name = "crc32",
+ .cra_driver_name = "crc32-vx",
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CRC32_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crc_ctx),
+ .cra_module = THIS_MODULE,
+@@ -259,6 +260,7 @@ static struct shash_alg crc32_vx_algs[]
+ .cra_name = "crc32be",
+ .cra_driver_name = "crc32be-vx",
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CRC32_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crc_ctx),
+ .cra_module = THIS_MODULE,
+@@ -279,6 +281,7 @@ static struct shash_alg crc32_vx_algs[]
+ .cra_name = "crc32c",
+ .cra_driver_name = "crc32c-vx",
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CRC32_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crc_ctx),
+ .cra_module = THIS_MODULE,
+--- a/arch/sparc/crypto/crc32c_glue.c
++++ b/arch/sparc/crypto/crc32c_glue.c
+@@ -133,6 +133,7 @@ static struct shash_alg alg = {
+ .cra_name = "crc32c",
+ .cra_driver_name = "crc32c-sparc64",
+ .cra_priority = SPARC_CR_OPCODE_PRIORITY,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(u32),
+ .cra_alignmask = 7,
+--- a/arch/x86/crypto/crc32-pclmul_glue.c
++++ b/arch/x86/crypto/crc32-pclmul_glue.c
+@@ -162,6 +162,7 @@ static struct shash_alg alg = {
+ .cra_name = "crc32",
+ .cra_driver_name = "crc32-pclmul",
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(u32),
+ .cra_module = THIS_MODULE,
+--- a/arch/x86/crypto/crc32c-intel_glue.c
++++ b/arch/x86/crypto/crc32c-intel_glue.c
+@@ -226,6 +226,7 @@ static struct shash_alg alg = {
+ .cra_name = "crc32c",
+ .cra_driver_name = "crc32c-intel",
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(u32),
+ .cra_module = THIS_MODULE,
+--- a/crypto/crc32_generic.c
++++ b/crypto/crc32_generic.c
+@@ -133,6 +133,7 @@ static struct shash_alg alg = {
+ .cra_name = "crc32",
+ .cra_driver_name = "crc32-generic",
+ .cra_priority = 100,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(u32),
+ .cra_module = THIS_MODULE,
+--- a/crypto/crc32c_generic.c
++++ b/crypto/crc32c_generic.c
+@@ -146,6 +146,7 @@ static struct shash_alg alg = {
+ .cra_name = "crc32c",
+ .cra_driver_name = "crc32c-generic",
+ .cra_priority = 100,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_alignmask = 3,
+ .cra_ctxsize = sizeof(struct chksum_ctx),
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -893,10 +893,9 @@ static int cryptd_create_hash(struct cry
+ if (err)
+ goto out_free_inst;
+
+- type = CRYPTO_ALG_ASYNC;
+- if (alg->cra_flags & CRYPTO_ALG_INTERNAL)
+- type |= CRYPTO_ALG_INTERNAL;
+- inst->alg.halg.base.cra_flags = type;
++ inst->alg.halg.base.cra_flags = CRYPTO_ALG_ASYNC |
++ (alg->cra_flags & (CRYPTO_ALG_INTERNAL |
++ CRYPTO_ALG_OPTIONAL_KEY));
+
+ inst->alg.halg.digestsize = salg->digestsize;
+ inst->alg.halg.statesize = salg->statesize;
+--- a/crypto/mcryptd.c
++++ b/crypto/mcryptd.c
+@@ -517,10 +517,9 @@ static int mcryptd_create_hash(struct cr
+ if (err)
+ goto out_free_inst;
+
+- type = CRYPTO_ALG_ASYNC;
+- if (alg->cra_flags & CRYPTO_ALG_INTERNAL)
+- type |= CRYPTO_ALG_INTERNAL;
+- inst->alg.halg.base.cra_flags = type;
++ inst->alg.halg.base.cra_flags = CRYPTO_ALG_ASYNC |
++ (alg->cra_flags & (CRYPTO_ALG_INTERNAL |
++ CRYPTO_ALG_OPTIONAL_KEY));
+
+ inst->alg.halg.digestsize = halg->digestsize;
+ inst->alg.halg.statesize = halg->statesize;
+--- a/drivers/crypto/bfin_crc.c
++++ b/drivers/crypto/bfin_crc.c
+@@ -494,7 +494,8 @@ static struct ahash_alg algs = {
+ .cra_driver_name = DRIVER_NAME,
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH |
+- CRYPTO_ALG_ASYNC,
++ CRYPTO_ALG_ASYNC |
++ CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct bfin_crypto_crc_ctx),
+ .cra_alignmask = 3,
+--- a/drivers/crypto/stm32/stm32_crc32.c
++++ b/drivers/crypto/stm32/stm32_crc32.c
+@@ -208,6 +208,7 @@ static struct shash_alg algs[] = {
+ .cra_name = "crc32",
+ .cra_driver_name = DRIVER_NAME,
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_alignmask = 3,
+ .cra_ctxsize = sizeof(struct stm32_crc_ctx),
+@@ -229,6 +230,7 @@ static struct shash_alg algs[] = {
+ .cra_name = "crc32c",
+ .cra_driver_name = DRIVER_NAME,
+ .cra_priority = 200,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_alignmask = 3,
+ .cra_ctxsize = sizeof(struct stm32_crc_ctx),
+--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto-adler.c
++++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto-adler.c
+@@ -120,6 +120,7 @@ static struct shash_alg alg = {
+ .cra_name = "adler32",
+ .cra_driver_name = "adler32-zlib",
+ .cra_priority = 100,
++ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
+ .cra_blocksize = CHKSUM_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(u32),
+ .cra_module = THIS_MODULE,
+--- a/include/linux/crypto.h
++++ b/include/linux/crypto.h
+@@ -107,6 +107,12 @@
+ #define CRYPTO_ALG_INTERNAL 0x00002000
+
+ /*
++ * Set if the algorithm has a ->setkey() method but can be used without
++ * calling it first, i.e. there is a default key.
++ */
++#define CRYPTO_ALG_OPTIONAL_KEY 0x00004000
++
++/*
+ * Transform masks and values (for crt_flags).
+ */
+ #define CRYPTO_TFM_REQ_MASK 0x000fff00
--- /dev/null
+From cd6ed77ad5d223dc6299fb58f62e0f5267f7e2ba Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 3 Jan 2018 11:16:22 -0800
+Subject: crypto: hash - introduce crypto_hash_alg_has_setkey()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit cd6ed77ad5d223dc6299fb58f62e0f5267f7e2ba upstream.
+
+Templates that use an shash spawn can use crypto_shash_alg_has_setkey()
+to determine whether the underlying algorithm requires a key or not.
+But there was no corresponding function for ahash spawns. Add it.
+
+Note that the new function actually has to support both shash and ahash
+algorithms, since the ahash API can be used with either.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/ahash.c | 11 +++++++++++
+ include/crypto/internal/hash.h | 2 ++
+ 2 files changed, 13 insertions(+)
+
+--- a/crypto/ahash.c
++++ b/crypto/ahash.c
+@@ -649,5 +649,16 @@ struct hash_alg_common *ahash_attr_alg(s
+ }
+ EXPORT_SYMBOL_GPL(ahash_attr_alg);
+
++bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg)
++{
++ struct crypto_alg *alg = &halg->base;
++
++ if (alg->cra_type != &crypto_ahash_type)
++ return crypto_shash_alg_has_setkey(__crypto_shash_alg(alg));
++
++ return __crypto_ahash_alg(alg)->setkey != NULL;
++}
++EXPORT_SYMBOL_GPL(crypto_hash_alg_has_setkey);
++
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Asynchronous cryptographic hash type");
+--- a/include/crypto/internal/hash.h
++++ b/include/crypto/internal/hash.h
+@@ -90,6 +90,8 @@ static inline bool crypto_shash_alg_has_
+ return alg->setkey != shash_no_setkey;
+ }
+
++bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg);
++
+ int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn,
+ struct hash_alg_common *alg,
+ struct crypto_instance *inst);
--- /dev/null
+From 9fa68f620041be04720d0cbfb1bd3ddfc6310b24 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 3 Jan 2018 11:16:27 -0800
+Subject: crypto: hash - prevent using keyed hashes without setting key
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 9fa68f620041be04720d0cbfb1bd3ddfc6310b24 upstream.
+
+Currently, almost none of the keyed hash algorithms check whether a key
+has been set before proceeding. Some algorithms are okay with this and
+will effectively just use a key of all 0's or some other bogus default.
+However, others will severely break, as demonstrated using
+"hmac(sha3-512-generic)", the unkeyed use of which causes a kernel crash
+via a (potentially exploitable) stack buffer overflow.
+
+A while ago, this problem was solved for AF_ALG by pairing each hash
+transform with a 'has_key' bool. However, there are still other places
+in the kernel where userspace can specify an arbitrary hash algorithm by
+name, and the kernel uses it as unkeyed hash without checking whether it
+is really unkeyed. Examples of this include:
+
+ - KEYCTL_DH_COMPUTE, via the KDF extension
+ - dm-verity
+ - dm-crypt, via the ESSIV support
+ - dm-integrity, via the "internal hash" mode with no key given
+ - drbd (Distributed Replicated Block Device)
+
+This bug is especially bad for KEYCTL_DH_COMPUTE as that requires no
+privileges to call.
+
+Fix the bug for all users by adding a flag CRYPTO_TFM_NEED_KEY to the
+->crt_flags of each hash transform that indicates whether the transform
+still needs to be keyed or not. Then, make the hash init, import, and
+digest functions return -ENOKEY if the key is still needed.
+
+The new flag also replaces the 'has_key' bool which algif_hash was
+previously using, thereby simplifying the algif_hash implementation.
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/ahash.c | 22 ++++++++++++++++----
+ crypto/algif_hash.c | 52 ++++++++++---------------------------------------
+ crypto/shash.c | 25 +++++++++++++++++++----
+ include/crypto/hash.h | 34 ++++++++++++++++++++++----------
+ include/linux/crypto.h | 2 +
+ 5 files changed, 75 insertions(+), 60 deletions(-)
+
+--- a/crypto/ahash.c
++++ b/crypto/ahash.c
+@@ -193,11 +193,18 @@ int crypto_ahash_setkey(struct crypto_ah
+ unsigned int keylen)
+ {
+ unsigned long alignmask = crypto_ahash_alignmask(tfm);
++ int err;
+
+ if ((unsigned long)key & alignmask)
+- return ahash_setkey_unaligned(tfm, key, keylen);
++ err = ahash_setkey_unaligned(tfm, key, keylen);
++ else
++ err = tfm->setkey(tfm, key, keylen);
++
++ if (err)
++ return err;
+
+- return tfm->setkey(tfm, key, keylen);
++ crypto_ahash_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
++ return 0;
+ }
+ EXPORT_SYMBOL_GPL(crypto_ahash_setkey);
+
+@@ -368,7 +375,12 @@ EXPORT_SYMBOL_GPL(crypto_ahash_finup);
+
+ int crypto_ahash_digest(struct ahash_request *req)
+ {
+- return crypto_ahash_op(req, crypto_ahash_reqtfm(req)->digest);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++
++ if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
++ return -ENOKEY;
++
++ return crypto_ahash_op(req, tfm->digest);
+ }
+ EXPORT_SYMBOL_GPL(crypto_ahash_digest);
+
+@@ -450,7 +462,6 @@ static int crypto_ahash_init_tfm(struct
+ struct ahash_alg *alg = crypto_ahash_alg(hash);
+
+ hash->setkey = ahash_nosetkey;
+- hash->has_setkey = false;
+ hash->export = ahash_no_export;
+ hash->import = ahash_no_import;
+
+@@ -465,7 +476,8 @@ static int crypto_ahash_init_tfm(struct
+
+ if (alg->setkey) {
+ hash->setkey = alg->setkey;
+- hash->has_setkey = true;
++ if (!(alg->halg.base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY))
++ crypto_ahash_set_flags(hash, CRYPTO_TFM_NEED_KEY);
+ }
+ if (alg->export)
+ hash->export = alg->export;
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -34,11 +34,6 @@ struct hash_ctx {
+ struct ahash_request req;
+ };
+
+-struct algif_hash_tfm {
+- struct crypto_ahash *hash;
+- bool has_key;
+-};
+-
+ static int hash_alloc_result(struct sock *sk, struct hash_ctx *ctx)
+ {
+ unsigned ds;
+@@ -307,7 +302,7 @@ static int hash_check_key(struct socket
+ int err = 0;
+ struct sock *psk;
+ struct alg_sock *pask;
+- struct algif_hash_tfm *tfm;
++ struct crypto_ahash *tfm;
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+
+@@ -321,7 +316,7 @@ static int hash_check_key(struct socket
+
+ err = -ENOKEY;
+ lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+- if (!tfm->has_key)
++ if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
+ goto unlock;
+
+ if (!pask->refcnt++)
+@@ -412,41 +407,17 @@ static struct proto_ops algif_hash_ops_n
+
+ static void *hash_bind(const char *name, u32 type, u32 mask)
+ {
+- struct algif_hash_tfm *tfm;
+- struct crypto_ahash *hash;
+-
+- tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+- if (!tfm)
+- return ERR_PTR(-ENOMEM);
+-
+- hash = crypto_alloc_ahash(name, type, mask);
+- if (IS_ERR(hash)) {
+- kfree(tfm);
+- return ERR_CAST(hash);
+- }
+-
+- tfm->hash = hash;
+-
+- return tfm;
++ return crypto_alloc_ahash(name, type, mask);
+ }
+
+ static void hash_release(void *private)
+ {
+- struct algif_hash_tfm *tfm = private;
+-
+- crypto_free_ahash(tfm->hash);
+- kfree(tfm);
++ crypto_free_ahash(private);
+ }
+
+ static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
+ {
+- struct algif_hash_tfm *tfm = private;
+- int err;
+-
+- err = crypto_ahash_setkey(tfm->hash, key, keylen);
+- tfm->has_key = !err;
+-
+- return err;
++ return crypto_ahash_setkey(private, key, keylen);
+ }
+
+ static void hash_sock_destruct(struct sock *sk)
+@@ -461,11 +432,10 @@ static void hash_sock_destruct(struct so
+
+ static int hash_accept_parent_nokey(void *private, struct sock *sk)
+ {
+- struct hash_ctx *ctx;
++ struct crypto_ahash *tfm = private;
+ struct alg_sock *ask = alg_sk(sk);
+- struct algif_hash_tfm *tfm = private;
+- struct crypto_ahash *hash = tfm->hash;
+- unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
++ struct hash_ctx *ctx;
++ unsigned int len = sizeof(*ctx) + crypto_ahash_reqsize(tfm);
+
+ ctx = sock_kmalloc(sk, len, GFP_KERNEL);
+ if (!ctx)
+@@ -478,7 +448,7 @@ static int hash_accept_parent_nokey(void
+
+ ask->private = ctx;
+
+- ahash_request_set_tfm(&ctx->req, hash);
++ ahash_request_set_tfm(&ctx->req, tfm);
+ ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ crypto_req_done, &ctx->wait);
+
+@@ -489,9 +459,9 @@ static int hash_accept_parent_nokey(void
+
+ static int hash_accept_parent(void *private, struct sock *sk)
+ {
+- struct algif_hash_tfm *tfm = private;
++ struct crypto_ahash *tfm = private;
+
+- if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
++ if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
+ return -ENOKEY;
+
+ return hash_accept_parent_nokey(private, sk);
+--- a/crypto/shash.c
++++ b/crypto/shash.c
+@@ -58,11 +58,18 @@ int crypto_shash_setkey(struct crypto_sh
+ {
+ struct shash_alg *shash = crypto_shash_alg(tfm);
+ unsigned long alignmask = crypto_shash_alignmask(tfm);
++ int err;
+
+ if ((unsigned long)key & alignmask)
+- return shash_setkey_unaligned(tfm, key, keylen);
++ err = shash_setkey_unaligned(tfm, key, keylen);
++ else
++ err = shash->setkey(tfm, key, keylen);
++
++ if (err)
++ return err;
+
+- return shash->setkey(tfm, key, keylen);
++ crypto_shash_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
++ return 0;
+ }
+ EXPORT_SYMBOL_GPL(crypto_shash_setkey);
+
+@@ -181,6 +188,9 @@ int crypto_shash_digest(struct shash_des
+ struct shash_alg *shash = crypto_shash_alg(tfm);
+ unsigned long alignmask = crypto_shash_alignmask(tfm);
+
++ if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
++ return -ENOKEY;
++
+ if (((unsigned long)data | (unsigned long)out) & alignmask)
+ return shash_digest_unaligned(desc, data, len, out);
+
+@@ -360,7 +370,8 @@ int crypto_init_shash_ops_async(struct c
+ crt->digest = shash_async_digest;
+ crt->setkey = shash_async_setkey;
+
+- crt->has_setkey = alg->setkey != shash_no_setkey;
++ crypto_ahash_set_flags(crt, crypto_shash_get_flags(shash) &
++ CRYPTO_TFM_NEED_KEY);
+
+ if (alg->export)
+ crt->export = shash_async_export;
+@@ -375,8 +386,14 @@ int crypto_init_shash_ops_async(struct c
+ static int crypto_shash_init_tfm(struct crypto_tfm *tfm)
+ {
+ struct crypto_shash *hash = __crypto_shash_cast(tfm);
++ struct shash_alg *alg = crypto_shash_alg(hash);
++
++ hash->descsize = alg->descsize;
++
++ if (crypto_shash_alg_has_setkey(alg) &&
++ !(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY))
++ crypto_shash_set_flags(hash, CRYPTO_TFM_NEED_KEY);
+
+- hash->descsize = crypto_shash_alg(hash)->descsize;
+ return 0;
+ }
+
+--- a/include/crypto/hash.h
++++ b/include/crypto/hash.h
+@@ -210,7 +210,6 @@ struct crypto_ahash {
+ unsigned int keylen);
+
+ unsigned int reqsize;
+- bool has_setkey;
+ struct crypto_tfm base;
+ };
+
+@@ -410,11 +409,6 @@ static inline void *ahash_request_ctx(st
+ int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen);
+
+-static inline bool crypto_ahash_has_setkey(struct crypto_ahash *tfm)
+-{
+- return tfm->has_setkey;
+-}
+-
+ /**
+ * crypto_ahash_finup() - update and finalize message digest
+ * @req: reference to the ahash_request handle that holds all information
+@@ -487,7 +481,12 @@ static inline int crypto_ahash_export(st
+ */
+ static inline int crypto_ahash_import(struct ahash_request *req, const void *in)
+ {
+- return crypto_ahash_reqtfm(req)->import(req, in);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++
++ if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
++ return -ENOKEY;
++
++ return tfm->import(req, in);
+ }
+
+ /**
+@@ -503,7 +502,12 @@ static inline int crypto_ahash_import(st
+ */
+ static inline int crypto_ahash_init(struct ahash_request *req)
+ {
+- return crypto_ahash_reqtfm(req)->init(req);
++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++
++ if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
++ return -ENOKEY;
++
++ return tfm->init(req);
+ }
+
+ /**
+@@ -855,7 +859,12 @@ static inline int crypto_shash_export(st
+ */
+ static inline int crypto_shash_import(struct shash_desc *desc, const void *in)
+ {
+- return crypto_shash_alg(desc->tfm)->import(desc, in);
++ struct crypto_shash *tfm = desc->tfm;
++
++ if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
++ return -ENOKEY;
++
++ return crypto_shash_alg(tfm)->import(desc, in);
+ }
+
+ /**
+@@ -871,7 +880,12 @@ static inline int crypto_shash_import(st
+ */
+ static inline int crypto_shash_init(struct shash_desc *desc)
+ {
+- return crypto_shash_alg(desc->tfm)->init(desc);
++ struct crypto_shash *tfm = desc->tfm;
++
++ if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
++ return -ENOKEY;
++
++ return crypto_shash_alg(tfm)->init(desc);
+ }
+
+ /**
+--- a/include/linux/crypto.h
++++ b/include/linux/crypto.h
+@@ -115,6 +115,8 @@
+ /*
+ * Transform masks and values (for crt_flags).
+ */
++#define CRYPTO_TFM_NEED_KEY 0x00000001
++
+ #define CRYPTO_TFM_REQ_MASK 0x000fff00
+ #define CRYPTO_TFM_RES_MASK 0xfff00000
+
--- /dev/null
+From fa59b92d299f2787e6bae1ff078ee0982e80211f Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 3 Jan 2018 11:16:24 -0800
+Subject: crypto: mcryptd - pass through absence of ->setkey()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit fa59b92d299f2787e6bae1ff078ee0982e80211f upstream.
+
+When the mcryptd template is used to wrap an unkeyed hash algorithm,
+don't install a ->setkey() method to the mcryptd instance. This change
+is necessary for mcryptd to keep working with unkeyed hash algorithms
+once we start enforcing that ->setkey() is called when present.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/mcryptd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/crypto/mcryptd.c
++++ b/crypto/mcryptd.c
+@@ -535,7 +535,8 @@ static int mcryptd_create_hash(struct cr
+ inst->alg.finup = mcryptd_hash_finup_enqueue;
+ inst->alg.export = mcryptd_hash_export;
+ inst->alg.import = mcryptd_hash_import;
+- inst->alg.setkey = mcryptd_hash_setkey;
++ if (crypto_hash_alg_has_setkey(halg))
++ inst->alg.setkey = mcryptd_hash_setkey;
+ inst->alg.digest = mcryptd_hash_digest_enqueue;
+
+ err = ahash_register_instance(tmpl, inst);
--- /dev/null
+From a16e772e664b9a261424107784804cffc8894977 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 3 Jan 2018 11:16:25 -0800
+Subject: crypto: poly1305 - remove ->setkey() method
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit a16e772e664b9a261424107784804cffc8894977 upstream.
+
+Since Poly1305 requires a nonce per invocation, the Linux kernel
+implementations of Poly1305 don't use the crypto API's keying mechanism
+and instead expect the key and nonce as the first 32 bytes of the data.
+But ->setkey() is still defined as a stub returning an error code. This
+prevents Poly1305 from being used through AF_ALG and will also break it
+completely once we start enforcing that all crypto API users (not just
+AF_ALG) call ->setkey() if present.
+
+Fix it by removing crypto_poly1305_setkey(), leaving ->setkey as NULL.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/crypto/poly1305_glue.c | 1 -
+ crypto/poly1305_generic.c | 17 +++++------------
+ include/crypto/poly1305.h | 2 --
+ 3 files changed, 5 insertions(+), 15 deletions(-)
+
+--- a/arch/x86/crypto/poly1305_glue.c
++++ b/arch/x86/crypto/poly1305_glue.c
+@@ -164,7 +164,6 @@ static struct shash_alg alg = {
+ .init = poly1305_simd_init,
+ .update = poly1305_simd_update,
+ .final = crypto_poly1305_final,
+- .setkey = crypto_poly1305_setkey,
+ .descsize = sizeof(struct poly1305_simd_desc_ctx),
+ .base = {
+ .cra_name = "poly1305",
+--- a/crypto/poly1305_generic.c
++++ b/crypto/poly1305_generic.c
+@@ -47,17 +47,6 @@ int crypto_poly1305_init(struct shash_de
+ }
+ EXPORT_SYMBOL_GPL(crypto_poly1305_init);
+
+-int crypto_poly1305_setkey(struct crypto_shash *tfm,
+- const u8 *key, unsigned int keylen)
+-{
+- /* Poly1305 requires a unique key for each tag, which implies that
+- * we can't set it on the tfm that gets accessed by multiple users
+- * simultaneously. Instead we expect the key as the first 32 bytes in
+- * the update() call. */
+- return -ENOTSUPP;
+-}
+-EXPORT_SYMBOL_GPL(crypto_poly1305_setkey);
+-
+ static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key)
+ {
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+@@ -76,6 +65,11 @@ static void poly1305_setskey(struct poly
+ dctx->s[3] = get_unaligned_le32(key + 12);
+ }
+
++/*
++ * Poly1305 requires a unique key for each tag, which implies that we can't set
++ * it on the tfm that gets accessed by multiple users simultaneously. Instead we
++ * expect the key as the first 32 bytes in the update() call.
++ */
+ unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
+ const u8 *src, unsigned int srclen)
+ {
+@@ -281,7 +275,6 @@ static struct shash_alg poly1305_alg = {
+ .init = crypto_poly1305_init,
+ .update = crypto_poly1305_update,
+ .final = crypto_poly1305_final,
+- .setkey = crypto_poly1305_setkey,
+ .descsize = sizeof(struct poly1305_desc_ctx),
+ .base = {
+ .cra_name = "poly1305",
+--- a/include/crypto/poly1305.h
++++ b/include/crypto/poly1305.h
+@@ -31,8 +31,6 @@ struct poly1305_desc_ctx {
+ };
+
+ int crypto_poly1305_init(struct shash_desc *desc);
+-int crypto_poly1305_setkey(struct crypto_shash *tfm,
+- const u8 *key, unsigned int keylen);
+ unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
+ const u8 *src, unsigned int srclen);
+ int crypto_poly1305_update(struct shash_desc *desc,
ahci-annotate-pci-ids-for-mobile-intel-chipsets-as-such.patch
ahci-add-pci-ids-for-intel-bay-trail-cherry-trail-and-apollo-lake-ahci.patch
ahci-add-intel-cannon-lake-pch-h-pci-id.patch
+crypto-hash-introduce-crypto_hash_alg_has_setkey.patch
+crypto-cryptd-pass-through-absence-of-setkey.patch
+crypto-mcryptd-pass-through-absence-of-setkey.patch
+crypto-poly1305-remove-setkey-method.patch
+crypto-hash-annotate-algorithms-taking-optional-key.patch
+crypto-hash-prevent-using-keyed-hashes-without-setting-key.patch