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)
 {
openSUSE Build Service is sponsored by