public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: tpmdd-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org,
	srajiv@linux.vnet.ibm.com,
	Debora Velarde <debora@linux.vnet.ibm.com>,
	Marcel Selhorst <m.selhorst@sirrix.com>,
	James Morris <jmorris@namei.org>,
	Jan Beulich <jbeulich@novell.com>
Subject: [PATCH] TPM: Fixup pubek sysfs file
Date: Thu, 3 Sep 2009 22:52:31 -0600	[thread overview]
Message-ID: <20090904045231.GW4973@obsidianresearch.com> (raw)

tpm_show_pubek is utterly and completely wrong, all the offsets
into the binary blob are wrong, the output is garbage. Do it again.

Before:
Algorithm: 00 0C 00 00
Encscheme: 08 00
Sigscheme: 00 00
Parameters: 00 00 00 00 01 00 AF 6B 30 9B 0D B3
Modulus length: -1266846667
Modulus:
68 45 8D CA A5 EF A8 8A DD 0F D7 84 8E 8D 1F 40
22 92 09 CF 12 C8 9F 6E 55 57 6A 2C A8 0B 5E 45
C7 5E 3D 56 DA 64 E6 E1 F7 8C DD 41 92 28 2E 06
41 02 3E 11 7D B2 C5 46 38 E5 8C 60 D2 96 EE 0C
D6 3D F8 99 E3 02 3A 32 7A 02 C8 31 29 98 28 B9
1B EF 30 A1 A0 45 A0 C0 05 0E C5 96 95 FD 91 47
0A 35 E0 69 B0 8B 49 BD B9 F6 5D 25 21 25 79 1B
20 0D C3 C7 1F 87 5E 5F 41 4B DE 32 DF 55 F3 BD
7F CA D8 7D 3A B4 D5 0A EF CF 8E 72 20 52 15 FA
FB C6 C0 2E C2 AB C6 07 D0 9D 96 6B 2E 30 F7 54
C4 A5 CD 9B 13 54 A0 D1 71 66 91 97 06 12 B5 2D
B2 33 62 FB 56 62 64 A8 AA E9 F2 F4 03 C3 F4 49
2A 09 0D 7D 75 99 6C F0 47 1E 7D D5 A5 CA CE EF
45 B2 DA 88 93 B4 EE EB FB B0 A6 A4 19 C4 B8 0D
04 46 AE BD C5 2E 30 84 49 57 25 34 78 E6 ED C4
50 AF 3B F6 86 43 54 0A D9 DB 54 9C 06 B3 50 7F

After:
Algorithm: 00 00 00 01
Encscheme: 00 03
Sigscheme: 00 01
Parameters: 00 00 08 00 00 00 00 02 00 00 00 00
Modulus length: 256
Modulus:
AF 6B 30 9B 0D B3 B4 7D 74 35 68 45 8D CA A5 EF
A8 8A DD 0F D7 84 8E 8D 1F 40 22 92 09 CF 12 C8
9F 6E 55 57 6A 2C A8 0B 5E 45 C7 5E 3D 56 DA 64
E6 E1 F7 8C DD 41 92 28 2E 06 41 02 3E 11 7D B2
C5 46 38 E5 8C 60 D2 96 EE 0C D6 3D F8 99 E3 02
3A 32 7A 02 C8 31 29 98 28 B9 1B EF 30 A1 A0 45
A0 C0 05 0E C5 96 95 FD 91 47 0A 35 E0 69 B0 8B
49 BD B9 F6 5D 25 21 25 79 1B 20 0D C3 C7 1F 87
5E 5F 41 4B DE 32 DF 55 F3 BD 7F CA D8 7D 3A B4
D5 0A EF CF 8E 72 20 52 15 FA FB C6 C0 2E C2 AB
C6 07 D0 9D 96 6B 2E 30 F7 54 C4 A5 CD 9B 13 54
A0 D1 71 66 91 97 06 12 B5 2D B2 33 62 FB 56 62
64 A8 AA E9 F2 F4 03 C3 F4 49 2A 09 0D 7D 75 99
6C F0 47 1E 7D D5 A5 CA CE EF 45 B2 DA 88 93 B4
EE EB FB B0 A6 A4 19 C4 B8 0D 04 46 AE BD C5 2E
30 84 49 57 25 34 78 E6 ED C4 50 AF 3B F6 86 43

I've checked this decoded output in two different ways.

Tested on a winbond WPCT200

Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
---
 drivers/char/tpm/tpm.c |   77 +++++++++++++++++++++++++++++++++---------------
 1 files changed, 53 insertions(+), 24 deletions(-)

Andrew: More testing found this too. In truth this file is probably
fairly useless since it won't output anything once the TPM is owned,
but if it is going to be there it may as well work right.

diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 5d5b324..196bc48 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -460,6 +460,11 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
 		dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
 		return err;
 	}
+	if (len != be32_to_cpu(cmd->header.out.length)) {
+		dev_dbg(chip->dev, "TPM returned the wrong length %x %x\n",
+			len, be32_to_cpu(cmd->header.out.length));
+		return -1;
+	}
 	return 0;
 }
 
@@ -811,43 +816,67 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
 {
 	u8 *data;
 	struct tpm_cmd_t tpm_cmd;
-	ssize_t err;
-	int i, rc;
+	ssize_t len;
+	int i, rc, key_len;
 	char *str = buf;
 
 	struct tpm_chip *chip = dev_get_drvdata(dev);
 
 	tpm_cmd.header.in = tpm_readpubek_header;
-	err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
-			"attempting to read the PUBEK");
-	if (err)
+	if (transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
+			 "attempting to read the PUBEK"))
+		goto out;
+
+	len = be32_to_cpu(tpm_cmd.header.out.length);
+	if (len <= 0)
 		goto out;
 
-	/* 
-	   ignore header 10 bytes
-	   algorithm 32 bits (1 == RSA )
-	   encscheme 16 bits
-	   sigscheme 16 bits
-	   parameters (RSA 12->bytes: keybit, #primes, expbit)  
-	   keylenbytes 32 bits
-	   256 byte modulus
-	   ignore checksum 20 bytes
+	/* Format (in bytes):
+	     10 RPC Header (tpm_cmd.header)
+	     xx TPM_PUBKEY pubEK
+		xx TPM_KEY_PARMS
+		  4 algorithmID
+		  2 encScheme
+		  2 sigcScheme
+		  4 parmSize
+		  xx parms (typically 12 bytes for a RSA key)
+		xx TPM_STORE_PUBKEY
+		  4 keyLength
+		  xx key (typically 256 for a RSA key)
+	     20 TPM_DIGEST checksum
 	 */
 	data = tpm_cmd.params.readpubek_out_buffer;
+	len -= 10;
+	if (len < 24)
+		goto out;
 	str +=
 	    sprintf(str,
 		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
 		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
-		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
-		    "Modulus length: %d\nModulus: \n",
-		    data[10], data[11], data[12], data[13], data[14],
-		    data[15], data[16], data[17], data[22], data[23],
-		    data[24], data[25], data[26], data[27], data[28],
-		    data[29], data[30], data[31], data[32], data[33],
-		    be32_to_cpu(*((__be32 *) (data + 34))));
-
-	for (i = 0; i < 256; i++) {
-		str += sprintf(str, "%02X ", data[i + 38]);
+		    " %02X %02X %02X %02X %02X %02X %02X %02X\n",
+		    data[0], data[1], data[2], data[3],
+		    data[4], data[5],
+		    data[6], data[7],
+		    data[12], data[13], data[14], data[15], data[16], data[17],
+		    data[18], data[19], data[20], data[21], data[22], data[23]);
+	/* Skip TPM_KEY_PARMS.parms and TPM_STORE_PBUKEY.keyLength */
+	i = 4 + 2 + 2 + 4 + be32_to_cpu(*((__be32 *) (data + 8))) + 4;
+	if (i > len)
+		goto out;
+	data += i;
+	len -= i;
+	key_len = be32_to_cpu(*((__be32 *) (data) - 1));
+
+	/* Note: The value printed here is the TPM_STORE_PUBKEY. For RSA keys
+	   this is a modulus, but it can vary for other key types. */
+	str += sprintf(str, "Modulus length: %d\nModulus: \n", key_len);
+
+	/* len is bounded, so key_len is bounded, so sprintf is bounded, so
+	   str doesn't overflow. Well, maybe. */
+	if (key_len > len)
+		goto out;
+	for (i = 0; i < key_len; i++) {
+		str += sprintf(str, "%02X ", data[i]);
 		if ((i + 1) % 16 == 0)
 			str += sprintf(str, "\n");
 	}
-- 
1.5.4.2


             reply	other threads:[~2009-09-04  4:52 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-04  4:52 Jason Gunthorpe [this message]
2009-09-04  5:02 ` [PATCH] TPM: Fixup pubek sysfs file Roland Dreier
2009-09-04 21:03   ` Andrew Morton
2009-09-04 21:23     ` Jason Gunthorpe
2009-09-11 16:28       ` Greg KH
     [not found]       ` <17754_1252731784_n8C533ou010944_20090911162837.GC17677@kroah.com>
2009-09-14 18:01         ` [tpmdd-devel] " Jonathan M. McCune
2009-09-14 18:34           ` Rajiv Andrade
2009-09-14 18:43             ` Jason Gunthorpe
2009-09-14 19:23               ` Jonathan M. McCune
2009-09-14 19:46                 ` Jason Gunthorpe
2009-09-14 19:50                   ` Greg KH
2009-09-15  3:06                   ` Mimi Zohar
2009-09-15 18:52                     ` Jonathan M. McCune
2009-09-15 16:34           ` Hal Finney
2009-09-11 16:28     ` Greg KH
2009-09-14 20:48 ` Rajiv Andrade

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=20090904045231.GW4973@obsidianresearch.com \
    --to=jgunthorpe@obsidianresearch.com \
    --cc=akpm@linux-foundation.org \
    --cc=debora@linux.vnet.ibm.com \
    --cc=jbeulich@novell.com \
    --cc=jmorris@namei.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.selhorst@sirrix.com \
    --cc=srajiv@linux.vnet.ibm.com \
    --cc=tpmdd-devel@lists.sourceforge.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox