]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ima: Define and use a digest_size field in the ima_algo_desc structure
authorRoberto Sassu <roberto.sassu@huawei.com>
Fri, 27 Feb 2026 12:06:45 +0000 (13:06 +0100)
committerMimi Zohar <zohar@linux.ibm.com>
Sun, 8 Mar 2026 12:26:08 +0000 (08:26 -0400)
Add the digest_size field to the ima_algo_desc structure to determine the
digest size from the correct source.

If the hash algorithm is among allocated PCR banks, take the value from the
TPM bank info (equal to the value from the crypto subsystem if the TPM
algorithm is supported by it; otherwise, not exceding the size of the
digest buffer in the tpm_digest structure, used by IMA).

If the hash algorithm is SHA1, use the predefined value. Lastly, if the
hash algorithm is the default one but not among the PCR banks, take the
digest size from the crypto subsystem (the default hash algorithm is
checked when parsing the ima_hash= command line option).

Finally, use the new information to correctly show the template digest in
ima_measurements_show() and ima_ascii_measurements_show().

Link: https://github.com/linux-integrity/linux/issues/14
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
security/integrity/ima/ima.h
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_fs.c

index 89ebe98ffc5e57621e342d7c25672aeb4a357750..c38a9eb945b6886721da3f08dfb8429b2e6e930d 100644 (file)
@@ -53,6 +53,7 @@ extern atomic_t ima_setxattr_allowed_hash_algorithms;
 struct ima_algo_desc {
        struct crypto_shash *tfm;
        enum hash_algo algo;
+       unsigned int digest_size;
 };
 
 /* set during initialization */
index aff61643415dec87dc33dd93964b29041ddc3b63..10022b0db4d582c5ba15d26d7ea2bae9e2532361 100644 (file)
@@ -109,6 +109,7 @@ static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo)
 
 int __init ima_init_crypto(void)
 {
+       unsigned int digest_size;
        enum hash_algo algo;
        long rc;
        int i;
@@ -147,7 +148,9 @@ int __init ima_init_crypto(void)
 
        for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
                algo = ima_tpm_chip->allocated_banks[i].crypto_id;
+               digest_size = ima_tpm_chip->allocated_banks[i].digest_size;
                ima_algo_array[i].algo = algo;
+               ima_algo_array[i].digest_size = digest_size;
 
                /* unknown TPM algorithm */
                if (algo == HASH_ALGO__LAST)
@@ -183,12 +186,15 @@ int __init ima_init_crypto(void)
                }
 
                ima_algo_array[ima_sha1_idx].algo = HASH_ALGO_SHA1;
+               ima_algo_array[ima_sha1_idx].digest_size = SHA1_DIGEST_SIZE;
        }
 
        if (ima_hash_algo_idx >= NR_BANKS(ima_tpm_chip) &&
            ima_hash_algo_idx != ima_sha1_idx) {
+               digest_size = hash_digest_size[ima_hash_algo];
                ima_algo_array[ima_hash_algo_idx].tfm = ima_shash_tfm;
                ima_algo_array[ima_hash_algo_idx].algo = ima_hash_algo;
+               ima_algo_array[ima_hash_algo_idx].digest_size = digest_size;
        }
 
        return 0;
index 012a58959ff022e29f09d7408aa6eb2966e66162..23d3a14b8ce362886b48122b55c152ccae7dd470 100644 (file)
@@ -132,16 +132,12 @@ int ima_measurements_show(struct seq_file *m, void *v)
        char *template_name;
        u32 pcr, namelen, template_data_len; /* temporary fields */
        bool is_ima_template = false;
-       enum hash_algo algo;
        int i, algo_idx;
 
        algo_idx = ima_sha1_idx;
-       algo = HASH_ALGO_SHA1;
 
-       if (m->file != NULL) {
+       if (m->file != NULL)
                algo_idx = (unsigned long)file_inode(m->file)->i_private;
-               algo = ima_algo_array[algo_idx].algo;
-       }
 
        /* get entry */
        e = qe->entry;
@@ -160,7 +156,8 @@ int ima_measurements_show(struct seq_file *m, void *v)
        ima_putc(m, &pcr, sizeof(e->pcr));
 
        /* 2nd: template digest */
-       ima_putc(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
+       ima_putc(m, e->digests[algo_idx].digest,
+                ima_algo_array[algo_idx].digest_size);
 
        /* 3rd: template name size */
        namelen = !ima_canonical_fmt ? strlen(template_name) :
@@ -229,16 +226,12 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
        struct ima_queue_entry *qe = v;
        struct ima_template_entry *e;
        char *template_name;
-       enum hash_algo algo;
        int i, algo_idx;
 
        algo_idx = ima_sha1_idx;
-       algo = HASH_ALGO_SHA1;
 
-       if (m->file != NULL) {
+       if (m->file != NULL)
                algo_idx = (unsigned long)file_inode(m->file)->i_private;
-               algo = ima_algo_array[algo_idx].algo;
-       }
 
        /* get entry */
        e = qe->entry;
@@ -252,7 +245,8 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
        seq_printf(m, "%2d ", e->pcr);
 
        /* 2nd: template hash */
-       ima_print_digest(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
+       ima_print_digest(m, e->digests[algo_idx].digest,
+                        ima_algo_array[algo_idx].digest_size);
 
        /* 3th:  template name */
        seq_printf(m, " %s", template_name);