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