[RFC PATCH v2 4/4] ima: Extend the real PCR12 with tempPCR value.

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

 



For each namespace do this calculation:
        tempPCR := HASH(tempPCR || tempValue);

And finally extend the real PCR12P:
        PCR12 := PCR_Extend(PCR12,tempPCR);

Then read the PCR12 and return its value to user-space.

Signed-off-by: Denis Semakin <denis.semakin@xxxxxxxxxx>
---
 security/integrity/ima/ima.h    |  2 +-
 security/integrity/ima/ima_fs.c | 83 +++++++++++++++++++++++++++++++--
 2 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index cca984301968..02d7b66098ca 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -27,7 +27,7 @@
 
 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
 		     IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
-enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 };
+enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10, TPM_PCR12 = 12 };
 
 /* digest size for IMA, fits SHA1 or MD5 */
 #define IMA_DIGEST_SIZE		SHA1_DIGEST_SIZE
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index d9e91b9f1564..8e517be7bba2 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -26,6 +26,7 @@
 #include "ima.h"
 
 extern struct list_head vpcr_list;
+static bool vpcr_mutex_acquired;
 
 bool ima_canonical_fmt;
 static int __init default_canonical_fmt_setup(char *str)
@@ -540,13 +541,28 @@ static const struct file_operations ima_active_ops = {
 	.write = ima_write_active,
 };
 
+struct {
+	struct ima_digest_data hdr;
+	char digest[SHA256_DIGEST_SIZE];
+} temp_vpcr_hash = {
+	.hdr = {
+		.algo = HASH_ALGO_SHA256,
+		.length = SHA256_DIGEST_SIZE,
+	},
+};
+
 static void *vpcr_start(struct seq_file *m, loff_t *pos)
 {
 	int err;
 
-	err = mutex_lock_interruptible(&vpcr_list_mutex);
-	if (err)
-		return ERR_PTR(err);
+	if (*pos == 0) {
+		err = mutex_lock_interruptible(&vpcr_list_mutex);
+		if (err) {
+			vpcr_mutex_acquired = false;
+			return ERR_PTR(err);
+		}
+		vpcr_mutex_acquired = true;
+	}
 
 	return seq_list_start(&vpcr_list, *pos);
 }
@@ -558,17 +574,76 @@ static void *vpcr_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void vpcr_stop(struct seq_file *m, void *v)
 {
+	int j;
+	int ret;
+	struct tpm_chip *tpm_chip;
+	struct tpm_digest *temp_tpm;
+	struct tpm_digest pcr12_digest;
+	struct ima_namespace *curr_ns = ima_ns_from_file(m->file);
+
+	if (!vpcr_mutex_acquired)
+		return;
+
+	tpm_chip = curr_ns->ima_tpm_chip;
+	pcr12_digest.alg_id = TPM_ALG_SHA256;
+
+	temp_tpm = kcalloc(tpm_chip->nr_allocated_banks,
+			   sizeof(*curr_ns->digests), GFP_NOFS);
+	if (!temp_tpm)
+		goto ex;
+
+	for (j = 0; j < tpm_chip->nr_allocated_banks; j++) {
+		temp_tpm[j].alg_id = tpm_chip->allocated_banks[j].alg_id;
+
+
+		if (temp_tpm[j].alg_id == TPM_ALG_SHA256)
+			memcpy(&temp_tpm[j].digest, &temp_vpcr_hash.digest,
+			       SHA256_DIGEST_SIZE);
+		else
+			memset(&temp_tpm[j].digest, 0,
+			       hash_digest_size[tpm_chip->allocated_banks[j].crypto_id]);
+	}
+
+	ret = tpm_pcr_extend(tpm_chip, TPM_PCR12, temp_tpm);
+	if (ret != 0) {
+		seq_puts(m, "TPM extend error\n");
+		goto free_mem;
+	}
+
+	ret = tpm_pcr_read(tpm_chip, TPM_PCR12, &pcr12_digest);
+	if (ret != 0) {
+		seq_puts(m, "TPM read error\n");
+		goto free_mem;
+	}
+
+	ima_putc(m, "PCR12: ", strlen("PCR12: "));
+	ima_putc(m, pcr12_digest.digest, SHA256_DIGEST_SIZE);
+
+free_mem:
+	kfree(temp_tpm);
+ex:
 	mutex_unlock(&vpcr_list_mutex);
+	vpcr_mutex_acquired = false;
 }
 
 static int vpcr_show(struct seq_file *m, void *v)
 {
+	int ret = 0;
+	u8 buf[IMA_MAX_DIGEST_SIZE * 2] = {0};
 	struct vpcr_entry *vpcr = list_entry(v, struct vpcr_entry, list);
+	struct ima_namespace *curr_ns = container_of(vpcr, struct ima_namespace,
+						     vpcr);
 
 	ima_putc(m, "cPCR: ", strlen("cPCR: "));
 	ima_putc(m, vpcr->vpcr_tmp, SHA256_DIGEST_SIZE);
 
-	return 0;
+	memcpy(buf, &temp_vpcr_hash.digest, SHA256_DIGEST_SIZE);
+	memcpy(buf + SHA256_DIGEST_SIZE, vpcr->vpcr_tmp,
+	       SHA256_DIGEST_SIZE);
+
+	ret = ima_calc_buffer_hash(curr_ns, buf, SHA256_DIGEST_SIZE * 2,
+				   &temp_vpcr_hash.hdr);
+	return ret;
 }
 
 const struct seq_operations vpcr_seq_ops = {
-- 
2.38.GIT




[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