xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_changeauth.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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 
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 "trousers_types.h"
22 #include "spi_utils.h"
23 #include "capabilities.h"
24 #include "tsplog.h"
25 #include "obj.h"
26 #include "authsess.h"
27 
28 TSS_RESULT
Tspi_ChangeAuth(TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HPOLICY hNewPolicy)29 Tspi_ChangeAuth(TSS_HOBJECT hObjectToChange,	/* in */
30 		TSS_HOBJECT hParentObject,	/* in */
31 		TSS_HPOLICY hNewPolicy)		/* in */
32 {
33 	UINT32 keyToChangeHandle;
34 	TSS_RESULT result;
35 	TSS_HCONTEXT tspContext;
36 
37 	if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext)))
38 		return result;
39 
40 	/* if the object to change is the TPM object, then the parent should
41 	 * be NULL.  If the object to change is not the TPM, then the parent
42 	 * object must be either an rsakey or the TPM */
43 	if (obj_is_tpm(hObjectToChange)) {
44 		if (hParentObject != NULL_HOBJECT)
45 			return TSPERR(TSS_E_BAD_PARAMETER);
46 	} else if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject)) {
47 		return TSPERR(TSS_E_INVALID_HANDLE);
48 	}
49 
50 	if (obj_is_tpm(hObjectToChange)) {
51 		if ((result = changeauth_owner(tspContext, hObjectToChange, NULL_HTPM, hNewPolicy)))
52 			return result;
53 	} else if (obj_is_rsakey(hObjectToChange)) {
54 		if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle)))
55 			return result;
56 
57 		if (keyToChangeHandle == TPM_KEYHND_SRK) {
58 			if ((result = changeauth_srk(tspContext, hObjectToChange, hParentObject,
59 						     hNewPolicy)))
60 				return result;
61 		} else {
62 			if ((result = changeauth_key(tspContext, hObjectToChange, hParentObject,
63 						     hNewPolicy)))
64 				return result;
65 		}
66 	} else if (obj_is_encdata(hObjectToChange)) {
67 		if ((result = changeauth_encdata(tspContext, hObjectToChange, hParentObject,
68 						 hNewPolicy)))
69 			return result;
70 	} else if (obj_is_policy(hObjectToChange) || obj_is_hash(hObjectToChange) ||
71 		   obj_is_pcrs(hObjectToChange) || obj_is_context(hObjectToChange)) {
72 		return TSPERR(TSS_E_BAD_PARAMETER);
73 	} else {
74 		return TSPERR(TSS_E_INVALID_HANDLE);
75 	}
76 
77 	if ((result = obj_policy_set_type(hNewPolicy, TSS_POLICY_USAGE)))
78 		return result;
79 
80 	return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange);
81 
82 }
83 
84 TSS_RESULT
Tspi_ChangeAuthAsym(TSS_HOBJECT hObjectToChange,TSS_HOBJECT hParentObject,TSS_HKEY hIdentKey,TSS_HPOLICY hNewPolicy)85 Tspi_ChangeAuthAsym(TSS_HOBJECT hObjectToChange,	/* in */
86 		    TSS_HOBJECT hParentObject,		/* in */
87 		    TSS_HKEY hIdentKey,			/* in */
88 		    TSS_HPOLICY hNewPolicy)		/* in */
89 {
90 #if 0
91 	TPM_AUTH auth;
92 	UINT64 offset;
93 	BYTE hashBlob[0x1000];
94 	TCPA_DIGEST digest;
95 	TCPA_RESULT result;
96 	UINT32 keyHandle;
97 	UINT32 idHandle;
98 	TSS_HPOLICY hPolicy;
99 	TSS_HPOLICY hParentPolicy;
100 	UINT32 keyToChangeHandle;
101 	TCPA_NONCE antiReplay;
102 	UINT32 bytesRequested;
103 	UINT64 tempSize;
104 	BYTE tempKey[512];
105 	TCPA_KEY_PARMS keyParms;
106 	/* XXX Wow... */
107 	BYTE ephParms[] = { 0, 0, 0x08, 0, 0, 0, 0, 0x02, 0, 0, 0, 0 };
108 	UINT32 KeySizeOut;
109 	BYTE *KeyDataOut;
110 	UINT32 CertifyInfoSize;
111 	BYTE *CertifyInfo;
112 	UINT32 sigSize;
113 	BYTE *sig;
114 	UINT32 ephHandle;
115 	TPM_CHANGEAUTH_VALIDATE caValidate;
116 	TCPA_SECRET newSecret, oldSecret;
117 	BYTE seed[20];
118 	BYTE a1[256];
119 	UINT32 a1Size;
120 	TSS_KEY ephemeralKey;
121 	TCPA_DIGEST newAuthLink;
122 	UINT32 encObjectSize;
123 	BYTE *encObject = NULL;
124 	UINT32 encDataSizeOut;
125 	BYTE *encDataOut;
126 	TCPA_NONCE saltNonce;
127 	TCPA_DIGEST changeProof;
128 	TSS_HPOLICY hOldPolicy;
129 	UINT32 caValidSize;
130 	UINT32 keyObjectSize;
131 	BYTE *keyObject;
132 	TSS_KEY keyContainer;
133 	TCPA_STORED_DATA dataContainer;
134 	BYTE *dataObject;
135 	UINT32 dataObjectSize;
136 	UINT16 entityType;
137 	TSS_BOOL useAuth = TRUE; // XXX
138 	TPM_AUTH *pAuth;
139 	BYTE dataBlob[1024];
140 	TSS_HCONTEXT tspContext;
141 	Trspi_HashCtx hashCtx;
142 
143 	if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext)))
144 		return result;
145 
146 	/*  grab all of the needed handles */
147 	if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &idHandle)))
148 		return result;
149 
150 	/*  get the secret for the parent */
151 	if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
152 		return result;
153 
154 	/*  get the parent secret */
155 	if ((result = Tspi_GetPolicyObject(hParentObject, TSS_POLICY_USAGE, &hParentPolicy)))
156 		return result;
157 
158 	if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject))
159 		return TSPERR(TSS_E_INVALID_HANDLE);
160 
161 	/*  get the keyObject  */
162 	if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle)))
163 		return result;
164 
165 	if (obj_is_rsakey(hObjectToChange) ||
166 	    obj_is_encdata(hObjectToChange)) {
167 
168 		if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle)))
169 			return result;
170 
171 		if (keyToChangeHandle == TPM_KEYHND_SRK) {
172 			return TSPERR(TSS_E_BAD_PARAMETER);
173 		} else {
174 			/*  generate container for ephemeral key */
175 			keyParms.algorithmID = 1;	/* rsa */
176 			keyParms.encScheme = 3;
177 			keyParms.sigScheme = 1;
178 			keyParms.parmSize = 12;
179 			keyParms.parms = malloc(12);
180 			if (keyParms.parms == NULL) {
181 				LogError("malloc of %d bytes failed.", 12);
182 				return TSPERR(TSS_E_OUTOFMEMORY);
183 			}
184 			memcpy(keyParms.parms, ephParms, 12);
185 
186 			tempSize = 0;
187 			Trspi_LoadBlob_KEY_PARMS(&tempSize, tempKey, &keyParms);
188 
189 			/*  generate antireplay nonce */
190 			bytesRequested = 20;
191 			if ((result = get_local_random(tspContext, FALSE, bytesRequested,
192 						       (BYTE **)antiReplay.nonce)))
193 				return result;
194 
195 			/* caluculate auth data */
196 			result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
197 			result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymStart);
198 			result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
199 						   antiReplay.nonce);
200 			result |= Trspi_Hash_KEY_PARMS(&hashCtx, &keyParms);
201 			if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
202 				return result;
203 
204 			if (useAuth) {
205 				if ((result = secret_PerformAuth_OIAP(hIdentKey,
206 								      TPM_ORD_ChangeAuthAsymStart,
207 								      hPolicy, FALSE, &digest,
208 								      &auth)))
209 					return result;
210 
211 				pAuth = &auth;
212 			} else {
213 				pAuth = NULL;
214 			}
215 
216 			if ((result = TCSP_ChangeAuthAsymStart(tspContext, idHandle, antiReplay,
217 							       tempSize, tempKey, pAuth,
218 							       &KeySizeOut, &KeyDataOut,
219 							       &CertifyInfoSize, &CertifyInfo,
220 							       &sigSize, &sig, &ephHandle)))
221 				return result;
222 
223 			/* Validate the Auth's */
224 			result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
225 			result |= Trspi_Hash_UINT32(&hashCtx, result);
226 			result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymStart);
227 			result |= Trspi_HashUpdate(&hashCtx, CertifyInfoSize, CertifyInfo);
228 			result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
229 			result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
230 			result |= Trspi_Hash_UINT32(&hashCtx, ephHandle);
231 			result |= Trspi_HashUpdate(&hashCtx, KeySizeOut, KeyDataOut);
232 			if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
233 				return result;
234 
235 			if (useAuth) {
236 				if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest,
237 									    &auth)))
238 					return result;
239 			}
240 
241 			/*  generate random data for asymfinish */
242 			if ((result = get_local_random(tspContext, FALSE, bytesRequested,
243 						       (BYTE **)&caValidate.n1.nonce)))
244 				return result;
245 
246 			if ((result = get_local_random(tspContext, FALSE, bytesRequested,
247 						       (BYTE **)&antiReplay.nonce)))
248 				return result;
249 
250 			if ((result = get_local_random(tspContext, FALSE, bytesRequested,
251 						       (BYTE **)&seed)))
252 				return result;
253 
254 			if ((result = Tspi_GetPolicyObject(hObjectToChange, TSS_POLICY_USAGE,
255 							  &hOldPolicy)))
256 				return result;
257 
258 			if ((result = obj_policy_get_secret(hNewPolicy, TR_SECRET_CTX_NEW,
259 							    &newSecret)))
260 				return result;
261 			if ((result = obj_policy_get_secret(hOldPolicy, TR_SECRET_CTX_NOT_NEW,
262 							    &oldSecret)))
263 				return result;
264 
265 			/* Encrypt the ChangeAuthValidate structure with the
266 			 * ephemeral key */
267 
268 			memcpy(caValidate.newAuthSecret.authdata, newSecret.authdata, 20);
269 
270 			offset = 0;
271 			Trspi_LoadBlob_CHANGEAUTH_VALIDATE(&offset, hashBlob, &caValidate);
272 			caValidSize = offset;
273 
274 			offset = 0;
275 			if ((result = UnloadBlob_TSS_KEY(&offset, KeyDataOut, &ephemeralKey)))
276 				return result;
277 
278 			Trspi_RSA_Encrypt(hashBlob, caValidSize, a1, &a1Size,
279 				       ephemeralKey.pubKey.key,
280 				       ephemeralKey.pubKey.keyLength);
281 
282 			free_key_refs(&ephemeralKey);
283 
284 			Trspi_HMAC(TSS_HASH_SHA1, 20, oldSecret.authdata,
285 					 20, newSecret.authdata,
286 					 newAuthLink.digest);
287 
288 			if (obj_is_rsakey(hObjectToChange)) {
289 				if ((result = obj_rsakey_get_blob(hObjectToChange,
290 						   &keyObjectSize, &keyObject)))
291 					return result;
292 
293 				__tspi_memset(&keyContainer, 0, sizeof(TSS_KEY));
294 
295 				offset = 0;
296 				if ((result = UnloadBlob_TSS_KEY(&offset,
297 								 keyObject,
298 								 &keyContainer)))
299 					return result;
300 
301 				encObjectSize = keyContainer.encSize;
302 				encObject = malloc(encObjectSize);
303 				if (encObject == NULL) {
304 					LogError("malloc of %d bytes failed.",
305 							encObjectSize);
306 					free_key_refs(&keyContainer);
307 					return TSPERR(TSS_E_OUTOFMEMORY);
308 				}
309 				memcpy(encObject, keyContainer.encData,
310 						encObjectSize);
311 				entityType = TCPA_ET_KEY;
312 			} else {
313 				if ((result = obj_encdata_get_data(hObjectToChange,
314 						   &dataObjectSize, &dataObject)))
315 					return result;
316 
317 				offset = 0;
318 				if ((result = Trspi_UnloadBlob_STORED_DATA(&offset,
319 									   dataObject,
320 									   &dataContainer)))
321 					return result;
322 
323 				encObjectSize = dataContainer.encDataSize;
324 				encObject = malloc(encObjectSize);
325 				if (encObject == NULL) {
326 					LogError("malloc of %d bytes failed.", encObjectSize);
327 					free(dataContainer.sealInfo);
328 					free(dataContainer.encData);
329 					return TSPERR(TSS_E_OUTOFMEMORY);
330 				}
331 				memcpy(encObject, dataContainer.encData,
332 						encObjectSize);
333 				entityType = TCPA_ET_DATA;
334 			}
335 
336 			result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
337 			result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymFinish);
338 			result |= Trspi_Hash_UINT16(&hashCtx, entityType);
339 			result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
340 						   newAuthLink.digest);
341 			result |= Trspi_Hash_UINT32(&hashCtx, a1Size);
342 			result |= Trspi_HashUpdate(&hashCtx, a1Size, a1);
343 			result |= Trspi_Hash_UINT32(&hashCtx, encObjectSize);
344 			result |= Trspi_HashUpdate(&hashCtx, encObjectSize, encObject);
345 			if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
346 				return result;
347 
348 			if (useAuth) {
349 				if ((result = secret_PerformAuth_OIAP(hParentObject,
350 								      TPM_ORD_ChangeAuthAsymFinish,
351 								      hParentPolicy, FALSE,
352 								      &digest, &auth))) {
353 					free(encObject);
354 					free_key_refs(&keyContainer);
355 					return result;
356 				}
357 				pAuth = &auth;
358 			} else {
359 				pAuth = NULL;
360 			}
361 
362 			if ((result = TCSP_ChangeAuthAsymFinish(tspContext, keyHandle, ephHandle,
363 							       entityType, newAuthLink, a1Size, a1,
364 							       encObjectSize, encObject, pAuth,
365 							       &encDataSizeOut, &encDataOut,
366 							       &saltNonce, &changeProof))) {
367 				free_key_refs(&keyContainer);
368 				free(encObject);
369 				return result;
370 			}
371 
372 			/* ---  Validate the Auth's */
373 			result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
374 			result |= Trspi_Hash_UINT32(&hashCtx, result);
375 			result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymFinish);
376 			result |= Trspi_Hash_UINT32(&hashCtx, encDataSizeOut);
377 			result |= Trspi_HashUpdate(&hashCtx, encDataSizeOut, encDataOut);
378 			result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
379 						   saltNonce.nonce);
380 			result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN,
381 						   changeProof.digest);
382 			if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
383 				return result;
384 
385 			if (useAuth) {
386 				if ((result = obj_policy_validate_auth_oiap(hParentPolicy,
387 									&digest,
388 									&auth))) {
389 					free_key_refs(&keyContainer);
390 					free(encObject);
391 					return result;
392 				}
393 			}
394 
395 			if (entityType == TCPA_ET_KEY ||
396 			    entityType == TCPA_ET_KEYHANDLE) {
397 				memcpy(keyContainer.encData, encDataOut, encDataSizeOut);
398 				keyContainer.encSize = encDataSizeOut;
399 
400 				offset = 0;
401 				LoadBlob_TSS_KEY(&offset, keyObject, &keyContainer);
402 				free_key_refs(&keyContainer);
403 				if ((result = obj_rsakey_set_tcpakey(hObjectToChange, offset,
404 								     keyObject))) {
405 					free(encObject);
406 					return result;
407 				}
408 			}
409 
410 			if (entityType == TCPA_ET_DATA) {
411 				memcpy(dataContainer.encData, encDataOut,
412 						encDataSizeOut);
413 				dataContainer.encDataSize = encDataSizeOut;
414 
415 				offset = 0;
416 				Trspi_LoadBlob_STORED_DATA(&offset, dataBlob,
417 							   &dataContainer);
418 				free(dataContainer.sealInfo);
419 				free(dataContainer.encData);
420 				obj_encdata_set_data(hObjectToChange,
421 						   offset, dataBlob);
422 			}
423 		}
424 	} else
425 		return TSPERR(TSS_E_BAD_PARAMETER);
426 
427 	free(encObject);
428 
429 	return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange);
430 #else
431 	return TSPERR(TSS_E_NOTIMPL);
432 #endif
433 }
434 
435