3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004-2007
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"
28
Tspi_Key_UnloadKey(TSS_HKEY hKey) /* in */
30
TSS_HCONTEXT tspContext;
31
TCS_KEY_HANDLE hTcsKey;
34
if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
37
if ((result = obj_rsakey_get_tcs_handle(hKey, &hTcsKey)))
40
return free_resource(tspContext, hTcsKey, TPM_RT_KEY);
44
Tspi_Key_LoadKey(TSS_HKEY hKey, /* in */
45
TSS_HKEY hUnwrappingKey) /* in */
51
TSS_HCONTEXT tspContext;
55
TCS_KEY_HANDLE tcsKey, tcsParentHandle;
58
Trspi_HashCtx hashCtx;
59
TPM_COMMAND_CODE ordinal;
61
if (!obj_is_rsakey(hUnwrappingKey))
62
return TSPERR(TSS_E_INVALID_HANDLE);
64
if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
67
if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
70
if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob)))
73
if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
76
if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy,
78
free_tspi(tspContext, keyBlob);
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);
91
if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
93
free_tspi(tspContext, keyBlob);
101
if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, keySize,
102
keyBlob, pAuth, &tcsKey, &keyslot))) {
103
free_tspi(tspContext, keyBlob);
107
free_tspi(tspContext, keyBlob);
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)))
118
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
122
return obj_rsakey_set_tcs_handle(hKey, tcsKey);
126
Tspi_Key_GetPubKey(TSS_HKEY hKey, /* in */
127
UINT32 * pulPubKeyLength, /* out */
128
BYTE ** prgbPubKey) /* out */
134
TSS_HCONTEXT tspContext;
136
TCS_KEY_HANDLE tcsKeyHandle;
138
Trspi_HashCtx hashCtx;
140
if (pulPubKeyLength == NULL || prgbPubKey == NULL)
141
return TSPERR(TSS_E_BAD_PARAMETER);
143
if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
146
if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE,
147
&hPolicy, &usesAuth)))
150
if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
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)))
159
if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetPubKey, hPolicy, FALSE,
167
if ((result = TCS_API(tspContext)->GetPubKey(tspContext, tcsKeyHandle, pAuth,
168
pulPubKeyLength, prgbPubKey)))
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)))
179
/* goto error here since prgbPubKey has been set */
180
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
184
if ((result = add_mem_entry(tspContext, *prgbPubKey)))
187
if (tcsKeyHandle == TPM_KEYHND_SRK)
188
obj_rsakey_set_pubkey(hKey, TRUE, *prgbPubKey);
194
*pulPubKeyLength = 0;
199
Tspi_Key_CreateKey(TSS_HKEY hKey, /* in */
200
TSS_HKEY hWrappingKey, /* in */
201
TSS_HPCRS hPcrComposite) /* in, may be NULL */
205
TCS_KEY_HANDLE parentTCSKeyHandle;
206
BYTE *keyBlob = NULL;
210
TSS_BOOL isCmk = FALSE;
213
TPM_HMAC msaApproval;
214
TPM_DIGEST msaDigest;
216
TSS_HCONTEXT tspContext;
217
Trspi_HashCtx hashCtx;
218
struct authsess *xsap = NULL;
220
if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
224
/* its possible that hPcrComposite could be a bad handle here,
225
* or that no indices of it are yet set, which would throw
226
* internal error. Blanket both those codes with bad
227
* parameter to help the user out */
228
if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
229
return TSPERR(TSS_E_BAD_PARAMETER);
232
if ((result = obj_rsakey_get_tcs_handle(hWrappingKey, &parentTCSKeyHandle)))
235
if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob)))
239
isCmk = obj_rsakey_is_cmk(hKey);
241
if ((result = obj_rsakey_get_msa_approval(hKey, &blobSize, &blob)))
243
memcpy(msaApproval.digest, blob, sizeof(msaApproval.digest));
244
free_tspi(tspContext, blob);
246
if ((result = obj_rsakey_get_msa_digest(hKey, &blobSize, &blob)))
248
memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest));
249
free_tspi(tspContext, blob);
253
ordinal = isCmk ? TPM_ORD_CMK_CreateKey : TPM_ORD_CreateWrapKey;
254
if ((result = authsess_xsap_init(tspContext, hWrappingKey, hKey, TSS_AUTH_POLICY_REQUIRED,
255
ordinal, TPM_ET_KEYHANDLE, &xsap)))
258
/* Setup the Hash Data for the HMAC */
259
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
261
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
262
result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
263
result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
264
result |= Trspi_Hash_HMAC(&hashCtx, msaApproval.digest);
265
result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest);
267
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
268
result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata);
269
result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthMig.authdata);
270
result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob);
272
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
275
if ((result = authsess_xsap_hmac(xsap, &digest)))
278
/* Now call the function */
280
if ((newKey = malloc(keySize)) == NULL) {
281
LogError("malloc of %u bytes failed.", keySize);
282
result = TSPERR(TSS_E_OUTOFMEMORY);
285
memcpy(newKey, keyBlob, keySize);
286
newKeySize = keySize;
288
if ((result = RPC_CMK_CreateKey(tspContext, parentTCSKeyHandle,
289
(TPM_ENCAUTH *)&xsap->encAuthUse,
290
&msaApproval, &msaDigest, &newKeySize, &newKey,
294
if ((result = TCS_API(tspContext)->CreateWrapKey(tspContext, parentTCSKeyHandle,
295
(TPM_ENCAUTH *)&xsap->encAuthUse,
296
(TPM_ENCAUTH *)&xsap->encAuthMig,
297
keySize, keyBlob, &newKeySize,
298
&newKey, xsap->pAuth)))
302
/* Validate the Authorization before using the new key */
303
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
304
result |= Trspi_Hash_UINT32(&hashCtx, result);
305
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
306
result |= Trspi_HashUpdate(&hashCtx, newKeySize, newKey);
307
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
310
if (authsess_xsap_verify(xsap, &digest)) {
311
result = TSPERR(TSS_E_TSP_AUTHFAIL);
315
/* Push the new key into the existing object */
316
result = obj_rsakey_set_tcpakey(hKey, newKeySize, newKey);
320
free_tspi(tspContext, keyBlob);
327
Tspi_Key_WrapKey(TSS_HKEY hKey, /* in */
328
TSS_HKEY hWrappingKey, /* in */
329
TSS_HPCRS hPcrComposite) /* in, may be NULL */
331
TSS_HPOLICY hUsePolicy, hMigPolicy;
332
TCPA_SECRET usage, migration;
334
BYTE *keyPrivBlob = NULL, *wrappingPubKey = NULL, *keyBlob = NULL;
335
UINT32 keyPrivBlobLen, wrappingPubKeyLen, keyBlobLen;
336
BYTE newPrivKey[214]; /* its not magic, see TPM 1.1b spec p.71 */
337
BYTE encPrivKey[256];
338
UINT32 newPrivKeyLen = 214, encPrivKeyLen = 256;
340
TSS_KEY keyContainer;
342
TSS_HCONTEXT tspContext;
343
Trspi_HashCtx hashCtx;
345
if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
349
if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite)))
353
/* get the key to be wrapped's private key */
354
if ((result = obj_rsakey_get_priv_blob(hKey, &keyPrivBlobLen, &keyPrivBlob)))
357
/* get the key to be wrapped's blob */
358
if ((result = obj_rsakey_get_blob(hKey, &keyBlobLen, &keyBlob)))
361
/* get the wrapping key's public key */
362
if ((result = obj_rsakey_get_modulus(hWrappingKey, &wrappingPubKeyLen, &wrappingPubKey)))
365
/* get the key to be wrapped's usage policy */
366
if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hUsePolicy, NULL)))
369
if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_MIGRATION, &hMigPolicy, NULL)))
372
if ((result = obj_policy_get_secret(hUsePolicy, TR_SECRET_CTX_NEW, &usage)))
375
if ((result = obj_policy_get_secret(hMigPolicy, TR_SECRET_CTX_NEW, &migration)))
378
memset(&keyContainer, 0, sizeof(TSS_KEY));
380
/* unload the key to be wrapped's blob */
382
if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer)))
385
/* load the key's attributes into an object and get its hash value */
386
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
387
result |= Hash_TSS_PRIVKEY_DIGEST(&hashCtx, &keyContainer);
388
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
391
free_key_refs(&keyContainer);
393
/* create the plaintext private key blob */
395
Trspi_LoadBlob_BYTE(&offset, TCPA_PT_ASYM, newPrivKey);
396
Trspi_LoadBlob(&offset, 20, newPrivKey, usage.authdata);
397
Trspi_LoadBlob(&offset, 20, newPrivKey, migration.authdata);
398
Trspi_LoadBlob(&offset, 20, newPrivKey, digest.digest);
399
Trspi_LoadBlob_UINT32(&offset, keyPrivBlobLen, newPrivKey);
400
Trspi_LoadBlob(&offset, keyPrivBlobLen, newPrivKey, keyPrivBlob);
401
newPrivKeyLen = offset;
403
/* encrypt the private key blob */
404
if ((result = Trspi_RSA_Encrypt(newPrivKey, newPrivKeyLen, encPrivKey,
405
&encPrivKeyLen, wrappingPubKey,
409
/* set the new encrypted private key in the wrapped key object */
410
if ((result = obj_rsakey_set_privkey(hKey, FALSE, encPrivKeyLen, encPrivKey)))
414
free_tspi(tspContext, keyPrivBlob);
415
free_tspi(tspContext, keyBlob);
416
free_tspi(tspContext, wrappingPubKey);
421
Tspi_Context_LoadKeyByBlob(TSS_HCONTEXT tspContext, /* in */
422
TSS_HKEY hUnwrappingKey, /* in */
423
UINT32 ulBlobLength, /* in */
424
BYTE * rgbBlobData, /* in */
425
TSS_HKEY * phKey) /* out */
433
TCS_KEY_HANDLE tcsParentHandle, myTCSKeyHandle;
434
TSS_KEY keyContainer;
438
UINT16 realKeyBlobSize;
439
TCPA_KEY_USAGE keyUsage;
441
Trspi_HashCtx hashCtx;
442
TPM_COMMAND_CODE ordinal;
444
if (phKey == NULL || rgbBlobData == NULL )
445
return TSPERR(TSS_E_BAD_PARAMETER);
447
if (!obj_is_rsakey(hUnwrappingKey))
448
return TSPERR(TSS_E_INVALID_HANDLE);
450
if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal)))
453
if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle)))
457
if ((result = UnloadBlob_TSS_KEY(&offset, rgbBlobData, &keyContainer)))
459
realKeyBlobSize = offset;
460
pubLen = keyContainer.pubKey.keyLength;
461
keyUsage = keyContainer.keyUsage;
462
/* free these now, since they're not used below */
463
free_key_refs(&keyContainer);
465
if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy, &useAuth)))
469
/* Create the Authorization */
470
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
471
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
472
result |= Trspi_HashUpdate(&hashCtx, ulBlobLength, rgbBlobData);
473
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
476
if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE,
485
if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, ulBlobLength,
486
rgbBlobData, pAuth, &myTCSKeyHandle,
491
/* --- Validate return auth */
492
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
493
result |= Trspi_Hash_UINT32(&hashCtx, result);
494
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
495
if (ordinal == TPM_ORD_LoadKey)
496
result |= Trspi_Hash_UINT32(&hashCtx, keyslot);
497
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
500
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
504
/* --- Create a new Object */
507
initFlags |= TSS_KEY_SIZE_2048;
508
else if (pubLen == 0x80)
509
initFlags |= TSS_KEY_SIZE_1024;
510
else if (pubLen == 0x40)
511
initFlags |= TSS_KEY_SIZE_512;
513
/* clear the key type field */
514
initFlags &= ~TSS_KEY_TYPE_MASK;
516
if (keyUsage == TPM_KEY_STORAGE)
517
initFlags |= TSS_KEY_TYPE_STORAGE;
519
initFlags |= TSS_KEY_TYPE_SIGNING; /* loading the blob
524
if ((result = obj_rsakey_add(tspContext, initFlags, phKey))) {
525
LogDebug("Failed create object");
526
return TSPERR(TSS_E_INTERNAL_ERROR);
529
if ((result = obj_rsakey_set_tcpakey(*phKey,realKeyBlobSize, rgbBlobData))) {
530
LogDebug("Key loaded but failed to setup the key object"
532
return TSPERR(TSS_E_INTERNAL_ERROR);
535
return obj_rsakey_set_tcs_handle(*phKey, myTCSKeyHandle);
539
Tspi_TPM_OwnerGetSRKPubKey(TSS_HTPM hTPM, /* in */
540
UINT32 * pulPuKeyLength, /* out */
541
BYTE ** prgbPubKey) /* out */
545
TSS_HCONTEXT tspContext;
548
Trspi_HashCtx hashCtx;
551
if (pulPuKeyLength == NULL || prgbPubKey == NULL)
552
return TSPERR(TSS_E_BAD_PARAMETER);
554
if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
557
hKey = TPM_KEYHND_SRK;
559
if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
562
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
563
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
564
result |= Trspi_Hash_UINT32(&hashCtx, hKey);
565
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
568
if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub,
569
hPolicy, FALSE, &digest, &auth)))
572
if ((result = TCS_API(tspContext)->OwnerReadInternalPub(tspContext, hKey, &auth,
573
pulPuKeyLength, prgbPubKey)))
576
/* Validate return auth */
577
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
578
result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
579
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub);
580
result |= Trspi_HashUpdate(&hashCtx, *pulPuKeyLength, *prgbPubKey);
581
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
584
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth)))
587
/* Call a special SRK-seeking command to transparently add the public data to the object */
588
if ((result = obj_rsakey_set_srk_pubkey(*prgbPubKey))) {
589
LogError("Error setting SRK public data, SRK key object may not exist");
592
if ((result = add_mem_entry(tspContext, *prgbPubKey)))
603
/* TSS 1.2-only interfaces */
604
#ifdef TSS_BUILD_TSS12
606
Tspi_TPM_KeyControlOwner(TSS_HTPM hTPM, /* in */
607
TSS_HKEY hTssKey, /* in */
608
UINT32 attribName, /* in */
609
TSS_BOOL attribValue, /* in */
610
TSS_UUID* pUuidData) /* out */
614
TSS_HCONTEXT tspContext;
615
TCS_KEY_HANDLE hTcsKey;
618
TPM_KEY_CONTROL tpmAttribName;
619
Trspi_HashCtx hashCtx;
625
/* Check valid TPM context, get TSP context */
626
if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
629
/* Get Tcs KeyHandle */
630
if ((result = obj_rsakey_get_tcs_handle(hTssKey, &hTcsKey)))
633
/* Validate/convert attribName */
634
switch (attribName) {
635
case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
636
tpmAttribName = TPM_KEY_CONTROL_OWNER_EVICT;
639
return TSPERR(TSS_E_BAD_PARAMETER);
642
/* Begin Auth - get TPM Policy Handler */
643
if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
646
/* Get associated pubKey */
647
if ((result = obj_rsakey_get_pub_blob(hTssKey, &pubKeyLen, &pubKey)))
650
/* Create hash digest */
651
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
652
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner);
653
LogDebugData(pubKeyLen, pubKey);
654
result |= Trspi_HashUpdate(&hashCtx, pubKeyLen, pubKey);
655
result |= Trspi_Hash_UINT32(&hashCtx, tpmAttribName);
656
result |= Trspi_Hash_BOOL(&hashCtx, attribValue);
657
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
658
free_tspi(tspContext, pubKey);
662
if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KeyControlOwner, hPolicy, FALSE,
663
&digest, &ownerAuth))) {
664
free_tspi(tspContext, pubKey);
668
if ((result = RPC_KeyControlOwner(tspContext, hTcsKey, pubKeyLen, pubKey, tpmAttribName,
669
attribValue, &ownerAuth, pUuidData))) {
670
free_tspi(tspContext, pubKey);
674
/* Validate return auth */
675
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
676
result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
677
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner);
678
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
681
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
684
/* change hKey internal flag, according to attrib[Name|Value] */
685
switch (attribName) {
686
case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT:
687
result = obj_rsakey_set_ownerevict(hTssKey, attribValue);
691
result = TSPERR(TSS_E_BAD_PARAMETER);