linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH ima-evm-utils] add support for reading per bank TPM 2.0 PCRs via sysfs
@ 2022-09-02 23:08 Tergel Myanganbayar
  2022-09-03  1:54 ` Stefan Berger
  0 siblings, 1 reply; 3+ messages in thread
From: Tergel Myanganbayar @ 2022-09-02 23:08 UTC (permalink / raw)
  To: linux-integrity
  Cc: Tergel Myanganbayar, Mimi Zohar, Petr Vorel, Stefan Berger,
	Tergel Myanganbayar

Until Linux kernel version 5.11, a TSS was required to read TPM 2.0 PCR
values. A feature which exposed the per bank TPM 2.0 PCRs directly via
sysfs was upstreamed in newer Kernel versions.

Use this recent feature in IMA-EVM-UTILS to remove TSS dependency.

Signed-off-by: Tergel Myanganbayar <tergel@linux.ibm.com>
---
 src/evmctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/evmctl.c b/src/evmctl.c
index 46a34cc..d5fe988 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1899,6 +1899,7 @@ static int read_one_bank(struct tpm_bank_info *tpm_bank, FILE *fp)
 
 static char *pcrs = "/sys/class/tpm/tpm0/device/pcrs";  /* Kernels >= 4.0 */
 static char *misc_pcrs = "/sys/class/misc/tpm0/device/pcrs";
+static char tpm2_pcr_path[28] = "/sys/class/tpm/tpm0/pcr-sha";
 
 /* Read one of the TPM 1.2 sysfs files if present */
 static int read_sysfs_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
@@ -1922,7 +1923,55 @@ static int read_sysfs_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
 	for (i = 1; i < num_banks; i++)
 		tpm_banks[i].supported = 0;
 	return 0;
+}
+
+static int read_tpm2_one_bank(struct tpm_bank_info *tpm_bank, int bank)
+{
+	FILE *fp;
+	char file_name[NAME_MAX];
+	char digest[MAX_DIGEST_SIZE + 1];
+	char *p;
+	int i;
+
+	for (i = 0; i < NUM_PCRS; i++) {
+		sprintf(file_name, "%s%d/%d", tpm2_pcr_path, bank, i);
+		fp = fopen(file_name, "r");
+		if (!fp)
+			return -1;
+
+		p = fgets(digest, (tpm_bank->digest_size * 2 + 1), fp);
+		if (!p)
+			return -1;
+
+		hex2bin(tpm_bank->pcr[i], digest, tpm_bank->digest_size);
+		fclose(fp);
+	}
+	return 0;
+}
+
+static int read_sysfs_tpm2_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
+{
+	int banks[2] = {1, 256};
+	int rt, j;
+	int tpm_enabled = 0;
 
+	if (imaevm_params.verbose > LOG_INFO)
+		log_info("Trying to read TPM 2.0 PCRs via sysfs.\n");
+
+	for (j = 0; j < num_banks; j++) {
+		rt = read_tpm2_one_bank(&tpm_banks[j], banks[j]);
+		tpm_banks[j].supported = 0;
+
+		if (rt < 0)
+			continue;
+
+		tpm_enabled = 1;
+		tpm_banks[j].supported = 1;
+	}
+
+	if (tpm_enabled == 0)
+		return -1;
+	return 0;
 }
 
 /* Read PCRs from per-bank file(s) specified via --pcrs */
@@ -2008,6 +2057,9 @@ static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
 	if (read_sysfs_pcrs(num_banks, bank) == 0)
 		return 0;
 
+	if (read_sysfs_tpm2_pcrs(num_banks, bank) == 0)
+		return 0;
+
 	/* Any userspace applications available for reading TPM 2.0 PCRs? */
 	if (!tpm2_pcr_supported()) {
 		log_debug("Failed to read TPM 2.0 PCRs\n");
@@ -2024,6 +2076,7 @@ static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
 					    bank[i].pcr[pcr_handle],
 					    bank[i].digest_size,
 					    &errmsg);
+			bank[i].supported = 1;
 			if (err) {
 				log_debug("Failed to read %s PCRs: (%s)\n",
 					  bank[i].algo_name, errmsg);
-- 
2.32.1 (Apple Git-133)


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

* Re: [PATCH ima-evm-utils] add support for reading per bank TPM 2.0 PCRs via sysfs
  2022-09-02 23:08 [PATCH ima-evm-utils] add support for reading per bank TPM 2.0 PCRs via sysfs Tergel Myanganbayar
@ 2022-09-03  1:54 ` Stefan Berger
  2022-09-04 17:08   ` Mimi Zohar
  0 siblings, 1 reply; 3+ messages in thread
From: Stefan Berger @ 2022-09-03  1:54 UTC (permalink / raw)
  To: Tergel Myanganbayar, linux-integrity
  Cc: Mimi Zohar, Petr Vorel, Tergel Myanganbayar



On 9/2/22 19:08, Tergel Myanganbayar wrote:
> Until Linux kernel version 5.11, a TSS was required to read TPM 2.0 PCR
> values. A feature which exposed the per bank TPM 2.0 PCRs directly via
> sysfs was upstreamed in newer Kernel versions.

>> Use this recent feature in IMA-EVM-UTILS to remove TSS dependency.
> 
> Signed-off-by: Tergel Myanganbayar <tergel@linux.ibm.com>
> ---
>   src/evmctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 53 insertions(+)
> 
> diff --git a/src/evmctl.c b/src/evmctl.c
> index 46a34cc..d5fe988 100644
> --- a/src/evmctl.c
> +++ b/src/evmctl.c
> @@ -1899,6 +1899,7 @@ static int read_one_bank(struct tpm_bank_info *tpm_bank, FILE *fp)
>   
>   static char *pcrs = "/sys/class/tpm/tpm0/device/pcrs";  /* Kernels >= 4.0 */
>   static char *misc_pcrs = "/sys/class/misc/tpm0/device/pcrs";
> +static char tpm2_pcr_path[28] = "/sys/class/tpm/tpm0/pcr-sha";

I don't think this 'constant' is necessary since it's only used once 
though the same may be true for the other two. If you want to keep it it 
should probably be written like this

static const char *tpm2_pcr_path = "/sys/class/tpm/tpm0/pcr-sha";

The others should also have a 'const'.
>   
>   /* Read one of the TPM 1.2 sysfs files if present */
>   static int read_sysfs_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
> @@ -1922,7 +1923,55 @@ static int read_sysfs_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
>   	for (i = 1; i < num_banks; i++)
>   		tpm_banks[i].supported = 0;
>   	return 0;
> +}
> +
> +static int read_tpm2_one_bank(struct tpm_bank_info *tpm_bank, int bank)
> +{
> +	FILE *fp;
> +	char file_name[NAME_MAX];
> +	char digest[MAX_DIGEST_SIZE + 1];
> +	char *p;
> +	int i;
> +
> +	for (i = 0; i < NUM_PCRS; i++) {
> +		sprintf(file_name, "%s%d/%d", tpm2_pcr_path, bank, i);

... and just write "/sys/class/tpm/tpm0/pcr-sha%d/%d" here ?

> +		fp = fopen(file_name, "r");
> +		if (!fp)
> +			return -1;
> +
> +		p = fgets(digest, (tpm_bank->digest_size * 2 + 1), fp);

no need for parenthesis

> +		if (!p)
> +			return -1;

fclose(fp) before the return

> +
> +		hex2bin(tpm_bank->pcr[i], digest, tpm_bank->digest_size);
> +		fclose(fp);
> +	}
> +	return 0;
> +}
> +
> +static int read_sysfs_tpm2_pcrs(int num_banks, struct tpm_bank_info *tpm_banks)
> +{
> +	int banks[2] = {1, 256};
> +	int rt, j;
> +	int tpm_enabled = 0;
>   
> +	if (imaevm_params.verbose > LOG_INFO)
> +		log_info("Trying to read TPM 2.0 PCRs via sysfs.\n");
> +
> +	for (j = 0; j < num_banks; j++) {
> +		rt = read_tpm2_one_bank(&tpm_banks[j], banks[j]);
> +		tpm_banks[j].supported = 0;
> +
> +		if (rt < 0)
> +			continue;
> +
> +		tpm_enabled = 1;
> +		tpm_banks[j].supported = 1;
> +	}
> +
> +	if (tpm_enabled == 0)
> +		return -1;
> +	return 0;


You could have just copied and pasted from read_tpm_banks():

return tpm_enabled ? 0 : 1;
>   }
>   
>   /* Read PCRs from per-bank file(s) specified via --pcrs */
> @@ -2008,6 +2057,9 @@ static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
>   	if (read_sysfs_pcrs(num_banks, bank) == 0)
>   		return 0;
>   
> +	if (read_sysfs_tpm2_pcrs(num_banks, bank) == 0)
> +		return 0;
> +
>   	/* Any userspace applications available for reading TPM 2.0 PCRs? */
>   	if (!tpm2_pcr_supported()) {
>   		log_debug("Failed to read TPM 2.0 PCRs\n");
> @@ -2024,6 +2076,7 @@ static int read_tpm_banks(int num_banks, struct tpm_bank_info *bank)
>   					    bank[i].pcr[pcr_handle],
>   					    bank[i].digest_size,
>   					    &errmsg);
> +			bank[i].supported = 1;

Is this a bugfix?

>   			if (err) {
>   				log_debug("Failed to read %s PCRs: (%s)\n",
>   					  bank[i].algo_name, errmsg);

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

* Re: [PATCH ima-evm-utils] add support for reading per bank TPM 2.0 PCRs via sysfs
  2022-09-03  1:54 ` Stefan Berger
@ 2022-09-04 17:08   ` Mimi Zohar
  0 siblings, 0 replies; 3+ messages in thread
From: Mimi Zohar @ 2022-09-04 17:08 UTC (permalink / raw)
  To: Stefan Berger, Tergel Myanganbayar, linux-integrity
  Cc: Petr Vorel, Tergel Myanganbayar

On Fri, 2022-09-02 at 21:54 -0400, Stefan Berger wrote:

> > +static int read_tpm2_one_bank(struct tpm_bank_info *tpm_bank, int bank)
> > +{
> > +	FILE *fp;
> > +	char file_name[NAME_MAX];
> > +	char digest[MAX_DIGEST_SIZE + 1];
> > +	char *p;
> > +	int i;
> > +
> > +	for (i = 0; i < NUM_PCRS; i++) {
> > +		sprintf(file_name, "%s%d/%d", tpm2_pcr_path, bank, i);
> 
> ... and just write "/sys/class/tpm/tpm0/pcr-sha%d/%d" here ?

Thanks, Stefan.  Although the only banks currently supported are sha1
and sha256, let's not hard code the hash algorithm.   The tpm_bank_info
struct contains the algo_name.   With this change, there's no need for
the "banks[]" definition in read_sysfs_tpm2_pcrs() or passing it to
read_tpm2_one_bank().

-- 
thanks,

Mimi


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

end of thread, other threads:[~2022-09-04 17:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-02 23:08 [PATCH ima-evm-utils] add support for reading per bank TPM 2.0 PCRs via sysfs Tergel Myanganbayar
2022-09-03  1:54 ` Stefan Berger
2022-09-04 17:08   ` Mimi Zohar

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).