On Fri, 29 Nov 2019 at 20:36, Eric Biggers <ebiggers@xxxxxxxxxx> wrote: > > From: Eric Biggers <ebiggers@xxxxxxxxxx> > > The essiv and hmac templates refuse to use any hash algorithm that has a > ->setkey() function, which includes not just algorithms that always need > a key, but also algorithms that optionally take a key. > > Previously the only optionally-keyed hash algorithms in the crypto API > were non-cryptographic algorithms like crc32, so this didn't really > matter. But that's changed with BLAKE2 support being added. BLAKE2 > should work with essiv and hmac, just like any other cryptographic hash. > > Fix this by allowing the use of both algorithms without a ->setkey() > function and algorithms that have the OPTIONAL_KEY flag set. > > Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx> Hey Eric, Even though I am not convinced that using hmac() with blake2 makes a lot of sense, I agree that the mere presence or absence of the setkey() hook should decide whether this is permitted. So, Acked-by: Ard Biesheuvel <ardb@xxxxxxxxxx> > --- > crypto/essiv.c | 2 +- > crypto/hmac.c | 4 ++-- > crypto/shash.c | 3 +-- > include/crypto/internal/hash.h | 6 ++++++ > 4 files changed, 10 insertions(+), 5 deletions(-) > > diff --git a/crypto/essiv.c b/crypto/essiv.c > index 808f2b362106..e4b32c2ea7ec 100644 > --- a/crypto/essiv.c > +++ b/crypto/essiv.c > @@ -442,7 +442,7 @@ static bool essiv_supported_algorithms(const char *essiv_cipher_name, > if (ivsize != alg->cra_blocksize) > goto out; > > - if (crypto_shash_alg_has_setkey(hash_alg)) > + if (crypto_shash_alg_needs_key(hash_alg)) > goto out; > > ret = true; > diff --git a/crypto/hmac.c b/crypto/hmac.c > index 8b2a212eb0ad..377f07733e2f 100644 > --- a/crypto/hmac.c > +++ b/crypto/hmac.c > @@ -185,9 +185,9 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) > return PTR_ERR(salg); > alg = &salg->base; > > - /* The underlying hash algorithm must be unkeyed */ > + /* The underlying hash algorithm must not require a key */ > err = -EINVAL; > - if (crypto_shash_alg_has_setkey(salg)) > + if (crypto_shash_alg_needs_key(salg)) > goto out_put_alg; > > ds = salg->digestsize; > diff --git a/crypto/shash.c b/crypto/shash.c > index e83c5124f6eb..7989258a46b4 100644 > --- a/crypto/shash.c > +++ b/crypto/shash.c > @@ -50,8 +50,7 @@ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, > > static void shash_set_needkey(struct crypto_shash *tfm, struct shash_alg *alg) > { > - if (crypto_shash_alg_has_setkey(alg) && > - !(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY)) > + if (crypto_shash_alg_needs_key(alg)) > crypto_shash_set_flags(tfm, CRYPTO_TFM_NEED_KEY); > } > > diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h > index bfc9db7b100d..f68dab38f160 100644 > --- a/include/crypto/internal/hash.h > +++ b/include/crypto/internal/hash.h > @@ -85,6 +85,12 @@ static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg) > return alg->setkey != shash_no_setkey; > } > > +static inline bool crypto_shash_alg_needs_key(struct shash_alg *alg) > +{ > + return crypto_shash_alg_has_setkey(alg) && > + !(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY); > +} > + > bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg); > > int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn, > -- > 2.24.0 >