ima: Use ima_hash_algo for collision detection in the measurement list
authorRoberto Sassu <roberto.sassu@huawei.com>
Wed, 25 Mar 2020 10:54:24 +0000 (11:54 +0100)
committerMimi Zohar <zohar@linux.ibm.com>
Mon, 20 Apr 2020 02:03:39 +0000 (22:03 -0400)
Before calculating a digest for each PCR bank, collisions were detected
with a SHA1 digest. This patch includes ima_hash_algo among the algorithms
used to calculate the template digest and checks collisions on that digest.

The position in the measurement entry array of the template digest
calculated with the IMA default hash algorithm is stored in the
ima_hash_algo_idx global variable and is determined at IMA initialization
time.

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_queue.c

index 2a7ed68e6414fdfab7457951ebb9afcfaeb6532c..467dfdbea25c6f0aecd7d1ccb8645e63b39e5b86 100644 (file)
@@ -53,6 +53,7 @@ extern int ima_policy_flag;
 /* set during initialization */
 extern int ima_hash_algo;
 extern int ima_sha1_idx __ro_after_init;
+extern int ima_hash_algo_idx __ro_after_init;
 extern int ima_extra_slots __ro_after_init;
 extern int ima_appraise;
 extern struct tpm_chip *ima_tpm_chip;
index a94972d3f929ad853d4a4a95c3bff50d34798b5e..5201f5ec2ce4f44d2fde323b865d86164abd83d9 100644 (file)
@@ -63,6 +63,7 @@ struct ima_algo_desc {
 };
 
 int ima_sha1_idx __ro_after_init;
+int ima_hash_algo_idx __ro_after_init;
 /*
  * Additional number of slots reserved, as needed, for SHA1
  * and IMA default algo.
@@ -122,15 +123,25 @@ int __init ima_init_crypto(void)
                return rc;
 
        ima_sha1_idx = -1;
+       ima_hash_algo_idx = -1;
 
        for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
                algo = ima_tpm_chip->allocated_banks[i].crypto_id;
                if (algo == HASH_ALGO_SHA1)
                        ima_sha1_idx = i;
+
+               if (algo == ima_hash_algo)
+                       ima_hash_algo_idx = i;
        }
 
-       if (ima_sha1_idx < 0)
+       if (ima_sha1_idx < 0) {
                ima_sha1_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++;
+               if (ima_hash_algo == HASH_ALGO_SHA1)
+                       ima_hash_algo_idx = ima_sha1_idx;
+       }
+
+       if (ima_hash_algo_idx < 0)
+               ima_hash_algo_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++;
 
        ima_algo_array = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots,
                                 sizeof(*ima_algo_array), GFP_KERNEL);
@@ -179,6 +190,12 @@ int __init ima_init_crypto(void)
                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;
 out_array:
        for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
index 82a9ca43b98971f18f0e1eba16e403d2f5c729a9..fb4ec270f620c8de4f4269c82196ff207d02025e 100644 (file)
@@ -55,8 +55,8 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value,
        key = ima_hash_key(digest_value);
        rcu_read_lock();
        hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) {
-               rc = memcmp(qe->entry->digests[ima_sha1_idx].digest,
-                           digest_value, TPM_DIGEST_SIZE);
+               rc = memcmp(qe->entry->digests[ima_hash_algo_idx].digest,
+                           digest_value, hash_digest_size[ima_hash_algo]);
                if ((rc == 0) && (qe->entry->pcr == pcr)) {
                        ret = qe;
                        break;
@@ -108,7 +108,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
 
        atomic_long_inc(&ima_htable.len);
        if (update_htable) {
-               key = ima_hash_key(entry->digests[ima_sha1_idx].digest);
+               key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
                hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
        }
 
@@ -160,7 +160,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
                           const char *op, struct inode *inode,
                           const unsigned char *filename)
 {
-       u8 *digest = entry->digests[ima_sha1_idx].digest;
+       u8 *digest = entry->digests[ima_hash_algo_idx].digest;
        struct tpm_digest *digests_arg = entry->digests;
        const char *audit_cause = "hash_added";
        char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];