The document of struct ahash_alg explicitly states that @finup, combination of @update and @final, is optional, while said nothing about @digest, which is combination of @init and @finup (@update and @final). This gives a illusion that @digest might be optional. However crypto_ahash_init_tfm() strangely does expect a non-NULL @digest, otherwise it'll result in NULL pointer dereference. Add default handlers for digest, export, import according to the behavior in the document, and mark them optional. Signed-off-by: David Yang <mmyangfl@xxxxxxxxx> --- crypto/ahash.c | 28 +++++++++++++++++++++++++--- include/crypto/hash.h | 12 ++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/crypto/ahash.c b/crypto/ahash.c index b8a607928e72..53abbfe58a5f 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -417,6 +417,28 @@ static int ahash_def_finup(struct ahash_request *req) return ahash_def_finup_finish1(req, err); } +static int ahash_def_digest(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + int err; + + err = tfm->init(req); + if (err) + return err; + + return ahash_def_finup(req); +} + +static int ahash_def_noexport(struct ahash_request *req, void *out) +{ + return -EINVAL; +} + +static int ahash_def_noimport(struct ahash_request *req, const void *in) +{ + return -EINVAL; +} + static void crypto_ahash_exit_tfm(struct crypto_tfm *tfm) { struct crypto_ahash *hash = __crypto_ahash_cast(tfm); @@ -439,9 +461,9 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm) hash->update = alg->update; hash->final = alg->final; hash->finup = alg->finup ?: ahash_def_finup; - hash->digest = alg->digest; - hash->export = alg->export; - hash->import = alg->import; + hash->digest = alg->digest ?: ahash_def_digest; + hash->export = alg->export ?: ahash_def_noexport; + hash->import = alg->import ?: ahash_def_noimport; if (alg->setkey) { hash->setkey = alg->setkey; diff --git a/include/crypto/hash.h b/include/crypto/hash.h index e69542d86a2b..17dee80ac76a 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Hash: Hash algorithms under the crypto API - * + * * Copyright (c) 2008 Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> */ @@ -110,7 +110,7 @@ struct ahash_request { * added to allow such hardware to be used at least by IPsec. Data * processing can happen synchronously [SHASH] or asynchronously [AHASH] * at this point. - * @digest: Combination of @init and @update and @final. This function + * @digest: **[optional]** Combination of @init and @update and @final. This function * effectively behaves as the entire chain of operations, @init, * @update and @final issued in sequence. Just like @finup, this was * added for hardware which cannot do even the @finup, but can only do @@ -129,15 +129,15 @@ struct ahash_request { * this function. This function must be called before any other of the * @init, @update, @final, @finup, @digest is called. No data * processing happens at this point. - * @export: Export partial state of the transformation. This function dumps the - * entire state of the ongoing transformation into a provided block of + * @export: **[optional]** Export partial state of the transformation. This function + * dumps the entire state of the ongoing transformation into a provided block of * data so it can be @import 'ed back later on. This is useful in case * you want to save partial result of the transformation after * processing certain amount of data and reload this partial result * multiple times later on for multiple re-use. No data processing * happens at this point. Driver must not use req->result. - * @import: Import partial state of the transformation. This function loads the - * entire state of the ongoing transformation from a provided block of + * @import: **[optional]** Import partial state of the transformation. This function + * loads the entire state of the ongoing transformation from a provided block of * data so the transformation can continue from this point onward. No * data processing happens at this point. Driver must not use * req->result. -- 2.39.2