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-2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <time.h>
16 #include <errno.h>
17 
18 #include "trousers/tss.h"
19 #include "trousers/trousers.h"
20 #include "trousers_types.h"
21 #include "spi_utils.h"
22 #include "capabilities.h"
23 #include "tsplog.h"
24 #include "obj.h"
25 
26 
27 TSS_RESULT
secret_TakeOwnership(TSS_HKEY hEndorsementPubKey,TSS_HTPM hTPM,TSS_HKEY hKeySRK,TPM_AUTH * auth,UINT32 * encOwnerAuthLength,BYTE * encOwnerAuth,UINT32 * encSRKAuthLength,BYTE * encSRKAuth)28 secret_TakeOwnership(TSS_HKEY hEndorsementPubKey,
29 		     TSS_HTPM hTPM,
30 		     TSS_HKEY hKeySRK,
31 		     TPM_AUTH * auth,
32 		     UINT32 * encOwnerAuthLength,
33 		     BYTE * encOwnerAuth, UINT32 * encSRKAuthLength, BYTE * encSRKAuth)
34 {
35 	TSS_RESULT result;
36 	UINT32 endorsementKeySize;
37 	BYTE *endorsementKey;
38 	TSS_KEY dummyKey;
39 	UINT64 offset;
40 	TCPA_SECRET ownerSecret;
41 	TCPA_SECRET srkSecret;
42 	TCPA_DIGEST digest;
43 	TSS_HPOLICY hSrkPolicy;
44 	TSS_HPOLICY hOwnerPolicy;
45 	UINT32 srkKeyBlobLength;
46 	BYTE *srkKeyBlob;
47 	TSS_HCONTEXT tspContext;
48 	UINT32 ownerMode, srkMode;
49 	Trspi_HashCtx hashCtx;
50 
51 
52 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
53 		return result;
54 
55 	/*************************************************
56 	 *	First, get the policy objects and check them for how
57 	 *		to handle the secrets.  If they cannot be found
58 	 *		or there is an error, then we must fail
59 	 **************************************************/
60 
61 	/* First get the Owner Policy */
62 	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
63 		return result;
64 
65 	/* Now get the SRK Policy */
66 	if ((result = obj_rsakey_get_policy(hKeySRK, TSS_POLICY_USAGE, &hSrkPolicy, NULL)))
67 		return result;
68 
69 	if ((result = obj_policy_get_mode(hOwnerPolicy, &ownerMode)))
70 		return result;
71 
72 	if ((result = obj_policy_get_mode(hSrkPolicy, &srkMode)))
73 		return result;
74 
75 	/* If the policy callback's aren't the same, that's an error if one is callback */
76 	if (srkMode == TSS_SECRET_MODE_CALLBACK || ownerMode == TSS_SECRET_MODE_CALLBACK) {
77 		if (srkMode != TSS_SECRET_MODE_CALLBACK || ownerMode != TSS_SECRET_MODE_CALLBACK) {
78 			LogError("Policy callback modes for SRK policy and Owner policy differ.");
79 			return TSPERR(TSS_E_BAD_PARAMETER);
80 		}
81 	}
82 
83 	if (ownerMode != TSS_SECRET_MODE_CALLBACK) {
84 		/* First, get the Endorsement Public Key for Encrypting */
85 		if ((result = obj_rsakey_get_blob(hEndorsementPubKey, &endorsementKeySize,
86 						  &endorsementKey)))
87 			return result;
88 
89 		/* now stick it in a Key Structure */
90 		offset = 0;
91 		if ((result = UnloadBlob_TSS_KEY(&offset, endorsementKey, &dummyKey))) {
92 			free_tspi(tspContext, endorsementKey);
93 			return result;
94 		}
95 		free_tspi(tspContext, endorsementKey);
96 
97 		if ((result = obj_policy_get_secret(hOwnerPolicy, TR_SECRET_CTX_NEW,
98 						    &ownerSecret))) {
99 			free(dummyKey.pubKey.key);
100 			free(dummyKey.algorithmParms.parms);
101 			return result;
102 		}
103 
104 		if ((result = obj_policy_get_secret(hSrkPolicy, TR_SECRET_CTX_NEW, &srkSecret))) {
105 			free(dummyKey.pubKey.key);
106 			free(dummyKey.algorithmParms.parms);
107 			return result;
108 		}
109 
110 		/* Encrypt the Owner, SRK Authorizations */
111 		if ((result = Trspi_RSA_Encrypt(ownerSecret.authdata, 20, encOwnerAuth,
112 						encOwnerAuthLength, dummyKey.pubKey.key,
113 						dummyKey.pubKey.keyLength))) {
114 			free(dummyKey.pubKey.key);
115 			free(dummyKey.algorithmParms.parms);
116 			return result;
117 		}
118 
119 		if ((result = Trspi_RSA_Encrypt(srkSecret.authdata, 20, encSRKAuth,
120 						encSRKAuthLength, dummyKey.pubKey.key,
121 						dummyKey.pubKey.keyLength))) {
122 			free(dummyKey.pubKey.key);
123 			free(dummyKey.algorithmParms.parms);
124 			return result;
125 		}
126 
127 		free(dummyKey.pubKey.key);
128 		free(dummyKey.algorithmParms.parms);
129 	} else {
130 		*encOwnerAuthLength = 256;
131 		*encSRKAuthLength = 256;
132 		if ((result = obj_policy_do_takeowner(hOwnerPolicy, hTPM, hEndorsementPubKey,
133 						      *encOwnerAuthLength, encOwnerAuth)))
134 			return result;
135 	}
136 
137 	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
138 		return result;
139 
140 	/* Authorizatin Digest Calculation */
141 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
142 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
143 	result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_OWNER);
144 	result |= Trspi_Hash_UINT32(&hashCtx, *encOwnerAuthLength);
145 	result |= Trspi_HashUpdate(&hashCtx, *encOwnerAuthLength, encOwnerAuth);
146 	result |= Trspi_Hash_UINT32(&hashCtx, *encSRKAuthLength);
147 	result |= Trspi_HashUpdate(&hashCtx, *encSRKAuthLength, encSRKAuth);
148 	result |= Trspi_HashUpdate(&hashCtx, srkKeyBlobLength, srkKeyBlob);
149 	free_tspi(tspContext, srkKeyBlob);
150 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
151 		return result;
152 
153 	/* HMAC for the final digest */
154 	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_TakeOwnership, hOwnerPolicy, FALSE,
155 					      &digest, auth)))
156 		return result;
157 
158 	return TSS_SUCCESS;
159 }
160 
161 #ifdef TSS_BUILD_TRANSPORT
162 TSS_RESULT
Transport_OwnerClear(TSS_HCONTEXT tspContext,TPM_AUTH * ownerAuth)163 Transport_OwnerClear(TSS_HCONTEXT tspContext,	/* in */
164 		     TPM_AUTH * ownerAuth)	/* in, out */
165 {
166 	TSS_RESULT result;
167 	UINT32 handlesLen = 0;
168 
169 	if ((result = obj_context_transport_init(tspContext)))
170 		return result;
171 
172 	LogDebugFn("Executing in a transport session");
173 
174 	return obj_context_transport_execute(tspContext, TPM_ORD_OwnerClear, 0, NULL, NULL,
175 					     &handlesLen, NULL, ownerAuth, NULL, NULL, NULL);
176 }
177 
178 TSS_RESULT
Transport_ForceClear(TSS_HCONTEXT tspContext)179 Transport_ForceClear(TSS_HCONTEXT tspContext)	/* in */
180 {
181 	TSS_RESULT result;
182 	UINT32 handlesLen = 0;
183 
184 	if ((result = obj_context_transport_init(tspContext)))
185 		return result;
186 
187 	LogDebugFn("Executing in a transport session");
188 
189 	return obj_context_transport_execute(tspContext, TPM_ORD_ForceClear, 0, NULL, NULL,
190 					     &handlesLen, NULL, NULL, NULL, NULL, NULL);
191 }
192 #endif
193 
194