1 
2 /*
3  * Licensed Materials - Property of IBM
4  *
5  * trousers - An open source TCG Software Stack
6  *
7  * (C) Copyright International Business Machines Corp. 2004-2006
8  *
9  */
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <inttypes.h>
15 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "spi_utils.h"
20 #include "capabilities.h"
21 #include "tsplog.h"
22 #include "obj.h"
23 
24 
25 TSS_RESULT
Tspi_TPM_TakeOwnership(TSS_HTPM hTPM,TSS_HKEY hKeySRK,TSS_HKEY hEndorsementPubKey)26 Tspi_TPM_TakeOwnership(TSS_HTPM hTPM,			/* in */
27 		       TSS_HKEY hKeySRK,		/* in */
28 		       TSS_HKEY hEndorsementPubKey)	/* in */
29 {
30 	TPM_AUTH privAuth;
31 	BYTE encOwnerAuth[256];
32 	UINT32 encOwnerAuthLength;
33 	BYTE encSRKAuth[256];
34 	UINT32 encSRKAuthLength;
35 	TCPA_DIGEST digest;
36 	TSS_RESULT result;
37 	TSS_HCONTEXT tspContext;
38 	UINT32 srkKeyBlobLength;
39 	BYTE *srkKeyBlob;
40 	TSS_HPOLICY hOwnerPolicy;
41 	UINT32 newSrkBlobSize;
42 	BYTE *newSrkBlob = NULL;
43 	BYTE oldAuthDataUsage;
44 	TSS_HKEY hPubEK;
45 	Trspi_HashCtx hashCtx;
46 
47 
48 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
49 		return result;
50 
51 	if (hEndorsementPubKey == NULL_HKEY) {
52 		if ((result = Tspi_TPM_GetPubEndorsementKey(hTPM, FALSE, NULL, &hPubEK))) {
53 			return result;
54 		}
55 	} else {
56 		hPubEK = hEndorsementPubKey;
57 	}
58 
59 	/* Get the srkKeyData */
60 	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
61 		return result;
62 
63 	/* Need to check for Atmel bug where authDataUsage is changed */
64 	oldAuthDataUsage = srkKeyBlob[10];
65 	LogDebug("oldAuthDataUsage is %.2X.  Wait to see if it changes", oldAuthDataUsage);
66 
67 	/* Now call the module that will encrypt the secrets.  This
68 	 * will either get the secrets from the policy objects or
69 	 * use the callback function to encrypt the secrets */
70 
71 	if ((result = secret_TakeOwnership(hPubEK, hTPM, hKeySRK, &privAuth, &encOwnerAuthLength,
72 					   encOwnerAuth, &encSRKAuthLength, encSRKAuth)))
73 		return result;
74 
75 	/* Now, take ownership is ready to call.  The auth structure should be complete
76 	 * and the encrypted data structures should be ready */
77 	if ((result = RPC_TakeOwnership(tspContext, TPM_PID_OWNER, encOwnerAuthLength, encOwnerAuth,
78 					encSRKAuthLength, encSRKAuth, srkKeyBlobLength, srkKeyBlob,
79 					&privAuth, &newSrkBlobSize, &newSrkBlob)))
80 		return result;
81 
82 	/* The final step is to validate the return Auth */
83 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
84 	result |= Trspi_Hash_UINT32(&hashCtx, result);
85 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
86 	result |= Trspi_HashUpdate(&hashCtx, newSrkBlobSize, newSrkBlob);
87 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
88 		return result;
89 
90 	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) {
91 		free(newSrkBlob);
92 		return result;
93 	}
94 	if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &privAuth))) {
95 		free(newSrkBlob);
96 		return result;
97 	}
98 
99 	/* Now that it's all happy, stuff the keyBlob into the object
100 	 * If atmel, need to adjust the authDataUsage if it changed */
101 	if (oldAuthDataUsage != newSrkBlob[10]) {	/* hardcoded blob stuff */
102 		LogDebug("auth data usage changed. Atmel bug. Fixing in key object");
103 		newSrkBlob[10] = oldAuthDataUsage;	/* this will fix it  */
104 	}
105 
106 	result = obj_rsakey_set_tcpakey(hKeySRK, newSrkBlobSize, newSrkBlob);
107 	free(newSrkBlob);
108 
109 	if (result)
110 		return result;
111 
112 	/* The SRK is loaded at this point, so insert it into the key handle list */
113 	return obj_rsakey_set_tcs_handle(hKeySRK, TPM_KEYHND_SRK);
114 }
115 
116 TSS_RESULT
Tspi_TPM_ClearOwner(TSS_HTPM hTPM,TSS_BOOL fForcedClear)117 Tspi_TPM_ClearOwner(TSS_HTPM hTPM,		/* in */
118 		    TSS_BOOL fForcedClear)	/* in */
119 {
120 	TCPA_RESULT result;
121 	TPM_AUTH auth;
122 	TSS_HCONTEXT tspContext;
123 	TCPA_DIGEST hashDigest;
124 	TSS_HPOLICY hPolicy;
125 	Trspi_HashCtx hashCtx;
126 
127 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
128 		return result;
129 
130 	if (!fForcedClear) {	/*  TPM_OwnerClear */
131 		if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
132 			return result;
133 
134 		/* Now do some Hash'ing */
135 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
136 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
137 		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
138 			return result;
139 
140 		/* hashDigest now has the hash result */
141 		if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerClear, hPolicy, FALSE,
142 						      &hashDigest, &auth)))
143 			return result;
144 
145 		if ((result = TCS_API(tspContext)->OwnerClear(tspContext, &auth)))
146 			return result;
147 
148 		/* validate auth */
149 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
150 		result |= Trspi_Hash_UINT32(&hashCtx, result);
151 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
152 		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
153 			return result;
154 
155 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
156 			return result;
157 	} else {
158 		if ((result = TCS_API(tspContext)->ForceClear(tspContext)))
159 			return result;
160 	}
161 
162 	return TSS_SUCCESS;
163 }
164