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@xxxxxxx> --- 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