[RFC][PATCH] ima: add crypto agility support for template-hash algorithm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The purpose of this patch is to add the possibility to configure the hash
algorithm to use when calculating the template-hash.
The ima_template_hash command line parameter has been introduced to enable
this configuration.
The entry will contain the hash_algo_name before the actual template-hash,
separated by a colon (:).
An example of the resulting ima log is the following:

10 sha256:64326[...]25313 ima-ng sha1:5fc9b[...]974e6 boot_aggregate
10 sha256:afd64[...]e3123 ima-ng sha1:5a493[...]f9566 /init
10 sha256:99329[...]a6353 ima-ng sha1:8c87d[...]3d8c7 /usr/bin/sh
10 sha256:a16ad[...]2ac0e ima-ng sha1:59d4b[...]330b0 /etc/ld.so.cache

This patch has been created starting from the master branch of the main tree:
<git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git>

Signed-off-by: Silvia Sisinni <silvia.sisinni@xxxxxxxxx>
Signed-off-by: Enrico Bravi <enrico.bravi@xxxxxxxxx>
---
 security/integrity/ima/Kconfig      | 30 +++++++++++++++++++++++++++
 security/integrity/ima/ima.h        |  2 ++
 security/integrity/ima/ima_crypto.c | 26 ++++++++++++++++++++++-
 security/integrity/ima/ima_fs.c     | 25 ++++++++++++++--------
 security/integrity/ima/ima_main.c   | 32 +++++++++++++++++++++++++++++
 5 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index a6bd817efc1a..9cdeedb2be53 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -121,6 +121,36 @@ config IMA_DEFAULT_HASH
 	default "wp512" if IMA_DEFAULT_HASH_WP512
 	default "sm3" if IMA_DEFAULT_HASH_SM3
 
+choice
+	prompt "Default template-hash algorithm"
+	default IMA_DEFAULT_TEMPLATE_HASH_SHA1
+	depends on IMA
+	help
+	   Select the default template-hash algorithm written in Measurement
+	   Log entries. The compiled default template-hash algorithm can
+	   be overwritten using the kernel command line 'ima_template_hash='
+	   option.
+
+	config IMA_DEFAULT_TEMPLATE_HASH_SHA1
+		bool "SHA1 (default)"
+		depends on CRYPTO_SHA1=y
+
+	config IMA_DEFAULT_TEMPLATE_HASH_SHA256
+		bool "SHA256"
+		depends on CRYPTO_SHA256=y
+
+	config IMA_DEFAULT_TEMPLATE_HASH_SHA512
+		bool "SHA512"
+		depends on CRYPTO_SHA512=y
+endchoice
+
+config IMA_DEFAULT_TEMPLATE_HASH
+	string
+	depends on IMA
+	default "sha1" if IMA_DEFAULT_TEMPLATE_HASH_SHA1
+	default "sha256" if IMA_DEFAULT_TEMPLATE_HASH_SHA256
+	default "sha512" if IMA_DEFAULT_TEMPLATE_HASH_SHA512
+
 config IMA_WRITE_POLICY
 	bool "Enable multiple writes to the IMA policy"
 	default n
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index c29db699c996..a19375b9a6e4 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -55,6 +55,8 @@ 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 int ima_template_hash_algo __ro_after_init;
+extern int ima_template_hash_algo_idx __ro_after_init;
 extern struct tpm_chip *ima_tpm_chip;
 extern const char boot_aggregate_name[];
 
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 51ad29940f05..448b55ed5033 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -64,6 +64,7 @@ struct ima_algo_desc {
 
 int ima_sha1_idx __ro_after_init;
 int ima_hash_algo_idx __ro_after_init;
+int ima_template_hash_algo_idx __ro_after_init;
 /*
  * Additional number of slots reserved, as needed, for SHA1
  * and IMA default algo.
@@ -124,6 +125,7 @@ int __init ima_init_crypto(void)
 
 	ima_sha1_idx = -1;
 	ima_hash_algo_idx = -1;
+	ima_template_hash_algo_idx = -1;
 
 	for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
 		algo = ima_tpm_chip->allocated_banks[i].crypto_id;
@@ -132,16 +134,28 @@ int __init ima_init_crypto(void)
 
 		if (algo == ima_hash_algo)
 			ima_hash_algo_idx = i;
+
+		if (algo == ima_template_hash_algo)
+			ima_template_hash_algo_idx = i;
 	}
 
 	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_template_hash_algo == HASH_ALGO_SHA1)
+			ima_template_hash_algo_idx = ima_sha1_idx;
 	}
 
-	if (ima_hash_algo_idx < 0)
+	if (ima_hash_algo_idx < 0) {
 		ima_hash_algo_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++;
+		if (ima_template_hash_algo == ima_hash_algo)
+			ima_template_hash_algo_idx = ima_hash_algo_idx;
+	}
+
+	if (ima_template_hash_algo_idx < 0)
+		ima_template_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);
@@ -196,6 +210,16 @@ int __init ima_init_crypto(void)
 		ima_algo_array[ima_hash_algo_idx].algo = ima_hash_algo;
 	}
 
+	if (ima_template_hash_algo_idx >= NR_BANKS(ima_tpm_chip) &&
+		ima_template_hash_algo_idx != ima_sha1_idx &&
+		ima_template_hash_algo_idx != ima_hash_algo_idx) {
+		ima_algo_array[ima_template_hash_algo_idx].tfm = ima_alloc_tfm(ima_template_hash_algo);
+		if (IS_ERR(ima_algo_array[ima_template_hash_algo_idx].tfm)) {
+			rc = PTR_ERR(ima_algo_array[ima_template_hash_algo_idx].tfm);
+			goto out_array;
+		}
+	}
+
 	return 0;
 out_array:
 	for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index cd1683dad3bf..5545602a6144 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -21,6 +21,7 @@
 #include <linux/rcupdate.h>
 #include <linux/parser.h>
 #include <linux/vmalloc.h>
+#include <crypto/hash_info.h>
 
 #include "ima.h"
 
@@ -130,7 +131,7 @@ int ima_measurements_show(struct seq_file *m, void *v)
 	struct ima_queue_entry *qe = v;
 	struct ima_template_entry *e;
 	char *template_name;
-	u32 pcr, namelen, template_data_len; /* temporary fields */
+	u32 pcr, namelen, template_hash_len, template_data_len; /* temporary fields */
 	bool is_ima_template = false;
 	int i;
 
@@ -150,18 +151,23 @@ int ima_measurements_show(struct seq_file *m, void *v)
 	pcr = !ima_canonical_fmt ? e->pcr : (__force u32)cpu_to_le32(e->pcr);
 	ima_putc(m, &pcr, sizeof(e->pcr));
 
-	/* 2nd: template digest */
-	ima_putc(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
+	/* 2nd: template digest size */
+	template_hash_len = !ima_canonical_fmt ? hash_digest_size[ima_template_hash_algo] :
+		(__force u32)cpu_to_le32(hash_digest_size[ima_template_hash_algo]);
+	ima_putc(m, &template_hash_len, sizeof(template_hash_len));
 
-	/* 3rd: template name size */
+	/* 3rd: template digest */
+	ima_putc(m, e->digests[ima_template_hash_algo_idx].digest, hash_digest_size[ima_template_hash_algo]);
+
+	/* 4th: template name size */
 	namelen = !ima_canonical_fmt ? strlen(template_name) :
 		(__force u32)cpu_to_le32(strlen(template_name));
 	ima_putc(m, &namelen, sizeof(namelen));
 
-	/* 4th:  template name */
+	/* 5th:  template name */
 	ima_putc(m, template_name, strlen(template_name));
 
-	/* 5th:  template length (except for 'ima' template) */
+	/* 6th:  template length (except for 'ima' template) */
 	if (strcmp(template_name, IMA_TEMPLATE_IMA_NAME) == 0)
 		is_ima_template = true;
 
@@ -171,7 +177,7 @@ int ima_measurements_show(struct seq_file *m, void *v)
 		ima_putc(m, &template_data_len, sizeof(e->template_data_len));
 	}
 
-	/* 6th:  template specific data */
+	/* 7th:  template specific data */
 	for (i = 0; i < e->template_desc->num_fields; i++) {
 		enum ima_show_type show = IMA_SHOW_BINARY;
 		const struct ima_template_field *field =
@@ -233,8 +239,9 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
 	/* 1st: PCR used (config option) */
 	seq_printf(m, "%2d ", e->pcr);
 
-	/* 2nd: SHA1 template hash */
-	ima_print_digest(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
+	/* 2nd: template hash (hash_algo_name:digest)*/
+	seq_printf(m, "%s:", hash_algo_name[ima_template_hash_algo]);
+	ima_print_digest(m, e->digests[ima_template_hash_algo_idx].digest, hash_digest_size[ima_template_hash_algo]);
 
 	/* 3th:  template name */
 	seq_printf(m, " %s", template_name);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index cc1217ac2c6f..fa31ecb66606 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -36,7 +36,9 @@ int ima_appraise;
 #endif
 
 int __ro_after_init ima_hash_algo = HASH_ALGO_SHA1;
+int __ro_after_init ima_template_hash_algo = HASH_ALGO_SHA1;
 static int hash_setup_done;
+static int template_hash_setup_done;
 
 static struct notifier_block ima_lsm_policy_notifier = {
 	.notifier_call = ima_lsm_policy_change,
@@ -76,6 +78,26 @@ static int __init hash_setup(char *str)
 }
 __setup("ima_hash=", hash_setup);
 
+static int __init template_hash_setup(char *str)
+{
+	int i;
+
+	if (template_hash_setup_done)
+		return 1;
+
+	i = match_string(hash_algo_name, HASH_ALGO__LAST, str);
+	if (i < 0) {
+		pr_err("invalid template-hash algorithm \"%s\"", str);
+		return 1;
+	}
+
+	ima_template_hash_algo = i;
+
+	template_hash_setup_done = 1;
+	return 1;
+}
+__setup("ima_template_hash=", template_hash_setup);
+
 enum hash_algo ima_get_current_hash_algo(void)
 {
 	return ima_hash_algo;
@@ -1096,6 +1118,7 @@ static int __init init_ima(void)
 	ima_appraise_parse_cmdline();
 	ima_init_template_list();
 	hash_setup(CONFIG_IMA_DEFAULT_HASH);
+	template_hash_setup(CONFIG_IMA_DEFAULT_TEMPLATE_HASH);
 	error = ima_init();
 
 	if (error && strcmp(hash_algo_name[ima_hash_algo],
@@ -1107,6 +1130,15 @@ static int __init init_ima(void)
 		error = ima_init();
 	}
 
+	if (error && strcmp(hash_algo_name[ima_template_hash_algo],
+			    CONFIG_IMA_DEFAULT_TEMPLATE_HASH) != 0) {
+		pr_info("Allocating %s failed, going to use default template-hash algorithm %s\n",
+			hash_algo_name[ima_template_hash_algo], CONFIG_IMA_DEFAULT_TEMPLATE_HASH);
+		template_hash_setup_done = 0;
+		template_hash_setup(CONFIG_IMA_DEFAULT_TEMPLATE_HASH);
+		error = ima_init();
+	}
+
 	if (error)
 		return error;

base-commit: 88035e5694a86a7167d490bb95e9df97a9bb162b 
-- 
2.34.1





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux