File trousers_0.2.9-tpm_1.2_dual_v20070206.patch of Package trousers
diff -ur ./src/include/obj.h ../trousers-0.2.9_tpm12/src/include/obj.h
--- ./src/include/obj.h 2007-01-27 00:22:46.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/include/obj.h 2007-02-06 07:30:18.000000000 +0100
@@ -24,6 +24,8 @@
/* When TRUE, the object has previously been registered in SYSTEM PS */
#define TSS_OBJ_FLAG_SYSTEM_PS 0x00000010
+
+
/* structures */
struct tsp_object {
@@ -97,6 +99,11 @@
TCS_CONTEXT_HANDLE tcsHandle;
BYTE *machineName;
UINT32 machineNameLength;
+ /*
+ twinkler@IAIK
+ This field holds the TPM version the context is connected to.
+ */
+ TCPA_VERSION tpmVersion;
};
struct tr_rsakey_obj {
@@ -321,6 +328,11 @@
TSS_BOOL obj_context_has_popups(TSS_HCONTEXT);
TSS_RESULT obj_context_get_hash_mode(TSS_HCONTEXT, UINT32 *);
TSS_RESULT obj_context_set_hash_mode(TSS_HCONTEXT, UINT32);
+/* twinkler@IAIK */
+TSS_RESULT obj_context_get_tpm_version(TSS_HCONTEXT tspContext, TCPA_VERSION *tpmVersion);
+TSS_RESULT obj_context_set_tpm_version(TSS_HCONTEXT tspContext, TCPA_VERSION tpmVersion);
+
+
/* obj_policy.c */
TSS_BOOL anyPopupPolicies(TSS_HCONTEXT);
diff -ur ./src/include/spi_utils.h ../trousers-0.2.9_tpm12/src/include/spi_utils.h
--- ./src/include/spi_utils.h 2007-01-12 20:51:20.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/include/spi_utils.h 2007-02-06 07:30:18.000000000 +0100
@@ -256,4 +256,6 @@
TSS_RESULT TCSP_LoadManuMaintPub(TCS_CONTEXT_HANDLE, TCPA_NONCE, UINT32, BYTE *, TCPA_DIGEST *);
TSS_RESULT TCSP_ReadManuMaintPub(TCS_CONTEXT_HANDLE, TCPA_NONCE, TCPA_DIGEST *);
+/* twinkler@IAIK */
+TSS_BOOL tpm_version(TSS_HCONTEXT tspContext, UINT32 maj, UINT32 min);
#endif
diff -ur ./src/include/trousers_types.h ../trousers-0.2.9_tpm12/src/include/trousers_types.h
--- ./src/include/trousers_types.h 2006-01-04 18:23:52.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/include/trousers_types.h 2007-02-06 07:30:18.000000000 +0100
@@ -69,8 +69,21 @@
#define TPM_ORD_UnBind (TCPA_PROTECTED_ORDINAL + 30)
#define TPM_ORD_CreateWrapKey (TCPA_PROTECTED_ORDINAL + 31)
+/*
+twinkler@IAIK
+TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+*/
+#define TPM_ORD_LoadKey2 (TCPA_PROTECTED_ORDINAL + 65)
#define TPM_ORD_LoadKey (TCPA_PROTECTED_ORDINAL + 32)
+
#define TPM_ORD_GetPubKey (TCPA_PROTECTED_ORDINAL + 33)
+
+/*
+twinkler@IAIK
+TPM_ORD_EvictKey is deprectated in spec. v1.2. It is replaced by TPM_ORD_FlushSpecific.
+*/
+#define TPM_ORD_FlushSpecific (TCPA_PROTECTED_ORDINAL + 186)
+#define TPM_RT_KEY 0x00000001 /* resource type key for FlushSpecific*/
#define TPM_ORD_EvictKey (TCPA_PROTECTED_ORDINAL + 34)
#define TPM_ORD_CreateMigrationBlob (TCPA_PROTECTED_ORDINAL + 40)
@@ -116,7 +129,14 @@
#define TPM_ORD_MakeIdentity (TCPA_PROTECTED_ORDINAL + 121)
#define TPM_ORD_ActivateTPMIdentity (TCPA_PROTECTED_ORDINAL + 122)
#define TPM_ORD_ReadPubek (TCPA_PROTECTED_ORDINAL + 124)
+
+/*
+twinkler@IAIK
+TPM_ORD_OwnerReadPubek is replaced by TPM_ORD_OwnerReadInternalPub + TPM_KH_XX in spec. v1.2
+*/
+#define TPM_ORD_OwnerReadInternalPub (TCPA_PROTECTED_ORDINAL + 129)
#define TPM_ORD_OwnerReadPubek (TCPA_PROTECTED_ORDINAL + 125)
+
#define TPM_ORD_DisablePubekRead (TCPA_PROTECTED_ORDINAL + 126)
#define TPM_ORD_GetAuditEvent (TCPA_PROTECTED_ORDINAL + 130)
diff -ur ./src/include/tss/tcpa_defines.h ../trousers-0.2.9_tpm12/src/include/tss/tcpa_defines.h
--- ./src/include/tss/tcpa_defines.h 2005-06-27 20:17:03.000000000 +0200
+++ ../trousers-0.2.9_tpm12/src/include/tss/tcpa_defines.h 2007-02-06 07:30:18.000000000 +0100
@@ -67,6 +67,12 @@
// The entity type TPM_ET_OWNER and TPM_ET_SRK are associated with
// specific key handles
// Errata: Not in spec
+/*
+twinkler@IAIK
+TPM_KH_EK is required in combination with TPM_ORD_OwnerReadInternalPub to
+get the public EK in spec. v1.2
+*/
+#define TPM_KH_EK (0x40000006)
#define TPM_KEYHND_OWNER (0x40000001)
#define TPM_KEYHND_SRK (0x40000000)
diff -ur ./src/tcs/tcskcm.c ../trousers-0.2.9_tpm12/src/tcs/tcskcm.c
--- ./src/tcs/tcskcm.c 2006-12-08 17:49:51.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tcs/tcskcm.c 2007-02-06 07:30:18.000000000 +0100
@@ -445,9 +445,29 @@
LoadBlob(&offset, cWrappedKeyBlobSize, txBlob, rgbWrappedKeyBlob, "wrapped blob");
if (pAuth != NULL) {
LoadBlob_Auth(&offset, txBlob, pAuth);
- LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_LoadKey, txBlob);
- } else
- LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_LoadKey, txBlob);
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (TPM_VERSION(1, 1)) {
+ LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_LoadKey, txBlob);
+ } else {
+ LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_LoadKey2, txBlob);
+ }
+
+ } else {
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (TPM_VERSION(1, 1)) {
+ LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_LoadKey, txBlob);
+ } else {
+ LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_LoadKey2, txBlob);
+ }
+
+ }
LogDebugUnrollKey(rgbWrappedKeyBlob);
LogDebugFn("Submitting request to the TPM");
@@ -614,7 +634,17 @@
/* calculate the paramDigest */
offset = 0;
- LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob, NULL);
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (TPM_VERSION(1, 1)) {
+ LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob, NULL);
+ } else {
+ LoadBlob_UINT32(&offset, TPM_ORD_LoadKey2, blob, NULL);
+ }
+
LoadBlob(&offset, keySize, blob, keyBlob, NULL);
if (Hash(TSS_HASH_SHA1, offset, blob,
(BYTE *)&pLoadKeyInfo->paramDigest.digest))
diff -ur ./src/tcs/tcspbg.c ../trousers-0.2.9_tpm12/src/tcs/tcspbg.c
--- ./src/tcs/tcspbg.c 2007-01-08 22:44:19.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tcs/tcspbg.c 2007-02-06 07:30:18.000000000 +0100
@@ -2196,10 +2196,29 @@
goto done;
offset = 10;
+
+ /*
+ twinkler@IAIK
+ TPM_KH_EK is used to specify the key read by TPM_ORD_OwnerReadInternalPub in spec v1.2
+ */
+ if (!TPM_VERSION(1, 1)) {
+ LoadBlob_UINT32(&offset, TPM_KH_EK, txBlob, "key handle");
+ }
+
LoadBlob_Auth(&offset, txBlob, ownerAuth);
- LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
- TPM_ORD_OwnerReadPubek, txBlob);
+ /*
+ twinkler@IAIK
+ TPM_ORD_OwnerReadPubek is replaced by TPM_ORD_OwnerReadInternalPub in spec. v1.2
+ */
+ if (TPM_VERSION(1, 1)) {
+ LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
+ TPM_ORD_OwnerReadPubek, txBlob);
+ } else {
+ LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
+ TPM_ORD_OwnerReadInternalPub, txBlob);
+ }
+
if ((result = req_mgr_submit_req(txBlob)))
goto done;
diff -ur ./src/tcs/tcs_utils.c ../trousers-0.2.9_tpm12/src/tcs/tcs_utils.c
--- ./src/tcs/tcs_utils.c 2006-12-14 23:17:39.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tcs/tcs_utils.c 2007-02-06 07:30:18.000000000 +0100
@@ -328,7 +328,17 @@
offset = 10;
LoadBlob_UINT32(&offset, slot, txBlob, "key handle");
- LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_EvictKey, txBlob);
+ /*
+ twinkler@IAIK
+ TPM_ORD_EvictKey is replaced by TPM_ORD_FlushSpecific
+ TPM_RT_KEY resource type specifies that the entity to flush is a key.
+ */
+ if (TPM_VERSION(1, 1)) {
+ LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_EvictKey, txBlob);
+ } else {
+ LoadBlob_UINT32(&offset, TPM_RT_KEY, txBlob, "TPM_RT_KEY");
+ LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_FlushSpecific, txBlob);
+ }
if ((result = req_mgr_submit_req(txBlob)))
return result;
diff -ur ./src/tcsd/svrside.c ../trousers-0.2.9_tpm12/src/tcsd/svrside.c
--- ./src/tcsd/svrside.c 2006-09-28 00:08:47.000000000 +0200
+++ ../trousers-0.2.9_tpm12/src/tcsd/svrside.c 2007-02-06 07:41:20.000000000 +0100
@@ -262,7 +262,11 @@
return -1;
}
client_len = (unsigned)sizeof(client_addr);
- LogInfo("%s: TCSD up and running.", PACKAGE_STRING);
+/*
+ twinkler@IAIK
+ Added an additional notice that this is a patched TrouSerS version.
+*/
+ LogInfo("%s (with TPM 1.2 DUAL patch by IAIK <thomas.winkler@iaik.tugraz.at>): TCSD up and running.", PACKAGE_STRING);
do {
newsd = accept(sd, (struct sockaddr *) &client_addr, &client_len);
LogDebug("accepted socket %i", newsd);
diff -ur ./src/tspi/obj_context.c ../trousers-0.2.9_tpm12/src/tspi/obj_context.c
--- ./src/tspi/obj_context.c 2007-01-25 22:49:47.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tspi/obj_context.c 2007-02-06 07:30:18.000000000 +0100
@@ -54,6 +54,13 @@
context->hashMode = TSS_TSPATTRIB_HASH_MODE_NULL;
#endif
+ /*
+ twinkler@IAIK
+ Setting major and minor to 0 indicates that the TPM version has not yet been determined.
+ */
+ context->tpmVersion.major = 0;
+ context->tpmVersion.minor = 0;
+
if ((result = obj_list_add(&context_list, NULL_HCONTEXT, 0, context, phObject))) {
free(context);
return result;
@@ -294,6 +301,44 @@
return TSS_SUCCESS;
}
+/* twinkler@IAIK */
+TSS_RESULT
+obj_context_get_tpm_version(TSS_HCONTEXT tspContext, TCPA_VERSION *tpmVersion)
+{
+ struct tsp_object *obj;
+ struct tr_context_obj *context;
+
+ if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ context = (struct tr_context_obj *)obj->data;
+ *tpmVersion = context->tpmVersion;
+
+ obj_list_put(&context_list);
+
+ return TSS_SUCCESS;
+}
+
+/* twinkler@IAIK */
+TSS_RESULT
+obj_context_set_tpm_version(TSS_HCONTEXT tspContext, TCPA_VERSION tpmVersion)
+{
+ struct tsp_object *obj;
+ struct tr_context_obj *context;
+
+ if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
+ return TSPERR(TSS_E_INVALID_HANDLE);
+
+ context = (struct tr_context_obj *)obj->data;
+ context->tpmVersion = tpmVersion;
+
+ obj_list_put(&context_list);
+
+ return TSS_SUCCESS;
+}
+
+
+
/* search the list of all policies bound to context @tspContext. If
* one is found of type popup, return TRUE, else return FALSE. */
TSS_BOOL
diff -ur ./src/tspi/spi_context.c ../trousers-0.2.9_tpm12/src/tspi/spi_context.c
--- ./src/tspi/spi_context.c 2007-01-25 22:53:12.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tspi/spi_context.c 2007-02-06 07:30:18.000000000 +0100
@@ -404,13 +404,33 @@
if (useAuth) {
/* --- Create the Authorization */
offset = 0;
- Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
+ } else {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey2, blob);
+ }
+
Trspi_LoadBlob(&offset, ulBlobLength, blob, rgbBlobData);
Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
- if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, TPM_ORD_LoadKey,
- hPolicy, &digest, &auth)))
- return result;
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, TPM_ORD_LoadKey,
+ hPolicy, &digest, &auth)))
+ return result;
+ } else {
+ if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, TPM_ORD_LoadKey2,
+ hPolicy, &digest, &auth)))
+ return result;
+ }
pAuth = &auth;
} else {
@@ -425,12 +445,56 @@
/* --- Validate return auth */
offset = 0;
Trspi_LoadBlob_UINT32(&offset, result, blob);
- Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
- Trspi_LoadBlob_UINT32(&offset, keyslot, blob);
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
+ } else {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey2, blob);
+ }
+
+ /*
+ twinkler@IAIK
+ keyslot is no longer part of the auth data in spec. v1.2.
+ */
+#define USE_FALLBACK_AUTH
+#ifndef USE_FALLBACK_AUTH
+ /*
+ This is the clean way to do it. TPM Emulator, however, claims to be a 1.2 TPM but does not
+ correctly implement the LoadKey2 command. To maintain compatibility with TPM Emulator we
+ use the #else branch where both auth data types are tried (see below).
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, keyslot, blob);
+ }
Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
return result;
+#else
+ /*
+ At first we try TPM 1.2 style auth data (without keyslot in the auth blob). If that fails,
+ the keyslot is added to the auth blob (TPM 1.1 style) and the blob is validated again.
+ */
+
+ BYTE tmpHMAC[TCPA_SHA1_160_HASH_LEN];
+ memcpy(tmpHMAC, &(auth.HMAC), TCPA_SHA1_160_HASH_LEN); /* save HMAC value in case we have to try 1.1 style auth */
+ Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
+
+ result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth);
+ if (result != TSS_SUCCESS) {
+// printf("v1.2 auth failed. trying 1.1 auth (with keyslot)\n");
+ Trspi_LoadBlob_UINT32(&offset, keyslot, blob);
+ memcpy(&(auth.HMAC), tmpHMAC, TCPA_SHA1_160_HASH_LEN); /* restore HMAC value */
+ Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
+ result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth);
+ if (result != TSS_SUCCESS) {
+ return result;
+ }
+ }
+#endif
}
/* --- Create a new Object */
@@ -513,11 +577,24 @@
&hPolicy, NULL))
return result;
- if (secret_PerformAuth_OIAP(keyHandle,
- TPM_ORD_LoadKey,
- hPolicy, &info.paramDigest,
- &info.authData))
- return result;
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ if (secret_PerformAuth_OIAP(keyHandle,
+ TPM_ORD_LoadKey,
+ hPolicy, &info.paramDigest,
+ &info.authData))
+ return result;
+ } else {
+ if (secret_PerformAuth_OIAP(keyHandle,
+ TPM_ORD_LoadKey2,
+ hPolicy, &info.paramDigest,
+ &info.authData))
+ return result;
+ }
+
if ((result = TCSP_LoadKeyByUUID(tspContext, uuidData, &info,
&tcsKeyHandle)))
diff -ur ./src/tspi/spi_data.c ../trousers-0.2.9_tpm12/src/tspi/spi_data.c
--- ./src/tspi/spi_data.c 2007-01-25 22:53:48.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tspi/spi_data.c 2007-02-06 07:30:18.000000000 +0100
@@ -266,13 +266,48 @@
LogDebugData(sizeof(digAtCreation), (BYTE *)&digAtCreation);
offset = 0;
- Trspi_LoadBlob_PCR_SELECTION(&offset, pcrData, &pcrSelect);
- free(pcrSelect.pcrSelect);
- Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, pcrData,
+
+ /* twinkler@IAIK */
+ /*
+ IFX 1.2 TPMs do not seem to accept a TPM_PCR_INFO for the pcrInfo paramter
+ (a BAD_PARAMETER error is returned by the TPM). TPM spec. 1.2 says that
+ alternatively a TPM_PCR_INFO_LONG MAY be passed to the TPM. When actually
+ doing that, IFX 1.2 TPMs do no longer complain.
+
+ Note: TrouSerS currently doesn't differentiate between PCRs at creation
+ and release time.
+ */
+
+ if (tpm_version(tspContext, 1, 1)) {
+
+ // start of TPM_PCR_INFO
+ Trspi_LoadBlob_PCR_SELECTION(&offset, pcrData, &pcrSelect);
+ free(pcrSelect.pcrSelect);
+ Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, pcrData,
digAtCreation.digest);
- /* XXX */
- Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, pcrData,
+ /* XXX */
+ Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, pcrData,
digAtCreation.digest);
+ // end of TPM_PCR_INFO
+
+ } else {
+
+ // start of TPM_PCR_INFO_LONG
+ Trspi_LoadBlob_UINT16(&offset, 0x006, pcrData); // TPM_TAG_PCR_INFO_LONG
+ Trspi_LoadBlob_BYTE(&offset, 0x1, pcrData); // localityAtCreation
+ Trspi_LoadBlob_BYTE(&offset, 0x1, pcrData); // localityAtRelease
+ Trspi_LoadBlob_PCR_SELECTION(&offset, pcrData, &pcrSelect); // creationPcrSelection
+ Trspi_LoadBlob_PCR_SELECTION(&offset, pcrData, &pcrSelect); // releasePcrSelection
+ free(pcrSelect.pcrSelect);
+ Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, pcrData,
+ digAtCreation.digest); // digestAtCreation
+ /* XXX */
+ Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, pcrData,
+ digAtCreation.digest); // digestAtRelease
+ // end of TPM_PCR_INFO_LONG
+
+ }
+
pcrDataSize = offset;
}
diff -ur ./src/tspi/spi_key.c ../trousers-0.2.9_tpm12/src/tspi/spi_key.c
--- ./src/tspi/spi_key.c 2007-01-27 00:21:08.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tspi/spi_key.c 2007-02-06 07:30:18.000000000 +0100
@@ -75,14 +75,41 @@
if (usesAuth) {
offset = 0;
- Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
+ } else {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey2, blob);
+ }
+
Trspi_LoadBlob(&offset, keySize, blob, keyBlob);
Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
- if ((result = secret_PerformAuth_OIAP(hUnwrappingKey,
- TPM_ORD_LoadKey,
- hPolicy, &digest,
- &auth)))
- return result;
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+
+ if ((result = secret_PerformAuth_OIAP(hUnwrappingKey,
+ TPM_ORD_LoadKey,
+ hPolicy, &digest,
+ &auth)))
+ return result;
+
+ } else {
+
+ if ((result = secret_PerformAuth_OIAP(hUnwrappingKey,
+ TPM_ORD_LoadKey2,
+ hPolicy, &digest,
+ &auth)))
+ return result;
+ }
+
pAuth = &auth;
} else {
pAuth = NULL;
@@ -95,12 +122,58 @@
if (usesAuth) {
offset = 0;
Trspi_LoadBlob_UINT32(&offset, result, blob);
- Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
- Trspi_LoadBlob_UINT32(&offset, keyslot, blob);
- Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
+ /*
+ twinkler@IAIK
+ TPM_ORD_LoadKey is replaced by TPM_ORD_LoadKey2 in spec. v1.2.
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob);
+ } else {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_LoadKey2, blob);
+ }
+
+ /*
+ twinkler@IAIK
+ keyslot is no longer part of the auth data in spec. v1.2.
+ */
+#define USE_FALLBACK_AUTH
+#ifndef USE_FALLBACK_AUTH
+ /*
+ This is the clean way to do it. TPM Emulator, however, claims to be a 1.2 TPM but does not
+ correctly implement the LoadKey2 command. To maintain compatibility with TPM Emulator we
+ use the #else branch where both auth data types are tried (see below).
+ */
+
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, keyslot, blob);
+ }
+ Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
+
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
return result;
+#else
+ /*
+ At first we try TPM 1.2 style auth data (without keyslot in the auth blob). If that fails,
+ the keyslot is added to the auth blob (TPM 1.1 style) and the blob is validated again.
+ */
+
+ BYTE tmpHMAC[TCPA_SHA1_160_HASH_LEN];
+ memcpy(tmpHMAC, &(auth.HMAC), TCPA_SHA1_160_HASH_LEN); /* save HMAC value in case we have to try 1.1 style auth */
+ Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
+
+ result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth);
+ if (result != TSS_SUCCESS) {
+// printf("v1.2 auth failed. trying 1.1 auth (with keyslot)\n");
+ Trspi_LoadBlob_UINT32(&offset, keyslot, blob);
+ memcpy(&(auth.HMAC), tmpHMAC, TCPA_SHA1_160_HASH_LEN); /* restore HMAC value */
+ Trspi_Hash(TSS_HASH_SHA1, offset, blob, digest.digest);
+ result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth);
+ if (result != TSS_SUCCESS) {
+ return result;
+ }
+ }
+#endif
}
return obj_rsakey_set_tcs_handle(hKey, tcsKey);
diff -ur ./src/tspi/spi_tpm.c ../trousers-0.2.9_tpm12/src/tspi/spi_tpm.c
--- ./src/tspi/spi_tpm.c 2007-01-18 21:14:16.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tspi/spi_tpm.c 2007-02-06 14:51:49.000000000 +0100
@@ -157,20 +157,56 @@
return result;
offset = 0;
- Trspi_LoadBlob_UINT32(&offset, TPM_ORD_OwnerReadPubek, hashblob);
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_OwnerReadPubek is replaced by TPM_ORD_OwnerReadInternalPub in spec. v1.2
+ To specify the public key, an additional key handle has to be provided (here: TPM_KH_EK)
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_OwnerReadPubek, hashblob);
+ } else {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_OwnerReadInternalPub, hashblob);
+ Trspi_LoadBlob_UINT32(&offset, TPM_KH_EK, hashblob);
+ }
+
+
Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
- if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadPubek,
- hPolicy, &digest,
- &ownerAuth)))
- return result;
+ /*
+ twinkler@IAIK
+ TPM_ORD_OwnerReadPubek is replaced by TPM_ORD_OwnerReadInternalPub in spec. v1.2
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadPubek,
+ hPolicy, &digest,
+ &ownerAuth)))
+ return result;
+ } else {
+ if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub,
+ hPolicy, &digest,
+ &ownerAuth)))
+ return result;
+ }
+
if ((result = TCSP_OwnerReadPubek(tspContext, &ownerAuth, &pubEKSize, &pubEK)))
return result;
offset = 0;
Trspi_LoadBlob_UINT32(&offset, result, hashblob);
- Trspi_LoadBlob_UINT32(&offset, TPM_ORD_OwnerReadPubek, hashblob);
+
+ /*
+ twinkler@IAIK
+ TPM_ORD_OwnerReadPubek is replaced by TPM_ORD_OwnerReadInternalPub in spec. v1.2
+ */
+ if (tpm_version(tspContext, 1, 1)) {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_OwnerReadPubek, hashblob);
+ } else {
+ Trspi_LoadBlob_UINT32(&offset, TPM_ORD_OwnerReadInternalPub, hashblob);
+ }
+
+
Trspi_LoadBlob(&offset, pubEKSize, hashblob, pubEK);
Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest);
diff -ur ./src/tspi/spi_utils.c ../trousers-0.2.9_tpm12/src/tspi/spi_utils.c
--- ./src/tspi/spi_utils.c 2007-01-12 20:50:53.000000000 +0100
+++ ../trousers-0.2.9_tpm12/src/tspi/spi_utils.c 2007-02-06 08:07:29.000000000 +0100
@@ -125,6 +125,104 @@
return ret;
}
+
+/*
+ twinkler@IAIK
+ This function tries to detect the version of the TPM this context is connected to.
+ Since each context can be connect to a different core service, each context might
+ be using a different TPM. Therefore, the TPM version is determined (and stored) on
+ a 'per context' basis.
+ The check is based on the TPM capabilites TPM_CAP_VERSION (spec v1.1) and
+ TPM_CAP_VERSION_VAL (spec v1.2).
+*/
+TSS_RESULT
+detect_tpm_version(TSS_HCONTEXT tspContext)
+{
+// TSS_HCONTEXT tcsContext;
+ UINT64 offset;
+ UINT32 respLen;
+ BYTE* resp;
+ TSS_RESULT result;
+ TCPA_VERSION version;
+
+ /* get TCS context for TSP context */
+/*
+ result = obj_context_is_connected(tspContext, &tcsContext);
+ if (result != TSS_SUCCESS) {
+ return result;
+ }
+*/
+
+ /* try to get the TPM version in 1.2 style */
+ result = TCSP_GetCapability(tspContext, TPM_CAP_VERSION_VAL, 0, NULL, &respLen, &resp);
+ if (result == TSS_SUCCESS) {
+ /* note: TPM_CAP_VERSION_VAL not only returns a TCPA_VERSION but a TPM_CAP_VERSION_INFO struct */
+ offset = sizeof(UINT16); // TPM_STRUCTURE_TAG (TPM_TAG_CAP_VERSION_INFO)
+ Trspi_UnloadBlob_TCPA_VERSION(&offset, resp, &version);
+ free(resp);
+ obj_context_set_tpm_version(tspContext, version);
+ return TSS_SUCCESS;
+
+ } else {
+ /* try to get the TPM version in 1.1 style */
+ result = TCSP_GetCapability(tspContext, TCPA_CAP_VERSION, 0, NULL, &respLen, &resp);
+ if (result != TSS_SUCCESS) {
+ return result;
+ }
+
+ offset = 0;
+ Trspi_UnloadBlob_TCPA_VERSION(&offset, resp, &version);
+ free(resp);
+ obj_context_set_tpm_version(tspContext, version);
+ return TSS_SUCCESS;
+ }
+}
+
+
+/*
+ twinkler@IAIK
+ This function is the service provider equivalent to the TPM_VERSION
+ macro of the core services.
+*/
+TSS_BOOL
+tpm_version(TSS_HCONTEXT tspContext, UINT32 maj, UINT32 min)
+{
+ TSS_RESULT result;
+ TCPA_VERSION version;
+
+ /*
+ get TPM version stored in the context
+ */
+ result = obj_context_get_tpm_version(tspContext, &version);
+ if (result != TSS_SUCCESS) {
+ return FALSE;
+ }
+
+// printf("TPM version: %d.%d\n", version.major, version.minor);
+
+ /*
+ if TPM version for this context has not been detected yet: try to get it
+ */
+ if (version.major == 0 && version.minor == 0) {
+ result = detect_tpm_version(tspContext);
+ if (result != TSS_SUCCESS) {
+ printf("Unable to detect TPM version. Error code: 0x%x\n", result);
+ return FALSE;
+ }
+ result = obj_context_get_tpm_version(tspContext, &version);
+ if (result != TSS_SUCCESS) {
+ return FALSE;
+ }
+ }
+
+ if (version.major == maj && version.minor == min) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
TSS_RESULT
Init_AuthNonce(TSS_HCONTEXT tspContext, TPM_AUTH * auth)
{