~ubuntu-branches/ubuntu/jaunty/trousers/jaunty

« back to all changes in this revision

Viewing changes to src/tcs/tcskcm.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-01-23 22:03:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123220300-fhtqja3c0oq0gp6z
Tags: 0.3.1-4
* Added patch from Aaron M. Ucko <ucko@debian.org> to allow trousers to
  build successfully on amd64, and presumably also other 64-bit
  architectures (Closes: #457400).
* Including udev rule for /dev/tpm from William Lima
  <wlima.amadeus@gmail.com> as suggested by David Smith <dds@google.com>
  (Closes: #459682).
* Added lintian overrides.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "spi_internal_types.h"
18
 
#include "tcs_internal_types.h"
19
 
#include "tcs_tsp.h"
20
 
#include "tcs_utils.h"
21
 
#include "tcs_int_literals.h"
22
 
#include "capabilities.h"
23
 
#include "tcslog.h"
24
 
#include "tcsps.h"
25
 
#include "req_mgr.h"
26
 
 
27
 
TSS_RESULT
28
 
TCS_RegisterKey_Internal(TCS_CONTEXT_HANDLE hContext,   /* in */
29
 
                         TSS_UUID *WrappingKeyUUID,     /* in */
30
 
                         TSS_UUID *KeyUUID,             /* in */
31
 
                         UINT32 cKeySize,               /* in */
32
 
                         BYTE * rgbKey,                 /* in */
33
 
                         UINT32 cVendorData,            /* in */
34
 
                         BYTE * gbVendorData            /* in */
35
 
    )
36
 
{
37
 
        TSS_RESULT result;
38
 
        TSS_BOOL is_reg;
39
 
 
40
 
        if ((result = ctx_verify_context(hContext)))
41
 
                return result;
42
 
 
43
 
        /* Check if key is already regisitered */
44
 
        if (isUUIDRegistered(KeyUUID, &is_reg) != TSS_SUCCESS) {
45
 
                LogError("Failed checking if UUID is registered.");
46
 
                return TCSERR(TSS_E_INTERNAL_ERROR);
47
 
        }
48
 
 
49
 
        if (is_reg == TRUE) {
50
 
                LogDebug("UUID is already registered");
51
 
                return TCSERR(TSS_E_KEY_ALREADY_REGISTERED);
52
 
        }
53
 
 
54
 
        LogDebugUnrollKey(rgbKey);
55
 
 
56
 
        /* Go ahead and store it in system persistant storage */
57
 
        if ((result = ps_write_key(KeyUUID, WrappingKeyUUID, gbVendorData,
58
 
                                   cVendorData, rgbKey, cKeySize))) {
59
 
                LogError("Error writing key to file");
60
 
                return result;
61
 
        }
62
 
 
63
 
        return TSS_SUCCESS;
64
 
}
65
 
 
66
 
TSS_RESULT
67
 
TCSP_UnregisterKey_Internal(TCS_CONTEXT_HANDLE hContext,        /* in */
68
 
                            TSS_UUID KeyUUID                    /* in */
69
 
    )
70
 
{
71
 
        TSS_RESULT result;
72
 
 
73
 
        if ((result = ctx_verify_context(hContext)))
74
 
                return result;
75
 
 
76
 
        return ps_remove_key(&KeyUUID);
77
 
}
78
 
 
79
 
TSS_RESULT
80
 
TCS_EnumRegisteredKeys_Internal(TCS_CONTEXT_HANDLE hContext,            /* in */
81
 
                                TSS_UUID * pKeyUUID,                    /* in */
82
 
                                UINT32 * pcKeyHierarchySize,            /* out */
83
 
                                TSS_KM_KEYINFO ** ppKeyHierarchy        /* out */
84
 
    )
85
 
{
86
 
        TSS_RESULT result = TSS_SUCCESS;
87
 
        UINT32 count = 0, i;
88
 
        TSS_KM_KEYINFO *ret = NULL;
89
 
        TSS_UUID tmp_uuid;
90
 
        struct key_disk_cache *disk_ptr, *tmp_ptrs[MAX_KEY_CHILDREN];
91
 
        struct key_mem_cache *mem_ptr;
92
 
        TSS_BOOL is_reg = FALSE;
93
 
 
94
 
        LogDebug("Enum Reg Keys");
95
 
 
96
 
        if (pcKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
97
 
                return TCSERR(TSS_E_BAD_PARAMETER);
98
 
 
99
 
        if ((result = ctx_verify_context(hContext)))
100
 
                return result;
101
 
 
102
 
        if (pKeyUUID != NULL) {
103
 
                /* First have to verify the key is registered */
104
 
                if ((result = isUUIDRegistered(pKeyUUID, &is_reg)))
105
 
                        return result;
106
 
 
107
 
                if (is_reg == FALSE) {
108
 
                        /* This return code is not listed as possible in the TSS 1.1 spec,
109
 
                         * but it makes more sense than just TCS_SUCCESS or TSS_E_FAIL */
110
 
                        return TCSERR(TSS_E_PS_KEY_NOTFOUND);
111
 
                }
112
 
        }
113
 
 
114
 
        /* this entire operation needs to be atomic wrt registered keys. We must
115
 
         * lock the mem cache as well to test if a given key is loaded. */
116
 
        pthread_mutex_lock(&disk_cache_lock);
117
 
        pthread_mutex_lock(&mem_cache_lock);
118
 
 
119
 
        /* return an array of all registered keys if pKeyUUID == NULL */
120
 
        if (pKeyUUID == NULL) {
121
 
                /*  determine the number of registered keys */
122
 
                for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
123
 
                        if (disk_ptr->flags & CACHE_FLAG_VALID)
124
 
                                count++;
125
 
                }
126
 
 
127
 
                /* malloc a structure for each of them */
128
 
                if (count != 0) {
129
 
                        ret = calloc(count, sizeof(TSS_KM_KEYINFO));
130
 
                        if (ret == NULL) {
131
 
                                LogError("malloc of %zd bytes failed.",
132
 
                                                (count * sizeof(TSS_KM_KEYINFO)));
133
 
                                count = 0;
134
 
                                result = TCSERR(TSS_E_OUTOFMEMORY);
135
 
                                goto done;
136
 
                        }
137
 
                } else {
138
 
                        goto done;
139
 
                }
140
 
 
141
 
                /* fill out the structure for each key */
142
 
                i = 0;
143
 
                for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
144
 
                        if (disk_ptr->flags & CACHE_FLAG_VALID) {
145
 
                                /* look for a mem cache entry to check if its loaded */
146
 
                                for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
147
 
                                        if (!memcmp(&mem_ptr->uuid, &disk_ptr->uuid, sizeof(TSS_UUID))) {
148
 
                                                if ((result = fill_key_info(disk_ptr, mem_ptr, &ret[i]))) {
149
 
                                                        free(ret);
150
 
                                                        ret = NULL;
151
 
                                                        count = 0;
152
 
                                                        goto done;
153
 
                                                }
154
 
                                                break;
155
 
                                        }
156
 
                                }
157
 
                                /* if there is no mem cache entry for this key, go ahead and call
158
 
                                 * fill_key_info(), it will pull everything from disk */
159
 
                                if (mem_ptr == NULL) {
160
 
                                        if ((result = fill_key_info(disk_ptr, NULL, &ret[i]))) {
161
 
                                                free(ret);
162
 
                                                ret = NULL;
163
 
                                                count = 0;
164
 
                                                goto done;
165
 
                                        }
166
 
                                }
167
 
                                i++;
168
 
                        }
169
 
                }
170
 
        } else {
171
 
                /* return a chain of a key and its parents up to the SRK */
172
 
                /*  determine the number of keys in the chain */
173
 
                memcpy(&tmp_uuid, pKeyUUID, sizeof(TSS_UUID));
174
 
                disk_ptr = key_disk_cache_head;
175
 
                while (disk_ptr != NULL && count < MAX_KEY_CHILDREN)
176
 
                {
177
 
                        if (disk_ptr->flags & CACHE_FLAG_VALID &&
178
 
                                !memcmp(&disk_ptr->uuid, &tmp_uuid, sizeof(TSS_UUID)))
179
 
                        {
180
 
                                /* increment count, then search for the parent */
181
 
                                count++;
182
 
                                /* save a pointer to this cache entry */
183
 
                                tmp_ptrs[count - 1] = disk_ptr;
184
 
                                /* if the parent of this key is NULL, we're at the root of the tree */
185
 
                                if (!memcmp(&disk_ptr->parent_uuid, &NULL_UUID, sizeof(TSS_UUID)))
186
 
                                        break;
187
 
                                /* overwrite tmp_uuid with the parent, which we will now search for */
188
 
                                memcpy(&tmp_uuid, &disk_ptr->parent_uuid, sizeof(TSS_UUID));
189
 
                                disk_ptr = key_disk_cache_head;
190
 
                                continue;
191
 
                        }
192
 
                        disk_ptr = disk_ptr->next;
193
 
                }
194
 
                /* when we reach this point, we have an array of TSS_UUID's that leads from the
195
 
                 * requested key up to the SRK*/
196
 
 
197
 
                /* malloc a structure for each of them */
198
 
                if (count != 0) {
199
 
                        ret = calloc(count, sizeof(TSS_KM_KEYINFO));
200
 
                        if (ret == NULL) {
201
 
                                LogError("malloc of %zd bytes failed.",
202
 
                                                (count * sizeof(TSS_KM_KEYINFO)));
203
 
                                count = 0;
204
 
                                result = TCSERR(TSS_E_OUTOFMEMORY);
205
 
                                goto done;
206
 
                        }
207
 
                } else {
208
 
                        goto done;
209
 
                }
210
 
 
211
 
                for (i = 0; i < count; i++) {
212
 
                        /* look for a mem cache entry to check if its loaded */
213
 
                        for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
214
 
                                if (!memcmp(&mem_ptr->uuid, &tmp_ptrs[i]->uuid, sizeof(TSS_UUID))) {
215
 
                                        if ((result = fill_key_info(tmp_ptrs[i], mem_ptr, &ret[i]))) {
216
 
                                                free(ret);
217
 
                                                ret = NULL;
218
 
                                                count = 0;
219
 
                                                goto done;
220
 
                                        }
221
 
                                        break;
222
 
                                }
223
 
                        }
224
 
                        /* if there is no mem cache entry for this key, go ahead and call
225
 
                         * fill_key_info(), it will pull everything from disk */
226
 
                        if (mem_ptr == NULL) {
227
 
                                if ((result = fill_key_info(tmp_ptrs[i], NULL, &ret[i]))) {
228
 
                                        free(ret);
229
 
                                        ret = NULL;
230
 
                                        count = 0;
231
 
                                        goto done;
232
 
                                }
233
 
                        }
234
 
                }
235
 
        }
236
 
done:
237
 
 
238
 
        pthread_mutex_unlock(&disk_cache_lock);
239
 
        pthread_mutex_unlock(&mem_cache_lock);
240
 
 
241
 
        *ppKeyHierarchy = ret;
242
 
        *pcKeyHierarchySize = count;
243
 
 
244
 
        return result;
245
 
}
246
 
 
247
 
TSS_RESULT
248
 
TCS_GetRegisteredKey_Internal(TCS_CONTEXT_HANDLE hContext,      /* in */
249
 
                              TSS_UUID *KeyUUID,                /* in */
250
 
                              TSS_KM_KEYINFO ** ppKeyInfo       /* out */
251
 
    )
252
 
{
253
 
        TSS_RESULT result;
254
 
        UINT64 offset;
255
 
        BYTE tcpaKeyBlob[1024];
256
 
        TCPA_KEY tcpaKey;
257
 
        UINT16 keySize = sizeof (tcpaKeyBlob);
258
 
        TSS_UUID parentUUID;
259
 
 
260
 
        /* This should be set in case we return before the malloc */
261
 
        *ppKeyInfo = NULL;
262
 
 
263
 
        if ((result = ctx_verify_context(hContext)))
264
 
                return result;
265
 
 
266
 
        if ((result = ps_get_key_by_uuid(KeyUUID, tcpaKeyBlob, &keySize))) {
267
 
                return TCSERR(TSS_E_PS_KEY_NOTFOUND);
268
 
        }
269
 
 
270
 
        if ((result = getParentUUIDByUUID(KeyUUID, &parentUUID)))
271
 
                return TCSERR(TSS_E_FAIL);
272
 
 
273
 
        *ppKeyInfo = malloc(sizeof(TSS_KM_KEYINFO));
274
 
        if (*ppKeyInfo == NULL) {
275
 
                LogError("malloc of %zd bytes failed.", sizeof(TSS_KM_KEYINFO));
276
 
                return TCSERR(TSS_E_OUTOFMEMORY);
277
 
        }
278
 
 
279
 
        offset = 0;
280
 
        UnloadBlob_KEY(&offset, tcpaKeyBlob, &tcpaKey);
281
 
 
282
 
        (*ppKeyInfo)->bAuthDataUsage = tcpaKey.authDataUsage;
283
 
 
284
 
        (*ppKeyInfo)->fIsLoaded = FALSE;
285
 
 
286
 
        (*ppKeyInfo)->versionInfo.bMajor = tcpaKey.ver.major;
287
 
        (*ppKeyInfo)->versionInfo.bMinor = tcpaKey.ver.minor;
288
 
        (*ppKeyInfo)->versionInfo.bRevMajor = tcpaKey.ver.revMajor;
289
 
        (*ppKeyInfo)->versionInfo.bRevMinor = tcpaKey.ver.revMinor;
290
 
 
291
 
        memcpy(&((*ppKeyInfo)->keyUUID), KeyUUID, sizeof(TSS_UUID));
292
 
 
293
 
        (*ppKeyInfo)->ulVendorDataLength = 0;
294
 
        (*ppKeyInfo)->rgbVendorData = 0;
295
 
 
296
 
        memcpy(&((*ppKeyInfo)->parentKeyUUID), &parentUUID, sizeof(TSS_UUID));
297
 
        return TSS_SUCCESS;
298
 
}
299
 
 
300
 
TSS_RESULT
301
 
TCS_GetRegisteredKeyBlob_Internal(TCS_CONTEXT_HANDLE hContext,  /* in */
302
 
                                  TSS_UUID *KeyUUID,            /* in */
303
 
                                  UINT32 * pcKeySize,           /* out */
304
 
                                  BYTE ** prgbKey               /* out */
305
 
    )
306
 
{
307
 
        UINT16 keySize;
308
 
        BYTE buffer[4096];
309
 
        TSS_RESULT result;
310
 
 
311
 
        if ((result = ctx_verify_context(hContext)))
312
 
                return result;
313
 
 
314
 
        keySize = sizeof(buffer);
315
 
        if ((result = ps_get_key_by_uuid(KeyUUID, buffer, &keySize)))
316
 
                return TCSERR(TSS_E_PS_KEY_NOTFOUND);
317
 
 
318
 
        *prgbKey = calloc(1, keySize);
319
 
        if (*prgbKey == NULL) {
320
 
                LogError("malloc of %d bytes failed.", keySize);
321
 
                return TCSERR(TSS_E_OUTOFMEMORY);
322
 
        } else {
323
 
                memcpy(*prgbKey, buffer, keySize);
324
 
        }
325
 
        *pcKeySize = keySize;
326
 
 
327
 
        return TSS_SUCCESS;
328
 
}
329
 
 
330
 
TSS_RESULT
331
 
TCSP_LoadKeyByBlob_Internal(TCS_CONTEXT_HANDLE hContext,        /* in */
332
 
                            TCS_KEY_HANDLE hUnwrappingKey,      /* in */
333
 
                            UINT32 cWrappedKeyBlobSize,         /* in */
334
 
                            BYTE * rgbWrappedKeyBlob,           /* in */
335
 
                            TPM_AUTH * pAuth,                   /* in, out */
336
 
                            TCS_KEY_HANDLE * phKeyTCSI,         /* out */
337
 
                            TCS_KEY_HANDLE * phKeyHMAC          /* out */
338
 
    )
339
 
{
340
 
        UINT64 offset;
341
 
        TSS_RESULT result;
342
 
        UINT32 paramSize;
343
 
        TCPA_KEY key;
344
 
        TCPA_KEY_HANDLE myKeySlot;
345
 
        TCS_KEY_HANDLE myTcsKeyHandle;
346
 
        TCPA_STORE_PUBKEY *parentPubKey = NULL;
347
 
        TCPA_KEY_HANDLE parentKeySlot;
348
 
        TSS_BOOL needToSendPacket = TRUE, canLoad;
349
 
        BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
350
 
 
351
 
        LogDebugFn("Enter");
352
 
        LogDebugUnrollKey(rgbWrappedKeyBlob);
353
 
 
354
 
        if ((result = ctx_verify_context(hContext)))
355
 
                return result;
356
 
 
357
 
        if (pAuth != NULL) {
358
 
                LogDebug("Auth Used");
359
 
                if ((result = auth_mgr_check(hContext, pAuth->AuthHandle)))
360
 
                        return result;
361
 
        } else {
362
 
                LogDebug("No Auth Used");
363
 
        }
364
 
 
365
 
        offset = 0;
366
 
        memset(&key, 0, sizeof(TCPA_KEY));
367
 
        if ((result = UnloadBlob_KEY(&offset, rgbWrappedKeyBlob, &key)))
368
 
                return result;
369
 
        cWrappedKeyBlobSize = offset;
370
 
 
371
 
        /******************************************
372
 
         *      The first thing to make sure is that the parent is loaded.
373
 
         *      If the parentKeySlot is invalid, then it either wasn't found in the cache
374
 
         *      or it was evicted.  Then checking if it was ever in the cache by calling
375
 
         *      getParentPubByPub will tell us whether or not there is an error.  If this
376
 
         *      unregistered parent was never loaded by the user, then he's hosed and
377
 
         *      this is an error.  If there is knowledge, then the shim is called to load
378
 
         *      the parent by it's public key.
379
 
         *********************************************/
380
 
 
381
 
        /* Check the mem cache to see if there is a TPM handle associated with the
382
 
         * parent's TCS handle */
383
 
        LogDebugFn("calling mc_get_slot_by_handle");
384
 
        if ((parentKeySlot = mc_get_slot_by_handle(hUnwrappingKey)) == NULL_TPM_HANDLE) {
385
 
                LogDebugFn("calling mc_get_pub_by_slot");
386
 
                parentPubKey = mc_get_pub_by_slot(hUnwrappingKey);
387
 
                if (parentPubKey == NULL) {
388
 
                        result = TCSERR(TCS_E_KM_LOADFAILED);
389
 
                        goto error;
390
 
                }
391
 
                LogDebugFn("calling LoadKeyShim");
392
 
                /* Otherwise, try to load it using the shim */
393
 
                if ((result = LoadKeyShim(hContext, parentPubKey, NULL, &parentKeySlot)))
394
 
                        goto error;
395
 
        }
396
 
        /*******************************************
397
 
         *Call LoadKeyShim
398
 
         *If it passes, we had prior knowledge of this key and we can avoid redundant copies of it
399
 
         *******************************************/
400
 
 
401
 
        /*---   If it's an authorized load, then assume that we brute-force load it every time */
402
 
        if (pAuth == NULL) {
403
 
                LogDebugFn("Checking if LoadKeyByBlob can be avoided by using"
404
 
                            " existing key");
405
 
 
406
 
                myTcsKeyHandle = mc_get_handle_by_pub(&key.pubKey, hUnwrappingKey);
407
 
                if (myTcsKeyHandle != NULL_TCS_HANDLE) {
408
 
                        LogDebugFn("tcs key handle exists");
409
 
 
410
 
                        myKeySlot = mc_get_slot_by_handle(myTcsKeyHandle);
411
 
                        if (myKeySlot != NULL_TPM_HANDLE && isKeyLoaded(myKeySlot) == TRUE) {
412
 
                                needToSendPacket = FALSE;
413
 
                                LogDebugFn("Don't need to reload this key.");
414
 
                                result = TSS_SUCCESS;
415
 
                                goto add_cache_entry;
416
 
                        }
417
 
                }
418
 
        }
419
 
 
420
 
        /******************************************
421
 
         *Now we just have to check if there is enough room in the chip.
422
 
         *********************************************/
423
 
 
424
 
        LogDebugFn("calling canILoadThisKey");
425
 
        if ((result = canILoadThisKey(&(key.algorithmParms), &canLoad)))
426
 
                goto error;
427
 
 
428
 
        if (canLoad == FALSE) {
429
 
                LogDebugFn("calling evictFirstKey");
430
 
                /* Evict a key that isn't the parent */
431
 
                if ((result = evictFirstKey(hUnwrappingKey)))
432
 
                        goto error;
433
 
        }
434
 
 
435
 
        LogDebugFn("Entering LoadKey by blob");
436
 
 
437
 
        /****************************************
438
 
         *      Now the parent is loaded and all of the info is ready.
439
 
         *      Send the loadkey command.  If the auth is a NULL Pointer
440
 
         *      then this represents a NoAuth load
441
 
         ********************************************/
442
 
 
443
 
        offset = 10;
444
 
        LoadBlob_UINT32(&offset, parentKeySlot, txBlob, "parentHandle");
445
 
        LoadBlob(&offset, cWrappedKeyBlobSize, txBlob, rgbWrappedKeyBlob, "wrapped blob");
446
 
        if (pAuth != NULL) {
447
 
                LoadBlob_Auth(&offset, txBlob, pAuth);
448
 
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_LoadKey, txBlob);
449
 
        } else
450
 
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_LoadKey, txBlob);
451
 
 
452
 
        LogDebugUnrollKey(rgbWrappedKeyBlob);
453
 
        LogDebugFn("Submitting request to the TPM");
454
 
        if ((result = req_mgr_submit_req(txBlob)))
455
 
                goto error;
456
 
 
457
 
        if (needToSendPacket == TRUE) {
458
 
                LogDebugFn("calling UnloadBlob_Header");
459
 
                if ((result = UnloadBlob_Header(txBlob, &paramSize))) {
460
 
                        LogDebugFn("UnloadBlob_Header failed: rc=0x%x", result);
461
 
                        goto error;
462
 
                }
463
 
 
464
 
                offset = 10;
465
 
                /*---   Finish unloading the stuff */
466
 
                UnloadBlob_UINT32(&offset, &myKeySlot, txBlob, "handle back");
467
 
                if (pAuth != NULL) {
468
 
                        UnloadBlob_Auth(&offset, txBlob, pAuth);
469
 
                }
470
 
        } else {
471
 
                LogDebugFn("Key slot is 0x%x", myKeySlot);
472
 
        }
473
 
 
474
 
        /***************************************
475
 
         *See if a TCSKeyHandle already exists.
476
 
         *      If it's 0, then it doesn't exist, and we need new knowledge of the key.
477
 
         *      If it exists, then just register the new keySlot with that existing handle
478
 
         *****************************************/
479
 
 
480
 
        LogDebugFn("calling mc_get_handle_by_pub");
481
 
add_cache_entry:
482
 
        if ((myTcsKeyHandle = mc_get_handle_by_pub(&key.pubKey, hUnwrappingKey))
483
 
             == NULL_TCS_HANDLE) {
484
 
                LogDebugFn("No existing key handle for this key, need to create a new one");
485
 
                /* Get a new TCS Key Handle */
486
 
                myTcsKeyHandle = getNextTcsKeyHandle();
487
 
                /* if it was an authorized load, then we can't make complete knowledge about it */
488
 
#if 0
489
 
                /* Add this info to the memory cache */
490
 
                if (pAuth == NULL) {
491
 
                        offset = 0;
492
 
                        destroy_key_refs(key);
493
 
                        if ((result = UnloadBlob_KEY(&offset, rgbWrappedKeyBlob, key)))
494
 
                                goto done;
495
 
                }
496
 
#endif
497
 
                LogDebugFn("calling mc_add_entry, TCS handle: 0x%x,"
498
 
                         " TPM handle 0x%x", myTcsKeyHandle, myKeySlot);
499
 
                if ((result = mc_add_entry(myTcsKeyHandle, myKeySlot, &key)))
500
 
                        goto error;
501
 
 
502
 
                LogDebugFn("ctx_mark_key_loaded");
503
 
                if (ctx_mark_key_loaded(hContext, myTcsKeyHandle)) {
504
 
                        LogError("Error marking key as loaded");
505
 
                        result = TCSERR(TSS_E_INTERNAL_ERROR);
506
 
                        goto error;
507
 
                }
508
 
 
509
 
                if ((result = mc_set_parent_by_handle(myTcsKeyHandle, hUnwrappingKey))) {
510
 
                        LogError("setParentBlobByHandle failed.");
511
 
                        goto error;
512
 
                }
513
 
        } else
514
 
                mc_set_slot_by_handle(myTcsKeyHandle, myKeySlot);
515
 
 
516
 
        result = TSS_SUCCESS;
517
 
 
518
 
        /* Setup the outHandles */
519
 
        *phKeyTCSI = myTcsKeyHandle;
520
 
        *phKeyHMAC = myKeySlot;
521
 
 
522
 
        LogDebugFn("Key handles for loadKeyByBlob slot:%.8X tcshandle:%.8X",
523
 
                 myKeySlot, myTcsKeyHandle);
524
 
error:
525
 
        destroy_key_refs(&key);
526
 
        auth_mgr_release_auth(pAuth, NULL, hContext);
527
 
        return result;
528
 
}
529
 
 
530
 
TSS_RESULT
531
 
TCSP_LoadKeyByUUID_Internal(TCS_CONTEXT_HANDLE hContext,        /* in */
532
 
                            TSS_UUID *KeyUUID,                  /* in */
533
 
                            TCS_LOADKEY_INFO * pLoadKeyInfo,    /* in, out */
534
 
                            TCS_KEY_HANDLE * phKeyTCSI          /* out */
535
 
    )
536
 
{
537
 
        UINT32 keyslot = 0, keySize;
538
 
        TSS_RESULT result;
539
 
        TSS_UUID parentUuid;
540
 
        BYTE keyBlob[0x1000];
541
 
        UINT16 blobSize = sizeof(keyBlob);
542
 
        UINT64 offset;
543
 
        TCS_KEY_HANDLE parentTCSKeyHandle;
544
 
 
545
 
        LogDebugFn("Enter: uuid: 0x%lx auth? 0x%x ***********", (unsigned long)KeyUUID,
546
 
                  pLoadKeyInfo == NULL ? 0xdeadbeef : pLoadKeyInfo->authData.AuthHandle);
547
 
 
548
 
        if ((result = ctx_verify_context(hContext)))
549
 
                return result;
550
 
 
551
 
        memset(&parentUuid, 0, sizeof(TSS_UUID));
552
 
 
553
 
        if (pLoadKeyInfo &&
554
 
            memcmp(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID))) {
555
 
                if (ps_get_key_by_uuid(&pLoadKeyInfo->keyUUID, keyBlob, &blobSize))
556
 
                        return TCSERR(TSS_E_PS_KEY_NOTFOUND);
557
 
 
558
 
                if (mc_get_handles_by_uuid(&pLoadKeyInfo->parentKeyUUID, &parentTCSKeyHandle,
559
 
                                           &keyslot))
560
 
                        return TCSERR(TCS_E_KM_LOADFAILED);
561
 
 
562
 
                return TCSP_LoadKeyByBlob_Internal(hContext, parentTCSKeyHandle,
563
 
                                                   blobSize, keyBlob,
564
 
                                                   &pLoadKeyInfo->authData,
565
 
                                                   phKeyTCSI, &keyslot);
566
 
        }
567
 
 
568
 
        /* if KeyUUID is already loaded, increment the ref count and return */
569
 
        if (mc_get_handles_by_uuid(KeyUUID, phKeyTCSI, &keyslot) == TSS_SUCCESS) {
570
 
                if (keyslot) {
571
 
                        if (ctx_mark_key_loaded(hContext, *phKeyTCSI)) {
572
 
                                LogError("Error marking key as loaded");
573
 
                                return TCSERR(TSS_E_INTERNAL_ERROR);
574
 
                        }
575
 
                        return TSS_SUCCESS;
576
 
                }
577
 
        }
578
 
        /*********************************************************************
579
 
         *      The first thing to do in this func is setup all the info and make sure
580
 
         *              that we get it all from either the keyfile or the keyCache
581
 
         *              also, it's important to return if the key is already loaded
582
 
         ***********************************************************************/
583
 
        LogDebugFn("calling ps_get_key_by_uuid");
584
 
        if (ps_get_key_by_uuid(KeyUUID, keyBlob, &blobSize))
585
 
                return TCSERR(TSS_E_PS_KEY_NOTFOUND);
586
 
        /* convert UINT16 to UIN32 */
587
 
        keySize = blobSize;
588
 
 
589
 
        LogDebugFn("calling getParentUUIDByUUID");
590
 
        /*---   Get my parent's UUID.  Since My key is registered, my parent should be as well. */
591
 
        if ((result = getParentUUIDByUUID(KeyUUID, &parentUuid)))
592
 
                return TCSERR(TCS_E_KM_LOADFAILED);
593
 
 
594
 
        if ((result = TCSP_LoadKeyByUUID_Internal(hContext, &parentUuid,
595
 
                                                  pLoadKeyInfo, &parentTCSKeyHandle)))
596
 
                return result;
597
 
 
598
 
        LogDebugFn("calling TCSP_LoadKeyByBlob_Internal");
599
 
        /*******************************************************
600
 
         * If no errors have happend up till now, then the parent is loaded and ready for use.
601
 
         * The parent's TCS Handle should be in parentTCSKeyHandle.
602
 
         ******************************************************/
603
 
        if ((result = TCSP_LoadKeyByBlob_Internal(hContext, parentTCSKeyHandle,
604
 
                                                  keySize, keyBlob,
605
 
                                                  NULL,
606
 
                                                  phKeyTCSI, &keyslot))) {
607
 
                LogDebugFn("TCSP_LoadKeyByBlob_Internal returned 0x%x", result);
608
 
                if (result == TCPA_E_AUTHFAIL && pLoadKeyInfo) {
609
 
                        BYTE blob[1000];
610
 
 
611
 
                        /* set up a load key info struct */
612
 
                        memcpy(&pLoadKeyInfo->parentKeyUUID, &parentUuid, sizeof(TSS_UUID));
613
 
                        memcpy(&pLoadKeyInfo->keyUUID, KeyUUID, sizeof(TSS_UUID));
614
 
 
615
 
                        /* calculate the paramDigest */
616
 
                        offset = 0;
617
 
                        LoadBlob_UINT32(&offset, TPM_ORD_LoadKey, blob, NULL);
618
 
                        LoadBlob(&offset, keySize, blob, keyBlob, NULL);
619
 
                        if (Hash(TSS_HASH_SHA1, offset, blob,
620
 
                                 (BYTE *)&pLoadKeyInfo->paramDigest.digest))
621
 
                                result = TCSERR(TSS_E_INTERNAL_ERROR);
622
 
 
623
 
                        result = TCSERR(TCS_E_KM_LOADFAILED);
624
 
                }
625
 
        }
626
 
 
627
 
        return result;
628
 
}
629
 
 
630
 
TSS_RESULT
631
 
TCSP_EvictKey_Internal(TCS_CONTEXT_HANDLE hContext,     /* in */
632
 
                       TCS_KEY_HANDLE hKey              /* in */
633
 
    )
634
 
{
635
 
        TSS_RESULT result;
636
 
        TCPA_KEY_HANDLE tpm_handle;
637
 
 
638
 
        if ((result = ctx_verify_context(hContext)))
639
 
                return result;
640
 
 
641
 
        tpm_handle = mc_get_slot_by_handle(hKey);
642
 
        if (tpm_handle == NULL_TPM_HANDLE)
643
 
                return TSS_SUCCESS;     /*let's call this success if the key is already evicted */
644
 
 
645
 
        if ((result = internal_EvictByKeySlot(tpm_handle)))
646
 
                return result;
647
 
 
648
 
        result = mc_set_slot_by_slot(tpm_handle, NULL_TPM_HANDLE);
649
 
 
650
 
        return result;
651
 
}
652
 
 
653
 
TSS_RESULT
654
 
TCSP_CreateWrapKey_Internal(TCS_CONTEXT_HANDLE hContext,        /* in */
655
 
                            TCS_KEY_HANDLE hWrappingKey,        /* in */
656
 
                            TCPA_ENCAUTH KeyUsageAuth,          /* in */
657
 
                            TCPA_ENCAUTH KeyMigrationAuth,      /* in */
658
 
                            UINT32 keyInfoSize,                 /* in */
659
 
                            BYTE * keyInfo,                     /* in */
660
 
                            UINT32 * keyDataSize,               /* out */
661
 
                            BYTE ** keyData,                    /* out */
662
 
                            TPM_AUTH * pAuth                    /* in, out */
663
 
    )
664
 
{
665
 
        UINT64 offset;
666
 
        UINT32 paramSize;
667
 
        TSS_RESULT result;
668
 
        TCPA_KEY keyContainer;
669
 
        TCPA_KEY_HANDLE parentSlot;
670
 
        BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
671
 
 
672
 
        LogDebug("Entering Create Wrap Key");
673
 
 
674
 
        if ((result = ctx_verify_context(hContext)))
675
 
                goto done;
676
 
 
677
 
        if ((result = auth_mgr_check(hContext, pAuth->AuthHandle)))
678
 
                goto done;
679
 
 
680
 
        /* Since hWrappingKey must already be loaded, we can fail immediately if
681
 
         * mc_get_slot_by_handle_lock() fails.*/
682
 
        parentSlot = mc_get_slot_by_handle_lock(hWrappingKey);
683
 
        if (parentSlot == NULL_TPM_HANDLE) {
684
 
                result = TCSERR(TSS_E_FAIL);
685
 
                goto done;
686
 
        }
687
 
 
688
 
        offset = 10;
689
 
        LoadBlob_UINT32(&offset, parentSlot, txBlob, "parent handle");
690
 
        LoadBlob(&offset, TCPA_ENCAUTH_SIZE, txBlob, KeyUsageAuth.authdata, "data usage encauth");
691
 
        LoadBlob(&offset, TCPA_ENCAUTH_SIZE, txBlob,
692
 
                        KeyMigrationAuth.authdata, "data mig encauth");
693
 
        LoadBlob(&offset, keyInfoSize, txBlob, keyInfo, "Key");
694
 
        LoadBlob_Auth(&offset, txBlob, pAuth);
695
 
        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset,
696
 
                        TPM_ORD_CreateWrapKey, txBlob);
697
 
        if ((result = req_mgr_submit_req(txBlob)))
698
 
                goto done;
699
 
 
700
 
        offset = 10;
701
 
        result = UnloadBlob_Header(txBlob, &paramSize);
702
 
 
703
 
        if (!result) {
704
 
                /* First get the data from the packet */
705
 
                if ((result = UnloadBlob_KEY(&offset, txBlob, &keyContainer)))
706
 
                        goto done;
707
 
 
708
 
                /* Here's how big it is */
709
 
                *keyDataSize = offset - 10;
710
 
                /* malloc the outBuffer */
711
 
                *keyData = calloc(1, *keyDataSize);
712
 
                if (*keyData == NULL) {
713
 
                        LogError("malloc of %d bytes failed.", *keyDataSize);
714
 
                        result = TCSERR(TSS_E_OUTOFMEMORY);
715
 
                } else {
716
 
                        /* Reset the offset and load it into the outbuf */
717
 
                        memcpy(*keyData, &txBlob[10], *keyDataSize);
718
 
                }
719
 
 
720
 
                UnloadBlob_Auth(&offset, txBlob, pAuth);
721
 
 
722
 
                destroy_key_refs(&keyContainer);
723
 
        }
724
 
        LogResult("Create Wrap Key", result);
725
 
 
726
 
done:
727
 
        auth_mgr_release_auth(pAuth, NULL, hContext);
728
 
        return result;
729
 
}
730
 
 
731
 
TSS_RESULT
732
 
TCSP_GetPubKey_Internal(TCS_CONTEXT_HANDLE hContext,    /* in */
733
 
                        TCS_KEY_HANDLE hKey,            /* in */
734
 
                        TPM_AUTH * pAuth,               /* in, out */
735
 
                        UINT32 * pcPubKeySize,          /* out */
736
 
                        BYTE ** prgbPubKey              /* out */
737
 
    )
738
 
{
739
 
        UINT64 offset;
740
 
        UINT32 paramSize;
741
 
        TSS_RESULT result;
742
 
        TCPA_PUBKEY pubContainer;
743
 
        TCPA_KEY_HANDLE keySlot;
744
 
        BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
745
 
 
746
 
        LogDebug("Entering Get pub key");
747
 
        if ((result = ctx_verify_context(hContext)))
748
 
                goto done;
749
 
 
750
 
        if (pAuth != NULL) {
751
 
                LogDebug("Auth Used");
752
 
                if ((result = auth_mgr_check(hContext, pAuth->AuthHandle)))
753
 
                        goto done;
754
 
        } else {
755
 
                LogDebug("No Auth");
756
 
        }
757
 
 
758
 
        if (ensureKeyIsLoaded(hContext, hKey, &keySlot)) {
759
 
                result = TCSERR(TCS_E_KM_LOADFAILED);
760
 
                goto done;
761
 
        }
762
 
 
763
 
        LogDebug("GetPubKey: handle: 0x%x, slot: 0x%x", hKey, keySlot);
764
 
        offset = 10;
765
 
        LoadBlob_UINT32(&offset, keySlot, txBlob, "key handle");
766
 
        if (pAuth != NULL) {
767
 
                LoadBlob_Auth(&offset, txBlob, pAuth);
768
 
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_GetPubKey, txBlob);
769
 
        } else {
770
 
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_GetPubKey, txBlob);
771
 
        }
772
 
 
773
 
        if ((result = req_mgr_submit_req(txBlob)))
774
 
                goto done;
775
 
 
776
 
        offset = 10;
777
 
        result = UnloadBlob_Header(txBlob, &paramSize);
778
 
 
779
 
        if (!result) {
780
 
                if ((result = UnloadBlob_PUBKEY(&offset, txBlob, &pubContainer)))
781
 
                        goto done;
782
 
                free(pubContainer.pubKey.key);
783
 
                free(pubContainer.algorithmParms.parms);
784
 
 
785
 
                *pcPubKeySize = offset - 10;
786
 
                *prgbPubKey = calloc(1, *pcPubKeySize);
787
 
                if (*prgbPubKey == NULL) {
788
 
                        LogError("malloc of %d bytes failed.", *pcPubKeySize);
789
 
                        result = TCSERR(TSS_E_OUTOFMEMORY);
790
 
                        goto done;
791
 
                }
792
 
                memcpy(*prgbPubKey, &txBlob[10], *pcPubKeySize);
793
 
 
794
 
                if (pAuth != NULL) {
795
 
                        UnloadBlob_Auth(&offset, txBlob, pAuth);
796
 
                }
797
 
        }
798
 
        LogResult("Get Public Key", result);
799
 
done:
800
 
        auth_mgr_release_auth(pAuth, NULL, hContext);
801
 
        return result;
802
 
}
803
 
 
804
 
TSS_RESULT
805
 
TCSP_MakeIdentity_Internal(TCS_CONTEXT_HANDLE hContext,                 /* in  */
806
 
                           TCPA_ENCAUTH identityAuth,                   /* in */
807
 
                           TCPA_CHOSENID_HASH IDLabel_PrivCAHash,       /* in */
808
 
                           UINT32 idKeyInfoSize,                        /* in */
809
 
                           BYTE * idKeyInfo,                            /* in */
810
 
                           TPM_AUTH * pSrkAuth,                         /* in, out */
811
 
                           TPM_AUTH * pOwnerAuth,                       /* in, out */
812
 
                           UINT32 * idKeySize,                          /* out */
813
 
                           BYTE ** idKey,                               /* out */
814
 
                           UINT32 * pcIdentityBindingSize,              /* out */
815
 
                           BYTE ** prgbIdentityBinding,                 /* out */
816
 
                           UINT32 * pcEndorsementCredentialSize,        /* out */
817
 
                           BYTE ** prgbEndorsementCredential,           /* out */
818
 
                           UINT32 * pcPlatformCredentialSize,           /* out */
819
 
                           BYTE ** prgbPlatformCredential,              /* out */
820
 
                           UINT32 * pcConformanceCredentialSize,        /* out */
821
 
                           BYTE ** prgbConformanceCredential            /* out */
822
 
    )
823
 
{
824
 
        UINT64 offset;
825
 
        UINT32 paramSize;
826
 
        TSS_RESULT result;
827
 
        TCPA_KEY idKeyContainer;
828
 
        BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
829
 
 
830
 
        if ((result = ctx_verify_context(hContext)))
831
 
                goto done;
832
 
 
833
 
        if (pSrkAuth != NULL) {
834
 
                LogDebug("SRK Auth Used");
835
 
                if ((result = auth_mgr_check(hContext, pSrkAuth->AuthHandle)))
836
 
                        goto done;
837
 
        } else {
838
 
                LogDebug("No SRK Auth");
839
 
        }
840
 
 
841
 
        if ((result = auth_mgr_check(hContext, pOwnerAuth->AuthHandle)))
842
 
                goto done;
843
 
 
844
 
        offset = 0;
845
 
 
846
 
        offset = 10;
847
 
        /*LoadBlob( &offset, idKeyInfoSize, txBlob, idKeyInfo, "idKeyInfo" );  */
848
 
        LoadBlob(&offset, TCPA_ENCAUTH_SIZE, txBlob, identityAuth.authdata, "encAuth");
849
 
        /*LoadBlob_UINT32( &offset, 20, txBlob, "label size"); */
850
 
        LoadBlob(&offset, 20, txBlob, IDLabel_PrivCAHash.digest, "label");
851
 
        LoadBlob(&offset, idKeyInfoSize, txBlob, idKeyInfo, "idKeyInfo");
852
 
        if (pSrkAuth != NULL) {
853
 
                LoadBlob_Auth(&offset, txBlob, pSrkAuth);
854
 
                LoadBlob_Auth(&offset, txBlob, pOwnerAuth);
855
 
                LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, offset, TPM_ORD_MakeIdentity, txBlob);
856
 
        } else {
857
 
                LoadBlob_Auth(&offset, txBlob, pOwnerAuth);
858
 
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, TPM_ORD_MakeIdentity, txBlob);
859
 
        }
860
 
 
861
 
        if ((result = req_mgr_submit_req(txBlob)))
862
 
                goto done;
863
 
 
864
 
        offset = 10;
865
 
        result = UnloadBlob_Header(txBlob, &paramSize);
866
 
 
867
 
        if (!result) {
868
 
                /* Call UnloadBlob_KEY to set the size of the key in &offset */
869
 
                if ((result = UnloadBlob_KEY(&offset, txBlob, &idKeyContainer)))
870
 
                        goto done;
871
 
 
872
 
                destroy_key_refs(&idKeyContainer);
873
 
                *idKeySize = offset - 10;
874
 
                *idKey = calloc(1, *idKeySize);
875
 
                if (*idKey == NULL) {
876
 
                        LogError("malloc of %d bytes failed.", *idKeySize);
877
 
                        result = TCSERR(TSS_E_OUTOFMEMORY);
878
 
                        goto done;
879
 
                }
880
 
                memcpy(*idKey, &txBlob[10], *idKeySize);
881
 
 
882
 
                UnloadBlob_UINT32(&offset, pcIdentityBindingSize, txBlob, NULL);
883
 
                *prgbIdentityBinding = calloc(1, *pcIdentityBindingSize);
884
 
                if (*prgbIdentityBinding == NULL) {
885
 
                        free(*idKey);
886
 
                        *idKeySize = 0;
887
 
                        LogError("malloc of %d bytes failed.", *pcIdentityBindingSize);
888
 
                        result = TCSERR(TSS_E_OUTOFMEMORY);
889
 
                        goto done;
890
 
                }
891
 
                UnloadBlob(&offset, *pcIdentityBindingSize, txBlob, *prgbIdentityBinding, NULL);
892
 
 
893
 
                /* If an error occurs, these will return NULL */
894
 
                get_credential(PLATFORM, pcPlatformCredentialSize, prgbPlatformCredential);
895
 
                get_credential(CONFORMANCE, pcConformanceCredentialSize, prgbConformanceCredential);
896
 
                get_credential(ENDORSEMENT, pcEndorsementCredentialSize, prgbEndorsementCredential);
897
 
 
898
 
                if (pSrkAuth != NULL)
899
 
                        UnloadBlob_Auth(&offset, txBlob, pSrkAuth);
900
 
                UnloadBlob_Auth(&offset, txBlob, pOwnerAuth);
901
 
        }
902
 
        LogResult("Make Identity", result);
903
 
done:
904
 
        auth_mgr_release_auth(pSrkAuth, pOwnerAuth, hContext);
905
 
        return result;
906
 
}
907
 
 
908
 
TSS_RESULT
909
 
TCSP_GetRegisteredKeyByPublicInfo_Internal(TCS_CONTEXT_HANDLE tcsContext,       /* in */
910
 
                                           TCPA_ALGORITHM_ID algID,             /* in */
911
 
                                           UINT32 ulPublicInfoLength,           /* in */
912
 
                                           BYTE * rgbPublicInfo,                /* in */
913
 
                                           UINT32 * keySize,                    /* out */
914
 
                                           BYTE ** keyBlob)                     /* out */
915
 
{
916
 
        TCPA_STORE_PUBKEY pubKey;
917
 
        TSS_RESULT result = TCSERR(TSS_E_FAIL);
918
 
 
919
 
        if ((result = ctx_verify_context(tcsContext)))
920
 
                return result;
921
 
 
922
 
        if (algID == TCPA_ALG_RSA) {
923
 
                /*---   Convert Public info to a structure */
924
 
                pubKey.keyLength = ulPublicInfoLength;
925
 
                pubKey.key = malloc(pubKey.keyLength);
926
 
                if (pubKey.key == NULL) {
927
 
                        LogError("malloc of %d bytes failed.", pubKey.keyLength);
928
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
929
 
                }
930
 
 
931
 
                memcpy(pubKey.key, rgbPublicInfo, pubKey.keyLength);
932
 
 
933
 
                if ((result = ps_get_key_by_pub(&pubKey, keySize, keyBlob))) {
934
 
                        LogDebug("Public key data not found in PS");
935
 
                        free(pubKey.key);
936
 
                        return TCSERR(TSS_E_PS_KEY_NOTFOUND);
937
 
                }
938
 
 
939
 
                free(pubKey.key);
940
 
        }
941
 
 
942
 
        return result;
943
 
}