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