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 <[email protected]> --- 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

