[RFC PATCH v1 7/7] ima: make SHA1 non-mandatory

Nicolai Stange
2025-03-13T17:35:34Z

For CONFIG_IMA_COMPAT_FALLBACK_TPM_EXTEND=n, SHA-1 is not a hard
requirement anymore. Make ima_init_crypto() continue on SHA-1
instantiation errors.

Note that the configure ima_hash must still be available. If that
happened to be set to SHA-1 and SHA-1 was missing, then IMA would
still fail to initialize.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
security/integrity/ima/ima_crypto.c | 60 ++++++++++++++---------------
1 file changed, 28 insertions(+), 32 deletions(-)

diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 118ea15d737b..f68435f2679f 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -147,56 +147,51 @@ int __init ima_init_crypto(void)
goto out;
}

+ ima_algo_array[ima_hash_algo_idx].tfm = ima_shash_tfm;
+ ima_algo_array[ima_hash_algo_idx].algo = ima_hash_algo;
+
+ if (ima_hash_algo != HASH_ALGO_SHA1) {
+ ima_algo_array[ima_sha1_idx].tfm =
+ ima_alloc_tfm(HASH_ALGO_SHA1);
+ if (IS_ERR(ima_algo_array[ima_sha1_idx].tfm)) {
+#if IS_ENABLED(CONFIG_IMA_COMPAT_FALLBACK_TPM_EXTEND)
+ /*
+ * For backwards compatible fallback PCR
+ * extension, SHA1 is the fallback for missing
+ * algos.
+ */
+ rc = PTR_ERR(ima_algo_array[ima_sha1_idx].tfm);
+ goto out_array;
+#endif
+ ima_algo_array[ima_sha1_idx].tfm = NULL;
+ ima_unsupported_tpm_banks_mask |= BIT(ima_sha1_idx);
+ }
+ ima_algo_array[ima_sha1_idx].algo = HASH_ALGO_SHA1;
+ }
+
for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
algo = ima_tpm_chip->allocated_banks[i].crypto_id;
ima_algo_array[i].algo = algo;

+ /* Initialized separately above. */
+ if (i == ima_hash_algo_idx || i == ima_sha1_idx)
+ continue;
+
/* unknown TPM algorithm */
if (algo == HASH_ALGO__LAST) {
ima_unsupported_tpm_banks_mask |= BIT(i);
continue;
}

- if (algo == ima_hash_algo) {
- ima_algo_array[i].tfm = ima_shash_tfm;
- continue;
- }
-
ima_algo_array[i].tfm = ima_alloc_tfm(algo);
if (IS_ERR(ima_algo_array[i].tfm)) {
- if (algo == HASH_ALGO_SHA1) {
- rc = PTR_ERR(ima_algo_array[i].tfm);
- ima_algo_array[i].tfm = NULL;
- goto out_array;
- }
-
ima_algo_array[i].tfm = NULL;
ima_unsupported_tpm_banks_mask |= BIT(i);
}
}

- if (ima_sha1_idx >= NR_BANKS(ima_tpm_chip)) {
- if (ima_hash_algo == HASH_ALGO_SHA1) {
- ima_algo_array[ima_sha1_idx].tfm = ima_shash_tfm;
- } else {
- ima_algo_array[ima_sha1_idx].tfm =
- ima_alloc_tfm(HASH_ALGO_SHA1);
- if (IS_ERR(ima_algo_array[ima_sha1_idx].tfm)) {
- rc = PTR_ERR(ima_algo_array[ima_sha1_idx].tfm);
- goto out_array;
- }
- }
-
- ima_algo_array[ima_sha1_idx].algo = HASH_ALGO_SHA1;
- }
-
- if (ima_hash_algo_idx >= NR_BANKS(ima_tpm_chip) &&
- ima_hash_algo_idx != ima_sha1_idx) {
- ima_algo_array[ima_hash_algo_idx].tfm = ima_shash_tfm;
- ima_algo_array[ima_hash_algo_idx].algo = ima_hash_algo;
- }
-
return 0;
+#if IS_ENABLED(CONFIG_IMA_COMPAT_FALLBACK_TPM_EXTEND)
out_array:
for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
if (!ima_algo_array[i].tfm ||
@@ -206,6 +201,7 @@ int __init ima_init_crypto(void)
crypto_free_shash(ima_algo_array[i].tfm);
}
kfree(ima_algo_array);
+#endif
out:
crypto_free_shash(ima_shash_tfm);
return rc;
--
2.47.1