It appears that TPM_CertifyKey succeeds only when the PCR values are correct
for the key being certified. So I can create a bind key restricted to PCR 0 =
12345678901234... at any time but I can only certify that if PCR 0 actually
contains that.  (I'm not sure why, from a security perspective; the PCR values
are included in the signed TPM_CERTIFY_INFO structure.)

Why it's returning TPM_BAD_LOCALITY instead of TPM_WRONGPCRVAL, I have no idea.

Now, there is another problem.

The TPM specification doesn't say TPM_CertifyKey2 is required in the (PCRs >=
16 or locality restriction) case. It says that TPM_CertifyKey returns a
TPM_CERTIFY_INFO2 in that case, and a TPM_CERTIFY_INFO otherwise. My TPM does
indeed do this.

When the TPM returns a TPM_CERTIFY_INFO2 structure, the extra fields,
"migrationAuthoritySize" and "migrationAuthority" are present in certifyInfo.
Trousers doesn't notice this, and interprets migrationAuthoritySize (which is,
in my case, zero) as TPM_CertifyInfo's outDataSize output. Thus it thinks
outData is empty.

The result of this is that Tspi_Key_CertifyKey returns successfully but with a
zero-length string in pValidationData.rgbValidationData.

Attached is a patch that fixes that. It looks for the TPM_STRUCTURE_TAG (or
TPM_VERSION) at the start of certifyInfo. Considering nobody seems to have
noticed problems with Tspi_Key_CertifyKey before, I wouldn't be surprised if
this patch breaks Trousers for someone else's TPM.
--- a/src/tcs/tcs_utils.c       2010-01-28 16:27:51.000000000 +0000
+++ b/src/tcs/tcs_utils.c       2011-08-31 16:56:58.000000000 +0000
@@ -395,9 +395,10 @@
        TSS_RESULT rc;
 
        if (!certify) {
+               TPM_VERSION version;
                UINT32 size;
 
-               UnloadBlob_VERSION(offset, blob, NULL);
+               UnloadBlob_VERSION(offset, blob, &version);
                UnloadBlob_UINT16(offset, NULL, blob);
                UnloadBlob_KEY_FLAGS(offset, blob, NULL);
                UnloadBlob_BOOL(offset, NULL, blob);
@@ -413,6 +414,14 @@
                if (size > 0)
                        UnloadBlob(offset, size, blob, NULL);
 
+               if (Decode_UINT16((BYTE *) &version) == TPM_TAG_CERTIFY_INFO2){
+                       /* This is a TPM_CERTIFY_INFO2 structure. */
+                       /* Read migrationAuthority. */
+                       UnloadBlob_UINT32(offset, &size, blob);
+                       if (size > 0)
+                               UnloadBlob(offset, size, blob, NULL);
+               }
+
                return TSS_SUCCESS;
        }
 
@@ -444,6 +453,15 @@
                certify->PCRInfo = NULL;
        }
 
+       if (Decode_UINT16((BYTE *) &certify->version) == TPM_TAG_CERTIFY_INFO2){
+               /* This is a TPM_CERTIFY_INFO2 structure. */
+               /* Read migrationAuthority. */
+               UINT32 size;
+               UnloadBlob_UINT32(offset, &size, blob);
+               if (size > 0)
+                       UnloadBlob(offset, size, blob, NULL);
+       }
+
        return TSS_SUCCESS;
 }
 
------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better 
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev
_______________________________________________
TrouSerS-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/trousers-users

Reply via email to