3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004-2006
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"
25
#include "hosttable.h"
26
#include "tcsd_wrap.h"
32
Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext, /* in */
33
TSS_FLAG persistentStorageType, /* in */
34
TSS_UUID uuidData, /* in */
35
TSS_HKEY * phKey) /* out */
39
UINT32 keyBlobSize, parentPSType;
41
TCS_KEY_HANDLE tcsKeyHandle;
42
TSS_HKEY parentTspHandle;
43
TCS_LOADKEY_INFO info;
46
return TSPERR(TSS_E_BAD_PARAMETER);
48
if ((!obj_is_context(tspContext)))
49
return TSPERR(TSS_E_INVALID_HANDLE);
51
/* This key is in the System Persistant storage */
52
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
54
memset(&info, 0, sizeof(TCS_LOADKEY_INFO));
56
result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle);
58
if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) {
62
/* load failed, due to some key in the chain needing auth
63
* which doesn't yet exist at the TCS level. However, the
64
* auth may already be set in policies at the TSP level.
65
* To find out, get the key handle of the key requiring
66
* auth. First, look at the list of keys in memory. */
67
if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) {
68
/* If that failed, look on disk, in User PS. */
69
if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID,
74
if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE,
78
if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, FALSE,
79
&info.paramDigest, &info.authData))
82
if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info,
88
if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize,
92
if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob,
93
TSS_OBJ_FLAG_SYSTEM_PS, phKey))) {
98
result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle);
102
if ((result = load_from_system_ps(tspContext, &uuidData, phKey)))
105
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
106
if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID)))
109
/* If the parent is not in memory, recursively call ourselves on it */
110
if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) {
111
if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType)))
114
if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType,
115
parentUUID, &parentTspHandle)))
119
if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey)))
122
/* The parent is loaded and we have the parent key handle, so call the TCS to
123
* actually load the child. */
124
return Tspi_Key_LoadKey(*phKey, parentTspHandle);
126
return TSPERR(TSS_E_BAD_PARAMETER);
133
Tspi_Context_RegisterKey(TSS_HCONTEXT tspContext, /* in */
134
TSS_HKEY hKey, /* in */
135
TSS_FLAG persistentStorageType, /* in */
136
TSS_UUID uuidKey, /* in */
137
TSS_FLAG persistentStorageTypeParent, /* in */
138
TSS_UUID uuidParentKey) /* in */
145
if (!obj_is_context(tspContext) || !obj_is_rsakey(hKey))
146
return TSPERR(TSS_E_INVALID_HANDLE);
148
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
149
if (persistentStorageTypeParent == TSS_PS_TYPE_USER) {
150
return TSPERR(TSS_E_NOTIMPL);
151
} else if (persistentStorageTypeParent == TSS_PS_TYPE_SYSTEM) {
152
if ((result = obj_rsakey_get_blob(hKey, &keyBlobSize,
156
if ((result = RPC_RegisterKey(tspContext, uuidParentKey, uuidKey,
157
keyBlobSize, keyBlob,
158
strlen(PACKAGE_STRING) + 1,
159
(BYTE *)PACKAGE_STRING)))
162
return TSPERR(TSS_E_BAD_PARAMETER);
164
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
165
if ((result = ps_is_key_registered(&uuidKey, &answer)))
169
return TSPERR(TSS_E_KEY_ALREADY_REGISTERED);
171
if ((result = obj_rsakey_get_blob (hKey, &keyBlobSize, &keyBlob)))
174
if ((result = ps_write_key(&uuidKey, &uuidParentKey,
175
persistentStorageTypeParent,
176
keyBlobSize, keyBlob)))
179
return TSPERR(TSS_E_BAD_PARAMETER);
182
if ((result = obj_rsakey_set_uuid(hKey, persistentStorageType, &uuidKey)))
189
Tspi_Context_UnregisterKey(TSS_HCONTEXT tspContext, /* in */
190
TSS_FLAG persistentStorageType, /* in */
191
TSS_UUID uuidKey, /* in */
192
TSS_HKEY *phKey) /* out */
194
BYTE *keyBlob = NULL;
199
return TSPERR(TSS_E_BAD_PARAMETER);
201
if ((!obj_is_context(tspContext)))
202
return TSPERR(TSS_E_INVALID_HANDLE);
204
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
205
/* get the key first, so it doesn't disappear when we
207
if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidKey, &keyBlobSize,
211
if ((obj_rsakey_add_by_key(tspContext, &uuidKey, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS,
219
/* now unregister it */
220
if ((result = RPC_UnregisterKey(tspContext, uuidKey)))
222
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
223
/* get the key first, so it doesn't disappear when we
225
if ((result = ps_get_key_by_uuid(tspContext, &uuidKey, phKey)))
228
/* now unregister it */
229
if ((result = ps_remove_key(&uuidKey)))
232
return TSPERR(TSS_E_BAD_PARAMETER);
239
Tspi_Context_GetKeyByUUID(TSS_HCONTEXT tspContext, /* in */
240
TSS_FLAG persistentStorageType, /* in */
241
TSS_UUID uuidData, /* in */
242
TSS_HKEY * phKey) /* out */
245
UINT32 keyBlobSize = 0;
246
BYTE *keyBlob = NULL;
249
return TSPERR(TSS_E_BAD_PARAMETER);
251
if ((!obj_is_context(tspContext)))
252
return TSPERR(TSS_E_INVALID_HANDLE);
254
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
255
if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize,
259
if ((obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS,
266
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
267
if (!obj_is_context(tspContext))
268
return TSPERR(TSS_E_INVALID_HANDLE);
270
if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey)))
273
return TSPERR(TSS_E_BAD_PARAMETER);
279
Tspi_Context_GetKeyByPublicInfo(TSS_HCONTEXT tspContext, /* in */
280
TSS_FLAG persistentStorageType, /* in */
281
TSS_ALGORITHM_ID algID, /* in */
282
UINT32 ulPublicInfoLength, /* in */
283
BYTE * rgbPublicInfo, /* in */
284
TSS_HKEY * phKey) /* out */
286
TCPA_ALGORITHM_ID tcsAlgID;
290
TSS_HKEY keyOutHandle;
292
TSS_KEY keyContainer;
296
return TSPERR(TSS_E_BAD_PARAMETER);
298
if (!obj_is_context(tspContext))
299
return TSPERR(TSS_E_INVALID_HANDLE);
303
tcsAlgID = TCPA_ALG_RSA;
306
LogError("Algorithm ID was not type RSA.");
307
return TSPERR(TSS_E_BAD_PARAMETER);
310
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
311
if ((result = RPC_GetRegisteredKeyByPublicInfo(tspContext, tcsAlgID,
312
ulPublicInfoLength, rgbPublicInfo,
313
&keyBlobSize, &keyBlob)))
316
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
317
return ps_get_key_by_pub(tspContext, ulPublicInfoLength, rgbPublicInfo,
320
return TSPERR(TSS_E_BAD_PARAMETER);
322
/* need to setup the init flags of the create object based on
323
* the size of the blob's pubkey */
325
if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) {
330
/* begin setting up the key object */
331
switch (keyContainer.pubKey.keyLength) {
333
flag |= TSS_KEY_SIZE_16384;
336
flag |= TSS_KEY_SIZE_8192;
339
flag |= TSS_KEY_SIZE_4096;
342
flag |= TSS_KEY_SIZE_2048;
345
flag |= TSS_KEY_SIZE_1024;
348
flag |= TSS_KEY_SIZE_512;
351
LogError("Key was not a known keylength.");
353
free_key_refs(&keyContainer);
354
return TSPERR(TSS_E_INTERNAL_ERROR);
357
if (keyContainer.keyUsage == TPM_KEY_SIGNING)
358
flag |= TSS_KEY_TYPE_SIGNING;
359
else if (keyContainer.keyUsage == TPM_KEY_STORAGE)
360
flag |= TSS_KEY_TYPE_STORAGE;
361
else if (keyContainer.keyUsage == TPM_KEY_IDENTITY)
362
flag |= TSS_KEY_TYPE_IDENTITY;
363
else if (keyContainer.keyUsage == TPM_KEY_AUTHCHANGE)
364
flag |= TSS_KEY_TYPE_AUTHCHANGE;
365
else if (keyContainer.keyUsage == TPM_KEY_BIND)
366
flag |= TSS_KEY_TYPE_BIND;
367
else if (keyContainer.keyUsage == TPM_KEY_LEGACY)
368
flag |= TSS_KEY_TYPE_LEGACY;
370
if (keyContainer.authDataUsage == TPM_AUTH_NEVER)
371
flag |= TSS_KEY_NO_AUTHORIZATION;
373
flag |= TSS_KEY_AUTHORIZATION;
375
if (keyContainer.keyFlags & TPM_MIGRATABLE)
376
flag |= TSS_KEY_MIGRATABLE;
378
flag |= TSS_KEY_NOT_MIGRATABLE;
380
if (keyContainer.keyFlags & TPM_VOLATILE)
381
flag |= TSS_KEY_VOLATILE;
383
flag |= TSS_KEY_NON_VOLATILE;
386
if (keyContainer.keyFlags & TPM_MIGRATEAUTHORITY)
387
flag |= TSS_KEY_CERTIFIED_MIGRATABLE;
389
flag |= TSS_KEY_NOT_CERTIFIED_MIGRATABLE;
392
/* Create a new Key Object */
393
if ((result = obj_rsakey_add(tspContext, flag, &keyOutHandle))) {
395
free_key_refs(&keyContainer);
398
/* Stick the info into this net KeyObject */
399
if ((result = obj_rsakey_set_tcpakey(keyOutHandle, keyBlobSize, keyBlob))) {
401
free_key_refs(&keyContainer);
406
free_key_refs(&keyContainer);
407
*phKey = keyOutHandle;
413
Tspi_Context_GetRegisteredKeysByUUID(TSS_HCONTEXT tspContext, /* in */
414
TSS_FLAG persistentStorageType, /* in */
415
TSS_UUID * pUuidData, /* in */
416
UINT32 * pulKeyHierarchySize, /* out */
417
TSS_KM_KEYINFO ** ppKeyHierarchy) /* out */
420
TSS_KM_KEYINFO *tcsHier, *tspHier;
421
UINT32 tcsHierSize, tspHierSize;
424
if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
425
return TSPERR(TSS_E_BAD_PARAMETER);
427
if (!obj_is_context(tspContext))
428
return TSPERR(TSS_E_INVALID_HANDLE);
431
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
432
if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData,
436
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
437
if ((result = ps_get_registered_keys(pUuidData, &tcs_uuid,
438
&tspHierSize, &tspHier)))
441
if ((result = RPC_EnumRegisteredKeys(tspContext, &tcs_uuid, &tcsHierSize,
447
result = merge_key_hierarchies(tspContext, tspHierSize, tspHier,
448
tcsHierSize, tcsHier, pulKeyHierarchySize,
453
return TSPERR(TSS_E_BAD_PARAMETER);
455
if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, &tcsHierSize,
459
if ((result = ps_get_registered_keys(pUuidData, NULL, &tspHierSize, &tspHier))) {
464
result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize,
465
tcsHier, pulKeyHierarchySize, ppKeyHierarchy);
470
if ((result = add_mem_entry(tspContext, *ppKeyHierarchy))) {
471
free(*ppKeyHierarchy);
472
*ppKeyHierarchy = NULL;
473
*pulKeyHierarchySize = 0;
480
Tspi_Context_GetRegisteredKeysByUUID2(TSS_HCONTEXT tspContext, /* in */
481
TSS_FLAG persistentStorageType, /* in */
482
TSS_UUID * pUuidData, /* in */
483
UINT32 * pulKeyHierarchySize, /* out */
484
TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */
487
TSS_KM_KEYINFO2 *tcsHier, *tspHier;
488
UINT32 tcsHierSize, tspHierSize;
491
/* If out parameters are NULL, return error */
492
if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
493
return TSPERR(TSS_E_BAD_PARAMETER);
495
if (!obj_is_context(tspContext))
496
return TSPERR(TSS_E_INVALID_HANDLE);
499
/* TSS 1.2 Spec: If a certain key UUID is provided, the returned array of
500
* TSS_KM_KEYINFO2 structures only contains data reflecting the path of the key
501
* hierarchy regarding that key. The first array entry is the key addressed by the
502
* given UUID followed by its parent key up to and including the root key. */
503
if (persistentStorageType == TSS_PS_TYPE_SYSTEM) {
504
if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData,
505
pulKeyHierarchySize, ppKeyHierarchy)))
507
} else if (persistentStorageType == TSS_PS_TYPE_USER) {
508
if ((result = ps_get_registered_keys2(pUuidData, &tcs_uuid, &tspHierSize,
511
/* The tcs_uuid returned by ps_get_registered_key2 will always be a parent
512
* of some key into the system ps of a user key into the user ps. This key
513
* needs to be searched for in the system ps to be merged */
514
if ((result = RPC_EnumRegisteredKeys2(tspContext, &tcs_uuid, &tcsHierSize,
520
result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier,
521
tcsHierSize, tcsHier, pulKeyHierarchySize,
526
return TSPERR(TSS_E_BAD_PARAMETER);
528
/* If this field is set to NULL, the returned array of TSS_KM_KEYINFO2 structures
529
* contains data reflecting the entire key hierarchy starting with root key. The
530
* array will include keys from both the user and the system TSS key store. The
531
* persistentStorageType field will be ignored. */
532
if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, &tcsHierSize,
536
if ((result = ps_get_registered_keys2(pUuidData, NULL, &tspHierSize, &tspHier))) {
541
result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize,
542
tcsHier, pulKeyHierarchySize, ppKeyHierarchy);
547
if ((result = add_mem_entry(tspContext, *ppKeyHierarchy))) {
548
free(*ppKeyHierarchy);
549
*ppKeyHierarchy = NULL;
550
*pulKeyHierarchySize = 0;