All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mimi Zohar <zohar@linux.ibm.com>
To: linux-integrity@vger.kernel.org
Cc: Roberto Sassu <roberto.sassu@huawei.com>,
	Vitaly Chikunov <vt@altlinux.org>,
	Patrick Uiterwijk <puiterwi@redhat.com>,
	Petr Vorel <pvorel@suse.cz>, Mimi Zohar <zohar@linux.ibm.com>
Subject: [RFC PATCH 3/8] ima-evm-utils: calculate the digests for multiple TPM banks
Date: Fri, 21 Feb 2020 13:38:53 -0500	[thread overview]
Message-ID: <1582310338-1562-4-git-send-email-zohar@linux.ibm.com> (raw)
In-Reply-To: <1582310338-1562-1-git-send-email-zohar@linux.ibm.com>

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


  parent reply	other threads:[~2020-02-21 18:39 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2020-02-21 18:38 ` [RFC PATCH 4/8] ima-evm-utils: add support in tpm2_read_pcrs to read different TPM banks 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1582310338-1562-4-git-send-email-zohar@linux.ibm.com \
    --to=zohar@linux.ibm.com \
    --cc=linux-integrity@vger.kernel.org \
    --cc=puiterwi@redhat.com \
    --cc=pvorel@suse.cz \
    --cc=roberto.sassu@huawei.com \
    --cc=vt@altlinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.