public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] dm-ima: use SHA-256 library
@ 2026-02-26  1:39 Eric Biggers
  0 siblings, 0 replies; only message in thread
From: Eric Biggers @ 2026-02-26  1:39 UTC (permalink / raw)
  To: dm-devel, Alasdair Kergon, Mike Snitzer, Mikulas Patocka,
	Benjamin Marzinski
  Cc: linux-crypto, linux-integrity, linux-kernel, Eric Biggers

Make dm_ima_measure_on_table_load() use the SHA-256 library API instead
of crypto_shash to calculate the SHA-256 hash value that it needs.  This
is simpler and more efficient.  It also ensures that SHA-256 is actually
available and doesn't fail due to the unreliable loading by name.

While doing this, also use kasprintf() to simplify building the string
version of the digest.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 drivers/md/Kconfig  |  1 +
 drivers/md/dm-ima.c | 54 +++++++++------------------------------------
 drivers/md/dm-ima.h |  1 -
 3 files changed, 11 insertions(+), 45 deletions(-)

diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index c58a9a8ea54e..53351048d3ec 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -224,10 +224,11 @@ config BLK_DEV_DM_BUILTIN
 config BLK_DEV_DM
 	tristate "Device mapper support"
 	select BLOCK_HOLDER_DEPRECATED if SYSFS
 	select BLK_DEV_DM_BUILTIN
 	select BLK_MQ_STACKING
+	select CRYPTO_LIB_SHA256 if IMA
 	depends on DAX || DAX=n
 	help
 	  Device-mapper is a low level volume manager.  It works by allowing
 	  people to specify mappings for ranges of logical sectors.  Various
 	  mapping types are available, in addition people may write their own
diff --git a/drivers/md/dm-ima.c b/drivers/md/dm-ima.c
index efb3cd4f9cd4..9495ca035056 100644
--- a/drivers/md/dm-ima.c
+++ b/drivers/md/dm-ima.c
@@ -10,13 +10,11 @@
 #include "dm-core.h"
 #include "dm-ima.h"
 
 #include <linux/ima.h>
 #include <linux/sched/mm.h>
-#include <crypto/hash.h>
-#include <linux/crypto.h>
-#include <crypto/hash_info.h>
+#include <crypto/sha2.h>
 
 #define DM_MSG_PREFIX "ima"
 
 /*
  * Internal function to prefix separator characters in input buffer with escape
@@ -176,23 +174,17 @@ void dm_ima_reset_data(struct mapped_device *md)
 void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags)
 {
 	size_t device_data_buf_len, target_metadata_buf_len, target_data_buf_len, l = 0;
 	char *target_metadata_buf = NULL, *target_data_buf = NULL, *digest_buf = NULL;
 	char *ima_buf = NULL, *device_data_buf = NULL;
-	int digest_size, last_target_measured = -1, r;
+	int last_target_measured = -1;
 	status_type_t type = STATUSTYPE_IMA;
 	size_t cur_total_buf_len = 0;
 	unsigned int num_targets, i;
-	SHASH_DESC_ON_STACK(shash, NULL);
-	struct crypto_shash *tfm = NULL;
-	u8 *digest = NULL;
+	struct sha256_ctx hash_ctx;
+	u8 digest[SHA256_DIGEST_SIZE];
 	bool noio = false;
-	/*
-	 * In below hash_alg_prefix_len assignment +1 is for the additional char (':'),
-	 * when prefixing the hash value with the hash algorithm name. e.g. sha256:<hash_value>.
-	 */
-	const size_t hash_alg_prefix_len = strlen(DM_IMA_TABLE_HASH_ALG) + 1;
 	char table_load_event_name[] = "dm_table_load";
 
 	ima_buf = dm_ima_alloc(DM_IMA_MEASUREMENT_BUF_LEN, noio);
 	if (!ima_buf)
 		return;
@@ -208,23 +200,11 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl
 	num_targets = table->num_targets;
 
 	if (dm_ima_alloc_and_copy_device_data(table->md, &device_data_buf, num_targets, noio))
 		goto error;
 
-	tfm = crypto_alloc_shash(DM_IMA_TABLE_HASH_ALG, 0, 0);
-	if (IS_ERR(tfm))
-		goto error;
-
-	shash->tfm = tfm;
-	digest_size = crypto_shash_digestsize(tfm);
-	digest = dm_ima_alloc(digest_size, noio);
-	if (!digest)
-		goto error;
-
-	r = crypto_shash_init(shash);
-	if (r)
-		goto error;
+	sha256_init(&hash_ctx);
 
 	memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len);
 	l += table->md->ima.dm_version_str_len;
 
 	device_data_buf_len = strlen(device_data_buf);
@@ -268,13 +248,11 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl
 		 * we have in the current buffer, and continue measuring the remaining
 		 * targets by prefixing the device metadata again.
 		 */
 		if (unlikely(cur_total_buf_len >= DM_IMA_MEASUREMENT_BUF_LEN)) {
 			dm_ima_measure_data(table_load_event_name, ima_buf, l, noio);
-			r = crypto_shash_update(shash, (const u8 *)ima_buf, l);
-			if (r < 0)
-				goto error;
+			sha256_update(&hash_ctx, (const u8 *)ima_buf, l);
 
 			memset(ima_buf, 0, DM_IMA_MEASUREMENT_BUF_LEN);
 			l = 0;
 
 			/*
@@ -309,34 +287,25 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl
 	}
 
 	if (!last_target_measured) {
 		dm_ima_measure_data(table_load_event_name, ima_buf, l, noio);
 
-		r = crypto_shash_update(shash, (const u8 *)ima_buf, l);
-		if (r < 0)
-			goto error;
+		sha256_update(&hash_ctx, (const u8 *)ima_buf, l);
 	}
 
 	/*
 	 * Finalize the table hash, and store it in table->md->ima.inactive_table.hash,
 	 * so that the table data can be verified against the future device state change
 	 * events, e.g. resume, rename, remove, table-clear etc.
 	 */
-	r = crypto_shash_final(shash, digest);
-	if (r < 0)
-		goto error;
-
-	digest_buf = dm_ima_alloc((digest_size*2) + hash_alg_prefix_len + 1, noio);
+	sha256_final(&hash_ctx, digest);
 
+	digest_buf = kasprintf(GFP_KERNEL, "sha256:%*phN", SHA256_DIGEST_SIZE,
+			       digest);
 	if (!digest_buf)
 		goto error;
 
-	snprintf(digest_buf, hash_alg_prefix_len + 1, "%s:", DM_IMA_TABLE_HASH_ALG);
-
-	for (i = 0; i < digest_size; i++)
-		snprintf((digest_buf + hash_alg_prefix_len + (i*2)), 3, "%02x", digest[i]);
-
 	if (table->md->ima.active_table.hash != table->md->ima.inactive_table.hash)
 		kfree(table->md->ima.inactive_table.hash);
 
 	table->md->ima.inactive_table.hash = digest_buf;
 	table->md->ima.inactive_table.hash_len = strlen(digest_buf);
@@ -352,13 +321,10 @@ void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_fl
 	goto exit;
 error:
 	kfree(digest_buf);
 	kfree(device_data_buf);
 exit:
-	kfree(digest);
-	if (tfm)
-		crypto_free_shash(tfm);
 	kfree(ima_buf);
 	kfree(target_metadata_buf);
 	kfree(target_data_buf);
 }
 
diff --git a/drivers/md/dm-ima.h b/drivers/md/dm-ima.h
index 568870a1a145..a403deca6093 100644
--- a/drivers/md/dm-ima.h
+++ b/drivers/md/dm-ima.h
@@ -13,11 +13,10 @@
 #define DM_IMA_MEASUREMENT_BUF_LEN	4096
 #define DM_IMA_DEVICE_BUF_LEN		1024
 #define DM_IMA_TARGET_METADATA_BUF_LEN	128
 #define DM_IMA_TARGET_DATA_BUF_LEN	2048
 #define DM_IMA_DEVICE_CAPACITY_BUF_LEN	128
-#define DM_IMA_TABLE_HASH_ALG		"sha256"
 
 #define __dm_ima_stringify(s) #s
 #define __dm_ima_str(s) __dm_ima_stringify(s)
 
 #define DM_IMA_VERSION_STR "dm_version="	\

base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
-- 
2.53.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-02-26  1:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-26  1:39 [PATCH] dm-ima: use SHA-256 library Eric Biggers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox