]> xenbits.xensource.com Git - seabios.git/commitdiff
tpm: Filter TPM commands in passthrough API
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Tue, 2 Feb 2016 18:09:19 +0000 (13:09 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 6 Feb 2016 01:49:15 +0000 (20:49 -0500)
Filter TPM commands in the passthrough API call by matching the
type of tag in the header with the version of the underlying TPM.
Return an error code if the tag indicates that the command is
for the wrong TPM version.

Fix a size check on the way.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
src/std/tcg.h
src/tcgbios.c

index 8466b14dcc9eb95fbc8461c92cb544d527a189f5..dbb3a60bf1a589166741b2410b720ea13fb5bad9 100644 (file)
@@ -74,6 +74,8 @@
 
 /* TPM command tags */
 #define TPM_TAG_RQU_CMD                  0x00c1
+#define TPM_TAG_RQU_AUTH1_CMD            0x00c2
+#define TPM_TAG_RQU_AUTH2_CMD            0x00c3
 
 /* interrupt identifiers (al register) */
 enum irq_ids {
index da457a42e9aaf679eebb06fe09db76e0899907db..d6010c193f1e7ef92b7a551ee80e345c375fe8fd 100644 (file)
@@ -1065,13 +1065,30 @@ pass_through_to_tpm_int(struct pttti *pttti, struct pttto *pttto)
     u32 rc = 0;
     struct tpm_req_header *trh = (void*)pttti->tpmopin;
 
-    if (pttti->ipblength < sizeof(struct pttti) + sizeof(trh)
+    if (pttti->ipblength < sizeof(struct pttti) + sizeof(*trh)
         || pttti->ipblength != sizeof(struct pttti) + be32_to_cpu(trh->totlen)
         || pttti->opblength < sizeof(struct pttto)) {
         rc = TCG_INVALID_INPUT_PARA;
         goto err_exit;
     }
 
+    u16 tag = be16_to_cpu(trh->tag);
+
+    switch (TPM_version) {
+    case TPM_VERSION_1_2:
+        if (tag != TPM_TAG_RQU_CMD && tag != TPM_TAG_RQU_AUTH1_CMD
+            && tag != TPM_TAG_RQU_AUTH2_CMD) {
+            rc = TCG_INVALID_INPUT_PARA;
+            goto err_exit;
+        }
+        break;
+    case TPM_VERSION_2:
+        if (tag != TPM2_ST_NO_SESSIONS && tag != TPM2_ST_SESSIONS) {
+            rc = TCG_INVALID_INPUT_PARA;
+            goto err_exit;
+        }
+    }
+
     u32 resbuflen = pttti->opblength - offsetof(struct pttto, tpmopout);
     int ret = tpmhw_transmit(0, trh, pttto->tpmopout, &resbuflen,
                              TPM_DURATION_TYPE_LONG /* worst case */);