linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest
@ 2020-02-21 18:38 Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 1/8] ima-evm-utils: treat unallocated banks as an error Mimi Zohar
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

IMA currently extends the different TPM banks by padding/truncating the
SHA1 template digest.  Although the IMA measurement list only includes
the SHA1 template digest, the template digest could be re-calculated
properly for each bank.  Roberto Sassu's proposed "ima: support stronger
algorithms for attestation" kernel patch set makes this change.

In order to test the proposed kernel change, this patch set walks the
IMA measurement list, re-calculating the per TPM bank template digest
and extending the TPM bank PCR with the bank specific digest.  The last
step, after walking the measurement list, is comparing the the resulting
TPM per bank PCR values with the actual TPM per bank PCR values.

(Verifying the non SHA1 TPM banks depends on a kernel built with
Roberto's "ima: support stronger algorithms for attestation" patch set.)

Mimi

Mimi Zohar (8):
  ima-evm-utils: treat unallocated banks as an error
  ima-evm-utils: increase the size of "zero" and "fox" variables
  ima-evm-utils: calculate the digests for multiple TPM banks
  ima-evm-utils: add support in tpm2_read_pcrs to read different TPM
    banks
  ima-evm-utils: read the PCRs for the requested TPM banks
  ima-evm-utils: compare re-calculated PCRs with the TPM values
  ima-evm-utils: use a common bank variable for TPM 1.2 and TPM 2.0
  ima-evm-utils: remove TPM 1.2 specific code

 src/evmctl.c | 349 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 284 insertions(+), 65 deletions(-)

-- 
2.7.5


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 1/8] ima-evm-utils: treat unallocated banks as an error
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 2/8] ima-evm-utils: increase the size of "zero" and "fox" variables Mimi Zohar
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

The TPM spec differentiates between an unknown bank and an unallocated
bank.  In terms of re-calculating the PCR, treat them as equivalent.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/evmctl.c b/src/evmctl.c
index be59ead45189..704615694cec 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1449,6 +1449,11 @@ static int tpm2_pcr_read(int idx, uint8_t *hwpcr, int len, char **errmsg)
 
 	/* get the popen "cmd" return code */
 	ret = pclose(fp);
+
+	/* Treat an unallocated bank as an error */
+	if (!ret && (strlen(pcr) < SHA_DIGEST_LENGTH))
+		ret = -1;
+
 	if (!ret)
 		hex2bin(hwpcr, pcr, SHA_DIGEST_LENGTH);
 	else
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 2/8] ima-evm-utils: increase the size of "zero" and "fox" variables
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 1/8] ima-evm-utils: treat unallocated banks as an error Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 3/8] ima-evm-utils: calculate the digests for multiple TPM banks Mimi Zohar
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

Opening a file for write when it is already opened for read, results in
a time of measure, time of use (ToMToU) error.  Similarly, when opening
a file for read, when it is already opened for write, results in a file
measurement error.  These violations are flagged by including 0x00's as
the template digest in the measurement list, but extending the TPM with
0xFF's.

In preparation of extending the TPM banks with bank specific digest
values, increase the "zero" and "fox" variable sizes.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/evmctl.c b/src/evmctl.c
index 704615694cec..9c8544a95b6a 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1477,8 +1477,8 @@ struct template_entry {
 	int template_buf_len;
 };
 
-static uint8_t zero[SHA_DIGEST_LENGTH];
-static uint8_t fox[SHA_DIGEST_LENGTH];
+static uint8_t zero[MAX_DIGEST_SIZE];
+static uint8_t fox[MAX_DIGEST_SIZE];
 
 int validate = 1;
 
@@ -1499,7 +1499,7 @@ static int ima_verify_template_hash(struct template_entry *entry)
 {
 	uint8_t digest[SHA_DIGEST_LENGTH];
 
-	if (!memcmp(zero, entry->header.digest, sizeof(zero)))
+	if (!memcmp(zero, entry->header.digest, sizeof(digest)))
 		return 0;
 
 	SHA1(entry->template, entry->template_len, digest);
@@ -1658,8 +1658,8 @@ static int ima_measurement(const char *file)
 	int i;
 
 	errno = 0;
-	memset(zero, 0, SHA_DIGEST_LENGTH);
-	memset(fox, 0xff, SHA_DIGEST_LENGTH);
+	memset(zero, 0, MAX_DIGEST_SIZE);
+	memset(fox, 0xff, MAX_DIGEST_SIZE);
 
 	log_debug("Initial PCR value: ");
 	log_debug_dump(pcr, sizeof(pcr));
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 3/8] ima-evm-utils: calculate the digests for multiple TPM banks
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 1/8] ima-evm-utils: treat unallocated banks as an error Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 2/8] ima-evm-utils: increase the size of "zero" and "fox" variables Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 4/8] ima-evm-utils: add support in tpm2_read_pcrs to read different " Mimi Zohar
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

IMA currently extends the different TPM banks by padding/truncating the
SHA1 template digest.  Although the IMA measurement list only includes
the SHA1 template digest, the template digest could be re-calculated
properly for each bank.

This patch adds support for properly calculating the template hash for
multiple TPM banks - "sha1" and "sha256".

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)

diff --git a/src/evmctl.c b/src/evmctl.c
index 9c8544a95b6a..61a0e15c8dd7 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -63,6 +63,7 @@
 #include <openssl/err.h>
 #include <openssl/rsa.h>
 #include <openssl/engine.h>
+#include "hash_info.h"
 
 #ifndef XATTR_APPAARMOR_SUFFIX
 #define XATTR_APPARMOR_SUFFIX "apparmor"
@@ -1647,8 +1648,165 @@ void ima_ng_show(struct template_entry *entry)
 	}
 }
 
+struct tpm_bank_info {
+	int digest_size;
+	int supported;
+	const char *algo_name;
+	uint8_t digest[MAX_DIGEST_SIZE];
+	uint8_t pcr[NUM_PCRS][MAX_DIGEST_SIZE];
+};
+
+static void set_bank_info(struct tpm_bank_info *bank, const char *algo_name)
+{
+	const EVP_MD *md;
+
+	bank->algo_name = algo_name;
+	md = EVP_get_digestbyname(bank->algo_name);
+	if (!md)
+		return;
+
+	bank->supported = 1;
+	bank->digest_size = EVP_MD_size(md);
+}
+
+static struct tpm_bank_info *init_tpm_banks(int *num_banks)
+{
+	struct tpm_bank_info *banks = NULL;
+	const char *default_algos[] = {"sha1", "sha256"};
+	int num_algos = sizeof(default_algos) / sizeof(default_algos[0]);
+	int i, j;
+
+	banks = calloc(num_algos, sizeof(struct tpm_bank_info));
+	if (!banks)
+		return banks;
+
+	/* re-calculate the PCRs digests for only known algorithms */
+	*num_banks = num_algos;
+	for (i = 0; i < num_algos; i++) {
+		for (j = 0; j < HASH_ALGO__LAST; j++) {
+			if (!strcmp(default_algos[i], hash_algo_name[j]))
+				set_bank_info(&banks[i], hash_algo_name[j]);
+		}
+	}
+	return banks;
+}
+
+/* Calculate the template hash for a particular hash algorithm */
+static int calculate_template_digest(EVP_MD_CTX *pctx, const EVP_MD *md,
+				     struct template_entry *entry,
+				     struct tpm_bank_info *bank)
+{
+	unsigned int mdlen;
+	int err;
+
+	err = EVP_DigestInit(pctx, md);
+	if (!err) {
+		printf("EVP_DigestInit() failed\n");
+		goto out;
+	}
+
+	err = EVP_DigestUpdate(pctx, entry->template, entry->template_len);
+	if (!err) {
+		printf("EVP_DigestUpdate() failed\n");
+		goto out;
+	}
+
+	err = EVP_DigestFinal(pctx, bank->digest, &mdlen);
+	if (!err)
+		printf("EVP_DigestUpdate() failed\n");
+out:
+	if (!err)
+		err = 1;
+	return err;
+}
+
+/* Extend a specific TPM bank with the template hash */
+static int extend_tpm_bank(EVP_MD_CTX *pctx, const EVP_MD *md,
+			   struct template_entry *entry,
+			   struct tpm_bank_info *bank)
+{
+	unsigned int mdlen;
+	int err;
+
+	err = EVP_DigestInit(pctx, md);
+	if (!err) {
+		printf("EVP_DigestInit() failed\n");
+		goto out;
+	}
+
+	err = EVP_DigestUpdate(pctx, bank->pcr[entry->header.pcr],
+			       bank->digest_size);
+	if (!err) {
+		printf("EVP_DigestUpdate() failed\n");
+		goto out;
+	}
+
+	if (validate && !memcmp(entry->header.digest, zero, SHA_DIGEST_LENGTH))
+		err = EVP_DigestUpdate(pctx, fox, bank->digest_size);
+	else
+		err = EVP_DigestUpdate(pctx, bank->digest, bank->digest_size);
+	if (!err) {
+		printf("EVP_DigestUpdate() failed\n");
+		goto out;
+	}
+
+	err = EVP_DigestFinal(pctx, bank->pcr[entry->header.pcr], &mdlen);
+	if (!err)
+		printf("EVP_DigestFinal() failed\n");
+
+out:
+	if (!err)
+		err = 1;
+	return err;
+}
+
+/* Calculate and extend the template hash for multiple hash algorithms */
+static void extend_tpm_banks(struct template_entry *entry, int num_banks,
+			     struct tpm_bank_info *bank)
+{
+	EVP_MD_CTX *pctx;
+	const EVP_MD *md;
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+	EVP_MD_CTX ctx;
+	pctx = &ctx;
+#else
+	pctx = EVP_MD_CTX_new();
+#endif
+	int err;
+	int i;
+
+	for (i = 0; i < num_banks; i++) {
+		if (!bank[i].supported)
+			continue;
+		md = EVP_get_digestbyname(bank[i].algo_name);
+		if (!md) {
+			printf("EVP_get_digestbyname(%s) failed\n",
+				bank[i].algo_name);
+			bank[i].supported = 0;
+			continue;
+		}
+
+		err = calculate_template_digest(pctx, md, entry, &bank[i]);
+		if (!err) {
+			bank[i].supported = 0;
+			continue;
+		}
+
+		/* extend TPM BANK with template digest */
+		err = extend_tpm_bank(pctx, md, entry, &bank[i]);
+		if (!err)
+			bank[i].supported = 0;
+	}
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+	EVP_MD_CTX_free(pctx);
+#endif
+}
+
 static int ima_measurement(const char *file)
 {
+	struct tpm_bank_info *pseudo_banks;
+	int num_banks = 0;
+
 	uint8_t pcr[NUM_PCRS][SHA_DIGEST_LENGTH] = {{0}};
 	uint8_t hwpcr[SHA_DIGEST_LENGTH];
 	struct template_entry entry = { .template = 0 };
@@ -1664,6 +1822,8 @@ static int ima_measurement(const char *file)
 	log_debug("Initial PCR value: ");
 	log_debug_dump(pcr, sizeof(pcr));
 
+	pseudo_banks = init_tpm_banks(&num_banks);
+
 	fp = fopen(file, "rb");
 	if (!fp) {
 		log_err("Failed to open measurement file: %s\n", file);
@@ -1702,6 +1862,8 @@ static int ima_measurement(const char *file)
 			goto out;
 		}
 
+		extend_tpm_banks(&entry, num_banks, pseudo_banks);
+
 		if (validate)
 			ima_verify_template_hash(&entry);
 
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 4/8] ima-evm-utils: add support in tpm2_read_pcrs to read different TPM banks
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
                   ` (2 preceding siblings ...)
  2020-02-21 18:38 ` [RFC PATCH 3/8] ima-evm-utils: calculate the digests for multiple TPM banks Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 5/8] ima-evm-utils: read the PCRs for the requested " Mimi Zohar
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

tpm2_read_pcrs() reads the sha1 PCRs in order to verify the measurmeent
list.  This patch adds support for reading other TPM banks.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/evmctl.c b/src/evmctl.c
index 61a0e15c8dd7..1eeab1d8268b 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1423,14 +1423,16 @@ static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
 }
 
 #ifdef HAVE_TSSPCRREAD
-static int tpm2_pcr_read(int idx, uint8_t *hwpcr, int len, char **errmsg)
+static int tpm2_pcr_read(const char *algo_name, int idx, uint8_t *hwpcr,
+			 int len, char **errmsg)
 {
 	FILE *fp;
 	char pcr[100];	/* may contain an error */
 	char cmd[50];
 	int ret;
 
-	sprintf(cmd, "tsspcrread -halg sha1 -ha %d -ns 2> /dev/null", idx);
+	sprintf(cmd, "tsspcrread -halg %s -ha %d -ns 2> /dev/null",
+		algo_name, idx);
 	fp = popen(cmd, "r");
 	if (!fp) {
 		ret = asprintf(errmsg, "popen failed: %s", strerror(errno));
@@ -1456,7 +1458,7 @@ static int tpm2_pcr_read(int idx, uint8_t *hwpcr, int len, char **errmsg)
 		ret = -1;
 
 	if (!ret)
-		hex2bin(hwpcr, pcr, SHA_DIGEST_LENGTH);
+		hex2bin(hwpcr, pcr, len);
 	else
 		*errmsg = strndup(pcr, strlen(pcr) - 1); /* remove newline */
 
@@ -1885,7 +1887,8 @@ static int ima_measurement(const char *file)
 #ifdef HAVE_TSSPCRREAD
 			char *errmsg = NULL;
 
-			err = tpm2_pcr_read(i, hwpcr, sizeof(hwpcr), &errmsg);
+			err = tpm2_pcr_read("sha1", i, hwpcr, sizeof(hwpcr),
+					    &errmsg);
 			if (err) {
 				log_info("Failed to read PCRs: (%s)\n", errmsg);
 				free(errmsg);
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 5/8] ima-evm-utils: read the PCRs for the requested TPM banks
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
                   ` (3 preceding siblings ...)
  2020-02-21 18:38 ` [RFC PATCH 4/8] ima-evm-utils: add support in tpm2_read_pcrs to read different " Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 6/8] ima-evm-utils: compare re-calculated PCRs with the TPM values Mimi Zohar
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

Read and store the PCRs for the requested banks to compare with the
re-calculated PCR values.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/src/evmctl.c b/src/evmctl.c
index 1eeab1d8268b..3e512cf4e3d2 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1423,6 +1423,7 @@ static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
 }
 
 #ifdef HAVE_TSSPCRREAD
+static int tpm2_pcrread = 1;
 static int tpm2_pcr_read(const char *algo_name, int idx, uint8_t *hwpcr,
 			 int len, char **errmsg)
 {
@@ -1464,6 +1465,13 @@ static int tpm2_pcr_read(const char *algo_name, int idx, uint8_t *hwpcr,
 
 	return ret;
 }
+#else
+static int tpm2_pcrread = 0;
+static int tpm2_pcr_read(const char *algo_name, int idx, uint8_t *hwpcr,
+			 int len, char **errmsg)
+{
+	return -1;
+}
 #endif
 
 #define TCG_EVENT_NAME_LEN_MAX	255
@@ -1804,9 +1812,47 @@ static void extend_tpm_banks(struct template_entry *entry, int num_banks,
 #endif
 }
 
+/*
+ * Attempt to read TPM PCRs from the multiple TPM 2.0 banks.
+ *
+ * On success reading from any TPM bank, return 0.
+ */
+static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
+{
+	int tpm_enabled = 0;
+	char *errmsg = NULL;
+	int i, j;
+	int err;
+
+	/* Any userspace applications available for reading TPM 2.0 PCRs? */
+	if (!tpm2_pcrread) {
+		log_info("Failed to read TPM 2.0 PCRs\n");
+		return 1;
+	}
+
+	for (i = 0; i < num_banks; i++) {
+		err = 0;
+		for (j = 0; j < NUM_PCRS && !err; j++) {
+			err = tpm2_pcr_read(bank[i].algo_name, j,
+					    bank[i].pcr[j], bank[i].digest_size,
+					    &errmsg);
+			if (err) {
+				log_info("Failed to read %s PCRs: (%s)\n",
+					 bank[i].algo_name, errmsg);
+				free(errmsg);
+				bank[i].supported = 0;
+			}
+		}
+		if (bank[i].supported)
+			tpm_enabled = 1;
+	}
+	return tpm_enabled ? 0 : 1;
+}
+
 static int ima_measurement(const char *file)
 {
 	struct tpm_bank_info *pseudo_banks;
+	struct tpm_bank_info *tpm_banks;
 	int num_banks = 0;
 
 	uint8_t pcr[NUM_PCRS][SHA_DIGEST_LENGTH] = {{0}};
@@ -1825,6 +1871,7 @@ static int ima_measurement(const char *file)
 	log_debug_dump(pcr, sizeof(pcr));
 
 	pseudo_banks = init_tpm_banks(&num_banks);
+	tpm_banks = init_tpm_banks(&num_banks);
 
 	fp = fopen(file, "rb");
 	if (!fp) {
@@ -1912,6 +1959,9 @@ static int ima_measurement(const char *file)
 
 	if (!verify_failed)
 		err = 0;
+	else
+		read_tpm_banks(num_banks, tpm_banks);
+
 out:
 	fclose(fp);
 	return err;
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 6/8] ima-evm-utils: compare re-calculated PCRs with the TPM values
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
                   ` (4 preceding siblings ...)
  2020-02-21 18:38 ` [RFC PATCH 5/8] ima-evm-utils: read the PCRs for the requested " Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 7/8] ima-evm-utils: use a common bank variable for TPM 1.2 and TPM 2.0 Mimi Zohar
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

After walking the measurement list, re-calculating and extending the TPM
PCRs with the appropriate template digest for each bank, compare the
re-calculated PCR values for each TPM bank with the actual TPM values.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/evmctl.c b/src/evmctl.c
index 3e512cf4e3d2..9e21d3963556 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1701,6 +1701,38 @@ static struct tpm_bank_info *init_tpm_banks(int *num_banks)
 	return banks;
 }
 
+static int compare_tpm_banks(int num_banks, struct tpm_bank_info *bank,
+			     struct tpm_bank_info *tpm_bank)
+{
+	int i, j;
+	int ret = 0;
+
+	for (i = 0; i < num_banks; i++) {
+		if (!bank[i].supported || !tpm_bank[i].supported)
+			continue;
+		for (j = 0; j < NUM_PCRS; j++) {
+			if (memcmp(bank[i].pcr[j], zero, bank[i].digest_size)
+			    == 0)
+				continue;
+			log_info("%s: PCRAgg  %d: ", bank[i].algo_name, j);
+			log_dump(bank[i].pcr[j], bank[i].digest_size);
+
+			log_info("%s: TPM PCR-%d: ", tpm_bank[i].algo_name, j);
+			log_dump(tpm_bank[i].pcr[j], tpm_bank[i].digest_size);
+
+			ret = memcmp(bank[i].pcr[j], tpm_bank[i].pcr[j],
+				     bank[i].digest_size);
+			if (!ret)
+				log_info("%s PCR-%d: succeed\n",
+					 bank[i].algo_name, j);
+			else
+				log_info("%s: PCRAgg %d does not match TPM PCR-%d\n",
+					 bank[i].algo_name, i, i);
+		}
+	}
+	return ret;
+}
+
 /* Calculate the template hash for a particular hash algorithm */
 static int calculate_template_digest(EVP_MD_CTX *pctx, const EVP_MD *md,
 				     struct template_entry *entry,
@@ -1959,8 +1991,10 @@ static int ima_measurement(const char *file)
 
 	if (!verify_failed)
 		err = 0;
+	else if (read_tpm_banks(num_banks, tpm_banks) != 0)
+		log_info("Failed to read TPM 2.0 PCRs\n");
 	else
-		read_tpm_banks(num_banks, tpm_banks);
+		err = compare_tpm_banks(num_banks, pseudo_banks, tpm_banks);
 
 out:
 	fclose(fp);
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 7/8] ima-evm-utils: use a common bank variable for TPM 1.2 and TPM 2.0
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
                   ` (5 preceding siblings ...)
  2020-02-21 18:38 ` [RFC PATCH 6/8] ima-evm-utils: compare re-calculated PCRs with the TPM values Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-21 18:38 ` [RFC PATCH 8/8] ima-evm-utils: remove TPM 1.2 specific code Mimi Zohar
  2020-02-22  0:11 ` [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Lakshmi Ramasubramanian
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

Extend read_tpm_banks() to support TPM 1.2, by reading TPM 1.2 SHA1 PCRs
into the first bank and mark the other banks as disabled.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/src/evmctl.c b/src/evmctl.c
index 9e21d3963556..49ce7ea2ce1a 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1399,7 +1399,7 @@ static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
 	char *p, pcr_str[7], buf[70]; /* length of the TPM string */
 	int result = -1;
 
-	sprintf(pcr_str, "PCR-%d", idx);
+	sprintf(pcr_str, "PCR-%2.2d", idx);
 
 	fp = fopen(pcrs, "r");
 	if (!fp)
@@ -1844,8 +1844,26 @@ static void extend_tpm_banks(struct template_entry *entry, int num_banks,
 #endif
 }
 
+/* Read TPM 1.2 PCRs */
+static int read_tpm_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
+{
+	int i;
+
+	for (i = 0; i < NUM_PCRS; i++) {
+		if (tpm_pcr_read(i, tpm_banks[0].pcr[i], SHA_DIGEST_LENGTH)) {
+			log_debug("Failed to read TPM 1.2 PCRs.\n");
+			return -1;
+		}
+	}
+
+	tpm_banks[0].supported = 1;
+	for (i = 1; i < num_banks; i++)
+		tpm_banks[i].supported = 0;
+	return 0;
+}
+
 /*
- * Attempt to read TPM PCRs from the multiple TPM 2.0 banks.
+ * Attempt to read TPM PCRs from either TPM 1.2 or multiple TPM 2.0 banks.
  *
  * On success reading from any TPM bank, return 0.
  */
@@ -1856,12 +1874,17 @@ static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
 	int i, j;
 	int err;
 
+	/* First try reading PCRs from exported TPM 1.2 securityfs file */
+	if (read_tpm_pcrs(num_banks, bank) == 0)
+		return 0;
+
 	/* Any userspace applications available for reading TPM 2.0 PCRs? */
 	if (!tpm2_pcrread) {
-		log_info("Failed to read TPM 2.0 PCRs\n");
+		log_debug("Failed to read TPM 2.0 PCRs\n");
 		return 1;
 	}
 
+	/* Read PCRs from multiple TPM 2.0 banks */
 	for (i = 0; i < num_banks; i++) {
 		err = 0;
 		for (j = 0; j < NUM_PCRS && !err; j++) {
@@ -1869,8 +1892,8 @@ static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
 					    bank[i].pcr[j], bank[i].digest_size,
 					    &errmsg);
 			if (err) {
-				log_info("Failed to read %s PCRs: (%s)\n",
-					 bank[i].algo_name, errmsg);
+				log_debug("Failed to read %s PCRs: (%s)\n",
+					  bank[i].algo_name, errmsg);
 				free(errmsg);
 				bank[i].supported = 0;
 			}
@@ -1991,8 +2014,8 @@ static int ima_measurement(const char *file)
 
 	if (!verify_failed)
 		err = 0;
-	else if (read_tpm_banks(num_banks, tpm_banks) != 0)
-		log_info("Failed to read TPM 2.0 PCRs\n");
+	if (read_tpm_banks(num_banks, tpm_banks) != 0)
+		log_info("Failed to read any TPM PCRs\n");
 	else
 		err = compare_tpm_banks(num_banks, pseudo_banks, tpm_banks);
 
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 8/8] ima-evm-utils: remove TPM 1.2 specific code
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
                   ` (6 preceding siblings ...)
  2020-02-21 18:38 ` [RFC PATCH 7/8] ima-evm-utils: use a common bank variable for TPM 1.2 and TPM 2.0 Mimi Zohar
@ 2020-02-21 18:38 ` Mimi Zohar
  2020-02-22  0:11 ` [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Lakshmi Ramasubramanian
  8 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2020-02-21 18:38 UTC (permalink / raw)
  To: linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel,
	Mimi Zohar

Now that read_tpm_banks() reads the TPM 1.2 PCRs, remove the TPM 1.2
specific code for reading and verifying the SHA1 PCRs.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
 src/evmctl.c | 64 +++---------------------------------------------------------
 1 file changed, 3 insertions(+), 61 deletions(-)

diff --git a/src/evmctl.c b/src/evmctl.c
index 49ce7ea2ce1a..b6b9d19749e6 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1493,19 +1493,6 @@ static uint8_t fox[MAX_DIGEST_SIZE];
 
 int validate = 1;
 
-void ima_extend_pcr(uint8_t *pcr, uint8_t *digest, int length)
-{
-	SHA_CTX ctx;
-
-	SHA1_Init(&ctx);
-	SHA1_Update(&ctx, pcr, length);
-	if (validate && !memcmp(digest, zero, length))
-		SHA1_Update(&ctx, fox, length);
-	else
-		SHA1_Update(&ctx, digest, length);
-	SHA1_Final(pcr, &ctx);
-}
-
 static int ima_verify_template_hash(struct template_entry *entry)
 {
 	uint8_t digest[SHA_DIGEST_LENGTH];
@@ -1910,21 +1897,14 @@ static int ima_measurement(const char *file)
 	struct tpm_bank_info *tpm_banks;
 	int num_banks = 0;
 
-	uint8_t pcr[NUM_PCRS][SHA_DIGEST_LENGTH] = {{0}};
-	uint8_t hwpcr[SHA_DIGEST_LENGTH];
 	struct template_entry entry = { .template = 0 };
 	FILE *fp;
 	int err = -1;
-	bool verify_failed = false;
-	int i;
 
 	errno = 0;
 	memset(zero, 0, MAX_DIGEST_SIZE);
 	memset(fox, 0xff, MAX_DIGEST_SIZE);
 
-	log_debug("Initial PCR value: ");
-	log_debug_dump(pcr, sizeof(pcr));
-
 	pseudo_banks = init_tpm_banks(&num_banks);
 	tpm_banks = init_tpm_banks(&num_banks);
 
@@ -1940,9 +1920,6 @@ static int ima_measurement(const char *file)
 		init_public_keys("/etc/keys/x509_evm.der");
 
 	while (fread(&entry.header, sizeof(entry.header), 1, fp)) {
-		ima_extend_pcr(pcr[entry.header.pcr], entry.header.digest,
-			       SHA_DIGEST_LENGTH);
-
 		if (!fread(entry.name, entry.header.name_len, 1, fp)) {
 			log_err("Unable to read template name\n");
 			goto out;
@@ -1977,47 +1954,12 @@ static int ima_measurement(const char *file)
 			ima_ng_show(&entry);
 	}
 
-
-	for (i = 0; i < NUM_PCRS; i++) {
-		if (memcmp(pcr[i], zero, SHA_DIGEST_LENGTH) == 0)
-			continue;
-
-		log_info("PCRAgg %.2d: ", i);
-		log_dump(pcr[i], SHA_DIGEST_LENGTH);
-
-		if (tpm_pcr_read(i, hwpcr, sizeof(hwpcr))) {
-#ifdef HAVE_TSSPCRREAD
-			char *errmsg = NULL;
-
-			err = tpm2_pcr_read("sha1", i, hwpcr, sizeof(hwpcr),
-					    &errmsg);
-			if (err) {
-				log_info("Failed to read PCRs: (%s)\n", errmsg);
-				free(errmsg);
-				exit(1);
-			}
-#else
-			log_info("Failed to read TPM 1.2 PCRs.\n");
-			exit(1);
-#endif
-		}
-
-		log_info("HW PCR-%d: ", i);
-		log_dump(hwpcr, sizeof(hwpcr));
-
-		if (memcmp(pcr[i], hwpcr, sizeof(SHA_DIGEST_LENGTH)) != 0) {
-			log_err("PCRAgg %d does not match HW PCR-%d\n", i, i);
-
-			verify_failed = true;
-		}
-	}
-
-	if (!verify_failed)
+	if (read_tpm_banks(num_banks, tpm_banks) != 0) {
 		err = 0;
-	if (read_tpm_banks(num_banks, tpm_banks) != 0)
 		log_info("Failed to read any TPM PCRs\n");
-	else
+	} else {
 		err = compare_tpm_banks(num_banks, pseudo_banks, tpm_banks);
+	}
 
 out:
 	fclose(fp);
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest
  2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
                   ` (7 preceding siblings ...)
  2020-02-21 18:38 ` [RFC PATCH 8/8] ima-evm-utils: remove TPM 1.2 specific code Mimi Zohar
@ 2020-02-22  0:11 ` Lakshmi Ramasubramanian
  2020-02-23  1:12   ` Mimi Zohar
  8 siblings, 1 reply; 12+ messages in thread
From: Lakshmi Ramasubramanian @ 2020-02-22  0:11 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel

Hi Mimi,

> IMA currently extends the different TPM banks by padding/truncating the
> SHA1 template digest.  Although the IMA measurement list only includes
> the SHA1 template digest, the template digest could be re-calculated
> properly for each bank.  Roberto Sassu's proposed "ima: support stronger
> algorithms for attestation" kernel patch set makes this change.
> 
> In order to test the proposed kernel change, this patch set walks the
> IMA measurement list, re-calculating the per TPM bank template digest
> and extending the TPM bank PCR with the bank specific digest.  The last
> step, after walking the measurement list, is comparing the the resulting
> TPM per bank PCR values with the actual TPM per bank PCR values.

I have built the kernel with Roberto's patch set and also built evmctl 
with your patch set.

Could you please include an example for how evmctl can be used to test 
Roberto's change?

thanks,
  -lakshmi

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest
  2020-02-22  0:11 ` [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Lakshmi Ramasubramanian
@ 2020-02-23  1:12   ` Mimi Zohar
  2020-02-24 16:23     ` Lakshmi Ramasubramanian
  0 siblings, 1 reply; 12+ messages in thread
From: Mimi Zohar @ 2020-02-23  1:12 UTC (permalink / raw)
  To: Lakshmi Ramasubramanian, linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel

On Fri, 2020-02-21 at 16:11 -0800, Lakshmi Ramasubramanian wrote:
> Hi Mimi,
> 
> > IMA currently extends the different TPM banks by padding/truncating the
> > SHA1 template digest.  Although the IMA measurement list only includes
> > the SHA1 template digest, the template digest could be re-calculated
> > properly for each bank.  Roberto Sassu's proposed "ima: support stronger
> > algorithms for attestation" kernel patch set makes this change.
> > 
> > In order to test the proposed kernel change, this patch set walks the
> > IMA measurement list, re-calculating the per TPM bank template digest
> > and extending the TPM bank PCR with the bank specific digest.  The last
> > step, after walking the measurement list, is comparing the the resulting
> > TPM per bank PCR values with the actual TPM per bank PCR values.
> 
> I have built the kernel with Roberto's patch set and also built evmctl 
> with your patch set.
> 
> Could you please include an example for how evmctl can be used to test 
> Roberto's change?

There are two aspects to Roberto's changes - extending the TPM banks
with the bank specific template digest and verifying the boot
aggregate.  This patch set only addresses the first aspect.

Assuming both the sha1 and sha256 TPM banks are enabled,

# tssgetcapability -cap 5
2 PCR selections
    hash TPM_ALG_SHA1
    TPMS
_PCR_SELECTION length 3
    ff ff ff 
    hash TPM_ALG_SHA256
    TPMS_PC
R_SELECTION length 3
    ff ff ff 

the output would look like:
 
# evmctl ima_measurement -v --list
/sys/kernel/security/integrity/ima/binary_runtime_measurements

sha1: PCRAgg  10: 7723f6d980725507e5d0eb643dc179aae0efb719
sha1: TPM PCR-10: 7723f6d980725507e5d0eb643dc179aae0efb719
sha1 PCR-10: succeed

sha256: PCRAgg  10:
5254d6dce62765f884dc67dac8d59a8721ae14495ae4a0cb73426d0c013a82b2
sha256: TPM PCR-10:
5254d6dce62765f884dc67dac8d59a8721ae14495ae4a0cb73426d0c013a82b2
sha256 PCR-10: succeed

Mimi


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest
  2020-02-23  1:12   ` Mimi Zohar
@ 2020-02-24 16:23     ` Lakshmi Ramasubramanian
  0 siblings, 0 replies; 12+ messages in thread
From: Lakshmi Ramasubramanian @ 2020-02-24 16:23 UTC (permalink / raw)
  To: Mimi Zohar, linux-integrity
  Cc: Roberto Sassu, Vitaly Chikunov, Patrick Uiterwijk, Petr Vorel

On 2/22/20 5:12 PM, Mimi Zohar wrote:

> 
> There are two aspects to Roberto's changes - extending the TPM banks
> with the bank specific template digest and verifying the boot
> aggregate.  This patch set only addresses the first aspect.
> 
> Assuming both the sha1 and sha256 TPM banks are enabled,
> 
> # tssgetcapability -cap 5
> 2 PCR selections
>      hash TPM_ALG_SHA1
>      TPMS
> _PCR_SELECTION length 3
>      ff ff ff
>      hash TPM_ALG_SHA256
>      TPMS_PC
> R_SELECTION length 3
>      ff ff ff
> 
> the output would look like:
>   
> # evmctl ima_measurement -v --list
> /sys/kernel/security/integrity/ima/binary_runtime_measurements
> 
> sha1: PCRAgg  10: 7723f6d980725507e5d0eb643dc179aae0efb719
> sha1: TPM PCR-10: 7723f6d980725507e5d0eb643dc179aae0efb719
> sha1 PCR-10: succeed
> 
> sha256: PCRAgg  10:
> 5254d6dce62765f884dc67dac8d59a8721ae14495ae4a0cb73426d0c013a82b2
> sha256: TPM PCR-10:
> 5254d6dce62765f884dc67dac8d59a8721ae14495ae4a0cb73426d0c013a82b2
> sha256 PCR-10: succeed
> 

Thanks Mimi and Roberto for the update.

tpm2_pcrread command outputs the PCR values.
The one for PCR-10 matches the data output by evmctl.

  -lakshmi



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-02-24 16:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-21 18:38 [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 1/8] ima-evm-utils: treat unallocated banks as an error Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 2/8] ima-evm-utils: increase the size of "zero" and "fox" variables Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 3/8] ima-evm-utils: calculate the digests for multiple TPM banks Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 4/8] ima-evm-utils: add support in tpm2_read_pcrs to read different " Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 5/8] ima-evm-utils: read the PCRs for the requested " Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 6/8] ima-evm-utils: compare re-calculated PCRs with the TPM values Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 7/8] ima-evm-utils: use a common bank variable for TPM 1.2 and TPM 2.0 Mimi Zohar
2020-02-21 18:38 ` [RFC PATCH 8/8] ima-evm-utils: remove TPM 1.2 specific code Mimi Zohar
2020-02-22  0:11 ` [RFC PATCH 0/8] ima-evm-utils: calculate per TPM bank template digest Lakshmi Ramasubramanian
2020-02-23  1:12   ` Mimi Zohar
2020-02-24 16:23     ` Lakshmi Ramasubramanian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).