[PATCH] crypto: hash - Add default handlers for digest, export, import

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]
  Powered by Linux