3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2007
17
#include "trousers/tss.h"
18
#include "trousers/trousers.h"
19
#include "trousers_types.h"
20
#include "spi_utils.h"
22
#include "tsp_delegate.h"
27
Tspi_TPM_Delegate_AddFamily(TSS_HTPM hTpm, /* in, must not be NULL */
29
TSS_HDELFAMILY* phFamily) /* out */
31
TPM_FAMILY_ID familyID = 0;
38
return TSPERR(TSS_E_BAD_PARAMETER);
39
*phFamily = NULL_HDELFAMILY;
41
if ((result = do_delegate_manage(hTpm, familyID, TPM_FAMILY_CREATE, sizeof(bLabel), &bLabel,
42
&outDataSize, &outData)))
46
Trspi_UnloadBlob_UINT32(&offset, &familyID, outData);
48
/* Create or update the delfamily object */
49
if ((result = update_delfamily_object(hTpm, familyID)))
52
obj_delfamily_find_by_familyid(hTpm, familyID, phFamily);
53
if (*phFamily == NULL_HDELFAMILY)
54
result = TSPERR(TSS_E_INTERNAL_ERROR);
63
Tspi_TPM_Delegate_GetFamily(TSS_HTPM hTpm, /* in, must not NULL */
64
UINT32 ulFamilyID, /* in */
65
TSS_HDELFAMILY* phFamily) /* out */
70
return TSPERR(TSS_E_BAD_PARAMETER);
71
*phFamily = NULL_HDELFAMILY;
73
/* Update the delfamily object */
74
if ((result = update_delfamily_object(hTpm, ulFamilyID)))
77
obj_delfamily_find_by_familyid(hTpm, ulFamilyID, phFamily);
78
if (*phFamily == NULL_HDELFAMILY)
79
result = TSPERR(TSS_E_BAD_PARAMETER);
85
Tspi_TPM_Delegate_InvalidateFamily(TSS_HTPM hTpm, /* in, must not be NULL */
86
TSS_HDELFAMILY hFamily) /* in */
88
TPM_FAMILY_ID familyID;
93
if ((result = obj_delfamily_get_familyid(hFamily, &familyID)))
96
if ((result = do_delegate_manage(hTpm, familyID, TPM_FAMILY_INVALIDATE, 0, NULL,
97
&outDataSize, &outData)))
100
/* Delete the delfamily object */
101
result = obj_delfamily_remove(hFamily, hTpm);
109
Tspi_TPM_Delegate_CreateDelegation(TSS_HOBJECT hObject, /* in */
110
BYTE bLabel, /* in */
111
UINT32 ulFlags, /* in */
112
TSS_HPCRS hPcrs, /* in */
113
TSS_HDELFAMILY hFamily, /* in */
114
TSS_HPOLICY hDelegation) /* in, out */
118
if (obj_is_tpm(hObject)) {
119
if ((result = create_owner_delegation(hObject, bLabel, ulFlags, hPcrs, hFamily,
122
} else if (obj_is_rsakey(hObject)) {
123
if ((result = create_key_delegation(hObject, bLabel, ulFlags, hPcrs, hFamily,
127
return TSPERR(TSS_E_INVALID_HANDLE);
133
Tspi_TPM_Delegate_CacheOwnerDelegation(TSS_HTPM hTpm, /* in */
134
TSS_HPOLICY hDelegation, /* in */
135
UINT32 ulIndex, /* in */
136
UINT32 ulFlags) /* in */
138
TSS_HCONTEXT hContext;
142
UINT32 secretMode = TSS_SECRET_MODE_NONE;
143
Trspi_HashCtx hashCtx;
145
TPM_AUTH ownerAuth, *pAuth;
148
if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
151
if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
154
if ((result = obj_policy_get_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER,
158
if (ulFlags & ~TSS_DELEGATE_CACHEOWNERDELEGATION_OVERWRITEEXISTING) {
159
result = TSPERR(TSS_E_BAD_PARAMETER);
163
if ((ulFlags & TSS_DELEGATE_CACHEOWNERDELEGATION_OVERWRITEEXISTING) == 0) {
164
TPM_DELEGATE_PUBLIC public;
166
/* Verify there is nothing occupying the specified row */
167
result = get_delegate_index(hContext, ulIndex, &public);
168
if (result == TSS_SUCCESS) {
169
free(public.pcrInfo.pcrSelection.pcrSelect);
170
result = TSPERR(TSS_E_DELFAMILY_ROWEXISTS);
175
if (hPolicy != NULL_HPOLICY) {
176
if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
180
if (secretMode != TSS_SECRET_MODE_NONE) {
181
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
182
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_LoadOwnerDelegation);
183
result |= Trspi_Hash_UINT32(&hashCtx, ulIndex);
184
result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
185
result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
186
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
190
if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_LoadOwnerDelegation,
191
hPolicy, FALSE, &digest, pAuth)))
196
if ((result = TCS_API(hContext)->Delegate_LoadOwnerDelegation(hContext, ulIndex, blobSize,
201
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
202
result |= Trspi_Hash_UINT32(&hashCtx, result);
203
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_LoadOwnerDelegation);
204
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
207
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
211
result = obj_policy_set_delegation_index(hDelegation, ulIndex);
214
free_tspi(hContext, blob);
220
Tspi_TPM_Delegate_UpdateVerificationCount(TSS_HTPM hTpm, /* in */
221
TSS_HPOLICY hDelegation) /* in, out */
223
TSS_HCONTEXT hContext;
225
UINT32 secretMode = TSS_SECRET_MODE_NONE;
226
Trspi_HashCtx hashCtx;
228
TPM_AUTH ownerAuth, *pAuth;
237
if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
240
if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
243
if (hPolicy != NULL_HPOLICY) {
244
if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
248
if ((result = obj_policy_is_delegation_index_set(hDelegation, &indexSet)))
253
if ((result = obj_policy_get_delegation_index(hDelegation, &index)))
255
inputSize = sizeof(UINT32);
256
input = calloc_tspi(hContext, inputSize);
258
LogError("malloc of %zd bytes failed.", sizeof(UINT32));
259
return TSPERR(TSS_E_OUTOFMEMORY);
262
Trspi_LoadBlob_UINT32(&offset, index, input);
264
if ((result = obj_policy_get_delegation_blob(hDelegation, 0,
265
&inputSize, &input)))
269
if (secretMode != TSS_SECRET_MODE_NONE) {
270
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
271
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_UpdateVerification);
272
result |= Trspi_Hash_UINT32(&hashCtx, inputSize);
273
result |= Trspi_HashUpdate(&hashCtx, inputSize, input);
274
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
278
if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_UpdateVerification,
279
hPolicy, FALSE, &digest, pAuth)))
284
if ((result = TCS_API(hContext)->Delegate_UpdateVerificationCount(hContext, inputSize,
285
input, pAuth, &outputSize,
290
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
291
result |= Trspi_Hash_UINT32(&hashCtx, result);
292
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_UpdateVerification);
293
result |= Trspi_Hash_UINT32(&hashCtx, outputSize);
294
result |= Trspi_HashUpdate(&hashCtx, outputSize, output);
295
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
298
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
302
result = obj_policy_set_delegation_blob(hDelegation, 0, outputSize, output);
305
free_tspi(hContext, input);
312
Tspi_TPM_Delegate_VerifyDelegation(TSS_HPOLICY hDelegation) /* in, out */
314
TSS_HCONTEXT hContext;
316
BYTE *delegate = NULL;
319
if ((result = obj_policy_get_tsp_context(hDelegation, &hContext)))
322
if ((result = obj_policy_get_delegation_blob(hDelegation, 0, &delegateSize, &delegate)))
325
result = TCS_API(hContext)->Delegate_VerifyDelegation(hContext, delegateSize, delegate);
327
free_tspi(hContext, delegate);
333
Tspi_TPM_Delegate_ReadTables(TSS_HCONTEXT hContext, /* in */
334
UINT32* pulFamilyTableSize, /* out */
335
TSS_FAMILY_TABLE_ENTRY** ppFamilyTable, /* out */
336
UINT32* pulDelegateTableSize, /* out */
337
TSS_DELEGATION_TABLE_ENTRY** ppDelegateTable) /* out */
339
UINT32 tpmFamilyTableSize, tpmDelegateTableSize;
340
BYTE *tpmFamilyTable = NULL, *tpmDelegateTable = NULL;
341
TPM_FAMILY_TABLE_ENTRY tpmFamilyEntry;
342
TSS_FAMILY_TABLE_ENTRY tssFamilyEntry, *tssFamilyTable = NULL;
343
UINT32 tssFamilyTableSize = 0;
344
TPM_DELEGATE_PUBLIC tpmDelegatePublic;
345
TSS_DELEGATION_TABLE_ENTRY tssDelegateEntry, *tssDelegateTable = NULL;
346
UINT32 tssDelegateTableSize = 0;
352
if (!pulFamilyTableSize || !ppFamilyTable || !pulDelegateTableSize || !ppDelegateTable)
353
return TSPERR(TSS_E_BAD_PARAMETER);
355
if (!obj_is_context(hContext))
356
return TSPERR(TSS_E_INVALID_HANDLE);
358
if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &tpmFamilyTableSize,
359
&tpmFamilyTable, &tpmDelegateTableSize,
363
if (tpmFamilyTableSize > 0) {
364
/* Create the TSS_FAMILY_TABLE_ENTRY array */
365
for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmFamilyTableSize;) {
366
Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&tpmOffset, tpmFamilyTable,
369
/* No pointers in the family table entries, so no
370
assignments required before doing LoadBlob */
371
Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(&tssOffset, NULL, &tssFamilyEntry);
374
if ((tssFamilyTable = calloc_tspi(hContext, tssOffset)) == NULL) {
375
LogError("malloc of %" PRIu64 " bytes failed.", tssOffset);
376
result = TSPERR(TSS_E_OUTOFMEMORY);
379
for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmFamilyTableSize; tssFamilyTableSize++) {
380
Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&tpmOffset, tpmFamilyTable,
383
tssFamilyEntry.familyID = tpmFamilyEntry.familyID;
384
tssFamilyEntry.label = tpmFamilyEntry.label.label;
385
tssFamilyEntry.verificationCount = tpmFamilyEntry.verificationCount;
386
tssFamilyEntry.enabled =
387
(tpmFamilyEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE;
388
tssFamilyEntry.locked =
389
(tpmFamilyEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ? TRUE : FALSE;
390
Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(&tssOffset, (BYTE *)tssFamilyTable,
395
if (tpmDelegateTableSize > 0) {
396
/* Create the TSS_DELEGATION_TABLE_ENTRY array */
397
for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmDelegateTableSize;) {
398
Trspi_UnloadBlob_UINT32(&tpmOffset, &tableIndex, tpmDelegateTable);
399
if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&tpmOffset, tpmDelegateTable,
400
&tpmDelegatePublic))) {
401
free_tspi(hContext, tssFamilyTable);
405
/* Some pointers in the delegate table entries, so
406
do some assignments before doing LoadBlob */
407
tssDelegateEntry.pcrInfo.sizeOfSelect =
408
tpmDelegatePublic.pcrInfo.pcrSelection.sizeOfSelect;
409
tssDelegateEntry.pcrInfo.selection =
410
tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect;
411
tssDelegateEntry.pcrInfo.sizeOfDigestAtRelease =
412
sizeof(tpmDelegatePublic.pcrInfo.digestAtRelease.digest);
413
tssDelegateEntry.pcrInfo.digestAtRelease =
414
tpmDelegatePublic.pcrInfo.digestAtRelease.digest;
415
Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(&tssOffset, NULL,
418
free(tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect);
421
if ((tssDelegateTable = calloc_tspi(hContext, tssOffset)) == NULL) {
422
LogError("malloc of %" PRIu64 " bytes failed.", tssOffset);
423
free_tspi(hContext, tssFamilyTable);
424
result = TSPERR(TSS_E_OUTOFMEMORY);
427
for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmDelegateTableSize; tssDelegateTableSize++) {
428
Trspi_UnloadBlob_UINT32(&tpmOffset, &tableIndex, tpmDelegateTable);
429
if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&tpmOffset,
430
tpmDelegateTable, &tpmDelegatePublic))) {
431
free_tspi(hContext, tssFamilyTable);
432
free_tspi(hContext, tssDelegateTable);
436
tssDelegateEntry.tableIndex = tableIndex;
437
tssDelegateEntry.label = tpmDelegatePublic.label.label;
438
tssDelegateEntry.pcrInfo.sizeOfSelect =
439
tpmDelegatePublic.pcrInfo.pcrSelection.sizeOfSelect;
440
tssDelegateEntry.pcrInfo.selection =
441
tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect;
442
tssDelegateEntry.pcrInfo.localityAtRelease =
443
tpmDelegatePublic.pcrInfo.localityAtRelease;
444
tssDelegateEntry.pcrInfo.sizeOfDigestAtRelease =
445
sizeof(tpmDelegatePublic.pcrInfo.digestAtRelease.digest);
446
tssDelegateEntry.pcrInfo.digestAtRelease =
447
tpmDelegatePublic.pcrInfo.digestAtRelease.digest;
448
tssDelegateEntry.per1 = tpmDelegatePublic.permissions.per1;
449
tssDelegateEntry.per2 = tpmDelegatePublic.permissions.per2;
450
tssDelegateEntry.familyID = tpmDelegatePublic.familyID;
451
tssDelegateEntry.verificationCount = tpmDelegatePublic.verificationCount;
452
Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(&tssOffset,
453
(BYTE *)tssDelegateTable, &tssDelegateEntry);
455
free(tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect);
459
*ppFamilyTable = tssFamilyTable;
460
*pulFamilyTableSize = tssFamilyTableSize;
461
*ppDelegateTable = tssDelegateTable;
462
*pulDelegateTableSize = tssDelegateTableSize;
465
free(tpmFamilyTable);
466
free(tpmDelegateTable);