xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_key.c (revision 8450a7c42673d65e3b1f6560d3b6ecd317a6cbe8)
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 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "trousers_types.h"
20 #include "spi_utils.h"
21 #include "capabilities.h"
22 #include "tsplog.h"
23 #include "obj.h"
24 #include "authsess.h"
25 
26 
27 TSS_RESULT
28 Tspi_Key_UnloadKey(TSS_HKEY hKey)	/* in */
29 {
30 	TSS_HCONTEXT tspContext;
31 	TCS_KEY_HANDLE hTcsKey;
32 	TSS_RESULT result;
33 
34 	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
35 		return result;
36 
37 	if ((result = obj_rsakey_get_tcs_handle(hKey, &hTcsKey)))
38 		return result;
39 
40 	return __tspi_free_resource(tspContext, hTcsKey, TPM_RT_KEY);
41 }
42 
43 TSS_RESULT
44 Tspi_Key_LoadKey(TSS_HKEY hKey,			/* in */
45 		 TSS_HKEY hUnwrappingKey)	/* in */
46 {
47 	TPM_AUTH auth;
48 	TCPA_DIGEST digest;
49 	TSS_RESULT result;
50 	UINT32 keyslot;
51 	TSS_HCONTEXT tspContext;
52 	TSS_HPOLICY hPolicy;
53 	UINT32 keySize;
54 	BYTE *keyBlob;
55 	TCS_KEY_HANDLE tcsKey, tcsParentHandle;
56 	TSS_BOOL usesAuth;
57 	TPM_AUTH *pAuth;
58 	Trspi_HashCtx hashCtx;
59 	TPM_COMMAND_CODE ordinal;
60 
61 	if (!obj_is_rsakey(hUnwrappingKey))
62 		return TSPERR(TSS_E_INVALID_HANDLE);
63 
64 	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
65 		return result;
66 
67 	if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
68 		return result;
69 
70 	if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob)))
71 		return result;
72 
73 	if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
74 		return result;
75 
76 	if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy,
77 					    &usesAuth))) {
78 		free_tspi(tspContext, keyBlob);
79 		return result;
80 	}
81 
82 	if (usesAuth) {
83 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
84 		result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
85 		result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
86 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
87 			free_tspi(tspContext, keyBlob);
88 			return result;
89 		}
90 
91 		if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
92 						      &digest, &auth))) {
93 			free_tspi(tspContext, keyBlob);
94 			return result;
95 		}
96 		pAuth = &auth;
97 	} else {
98 		pAuth = NULL;
99 	}
100 
101 	if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, keySize,
102 							 keyBlob, pAuth, &tcsKey, &keyslot))) {
103 		free_tspi(tspContext, keyBlob);
104 		return result;
105 	}
106 
107 	free_tspi(tspContext, keyBlob);
108 
109 	if (usesAuth) {
110 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
111 		result |= Trspi_Hash_UINT32(&hashCtx, result);
112 		result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
113 		if (ordinal == TPM_ORD_LoadKey)
114 			result |= Trspi_Hash_UINT32(&hashCtx, keyslot);
115 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
116 			return result;
117 
118 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
119 			return result;
120 	}
121 
122 	return obj_rsakey_set_tcs_handle(hKey, tcsKey);
123 }
124 
125 TSS_RESULT
126 Tspi_Key_GetPubKey(TSS_HKEY hKey,		/* in */
127 		   UINT32 * pulPubKeyLength,	/* out */
128 		   BYTE ** prgbPubKey)		/* out */
129 {
130 	TPM_AUTH auth;
131 	TPM_AUTH *pAuth;
132 	TCPA_DIGEST digest;
133 	TCPA_RESULT result;
134 	TSS_HCONTEXT tspContext;
135 	TSS_HPOLICY hPolicy;
136 	TCS_KEY_HANDLE tcsKeyHandle;
137 	TSS_BOOL usesAuth;
138 	Trspi_HashCtx hashCtx;
139 
140 	if (pulPubKeyLength == NULL || prgbPubKey == NULL)
141 		return TSPERR(TSS_E_BAD_PARAMETER);
142 
143 	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
144 		return result;
145 
146 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE,
147 					    &hPolicy, &usesAuth)))
148 		return result;
149 
150 	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
151 		return result;
152 
153 	if (usesAuth) {
154 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
155 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetPubKey);
156 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
157 			return result;
158 
159 		if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetPubKey, hPolicy, FALSE,
160 						      &digest, &auth)))
161 			return result;
162 		pAuth = &auth;
163 	} else {
164 		pAuth = NULL;
165 	}
166 
167 	if ((result = TCS_API(tspContext)->GetPubKey(tspContext, tcsKeyHandle, pAuth,
168 						     pulPubKeyLength, prgbPubKey)))
169 		return result;
170 
171 	if (usesAuth) {
172 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
173 		result |= Trspi_Hash_UINT32(&hashCtx, result);
174 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetPubKey);
175 		result |= Trspi_HashUpdate(&hashCtx, *pulPubKeyLength, *prgbPubKey);
176 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
177 			goto error;
178 
179 		/* goto error here since prgbPubKey has been set */
180 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
181 			goto error;
182 	}
183 
184 	if ((result = __tspi_add_mem_entry(tspContext, *prgbPubKey)))
185 		goto error;
186 
187 	if (tcsKeyHandle == TPM_KEYHND_SRK)
188 		obj_rsakey_set_pubkey(hKey, TRUE, *prgbPubKey);
189 
190 	return TSS_SUCCESS;
191 error:
192 	free(*prgbPubKey);
193 	*prgbPubKey = NULL;
194 	*pulPubKeyLength = 0;
195 	return result;
196 }
197 
198 TSS_RESULT
199 Tspi_Key_CreateKey(TSS_HKEY hKey,		/* in */
200 		   TSS_HKEY hWrappingKey,	/* in */
201 		   TSS_HPCRS hPcrComposite)	/* in, may be NULL */
202 {
203 #ifdef TSS_BUILD_CMK
204 	UINT32 blobSize;
205 	BYTE *blob;
206 	TSS_BOOL isCmk = FALSE;
207 	TPM_HMAC msaApproval;
208 	TPM_DIGEST msaDigest;
209 #endif
210 	TCPA_DIGEST digest;
211 	TCPA_RESULT result;
212 	TCS_KEY_HANDLE parentTCSKeyHandle;
213 	BYTE *keyBlob = NULL;
214 	UINT32 keySize;
215 	UINT32 newKeySize;
216 	BYTE *newKey = NULL;
217 	UINT32 ordinal = TPM_ORD_CreateWrapKey;
218 	TSS_HCONTEXT tspContext;
219 	Trspi_HashCtx hashCtx;
220 	struct authsess *xsap = NULL;
221 
222 	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
223 		return result;
224 
225 	if (hPcrComposite) {
226 		/* its possible that hPcrComposite could be a bad handle here,
227 		 * or that no indices of it are yet set, which would throw
228 		 * internal error. Blanket both those codes with bad
229 		 * parameter to help the user out */
230 		if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
231 			return TSPERR(TSS_E_BAD_PARAMETER);
232 	}
233 
234 	if ((result = obj_rsakey_get_tcs_handle(hWrappingKey, &parentTCSKeyHandle)))
235 		return result;
236 
237 	if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob)))
238 		return result;
239 
240 #ifdef TSS_BUILD_CMK
241 	isCmk = obj_rsakey_is_cmk(hKey);
242 	if (isCmk) {
243 		if ((result = obj_rsakey_get_msa_approval(hKey, &blobSize, &blob)))
244 			goto done;
245 		memcpy(msaApproval.digest, blob, sizeof(msaApproval.digest));
246 		free_tspi(tspContext, blob);
247 
248 		if ((result = obj_rsakey_get_msa_digest(hKey, &blobSize, &blob)))
249 			goto done;
250 		memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest));
251 		free_tspi(tspContext, blob);
252 
253 		ordinal = TPM_ORD_CMK_CreateKey;
254 	}
255 #endif
256 
257 	if ((result = authsess_xsap_init(tspContext, hWrappingKey, hKey, TSS_AUTH_POLICY_REQUIRED,
258 					 ordinal, TPM_ET_KEYHANDLE, &xsap)))
259 		return result;
260 
261 	/* Setup the Hash Data for the HMAC */
262 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
263 	result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
264 #ifdef TSS_BUILD_CMK
265 	if (isCmk) {
266 		result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
267 		result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
268 		result |= Trspi_Hash_HMAC(&hashCtx, msaApproval.digest);
269 		result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest);
270 	} else {
271 #endif
272 		result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata);
273 		result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthMig.authdata);
274 		result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
275 #ifdef TSS_BUILD_CMK
276 	}
277 #endif
278 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
279 		goto done;
280 
281 	if ((result = authsess_xsap_hmac(xsap, &digest)))
282 		goto done;
283 
284 	/* Now call the function */
285 #ifdef TSS_BUILD_CMK
286 	if (isCmk) {
287 		if ((newKey = malloc(keySize)) == NULL) {
288 			LogError("malloc of %u bytes failed.", keySize);
289 			result = TSPERR(TSS_E_OUTOFMEMORY);
290 			goto done;
291 		}
292 		memcpy(newKey, keyBlob, keySize);
293 		newKeySize = keySize;
294 
295 		if ((result = RPC_CMK_CreateKey(tspContext, parentTCSKeyHandle,
296 						(TPM_ENCAUTH *)&xsap->encAuthUse,
297 						&msaApproval, &msaDigest, &newKeySize, &newKey,
298 						xsap->pAuth)))
299 			goto done;
300 	} else {
301 #endif
302 		if ((result = TCS_API(tspContext)->CreateWrapKey(tspContext, parentTCSKeyHandle,
303 								 (TPM_ENCAUTH *)&xsap->encAuthUse,
304 								 (TPM_ENCAUTH *)&xsap->encAuthMig,
305 								 keySize, keyBlob, &newKeySize,
306 								 &newKey, xsap->pAuth)))
307 			goto done;
308 #ifdef TSS_BUILD_CMK
309 	}
310 #endif
311 
312 	/* Validate the Authorization before using the new key */
313 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
314 	result |= Trspi_Hash_UINT32(&hashCtx, result);
315 	result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
316 	result |= Trspi_HashUpdate(&hashCtx, newKeySize, newKey);
317 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
318 		goto done;
319 
320 	if (authsess_xsap_verify(xsap, &digest)) {
321 		result = TSPERR(TSS_E_TSP_AUTHFAIL);
322 		goto done;
323 	}
324 
325 	/* Push the new key into the existing object */
326 	result = obj_rsakey_set_tcpakey(hKey, newKeySize, newKey);
327 
328 done:
329 	authsess_free(xsap);
330 	free_tspi(tspContext, keyBlob);
331 	free(newKey);
332 
333 	return result;
334 }
335 
336 TSS_RESULT
337 Tspi_Key_WrapKey(TSS_HKEY hKey,			/* in */
338 		 TSS_HKEY hWrappingKey,		/* in */
339 		 TSS_HPCRS hPcrComposite)	/* in, may be NULL */
340 {
341 	TSS_HPOLICY hUsePolicy, hMigPolicy;
342 	TCPA_SECRET usage, migration;
343 	TSS_RESULT result;
344 	BYTE *keyPrivBlob = NULL, *wrappingPubKey = NULL, *keyBlob = NULL;
345 	UINT32 keyPrivBlobLen, wrappingPubKeyLen, keyBlobLen;
346 	BYTE newPrivKey[214]; /* its not magic, see TPM 1.1b spec p.71 */
347 	BYTE encPrivKey[256];
348 	UINT32 newPrivKeyLen = 214, encPrivKeyLen = 256;
349 	UINT64 offset;
350 	TSS_KEY keyContainer;
351 	TCPA_DIGEST digest;
352 	TSS_HCONTEXT tspContext;
353 	Trspi_HashCtx hashCtx;
354 
355 	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
356 		return result;
357 
358 	if (hPcrComposite) {
359 		if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
360 			return result;
361 	}
362 
363 	/* get the key to be wrapped's private key */
364 	if ((result = obj_rsakey_get_priv_blob(hKey, &keyPrivBlobLen, &keyPrivBlob)))
365 		goto done;
366 
367 	/* get the key to be wrapped's blob */
368 	if ((result = obj_rsakey_get_blob(hKey, &keyBlobLen, &keyBlob)))
369 		goto done;
370 
371 	/* get the wrapping key's public key */
372 	if ((result = obj_rsakey_get_modulus(hWrappingKey, &wrappingPubKeyLen, &wrappingPubKey)))
373 		goto done;
374 
375 	/* get the key to be wrapped's usage policy */
376 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hUsePolicy, NULL)))
377 		goto done;
378 
379 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_MIGRATION, &hMigPolicy, NULL)))
380 		goto done;
381 
382 	if ((result = obj_policy_get_secret(hUsePolicy, TR_SECRET_CTX_NEW, &usage)))
383 		goto done;
384 
385 	if ((result = obj_policy_get_secret(hMigPolicy, TR_SECRET_CTX_NEW, &migration)))
386 		goto done;
387 
388 	memset(&keyContainer, 0, sizeof(TSS_KEY));
389 
390 	/* unload the key to be wrapped's blob */
391 	offset = 0;
392 	if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer)))
393 		return result;
394 
395 	/* load the key's attributes into an object and get its hash value */
396 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
397 	result |= Hash_TSS_PRIVKEY_DIGEST(&hashCtx, &keyContainer);
398 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
399 		return result;
400 
401 	free_key_refs(&keyContainer);
402 
403 	/* create the plaintext private key blob */
404 	offset = 0;
405 	Trspi_LoadBlob_BYTE(&offset, TCPA_PT_ASYM, newPrivKey);
406 	Trspi_LoadBlob(&offset, 20, newPrivKey, usage.authdata);
407 	Trspi_LoadBlob(&offset, 20, newPrivKey, migration.authdata);
408 	Trspi_LoadBlob(&offset, 20, newPrivKey, digest.digest);
409 	Trspi_LoadBlob_UINT32(&offset, keyPrivBlobLen, newPrivKey);
410 	Trspi_LoadBlob(&offset, keyPrivBlobLen, newPrivKey, keyPrivBlob);
411 	newPrivKeyLen = offset;
412 
413 	/* encrypt the private key blob */
414 	if ((result = Trspi_RSA_Encrypt(newPrivKey, newPrivKeyLen, encPrivKey,
415 					&encPrivKeyLen, wrappingPubKey,
416 					wrappingPubKeyLen)))
417 		goto done;
418 
419 	/* set the new encrypted private key in the wrapped key object */
420 	if ((result = obj_rsakey_set_privkey(hKey, FALSE, encPrivKeyLen, encPrivKey)))
421 		goto done;
422 
423 done:
424 	free_tspi(tspContext, keyPrivBlob);
425 	free_tspi(tspContext, keyBlob);
426 	free_tspi(tspContext, wrappingPubKey);
427 	return result;
428 }
429 
430 TSS_RESULT
431 Tspi_Context_LoadKeyByBlob(TSS_HCONTEXT tspContext,	/* in */
432 			   TSS_HKEY hUnwrappingKey,	/* in */
433 			   UINT32 ulBlobLength,		/* in */
434 			   BYTE * rgbBlobData,		/* in */
435 			   TSS_HKEY * phKey)		/* out */
436 {
437 	TPM_AUTH auth;
438 	UINT64 offset;
439 	TCPA_DIGEST digest;
440 	TSS_RESULT result;
441 	UINT32 keyslot;
442 	TSS_HPOLICY hPolicy;
443 	TCS_KEY_HANDLE tcsParentHandle, myTCSKeyHandle;
444 	TSS_KEY keyContainer;
445 	TSS_BOOL useAuth;
446 	TPM_AUTH *pAuth;
447 	TSS_FLAG initFlags;
448 	UINT16 realKeyBlobSize;
449 	TCPA_KEY_USAGE keyUsage;
450 	UINT32 pubLen;
451 	Trspi_HashCtx hashCtx;
452 	TPM_COMMAND_CODE ordinal;
453 
454 	if (phKey == NULL || rgbBlobData == NULL )
455 		return TSPERR(TSS_E_BAD_PARAMETER);
456 
457 	if (!obj_is_rsakey(hUnwrappingKey))
458 		return TSPERR(TSS_E_INVALID_HANDLE);
459 
460 	if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
461 		return result;
462 
463 	if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
464 		return result;
465 
466 	offset = 0;
467 	if ((result = UnloadBlob_TSS_KEY(&offset, rgbBlobData, &keyContainer)))
468 		return result;
469 	realKeyBlobSize = offset;
470 	pubLen = keyContainer.pubKey.keyLength;
471 	keyUsage = keyContainer.keyUsage;
472 	/* free these now, since they're not used below */
473 	free_key_refs(&keyContainer);
474 
475 	if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
476 		return result;
477 
478 	if (useAuth) {
479 		/* Create the Authorization */
480 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
481 		result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
482 		result |= Trspi_HashUpdate(&hashCtx, ulBlobLength, rgbBlobData);
483 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
484 			return result;
485 
486 		if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
487 						      &digest, &auth)))
488 			return result;
489 
490 		pAuth = &auth;
491 	} else {
492 		pAuth = NULL;
493 	}
494 
495 	if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, ulBlobLength,
496 							 rgbBlobData, pAuth, &myTCSKeyHandle,
497 							 &keyslot)))
498 		return result;
499 
500 	if (useAuth) {
501 		/* ---  Validate return auth */
502 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
503 		result |= Trspi_Hash_UINT32(&hashCtx, result);
504 		result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
505 		if (ordinal == TPM_ORD_LoadKey)
506 			result |= Trspi_Hash_UINT32(&hashCtx, keyslot);
507 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
508 			return result;
509 
510 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
511 			return result;
512 	}
513 
514 	/* ---  Create a new Object */
515 	initFlags = 0;
516 	if (pubLen == 0x100)
517 		initFlags |= TSS_KEY_SIZE_2048;
518 	else if (pubLen == 0x80)
519 		initFlags |= TSS_KEY_SIZE_1024;
520 	else if (pubLen == 0x40)
521 		initFlags |= TSS_KEY_SIZE_512;
522 
523 	/* clear the key type field */
524 	initFlags &= ~TSS_KEY_TYPE_MASK;
525 
526 	if (keyUsage == TPM_KEY_STORAGE)
527 		initFlags |= TSS_KEY_TYPE_STORAGE;
528 	else
529 		initFlags |= TSS_KEY_TYPE_SIGNING;	/* loading the blob
530 							   will fix this
531 							   back to what it
532 							   should be. */
533 
534 	if ((result = obj_rsakey_add(tspContext, initFlags, phKey))) {
535 		LogDebug("Failed create object");
536 		return TSPERR(TSS_E_INTERNAL_ERROR);
537 	}
538 
539 	if ((result = obj_rsakey_set_tcpakey(*phKey,realKeyBlobSize, rgbBlobData))) {
540 		LogDebug("Key loaded but failed to setup the key object"
541 			  "correctly");
542 		return TSPERR(TSS_E_INTERNAL_ERROR);
543 	}
544 
545 	return obj_rsakey_set_tcs_handle(*phKey, myTCSKeyHandle);
546 }
547 
548 TSS_RESULT
549 Tspi_TPM_OwnerGetSRKPubKey(TSS_HTPM hTPM,		/* in */
550 			   UINT32 * pulPuKeyLength,	/* out */
551 			   BYTE ** prgbPubKey)		/* out */
552 {
553 	TSS_RESULT result;
554 	TSS_HPOLICY hPolicy;
555 	TSS_HCONTEXT tspContext;
556 	TCS_KEY_HANDLE hKey;
557 	TPM_AUTH auth;
558 	Trspi_HashCtx hashCtx;
559 	TCPA_DIGEST digest;
560 
561 	if (pulPuKeyLength == NULL || prgbPubKey == NULL)
562 		return TSPERR(TSS_E_BAD_PARAMETER);
563 
564 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
565 		return result;
566 
567 	hKey = TPM_KEYHND_SRK;
568 
569 	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
570 		return result;
571 
572 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
573 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
574 	result |= Trspi_Hash_UINT32(&hashCtx, hKey);
575 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
576 		return result;
577 
578 	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub,
579 					      hPolicy, FALSE, &digest, &auth)))
580 		return result;
581 
582 	if ((result = TCS_API(tspContext)->OwnerReadInternalPub(tspContext, hKey, &auth,
583 								pulPuKeyLength, prgbPubKey)))
584 		return result;
585 
586 	/* Validate return auth */
587 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
588 	result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
589 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
590 	result |= Trspi_HashUpdate(&hashCtx, *pulPuKeyLength, *prgbPubKey);
591 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
592 		goto error;
593 
594 	if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
595 		goto error;
596 
597 	/* Call a special SRK-seeking command to transparently add the public data to the object */
598 	if ((result = obj_rsakey_set_srk_pubkey(*prgbPubKey))) {
599 		LogError("Error setting SRK public data, SRK key object may not exist");
600 	}
601 
602 	if ((result = __tspi_add_mem_entry(tspContext, *prgbPubKey)))
603 		goto error;
604 
605 	return result;
606 
607 error:
608 	free(*prgbPubKey);
609 	pulPuKeyLength = 0;
610 	return result;
611 }
612 
613 /* TSS 1.2-only interfaces */
614 #ifdef TSS_BUILD_TSS12
615 TSS_RESULT
616 Tspi_TPM_KeyControlOwner(TSS_HTPM hTPM,		/* in */
617 			 TSS_HKEY hTssKey,	/* in */
618 			 UINT32 attribName,	/* in */
619 			 TSS_BOOL attribValue,	/* in */
620 			 TSS_UUID* pUuidData)	/* out */
621 {
622 	TSS_RESULT result;
623 	TSS_HPOLICY hPolicy;
624 	TSS_HCONTEXT tspContext;
625 	TCS_KEY_HANDLE hTcsKey;
626 	BYTE *pubKey = NULL;
627 	UINT32 pubKeyLen;
628 	TPM_KEY_CONTROL tpmAttribName;
629 	Trspi_HashCtx hashCtx;
630 	TCPA_DIGEST digest;
631 	TPM_AUTH ownerAuth;
632 
633 	LogDebugFn("Enter");
634 
635 	/* Check valid TPM context, get TSP context */
636 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
637 		return result;
638 
639 	/* Get Tcs KeyHandle */
640 	if ((result = obj_rsakey_get_tcs_handle(hTssKey, &hTcsKey)))
641 		return result;
642 
643 	/* Validate/convert attribName */
644 	switch (attribName) {
645 		case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
646 			tpmAttribName = TPM_KEY_CONTROL_OWNER_EVICT;
647 			break;
648 		default:
649 			return TSPERR(TSS_E_BAD_PARAMETER);
650 	}
651 
652 	/* Begin Auth - get TPM Policy Handler */
653 	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
654 		return result;
655 
656 	/* Get associated pubKey */
657 	if ((result = obj_rsakey_get_pub_blob(hTssKey, &pubKeyLen, &pubKey)))
658 		return result;
659 
660 	/* Create hash digest */
661 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
662 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner);
663 	LogDebugData(pubKeyLen, pubKey);
664 	result |= Trspi_HashUpdate(&hashCtx, pubKeyLen, pubKey);
665 	result |= Trspi_Hash_UINT32(&hashCtx, tpmAttribName);
666 	result |= Trspi_Hash_BOOL(&hashCtx, attribValue);
667 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
668 		free_tspi(tspContext, pubKey);
669 		return result;
670 	}
671 
672 	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KeyControlOwner, hPolicy, FALSE,
673 					      &digest, &ownerAuth))) {
674 		free_tspi(tspContext, pubKey);
675 		return result;
676 	}
677 
678 	if ((result = RPC_KeyControlOwner(tspContext, hTcsKey, pubKeyLen, pubKey, tpmAttribName,
679 					  attribValue, &ownerAuth, pUuidData))) {
680 		free_tspi(tspContext, pubKey);
681 		return result;
682 	}
683 
684 	/* Validate return auth */
685 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
686 	result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
687 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner);
688 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
689 		return result;
690 
691 	if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
692 		return result;
693 
694 	/* change hKey internal flag, according to attrib[Name|Value] */
695 	switch (attribName) {
696 		case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
697 			result = obj_rsakey_set_ownerevict(hTssKey, attribValue);
698 			break;
699 		default:
700 			/* NOT-REACHED */
701 			result = TSPERR(TSS_E_BAD_PARAMETER);
702 	}
703 
704 	return result;
705 }
706 #endif
707