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
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_types.h"
18 #include "tcs_tsp.h"
19 #include "tcs_utils.h"
20 #include "tcs_int_literals.h"
21 #include "capabilities.h"
22 #include "tcslog.h"
23 #include "tcsps.h"
24
25 TSS_RESULT
TCS_RegisterKey_Internal(TCS_CONTEXT_HANDLE hContext,TSS_UUID * WrappingKeyUUID,TSS_UUID * KeyUUID,UINT32 cKeySize,BYTE * rgbKey,UINT32 cVendorData,BYTE * gbVendorData)26 TCS_RegisterKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
27 TSS_UUID *WrappingKeyUUID, /* in */
28 TSS_UUID *KeyUUID, /* in */
29 UINT32 cKeySize, /* in */
30 BYTE * rgbKey, /* in */
31 UINT32 cVendorData, /* in */
32 BYTE * gbVendorData) /* in */
33 {
34 TSS_RESULT result;
35 TSS_BOOL is_reg;
36
37 if ((result = ctx_verify_context(hContext)))
38 return result;
39
40 /* Check if key is already regisitered */
41 if (isUUIDRegistered(KeyUUID, &is_reg) != TSS_SUCCESS) {
42 LogError("Failed checking if UUID is registered.");
43 return TCSERR(TSS_E_INTERNAL_ERROR);
44 }
45
46 if (is_reg == TRUE || TSS_UUID_IS_OWNEREVICT(KeyUUID)) {
47 LogDebug("UUID is already registered");
48 return TCSERR(TSS_E_KEY_ALREADY_REGISTERED);
49 }
50
51 LogDebugUnrollKey(rgbKey);
52
53 /* Go ahead and store it in system persistant storage */
54 if ((result = ps_write_key(KeyUUID, WrappingKeyUUID, gbVendorData, cVendorData, rgbKey,
55 cKeySize))) {
56 LogError("Error writing key to file");
57 return result;
58 }
59
60 return TSS_SUCCESS;
61 }
62
63 TSS_RESULT
TCS_UnregisterKey_Internal(TCS_CONTEXT_HANDLE hContext,TSS_UUID KeyUUID)64 TCS_UnregisterKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
65 TSS_UUID KeyUUID) /* in */
66 {
67 TSS_RESULT result;
68
69 if ((result = ctx_verify_context(hContext)))
70 return result;
71
72 return ps_remove_key(&KeyUUID);
73 }
74
75 TSS_RESULT
TCS_EnumRegisteredKeys_Internal(TCS_CONTEXT_HANDLE hContext,TSS_UUID * pKeyUUID,UINT32 * pcKeyHierarchySize,TSS_KM_KEYINFO ** ppKeyHierarchy)76 TCS_EnumRegisteredKeys_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
77 TSS_UUID * pKeyUUID, /* in */
78 UINT32 * pcKeyHierarchySize, /* out */
79 TSS_KM_KEYINFO ** ppKeyHierarchy) /* out */
80 {
81 TSS_RESULT result = TSS_SUCCESS;
82 UINT32 count = 0, i;
83 TSS_KM_KEYINFO *ret = NULL;
84 TSS_UUID tmp_uuid;
85 struct key_disk_cache *disk_ptr, *tmp_ptrs[MAX_KEY_CHILDREN];
86 struct key_mem_cache *mem_ptr;
87 TSS_BOOL is_reg = FALSE;
88
89 LogDebug("Enum Reg Keys");
90
91 if (pcKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
92 return TCSERR(TSS_E_BAD_PARAMETER);
93
94 if ((result = ctx_verify_context(hContext)))
95 return result;
96
97 if (pKeyUUID != NULL) {
98 /* First have to verify the key is registered */
99 if ((result = isUUIDRegistered(pKeyUUID, &is_reg)))
100 return result;
101
102 if (is_reg == FALSE) {
103 /* This return code is not listed as possible in the TSS 1.1 spec,
104 * but it makes more sense than just TCS_SUCCESS or TSS_E_FAIL */
105 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
106 }
107 }
108
109 /* this entire operation needs to be atomic wrt registered keys. We must
110 * lock the mem cache as well to test if a given key is loaded. */
111 MUTEX_LOCK(disk_cache_lock);
112 MUTEX_LOCK(mem_cache_lock);
113
114 /* return an array of all registered keys if pKeyUUID == NULL */
115 if (pKeyUUID == NULL) {
116 /* determine the number of registered keys */
117 for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
118 if (disk_ptr->flags & CACHE_FLAG_VALID)
119 count++;
120 }
121
122 /* malloc a structure for each of them */
123 if (count != 0) {
124 ret = calloc(count, sizeof(TSS_KM_KEYINFO));
125 if (ret == NULL) {
126 LogError("malloc of %zd bytes failed.",
127 (count * sizeof(TSS_KM_KEYINFO)));
128 count = 0;
129 result = TCSERR(TSS_E_OUTOFMEMORY);
130 goto done;
131 }
132 } else {
133 goto done;
134 }
135
136 /* fill out the structure for each key */
137 i = 0;
138 for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
139 if (disk_ptr->flags & CACHE_FLAG_VALID) {
140 /* look for a mem cache entry to check if its loaded */
141 for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
142 if (!memcmp(&mem_ptr->uuid, &disk_ptr->uuid, sizeof(TSS_UUID))) {
143 if ((result = fill_key_info(disk_ptr, mem_ptr, &ret[i]))) {
144 free(ret);
145 ret = NULL;
146 count = 0;
147 goto done;
148 }
149 break;
150 }
151 }
152 /* if there is no mem cache entry for this key, go ahead and call
153 * fill_key_info(), it will pull everything from disk */
154 if (mem_ptr == NULL) {
155 if ((result = fill_key_info(disk_ptr, NULL, &ret[i]))) {
156 free(ret);
157 ret = NULL;
158 count = 0;
159 goto done;
160 }
161 }
162 i++;
163 }
164 }
165 } else {
166 /* return a chain of a key and its parents up to the SRK */
167 /* determine the number of keys in the chain */
168 memcpy(&tmp_uuid, pKeyUUID, sizeof(TSS_UUID));
169 disk_ptr = key_disk_cache_head;
170 while (disk_ptr != NULL && count < MAX_KEY_CHILDREN)
171 {
172 if (disk_ptr->flags & CACHE_FLAG_VALID &&
173 !memcmp(&disk_ptr->uuid, &tmp_uuid, sizeof(TSS_UUID)))
174 {
175 /* increment count, then search for the parent */
176 count++;
177 /* save a pointer to this cache entry */
178 tmp_ptrs[count - 1] = disk_ptr;
179 /* if the parent of this key is NULL, we're at the root of the tree */
180 if (!memcmp(&disk_ptr->parent_uuid, &NULL_UUID, sizeof(TSS_UUID)))
181 break;
182 /* overwrite tmp_uuid with the parent, which we will now search for */
183 memcpy(&tmp_uuid, &disk_ptr->parent_uuid, sizeof(TSS_UUID));
184 disk_ptr = key_disk_cache_head;
185 continue;
186 }
187 disk_ptr = disk_ptr->next;
188 }
189 /* when we reach this point, we have an array of TSS_UUID's that leads from the
190 * requested key up to the SRK*/
191
192 /* malloc a structure for each of them */
193 if (count != 0) {
194 ret = calloc(count, sizeof(TSS_KM_KEYINFO));
195 if (ret == NULL) {
196 LogError("malloc of %zd bytes failed.",
197 (count * sizeof(TSS_KM_KEYINFO)));
198 count = 0;
199 result = TCSERR(TSS_E_OUTOFMEMORY);
200 goto done;
201 }
202 } else {
203 goto done;
204 }
205
206 for (i = 0; i < count; i++) {
207 /* look for a mem cache entry to check if its loaded */
208 for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
209 if (!memcmp(&mem_ptr->uuid, &tmp_ptrs[i]->uuid, sizeof(TSS_UUID))) {
210 if ((result = fill_key_info(tmp_ptrs[i], mem_ptr, &ret[i]))) {
211 free(ret);
212 ret = NULL;
213 count = 0;
214 goto done;
215 }
216 break;
217 }
218 }
219 /* if there is no mem cache entry for this key, go ahead and call
220 * fill_key_info(), it will pull everything from disk */
221 if (mem_ptr == NULL) {
222 if ((result = fill_key_info(tmp_ptrs[i], NULL, &ret[i]))) {
223 free(ret);
224 ret = NULL;
225 count = 0;
226 goto done;
227 }
228 }
229 }
230 }
231 done:
232
233 MUTEX_UNLOCK(disk_cache_lock);
234 MUTEX_UNLOCK(mem_cache_lock);
235
236 *ppKeyHierarchy = ret;
237 *pcKeyHierarchySize = count;
238
239 return result;
240 }
241
242 TSS_RESULT
TCS_EnumRegisteredKeys_Internal2(TCS_CONTEXT_HANDLE hContext,TSS_UUID * pKeyUUID,UINT32 * pcKeyHierarchySize,TSS_KM_KEYINFO2 ** ppKeyHierarchy)243 TCS_EnumRegisteredKeys_Internal2(TCS_CONTEXT_HANDLE hContext, /* in */
244 TSS_UUID * pKeyUUID, /* in */
245 UINT32 * pcKeyHierarchySize, /* out */
246 TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */
247 {
248 TSS_RESULT result = TSS_SUCCESS;
249 UINT32 count = 0, i;
250 TSS_KM_KEYINFO2 *ret = NULL;
251 TSS_UUID tmp_uuid;
252 struct key_disk_cache *disk_ptr, *tmp_ptrs[MAX_KEY_CHILDREN];
253 struct key_mem_cache *mem_ptr;
254 TSS_BOOL is_reg = FALSE;
255
256 LogDebug("Enum Reg Keys2");
257
258 if (pcKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
259 return TCSERR(TSS_E_BAD_PARAMETER);
260
261 if ((result = ctx_verify_context(hContext)))
262 return result;
263
264 if (pKeyUUID != NULL) {
265 /* First have to verify the key is registered */
266 if ((result = isUUIDRegistered(pKeyUUID, &is_reg)))
267 return result;
268
269 if (is_reg == FALSE) {
270 /* This return code is not listed as possible in the TSS 1.1 spec,
271 * but it makes more sense than just TCS_SUCCESS or TSS_E_FAIL */
272 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
273 }
274 }
275
276 /* this entire operation needs to be atomic wrt registered keys. We must
277 * lock the mem cache as well to test if a given key is loaded. */
278 MUTEX_LOCK(disk_cache_lock);
279 MUTEX_LOCK(mem_cache_lock);
280
281 /* return an array of all registered keys if pKeyUUID == NULL */
282 if (pKeyUUID == NULL) {
283 /* determine the number of registered keys */
284 for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
285 if (disk_ptr->flags & CACHE_FLAG_VALID)
286 count++;
287 }
288
289 /* malloc a structure for each of them */
290 if (count != 0) {
291 ret = calloc(count, sizeof(TSS_KM_KEYINFO2));
292 if (ret == NULL) {
293 LogError("malloc of %zd bytes failed.",
294 (count * sizeof(TSS_KM_KEYINFO2)));
295 count = 0;
296 result = TCSERR(TSS_E_OUTOFMEMORY);
297 goto done;
298 }
299 } else {
300 goto done;
301 }
302
303 /* fill out the structure for each key */
304 i = 0;
305 for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
306 if (disk_ptr->flags & CACHE_FLAG_VALID) {
307 /* look for a mem cache entry to check if its loaded */
308 for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
309 if (!memcmp(&mem_ptr->uuid, &disk_ptr->uuid, sizeof(TSS_UUID))) {
310 if ((result = fill_key_info2(disk_ptr, mem_ptr, &ret[i]))) {
311 free(ret);
312 ret = NULL;
313 count = 0;
314 goto done;
315 }
316 break;
317 }
318 }
319 /* if there is no mem cache entry for this key, go ahead and call
320 * fill_key_info2(), it will pull everything from disk */
321 if (mem_ptr == NULL) {
322 if ((result = fill_key_info2(disk_ptr, NULL, &ret[i]))) {
323 free(ret);
324 ret = NULL;
325 count = 0;
326 goto done;
327 }
328 }
329 i++;
330 }
331 }
332 } else {
333 /* return a chain of a key and its parents up to the SRK */
334 /* determine the number of keys in the chain */
335 memcpy(&tmp_uuid, pKeyUUID, sizeof(TSS_UUID));
336 disk_ptr = key_disk_cache_head;
337 while (disk_ptr != NULL && count < MAX_KEY_CHILDREN)
338 {
339 if (disk_ptr->flags & CACHE_FLAG_VALID &&
340 !memcmp(&disk_ptr->uuid, &tmp_uuid, sizeof(TSS_UUID)))
341 {
342 /* increment count, then search for the parent */
343 count++;
344 /* save a pointer to this cache entry */
345 tmp_ptrs[count - 1] = disk_ptr;
346 /* if the parent of this key is NULL, we're at the root of the tree */
347 if (!memcmp(&disk_ptr->parent_uuid, &NULL_UUID, sizeof(TSS_UUID)))
348 break;
349 /* overwrite tmp_uuid with the parent, which we will now search for */
350 memcpy(&tmp_uuid, &disk_ptr->parent_uuid, sizeof(TSS_UUID));
351 disk_ptr = key_disk_cache_head;
352 continue;
353 }
354 disk_ptr = disk_ptr->next;
355 }
356 /* when we reach this point, we have an array of TSS_UUID's that leads from the
357 * requested key up to the SRK*/
358
359 /* malloc a structure for each of them */
360 if (count != 0) {
361 ret = calloc(count, sizeof(TSS_KM_KEYINFO2));
362 if (ret == NULL) {
363 LogError("malloc of %zd bytes failed.",
364 (count * sizeof(TSS_KM_KEYINFO2)));
365 count = 0;
366 result = TCSERR(TSS_E_OUTOFMEMORY);
367 goto done;
368 }
369 } else {
370 goto done;
371 }
372
373 for (i = 0; i < count; i++) {
374 /* look for a mem cache entry to check if its loaded */
375 for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
376 if (!memcmp(&mem_ptr->uuid, &tmp_ptrs[i]->uuid, sizeof(TSS_UUID))) {
377 if ((result = fill_key_info2(tmp_ptrs[i], mem_ptr, &ret[i]))) {
378 free(ret);
379 ret = NULL;
380 count = 0;
381 goto done;
382 }
383 break;
384 }
385 }
386 /* if there is no mem cache entry for this key, go ahead and call
387 * fill_key_info(), it will pull everything from disk */
388 if (mem_ptr == NULL) {
389 if ((result = fill_key_info2(tmp_ptrs[i], NULL, &ret[i]))) {
390 free(ret);
391 ret = NULL;
392 count = 0;
393 goto done;
394 }
395 }
396 }
397 }
398 done:
399
400 MUTEX_UNLOCK(disk_cache_lock);
401 MUTEX_UNLOCK(mem_cache_lock);
402
403 *ppKeyHierarchy = ret;
404 *pcKeyHierarchySize = count;
405
406 return result;
407 }
408
409 TSS_RESULT
TCS_GetRegisteredKey_Internal(TCS_CONTEXT_HANDLE hContext,TSS_UUID * KeyUUID,TSS_KM_KEYINFO ** ppKeyInfo)410 TCS_GetRegisteredKey_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
411 TSS_UUID *KeyUUID, /* in */
412 TSS_KM_KEYINFO ** ppKeyInfo) /* out */
413 {
414 TSS_RESULT result;
415 UINT64 offset;
416 BYTE tcpaKeyBlob[1024];
417 TSS_KEY tcpaKey;
418 UINT16 keySize = sizeof (tcpaKeyBlob);
419 TSS_UUID parentUUID;
420
421 /* This should be set in case we return before the malloc */
422 *ppKeyInfo = NULL;
423
424 if ((result = ctx_verify_context(hContext)))
425 return result;
426
427 if ((result = ps_get_key_by_uuid(KeyUUID, tcpaKeyBlob, &keySize))) {
428 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
429 }
430
431 if ((result = getParentUUIDByUUID(KeyUUID, &parentUUID)))
432 return TCSERR(TSS_E_FAIL);
433
434 *ppKeyInfo = malloc(sizeof(TSS_KM_KEYINFO));
435 if (*ppKeyInfo == NULL) {
436 LogError("malloc of %zd bytes failed.", sizeof(TSS_KM_KEYINFO));
437 return TCSERR(TSS_E_OUTOFMEMORY);
438 }
439
440 offset = 0;
441 UnloadBlob_TSS_KEY(&offset, tcpaKeyBlob, &tcpaKey);
442
443 (*ppKeyInfo)->bAuthDataUsage = tcpaKey.authDataUsage;
444
445 (*ppKeyInfo)->fIsLoaded = FALSE;
446
447 if (tcpaKey.hdr.key12.tag == TPM_TAG_KEY12) {
448 (*ppKeyInfo)->versionInfo.bMajor = TSS_SPEC_MAJOR;
449 (*ppKeyInfo)->versionInfo.bMinor = TSS_SPEC_MINOR;
450 (*ppKeyInfo)->versionInfo.bRevMajor = 0;
451 (*ppKeyInfo)->versionInfo.bRevMinor = 0;
452 } else {
453 (*ppKeyInfo)->versionInfo.bMajor = tcpaKey.hdr.key11.ver.major;
454 (*ppKeyInfo)->versionInfo.bMinor = tcpaKey.hdr.key11.ver.minor;
455 (*ppKeyInfo)->versionInfo.bRevMajor = tcpaKey.hdr.key11.ver.revMajor;
456 (*ppKeyInfo)->versionInfo.bRevMinor = tcpaKey.hdr.key11.ver.revMinor;
457 }
458
459 memcpy(&((*ppKeyInfo)->keyUUID), KeyUUID, sizeof(TSS_UUID));
460
461 (*ppKeyInfo)->ulVendorDataLength = 0;
462 (*ppKeyInfo)->rgbVendorData = 0;
463
464 memcpy(&((*ppKeyInfo)->parentKeyUUID), &parentUUID, sizeof(TSS_UUID));
465 return TSS_SUCCESS;
466 }
467
468 TSS_RESULT
TCS_GetRegisteredKeyBlob_Internal(TCS_CONTEXT_HANDLE hContext,TSS_UUID * KeyUUID,UINT32 * pcKeySize,BYTE ** prgbKey)469 TCS_GetRegisteredKeyBlob_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
470 TSS_UUID *KeyUUID, /* in */
471 UINT32 * pcKeySize, /* out */
472 BYTE ** prgbKey) /* out */
473 {
474 UINT16 keySize;
475 BYTE buffer[4096];
476 TSS_RESULT result;
477
478 if ((result = ctx_verify_context(hContext)))
479 return result;
480
481 keySize = sizeof(buffer);
482 if ((result = ps_get_key_by_uuid(KeyUUID, buffer, &keySize)))
483 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
484
485 *prgbKey = calloc(1, keySize);
486 if (*prgbKey == NULL) {
487 LogError("malloc of %d bytes failed.", keySize);
488 return TCSERR(TSS_E_OUTOFMEMORY);
489 } else {
490 memcpy(*prgbKey, buffer, keySize);
491 }
492 *pcKeySize = keySize;
493
494 return TSS_SUCCESS;
495 }
496
497 TSS_RESULT
TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext,TSS_UUID * KeyUUID,TCS_LOADKEY_INFO * pLoadKeyInfo,TCS_KEY_HANDLE * phKeyTCSI)498 TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext, /* in */
499 TSS_UUID *KeyUUID, /* in */
500 TCS_LOADKEY_INFO * pLoadKeyInfo, /* in, out */
501 TCS_KEY_HANDLE * phKeyTCSI) /* out */
502 {
503 UINT32 keyslot = 0, keySize;
504 UINT32 ordinal;
505 TSS_RESULT result;
506 TSS_UUID parentUuid;
507 BYTE keyBlob[0x1000];
508 UINT16 blobSize = sizeof(keyBlob);
509 UINT64 offset;
510 TCS_KEY_HANDLE parentTCSKeyHandle;
511
512 if (TPM_VERSION_IS(1,2))
513 ordinal = TPM_ORD_LoadKey2;
514 else
515 ordinal = TPM_ORD_LoadKey;
516
517 LogDebugFn("Enter: uuid: 0x%lx auth? 0x%x ***********", (unsigned long)KeyUUID,
518 pLoadKeyInfo == NULL ? 0xdeadbeef : pLoadKeyInfo->authData.AuthHandle);
519
520 if ((result = ctx_verify_context(hContext)))
521 return result;
522
523 memset(&parentUuid, 0, sizeof(TSS_UUID));
524
525 if (pLoadKeyInfo &&
526 memcmp(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID))) {
527 if (ps_get_key_by_uuid(&pLoadKeyInfo->keyUUID, keyBlob, &blobSize))
528 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
529
530 if (mc_get_handles_by_uuid(&pLoadKeyInfo->parentKeyUUID, &parentTCSKeyHandle,
531 &keyslot))
532 return TCSERR(TCS_E_KM_LOADFAILED);
533
534 return LoadKeyByBlob_Internal(ordinal, hContext, parentTCSKeyHandle,
535 blobSize, keyBlob,
536 &pLoadKeyInfo->authData,
537 phKeyTCSI, &keyslot);
538 }
539
540 /* if KeyUUID is already loaded, increment the ref count and return */
541 if (mc_get_handles_by_uuid(KeyUUID, phKeyTCSI, &keyslot) == TSS_SUCCESS) {
542 if (keyslot) {
543 if (ctx_mark_key_loaded(hContext, *phKeyTCSI)) {
544 LogError("Error marking key as loaded");
545 return TCSERR(TSS_E_INTERNAL_ERROR);
546 }
547 return TSS_SUCCESS;
548 }
549 }
550 /*********************************************************************
551 * The first thing to do in this func is setup all the info and make sure
552 * that we get it all from either the keyfile or the keyCache
553 * also, it's important to return if the key is already loaded
554 ***********************************************************************/
555 LogDebugFn("calling ps_get_key_by_uuid");
556 if (ps_get_key_by_uuid(KeyUUID, keyBlob, &blobSize))
557 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
558 /* convert UINT16 to UIN32 */
559 keySize = blobSize;
560
561 LogDebugFn("calling getParentUUIDByUUID");
562 /*--- Get my parent's UUID. Since My key is registered, my parent should be as well. */
563 if ((result = getParentUUIDByUUID(KeyUUID, &parentUuid)))
564 return TCSERR(TCS_E_KM_LOADFAILED);
565
566 if ((result = TCSP_LoadKeyByUUID_Internal(hContext, &parentUuid,
567 pLoadKeyInfo, &parentTCSKeyHandle)))
568 return result;
569
570 LogDebugFn("calling LoadKeyByBlob_Internal");
571 /*******************************************************
572 * If no errors have happend up till now, then the parent is loaded and ready for use.
573 * The parent's TCS Handle should be in parentTCSKeyHandle.
574 ******************************************************/
575 if ((result = LoadKeyByBlob_Internal(ordinal, hContext, parentTCSKeyHandle,
576 keySize, keyBlob,
577 NULL,
578 phKeyTCSI, &keyslot))) {
579 LogDebugFn("LoadKeyByBlob_Internal returned 0x%x", result);
580 if (result == TCPA_E_AUTHFAIL && pLoadKeyInfo) {
581 BYTE blob[1000];
582
583 /* set up a load key info struct */
584 memcpy(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID));
585 memcpy(&pLoadKeyInfo->keyUUID, KeyUUID, sizeof(TSS_UUID));
586
587 /* calculate the paramDigest */
588 offset = 0;
589 LoadBlob_UINT32(&offset, ordinal, blob);
590 LoadBlob(&offset, keySize, blob, keyBlob);
591 if (Hash(TSS_HASH_SHA1, offset, blob,
592 (BYTE *)&pLoadKeyInfo->paramDigest.digest))
593 result = TCSERR(TSS_E_INTERNAL_ERROR);
594
595 result = TCSERR(TCS_E_KM_LOADFAILED);
596 }
597 }
598
599 return result;
600 }
601
602 TSS_RESULT
TCSP_GetRegisteredKeyByPublicInfo_Internal(TCS_CONTEXT_HANDLE tcsContext,TCPA_ALGORITHM_ID algID,UINT32 ulPublicInfoLength,BYTE * rgbPublicInfo,UINT32 * keySize,BYTE ** keyBlob)603 TCSP_GetRegisteredKeyByPublicInfo_Internal(TCS_CONTEXT_HANDLE tcsContext, /* in */
604 TCPA_ALGORITHM_ID algID, /* in */
605 UINT32 ulPublicInfoLength, /* in */
606 BYTE * rgbPublicInfo, /* in */
607 UINT32 * keySize, /* out */
608 BYTE ** keyBlob) /* out */
609 {
610 TCPA_STORE_PUBKEY pubKey;
611 TSS_RESULT result = TCSERR(TSS_E_FAIL);
612
613 pubKey.key = NULL;
614
615 if ((result = ctx_verify_context(tcsContext)))
616 return result;
617
618 if (algID == TCPA_ALG_RSA) {
619 /*--- Convert Public info to a structure */
620 pubKey.keyLength = ulPublicInfoLength;
621 pubKey.key = malloc(pubKey.keyLength);
622 if (pubKey.key == NULL) {
623 LogError("malloc of %d bytes failed.", pubKey.keyLength);
624 return TCSERR(TSS_E_OUTOFMEMORY);
625 }
626
627 memcpy(pubKey.key, rgbPublicInfo, pubKey.keyLength);
628
629 if ((result = ps_get_key_by_pub(&pubKey, keySize, keyBlob))) {
630 LogDebug("Public key data not found in PS");
631 free(pubKey.key);
632 return TCSERR(TSS_E_PS_KEY_NOTFOUND);
633 }
634 }
635 free(pubKey.key);
636
637 return result;
638 }
639