All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] TPM: Fixup pubek sysfs file
@ 2009-09-04  4:52 Jason Gunthorpe
  2009-09-04  5:02 ` Roland Dreier
  2009-09-14 20:48 ` Rajiv Andrade
  0 siblings, 2 replies; 16+ messages in thread
From: Jason Gunthorpe @ 2009-09-04  4:52 UTC (permalink / raw)
  To: Andrew Morton
  Cc: tpmdd-devel, linux-kernel, srajiv, Debora Velarde,
	Marcel Selhorst, James Morris, Jan Beulich

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


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

end of thread, other threads:[~2009-09-15 18:54 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-04  4:52 [PATCH] TPM: Fixup pubek sysfs file Jason Gunthorpe
2009-09-04  5:02 ` 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

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.