~ubuntu-branches/ubuntu/hardy/trousers/hardy-proposed

« back to all changes in this revision

Viewing changes to src/tcs/tcs_utils.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:
4
4
 *
5
5
 * trousers - An open source TCG Software Stack
6
6
 *
7
 
 * (C) Copyright International Business Machines Corp. 2004-2006
 
7
 * (C) Copyright International Business Machines Corp. 2004-2007
8
8
 *
9
9
 */
10
10
 
18
18
#include <sys/mman.h>
19
19
#include <fcntl.h>
20
20
#include <errno.h>
21
 
#include <sys/types.h>
22
 
#include <sys/socket.h>
23
 
 
24
 
#include <openssl/evp.h>
25
21
 
26
22
#include "trousers/tss.h"
27
23
#include "trousers_types.h"
28
 
#include "spi_internal_types.h"
29
 
#include "tcs_internal_types.h"
 
24
#include "trousers_types.h"
30
25
#include "tcs_tsp.h"
31
26
#include "tcs_utils.h"
32
27
#include "tcs_int_literals.h"
33
28
#include "capabilities.h"
34
29
#include "tcsps.h"
35
30
#include "tcslog.h"
36
 
#include "tddl.h"
37
 
#include "req_mgr.h"
38
 
#include "tcsd_wrap.h"
39
 
#include "tcsd.h"
40
 
 
41
 
struct key_mem_cache *key_mem_cache_head = NULL;
42
 
TSS_UUID NULL_UUID = { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0 } };
43
 
 
44
 
TSS_BOOL firstVendorCheck = 1;
45
 
 
46
 
TSS_RESULT
47
 
fill_key_info(struct key_disk_cache *d,
48
 
                struct key_mem_cache *m,
49
 
                TSS_KM_KEYINFO *key_info)
50
 
{
51
 
        BYTE tmp_blob[2048];
52
 
        UINT16 tmp_blob_size = 2048;
53
 
        TCPA_KEY tmp_key;
54
 
        UINT64 offset;
55
 
        TSS_RESULT result;
56
 
 
57
 
        if (m == NULL) {
58
 
                key_info->fIsLoaded = FALSE;
59
 
 
60
 
                /* read key from disk */
61
 
                if ((result = ps_get_key_by_cache_entry(d, (BYTE *)&tmp_blob, &tmp_blob_size)))
62
 
                        return result;
63
 
 
64
 
                offset = 0;
65
 
                /* XXX add a real context handle here */
66
 
                if ((result = UnloadBlob_KEY(&offset, tmp_blob, &tmp_key)))
67
 
                        return result;
68
 
 
69
 
                memcpy(&key_info->versionInfo, &tmp_key.ver, sizeof(TSS_VERSION));
70
 
                memcpy(&key_info->bAuthDataUsage, &tmp_key.authDataUsage, sizeof(TCPA_AUTH_DATA_USAGE));
71
 
                destroy_key_refs(&tmp_key);
72
 
        } else {
73
 
                if (m->tpm_handle == NULL_TPM_HANDLE)
74
 
                        key_info->fIsLoaded = FALSE;
75
 
                else
76
 
                        key_info->fIsLoaded = TRUE;
77
 
 
78
 
                memcpy(&key_info->versionInfo, &m->blob->ver, sizeof(TSS_VERSION));
79
 
                memcpy(&key_info->bAuthDataUsage, &m->blob->authDataUsage, sizeof(TCPA_AUTH_DATA_USAGE));
80
 
        }
81
 
 
82
 
        memcpy(&key_info->keyUUID, &d->uuid, sizeof(TSS_UUID));
83
 
        memcpy(&key_info->parentKeyUUID, &d->parent_uuid, sizeof(TSS_UUID));
84
 
 
85
 
        /* XXX consider filling in something useful here */
86
 
        key_info->ulVendorDataLength = 0;
87
 
        key_info->rgbVendorData = NULL;
88
 
 
89
 
        return TSS_SUCCESS;
90
 
}
91
 
 
92
 
TSS_RESULT
93
 
get_current_version(TCPA_VERSION *version)
94
 
{
95
 
        TCPA_CAPABILITY_AREA capArea = TPM_CAP_VERSION_VAL;
96
 
        UINT32 respSize;
97
 
        BYTE *resp;
98
 
        TSS_RESULT result;
99
 
        UINT64 offset;
100
 
 
101
 
        /* try the 1.2 way first */
102
 
        result = TCSP_GetCapability_Internal(InternalContext,
103
 
                        capArea,
104
 
                        0,
105
 
                        NULL,
106
 
                        &respSize,
107
 
                        &resp);
108
 
        if (result == TSS_SUCCESS) {
109
 
                offset = sizeof(UINT16); // XXX hack
110
 
                UnloadBlob_VERSION(&offset, resp, version);
111
 
                free(resp);
112
 
        } else if (result == TCPA_E_BAD_MODE) {
113
 
                /* if the TPM doesn't understand VERSION_VAL, try the 1.1 way */
114
 
                capArea = TCPA_CAP_VERSION;
115
 
                result = TCSP_GetCapability_Internal(InternalContext,
116
 
                                capArea,
117
 
                                0,
118
 
                                NULL,
119
 
                                &respSize,
120
 
                                &resp);
121
 
                if (result == TSS_SUCCESS) {
122
 
                        offset = 0;
123
 
                        UnloadBlob_VERSION(&offset, resp, version);
124
 
                        free(resp);
125
 
                }
126
 
        }
127
 
 
128
 
        return result;
129
 
}
130
 
 
131
 
TSS_RESULT
132
 
get_cap_uint32(TCPA_CAPABILITY_AREA capArea, BYTE *subCap, UINT32 subCapSize, UINT32 *v)
133
 
{
134
 
        UINT32 respSize;
135
 
        BYTE *resp;
136
 
        TSS_RESULT result;
137
 
        UINT64 offset;
138
 
 
139
 
        result = TCSP_GetCapability_Internal(InternalContext,
140
 
                        capArea,
141
 
                        subCapSize,
142
 
                        subCap,
143
 
                        &respSize,
144
 
                        &resp);
145
 
        if (!result) {
146
 
                offset = 0;
147
 
                switch (respSize) {
148
 
                        case 1:
149
 
                                UnloadBlob_BYTE(&offset, (BYTE *)v, resp, NULL);
150
 
                                break;
151
 
                        case sizeof(UINT16):
152
 
                                UnloadBlob_UINT16(&offset, (UINT16 *)v, resp, NULL);
153
 
                                break;
154
 
                        case sizeof(UINT32):
155
 
                                UnloadBlob_UINT32(&offset, v, resp, NULL);
156
 
                                break;
157
 
                        default:
158
 
                                LogDebug("TCSP_GetCapability_Internal returned"
159
 
                                          " %u bytes", respSize);
160
 
                                result = TCSERR(TSS_E_FAIL);
161
 
                                break;
162
 
                }
163
 
                free(resp);
164
 
        }
165
 
 
166
 
        return result;
167
 
}
168
 
 
169
 
 
170
 
TSS_RESULT
171
 
get_max_auths(UINT32 *auths)
172
 
{
173
 
        TCS_AUTHHANDLE handles[TSS_MAX_AUTHS_CAP];
174
 
        TCPA_NONCE nonce;
175
 
        UINT32 subCap;
176
 
        TSS_RESULT result;
177
 
        int i;
178
 
 
179
 
        if (TPM_VERSION(1,2)) {
180
 
                UINT32ToArray(TPM_CAP_PROP_MAX_AUTHSESS, (BYTE *)(&subCap));
181
 
                result = get_cap_uint32(TPM_CAP_PROPERTY, (BYTE *)&subCap,
182
 
                                        sizeof(subCap), auths);
183
 
        } else if (TPM_VERSION(1,1)) {
184
 
                /* open auth sessions until we get a failure */
185
 
                for (i = 0; i < TSS_MAX_AUTHS_CAP; i++) {
186
 
                        result = TCSP_OIAP_Internal(InternalContext,
187
 
                                                    &(handles[i]), &nonce);
188
 
                        if (result != TSS_SUCCESS) {
189
 
                                /* this is not off by one since we're 0 indexed */
190
 
                                *auths = i;
191
 
                                break;
192
 
                        }
193
 
                }
194
 
 
195
 
                if (i == TSS_MAX_AUTHS_CAP)
196
 
                        *auths = TSS_MAX_AUTHS_CAP;
197
 
 
198
 
                /* close the auth sessions */
199
 
                for (i = 0; (UINT32)i < *auths; i++) {
200
 
                        internal_TerminateHandle(handles[i]);
201
 
                }
202
 
        } else {
203
 
                result = TCSERR(TSS_E_INTERNAL_ERROR);
204
 
                *auths = 0;
205
 
        }
206
 
 
207
 
        if (*auths < 2) {
208
 
                LogError("%s reported only %u auth available!", __FUNCTION__, *auths);
209
 
                LogError("Your TPM must be reset before the TCSD can be started.");
210
 
        } else {
211
 
                LogDebug("get_max_auths reports %u auth contexts found", *auths);
212
 
                result = TSS_SUCCESS;
213
 
        }
214
 
 
215
 
        return result;
216
 
}
217
 
 
218
 
/* This is only called from init paths, so printing an error message is
219
 
 * appropriate if something goes wrong */
220
 
TSS_RESULT
221
 
get_tpm_metrics(struct tpm_properties *p)
222
 
{
223
 
        TSS_RESULT result;
224
 
        UINT32 subCap, rv = 0;
225
 
 
226
 
        if ((result = get_current_version(&p->version)))
227
 
                goto err;
228
 
 
229
 
        UINT32ToArray(TPM_ORD_SaveKeyContext, (BYTE *)&subCap);
230
 
        if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv)))
231
 
                goto err;
232
 
        p->keyctx_swap = rv ? TRUE : FALSE;
233
 
 
234
 
        rv = 0;
235
 
        UINT32ToArray(TPM_ORD_SaveAuthContext, (BYTE *)&subCap);
236
 
        if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv)))
237
 
                goto err;
238
 
        p->authctx_swap = rv ? TRUE : FALSE;
239
 
 
240
 
        UINT32ToArray(TPM_CAP_PROP_PCR, (BYTE *)&subCap);
241
 
        if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
242
 
                                        &p->num_pcrs)))
243
 
                goto err;
244
 
 
245
 
        UINT32ToArray(TPM_CAP_PROP_DIR, (BYTE *)&subCap);
246
 
        if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
247
 
                                        &p->num_dirs)))
248
 
                goto err;
249
 
 
250
 
        UINT32ToArray(TPM_CAP_PROP_SLOTS, (BYTE *)&subCap);
251
 
        if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
252
 
                                        &p->num_keys)))
253
 
                goto err;
254
 
 
255
 
        UINT32ToArray(TPM_CAP_PROP_MANUFACTURER, (BYTE *)&subCap);
256
 
        if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
257
 
                                        (UINT32 *)&p->manufacturer)))
258
 
                goto err;
259
 
 
260
 
        result = get_max_auths(&(p->num_auths));
261
 
 
262
 
err:
263
 
        if (result)
264
 
                LogError("TCS GetCapability failed with result = 0x%x", result);
265
 
 
266
 
        return result;
267
 
}
 
31
 
 
32
 
 
33
TCS_CONTEXT_HANDLE InternalContext = 0x30000000;
 
34
TSS_UUID SRK_UUID = TSS_UUID_SRK;
 
35
 
268
36
 
269
37
void
270
38
LogData(char *string, UINT32 data)
284
52
#endif
285
53
}
286
54
 
287
 
TSS_RESULT
288
 
canILoadThisKey(TCPA_KEY_PARMS *parms, TSS_BOOL *b)
289
 
{
290
 
        UINT64 offset;
291
 
        UINT16 subCapLength;
292
 
        BYTE subCap[100];
293
 
        TCPA_RESULT result;
294
 
        UINT32 respDataLength;
295
 
        BYTE *respData;
296
 
 
297
 
        offset = 0;
298
 
        LoadBlob_KEY_PARMS(&offset, subCap, parms);
299
 
        subCapLength = offset;
300
 
 
301
 
        if ((result = TCSP_GetCapability_Internal(InternalContext,      /* in */
302
 
                                            TCPA_CAP_CHECK_LOADED,      /* in */
303
 
                                            subCapLength,       /* in */
304
 
                                            subCap,     /* in */
305
 
                                            &respDataLength,    /* out */
306
 
                                            &respData))) {      /* out */
307
 
                *b = FALSE;
308
 
                LogDebugFn("NO");
309
 
                return result;
310
 
        }
311
 
 
312
 
        *b = respData[0];
313
 
        free(respData);
314
 
        LogDebugFn("%s", *b ? "YES" : "NO");
315
 
 
316
 
        return TSS_SUCCESS;
317
 
}
318
 
 
319
 
TCPA_RESULT
320
 
internal_EvictByKeySlot(TCPA_KEY_HANDLE slot)
321
 
{
322
 
        TCPA_RESULT result;
323
 
        UINT32 paramSize;
324
 
        UINT64 offset;
325
 
        BYTE txBlob[TSS_TPM_TXBLOB_SIZE];
326
 
 
327
 
        LogDebug("Entering Evict Key");
328
 
 
329
 
        offset = 10;
330
 
        LoadBlob_UINT32(&offset, slot, txBlob, "key handle");
331
 
        LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, TPM_ORD_EvictKey, txBlob);
332
 
 
333
 
        if ((result = req_mgr_submit_req(txBlob)))
334
 
                return result;
335
 
 
336
 
        result = UnloadBlob_Header(txBlob, &paramSize);
337
 
 
338
 
        LogResult("Evict Key", result);
339
 
        return result;
340
 
}
341
 
 
342
 
TSS_RESULT
343
 
clearUnknownKeys(TCS_CONTEXT_HANDLE hContext, UINT32 *cleared)
344
 
{
345
 
        TSS_RESULT result = TSS_SUCCESS;
346
 
        TCPA_KEY_HANDLE_LIST keyList = { 0, NULL };
347
 
        int i;
348
 
        BYTE *respData = NULL;
349
 
        UINT32 respDataSize = 0, count = 0;
350
 
        TCPA_CAPABILITY_AREA capArea = -1;
351
 
        UINT64 offset = 0;
352
 
        TSS_BOOL found = FALSE;
353
 
        struct key_mem_cache *tmp;
354
 
 
355
 
        capArea = TCPA_CAP_KEY_HANDLE;
356
 
 
357
 
        if ((result = TCSP_GetCapability_Internal(hContext, capArea, 0, NULL,
358
 
                                                &respDataSize, &respData)))
359
 
                return result;
360
 
 
361
 
        if ((result = UnloadBlob_KEY_HANDLE_LIST(&offset, respData, &keyList)))
362
 
                goto done;
363
 
 
364
 
#ifdef TSS_DEBUG
365
 
        LogDebug("Loaded TPM key handles:");
366
 
        for (i = 0; i < keyList.loaded; i++) {
367
 
                LogDebugFn("%d: %x", i, keyList.handle[i]);
368
 
        }
369
 
 
370
 
        LogDebug("Loaded TCSD key handles:");
371
 
        i=0;
372
 
        for (tmp = key_mem_cache_head; tmp; tmp = tmp->next) {
373
 
                LogDebugFn("%d: 0x%x -> 0x%x", i++, tmp->tpm_handle,
374
 
                            tmp->tcs_handle);
375
 
        }
376
 
#endif
377
 
 
378
 
        for (i = 0; i < keyList.loaded; i++) {
379
 
                /* as long as we're only called from evictFirstKey(), we don't
380
 
                 * need to lock here */
381
 
                for (tmp = key_mem_cache_head; tmp; tmp = tmp->next) {
382
 
                        if (tmp->tpm_handle == keyList.handle[i]) {
383
 
                                found = TRUE;
384
 
                                break;
385
 
                        }
386
 
                }
387
 
                if (found)
388
 
                        found = FALSE;
389
 
                else {
390
 
                        if ((result = internal_EvictByKeySlot(keyList.handle[i])))
391
 
                                goto done;
392
 
                        else
393
 
                                count++;
394
 
                }
395
 
        }
396
 
 
397
 
        *cleared = count;
398
 
done:
399
 
        free(keyList.handle);
400
 
        free(respData);
401
 
 
402
 
        return TSS_SUCCESS;
403
 
}
404
 
 
405
 
#if 0
406
 
TCPA_RESULT
407
 
clearKeysFromChip(TCS_CONTEXT_HANDLE hContext)
408
 
{
409
 
        TCPA_RESULT result;
410
 
        TCPA_KEY_HANDLE_LIST keyList;
411
 
        UINT32 i;
412
 
        BYTE *respData = 0;
413
 
        UINT32 respDataSize = 0;
414
 
        TCPA_CAPABILITY_AREA capArea = -1;
415
 
        UINT16 offset = 0;
416
 
 
417
 
        capArea = TCPA_CAP_KEY_HANDLE;
418
 
 
419
 
        if ((result = TCSP_GetCapability_Internal(hContext, capArea, 0, NULL,
420
 
                                        &respDataSize, &respData)))
421
 
                return result;
422
 
 
423
 
        if ((result = UnloadBlob_KEY_HANDLE_LIST(&offset, respData, &keyList)))
424
 
                return result;
425
 
        for (i = 0; i < keyList.loaded; i++) {
426
 
                if (keyList.handle[i] == SRK_TPM_HANDLE ||      /*can't evict SRK */
427
 
                    keyList.handle[i] == EK_TPM_HANDLE) /*can't evict EK */
428
 
                        continue;
429
 
                if ((result = internal_EvictByKeySlot(keyList.handle[i])))
430
 
                        return result;
431
 
        }
432
 
        return TSS_SUCCESS;
433
 
}
434
 
#endif
435
 
 
436
55
UINT16
437
56
Decode_UINT16(BYTE * in)
438
57
{
443
62
}
444
63
 
445
64
void
 
65
UINT64ToArray(UINT64 i, BYTE * out)
 
66
{
 
67
        out[0] = (BYTE) ((i >> 56) & 0xFF);
 
68
        out[1] = (BYTE) ((i >> 48) & 0xFF);
 
69
        out[2] = (BYTE) ((i >> 40) & 0xFF);
 
70
        out[3] = (BYTE) ((i >> 32) & 0xFF);
 
71
        out[4] = (BYTE) ((i >> 24) & 0xFF);
 
72
        out[5] = (BYTE) ((i >> 16) & 0xFF);
 
73
        out[6] = (BYTE) ((i >> 8) & 0xFF);
 
74
        out[7] = (BYTE) (i & 0xFF);
 
75
}
 
76
 
 
77
void
446
78
UINT32ToArray(UINT32 i, BYTE * out)
447
79
{
448
80
        out[0] = (BYTE) ((i >> 24) & 0xFF);
471
103
        return x;
472
104
}
473
105
 
474
 
void
475
 
LoadBlob_UINT32(UINT64 * offset, UINT32 in, BYTE * blob, char *log)
 
106
UINT64
 
107
Decode_UINT64(BYTE *y)
 
108
{
 
109
        UINT64 x = 0;
 
110
 
 
111
        x = y[0];
 
112
        x = ((x << 8) | (y[1] & 0xFF));
 
113
        x = ((x << 8) | (y[2] & 0xFF));
 
114
        x = ((x << 8) | (y[3] & 0xFF));
 
115
        x = ((x << 8) | (y[4] & 0xFF));
 
116
        x = ((x << 8) | (y[5] & 0xFF));
 
117
        x = ((x << 8) | (y[6] & 0xFF));
 
118
        x = ((x << 8) | (y[7] & 0xFF));
 
119
 
 
120
        return x;
 
121
}
 
122
 
 
123
void
 
124
LoadBlob_UINT64(UINT64 *offset, UINT64 in, BYTE * blob)
 
125
{
 
126
        if (blob)
 
127
                UINT64ToArray(in, &blob[*offset]);
 
128
        *offset += sizeof(UINT64);
 
129
}
 
130
 
 
131
void
 
132
LoadBlob_UINT32(UINT64 *offset, UINT32 in, BYTE * blob)
476
133
{
477
134
        if (blob)
478
135
                UINT32ToArray(in, &blob[*offset]);
479
 
        *offset += 4;
480
 
#if 0
481
 
        if (log)
482
 
                LogData(log, in);
483
 
#endif
 
136
        *offset += sizeof(UINT32);
484
137
}
485
138
 
486
139
void
487
 
LoadBlob_UINT16(UINT64 * offset, UINT16 in, BYTE * blob, char *log)
 
140
LoadBlob_UINT16(UINT64 *offset, UINT16 in, BYTE * blob)
488
141
{
489
142
        if (blob)
490
143
                UINT16ToArray(in, &blob[*offset]);
491
 
        *offset += 2;
492
 
#if 0
493
 
        if (log)
494
 
                LogData(log, in);
495
 
#endif
496
 
}
497
 
 
498
 
void
499
 
UnloadBlob_UINT32(UINT64 * offset, UINT32 * out, BYTE * blob, char *log)
500
 
{
501
 
        *out = Decode_UINT32(&blob[*offset]);
502
 
        *offset += 4;
503
 
#if 0
504
 
        if (log)
505
 
                LogData(log, *out);
506
 
#endif
507
 
}
508
 
 
509
 
void
510
 
UnloadBlob_UINT16(UINT64 * offset, UINT16 * out, BYTE * blob, char *log)
511
 
{
512
 
        *out = Decode_UINT16(&blob[*offset]);
513
 
        *offset += 2;
514
 
#if 0
515
 
        if (log)
516
 
                LogData(log, *out);
517
 
#endif
518
 
}
519
 
 
520
 
void
521
 
LoadBlob_BYTE(UINT64 * offset, BYTE data, BYTE * blob, char *log)
522
 
{
523
 
        if (blob)
524
 
                blob[*offset] = data;
525
 
        (*offset)++;
526
 
#if 0
527
 
        if (log)
528
 
                LogDebug("%s: %c", log, data);
529
 
#endif
530
 
}
531
 
 
532
 
void
533
 
UnloadBlob_BYTE(UINT64 * offset, BYTE * dataOut, BYTE * blob, char *log)
534
 
{
535
 
        *dataOut = blob[*offset];
536
 
        (*offset)++;
537
 
#if 0
538
 
        if (log)
539
 
                LogDebug("%s: %c", log, *dataOut);
540
 
#endif
541
 
}
542
 
 
543
 
void
544
 
LoadBlob_BOOL(UINT64 * offset, TSS_BOOL data, BYTE * blob, char *log)
545
 
{
546
 
        if (blob)
547
 
                blob[*offset] = data;
548
 
        (*offset)++;
549
 
#if 0
550
 
        if (log)
551
 
                LogDebug("%s: %c", log, data);
552
 
#endif
553
 
}
554
 
 
555
 
void
556
 
UnloadBlob_BOOL(UINT64 * offset, TSS_BOOL *dataOut, BYTE * blob, char *log)
557
 
{
558
 
        *dataOut = blob[*offset];
559
 
        (*offset)++;
560
 
#if 0
561
 
        if (log)
562
 
                LogDebug("%s: %c", log, *dataOut);
563
 
#endif
564
 
}
565
 
 
566
 
void
567
 
LoadBlob(UINT64 * offset, UINT32 size, BYTE * container, BYTE * object,
568
 
         char *log)
569
 
{
 
144
        *offset += sizeof(UINT16);
 
145
}
 
146
 
 
147
void
 
148
UnloadBlob_UINT64(UINT64 *offset, UINT64 * out, BYTE * blob)
 
149
{
 
150
        if (out)
 
151
                *out = Decode_UINT64(&blob[*offset]);
 
152
        *offset += sizeof(UINT64);
 
153
}
 
154
 
 
155
void
 
156
UnloadBlob_UINT32(UINT64 *offset, UINT32 * out, BYTE * blob)
 
157
{
 
158
        if (out)
 
159
                *out = Decode_UINT32(&blob[*offset]);
 
160
        *offset += sizeof(UINT32);
 
161
}
 
162
 
 
163
void
 
164
UnloadBlob_UINT16(UINT64 *offset, UINT16 * out, BYTE * blob)
 
165
{
 
166
        if (out)
 
167
                *out = Decode_UINT16(&blob[*offset]);
 
168
        *offset += sizeof(UINT16);
 
169
}
 
170
 
 
171
void
 
172
LoadBlob_BYTE(UINT64 *offset, BYTE data, BYTE * blob)
 
173
{
 
174
        if (blob)
 
175
                blob[*offset] = data;
 
176
        (*offset)++;
 
177
}
 
178
 
 
179
void
 
180
UnloadBlob_BYTE(UINT64 *offset, BYTE * dataOut, BYTE * blob)
 
181
{
 
182
        if (dataOut)
 
183
                *dataOut = blob[*offset];
 
184
        (*offset)++;
 
185
}
 
186
 
 
187
void
 
188
LoadBlob_BOOL(UINT64 *offset, TSS_BOOL data, BYTE * blob)
 
189
{
 
190
        if (blob)
 
191
                blob[*offset] = data;
 
192
        (*offset)++;
 
193
}
 
194
 
 
195
void
 
196
UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE * blob)
 
197
{
 
198
        if (dataOut)
 
199
                *dataOut = blob[*offset];
 
200
        (*offset)++;
 
201
}
 
202
 
 
203
void
 
204
LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
 
205
{
 
206
        if (size == 0)
 
207
                return;
 
208
 
570
209
        if (container)
571
210
                memcpy(&container[*offset], object, size);
572
211
        (*offset) += (UINT64) size;
573
212
}
574
213
 
575
214
void
576
 
UnloadBlob(UINT64 * offset, UINT32 size, BYTE * container, BYTE * object,
577
 
           char *log)
 
215
UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
578
216
{
579
 
        memcpy(object, &container[*offset], size);
 
217
        if (size == 0)
 
218
                return;
 
219
 
 
220
        if (object)
 
221
                memcpy(object, &container[*offset], size);
580
222
        (*offset) += (UINT64) size;
581
 
#if 0
582
 
        /* commenting out for now, logs getting too chatty */
583
 
        if (log && size) {
584
 
                LogDebug(log);
585
 
                /* XXX Crashes sometimes. Investigate. */
586
 
                //LogBlob(size, object);
587
 
        }
588
 
#endif
589
223
}
590
224
 
591
225
void
592
 
LoadBlob_Header(UINT16 tag, UINT32 paramSize, UINT32 ordinal,
593
 
                BYTE * blob)
 
226
LoadBlob_Header(UINT16 tag, UINT32 paramSize, UINT32 ordinal, BYTE * blob)
594
227
{
595
228
 
596
229
        UINT16ToArray(tag, &blob[0]);
604
237
#endif
605
238
}
606
239
 
607
 
TCPA_RESULT
 
240
TSS_RESULT
608
241
UnloadBlob_Header(BYTE * blob, UINT32 * size)
609
242
{
610
243
        UINT16 temp = Decode_UINT16(blob);
616
249
}
617
250
 
618
251
void
619
 
LoadBlob_MIGRATIONKEYAUTH(UINT64 * offset, BYTE * blob,
620
 
                          TCPA_MIGRATIONKEYAUTH * mkAuth)
621
 
{
622
 
        LoadBlob_PUBKEY(offset, blob, &mkAuth->migrationKey);
623
 
        LoadBlob_UINT16(offset, mkAuth->migrationScheme, blob,
624
 
                        "mkauth migScheme");
625
 
        LoadBlob(offset, 20, blob, mkAuth->digest.digest, "mkauth digest");
626
 
}
627
 
 
628
 
TSS_RESULT
629
 
UnloadBlob_MIGRATIONKEYAUTH(UINT64 * offset,
630
 
                            BYTE * blob, TCPA_MIGRATIONKEYAUTH * mkAuth)
631
 
{
632
 
        TSS_RESULT result;
633
 
 
634
 
        if ((result = UnloadBlob_PUBKEY(offset, blob, &mkAuth->migrationKey)))
635
 
                return result;
636
 
 
637
 
        UnloadBlob_UINT16(offset, &mkAuth->migrationScheme, blob,
638
 
                          "mkauth migScheme");
639
 
        UnloadBlob(offset, 20, blob, mkAuth->digest.digest, "mkauth digest");
640
 
 
641
 
        return result;
642
 
}
643
 
 
644
 
void
645
 
LoadBlob_Auth(UINT64 * offset, BYTE * blob, TPM_AUTH * auth)
646
 
{
647
 
        LoadBlob_UINT32(offset, auth->AuthHandle, blob, "Auth AuthHandle");
648
 
        LoadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceOdd.nonce, "Auth: NonceOdd");
649
 
        LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob, "CAS");
650
 
        LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&auth->HMAC, "auth: HMAC");
651
 
}
652
 
 
653
 
void
654
 
UnloadBlob_Auth(UINT64 * offset, BYTE * blob, TPM_AUTH * auth)
655
 
{
656
 
        UnloadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceEven.nonce, "Nonce Even");
657
 
        UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob, "CAS");
658
 
        UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&auth->HMAC, "Auth HMAC");
659
 
}
660
 
 
661
 
void
662
 
LoadBlob_KEY_PARMS(UINT64 * offset, BYTE * blob,
663
 
                   TCPA_KEY_PARMS * keyInfo)
664
 
{
665
 
        LoadBlob_UINT32(offset, keyInfo->algorithmID, blob, "KEY_PARMS: algID");
666
 
        LoadBlob_UINT16(offset, keyInfo->encScheme, blob,
667
 
                        "KEY_PARMS: encScheme");
668
 
        LoadBlob_UINT16(offset, keyInfo->sigScheme, blob,
669
 
                        "KEY_PARMS: sigScheme");
670
 
        LoadBlob_UINT32(offset, keyInfo->parmSize, blob, "KEY_PARMS: parmSize");
671
 
        LoadBlob(offset, keyInfo->parmSize, blob, keyInfo->parms,
672
 
                 "KEY_PARMS: parms");
673
 
}
674
 
 
675
 
TSS_RESULT
676
 
UnloadBlob_KEY_PARMS(UINT64 * offset, BYTE * blob,
677
 
                     TCPA_KEY_PARMS * keyParms)
678
 
{
679
 
        UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob,
680
 
                          "KEY_PARMS: algID");
681
 
        UnloadBlob_UINT16(offset, &keyParms->encScheme, blob,
682
 
                          "KEY_PARMS: encScheme");
683
 
        UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob,
684
 
                          "KEY_PARMS: sigScheme");
685
 
        UnloadBlob_UINT32(offset, &keyParms->parmSize, blob,
686
 
                          "KEY_PARMS: parmSize");
 
252
LoadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
 
253
{
 
254
        LoadBlob_UINT32(offset, auth->AuthHandle, blob);
 
255
        LoadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceOdd.nonce);
 
256
        LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob);
 
257
        LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&auth->HMAC);
 
258
}
 
259
 
 
260
void
 
261
UnloadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
 
262
{
 
263
        if (!auth) {
 
264
                UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
 
265
                UnloadBlob_BOOL(offset, NULL, blob);
 
266
                UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
 
267
 
 
268
                return;
 
269
        }
 
270
 
 
271
        UnloadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceEven.nonce);
 
272
        UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob);
 
273
        UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&auth->HMAC);
 
274
}
 
275
 
 
276
void
 
277
UnloadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *out)
 
278
{
 
279
        if (!out) {
 
280
                *offset += (sizeof(BYTE) * 4);
 
281
                return;
 
282
        }
 
283
 
 
284
        UnloadBlob_BYTE(offset, &out->major, blob);
 
285
        UnloadBlob_BYTE(offset, &out->minor, blob);
 
286
        UnloadBlob_BYTE(offset, &out->revMajor, blob);
 
287
        UnloadBlob_BYTE(offset, &out->revMinor, blob);
 
288
}
 
289
 
 
290
void
 
291
LoadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *ver)
 
292
{
 
293
        LoadBlob_BYTE(offset, ver->major, blob);
 
294
        LoadBlob_BYTE(offset, ver->minor, blob);
 
295
        LoadBlob_BYTE(offset, ver->revMajor, blob);
 
296
        LoadBlob_BYTE(offset, ver->revMinor, blob);
 
297
}
 
298
 
 
299
void
 
300
UnloadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out)
 
301
{
 
302
        if (!out) {
 
303
                *offset += (sizeof(BYTE) * 4);
 
304
                return;
 
305
        }
 
306
 
 
307
        UnloadBlob_BYTE(offset, &out->major, blob);
 
308
        UnloadBlob_BYTE(offset, &out->minor, blob);
 
309
        UnloadBlob_BYTE(offset, &out->revMajor, blob);
 
310
        UnloadBlob_BYTE(offset, &out->revMinor, blob);
 
311
}
 
312
 
 
313
void
 
314
LoadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *ver)
 
315
{
 
316
        LoadBlob_BYTE(offset, ver->major, blob);
 
317
        LoadBlob_BYTE(offset, ver->minor, blob);
 
318
        LoadBlob_BYTE(offset, ver->revMajor, blob);
 
319
        LoadBlob_BYTE(offset, ver->revMinor, blob);
 
320
}
 
321
 
 
322
TSS_RESULT
 
323
UnloadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms)
 
324
{
 
325
        if (!keyParms) {
 
326
                UINT32 parmSize;
 
327
 
 
328
                UnloadBlob_UINT32(offset, NULL, blob);
 
329
                UnloadBlob_UINT16(offset, NULL, blob);
 
330
                UnloadBlob_UINT16(offset, NULL, blob);
 
331
                UnloadBlob_UINT32(offset, &parmSize, blob);
 
332
 
 
333
                if (parmSize > 0)
 
334
                        UnloadBlob(offset, parmSize, blob, NULL);
 
335
 
 
336
                return TSS_SUCCESS;
 
337
        }
 
338
 
 
339
        UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob);
 
340
        UnloadBlob_UINT16(offset, &keyParms->encScheme, blob);
 
341
        UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob);
 
342
        UnloadBlob_UINT32(offset, &keyParms->parmSize, blob);
687
343
 
688
344
        if (keyParms->parmSize == 0)
689
345
                keyParms->parms = NULL;
695
351
                        return TCSERR(TSS_E_OUTOFMEMORY);
696
352
                }
697
353
 
698
 
                UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms,
699
 
                                "KEY_PARMS: parms");
700
 
        }
701
 
 
702
 
        return TSS_SUCCESS;
703
 
}
704
 
 
705
 
TSS_RESULT
706
 
UnloadBlob_STORE_PUBKEY(UINT64 * offset, BYTE * blob,
707
 
                        TCPA_STORE_PUBKEY * store)
708
 
{
709
 
        UnloadBlob_UINT32(offset, &store->keyLength, blob,
710
 
                          "STORE_PUBKEY KeyLength");
711
 
 
712
 
        if (store->keyLength == 0) {
713
 
                store->key = NULL;
714
 
                LogWarn("Unloading a public key of size 0!");
715
 
        } else {
716
 
                store->key = (BYTE *)malloc(store->keyLength);
717
 
                if (store->key == NULL) {
718
 
                        LogError("malloc of %u bytes failed.", store->keyLength);
719
 
                        store->keyLength = 0;
720
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
721
 
                }
722
 
 
723
 
                UnloadBlob(offset, store->keyLength, blob, store->key,
724
 
                                "STORE_PUBKEY key");
725
 
        }
726
 
 
727
 
        return TSS_SUCCESS;
728
 
}
729
 
 
730
 
void
731
 
LoadBlob_STORE_PUBKEY(UINT64 * offset, BYTE * blob,
732
 
                      TCPA_STORE_PUBKEY * store)
733
 
{
734
 
        LoadBlob_UINT32(offset, store->keyLength, blob,
735
 
                        "STORE_PUBKEY keyLength");
736
 
        LoadBlob(offset, store->keyLength, blob, store->key,
737
 
                 "STORE_PUBKEY key");
738
 
}
739
 
 
740
 
void
741
 
UnloadBlob_VERSION(UINT64 * offset, BYTE * blob, TCPA_VERSION * out)
742
 
{
743
 
        UnloadBlob_BYTE(offset, &out->major, blob, NULL);
744
 
        UnloadBlob_BYTE(offset, &out->minor, blob, NULL);
745
 
        UnloadBlob_BYTE(offset, &out->revMajor, blob, NULL);
746
 
        UnloadBlob_BYTE(offset, &out->revMinor, blob, NULL);
747
 
}
748
 
 
749
 
void
750
 
LoadBlob_VERSION(UINT64 * offset, BYTE * blob, TCPA_VERSION * ver)
751
 
{
752
 
        LoadBlob_BYTE(offset, ver->major, blob, NULL);
753
 
        LoadBlob_BYTE(offset, ver->minor, blob, NULL);
754
 
        LoadBlob_BYTE(offset, ver->revMajor, blob, NULL);
755
 
        LoadBlob_BYTE(offset, ver->revMinor, blob, NULL);
756
 
}
757
 
 
758
 
TSS_RESULT
759
 
UnloadBlob_KEY(UINT64 * offset, BYTE * blob, TCPA_KEY * key)
760
 
{
761
 
        TSS_RESULT rc;
762
 
 
763
 
        UnloadBlob_VERSION(offset, blob, &key->ver);
764
 
        UnloadBlob_UINT16(offset, &key->keyUsage, blob, "KEY keyUsage");
765
 
        UnloadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
766
 
        UnloadBlob_BOOL(offset, (TSS_BOOL *)&key->authDataUsage, blob, "KEY AuthDataUsage");
767
 
        if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &key->algorithmParms)))
768
 
                return rc;
769
 
        UnloadBlob_UINT32(offset, &key->PCRInfoSize, blob, "KEY PCRInfoSize");
770
 
 
771
 
        if (key->PCRInfoSize == 0)
772
 
                key->PCRInfo = NULL;
773
 
        else {
774
 
                key->PCRInfo = malloc(key->PCRInfoSize);
775
 
                if (key->PCRInfo == NULL) {
776
 
                        LogError("malloc of %u bytes failed.", key->PCRInfoSize);
777
 
                        key->PCRInfoSize = 0;
778
 
                        free(key->algorithmParms.parms);
779
 
                        key->algorithmParms.parms = NULL;
780
 
                        key->algorithmParms.parmSize = 0;
781
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
782
 
                }
783
 
                UnloadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo, "KEY PCRInfo");
784
 
        }
785
 
 
786
 
        if ((rc = UnloadBlob_STORE_PUBKEY(offset, blob, &key->pubKey))) {
787
 
                free(key->PCRInfo);
788
 
                key->PCRInfo = NULL;
789
 
                key->PCRInfoSize = 0;
790
 
                free(key->algorithmParms.parms);
791
 
                key->algorithmParms.parms = NULL;
792
 
                key->algorithmParms.parmSize = 0;
793
 
                return rc;
794
 
        }
795
 
        UnloadBlob_UINT32(offset, &key->encSize, blob, "KEY encSize");
796
 
 
797
 
        if (key->encSize == 0)
798
 
                key->encData = NULL;
799
 
        else {
800
 
                key->encData = (BYTE *)malloc(key->encSize);
801
 
                if (key->encData == NULL) {
802
 
                        LogError("malloc of %d bytes failed.", key->encSize);
803
 
                        key->encSize = 0;
804
 
                        free(key->algorithmParms.parms);
805
 
                        key->algorithmParms.parms = NULL;
806
 
                        key->algorithmParms.parmSize = 0;
807
 
                        free(key->PCRInfo);
808
 
                        key->PCRInfo = NULL;
809
 
                        key->PCRInfoSize = 0;
810
 
                        free(key->pubKey.key);
811
 
                        key->pubKey.key = NULL;
812
 
                        key->pubKey.keyLength = 0;
813
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
814
 
                }
815
 
                UnloadBlob(offset, key->encSize, blob, key->encData, "KEY encData");
816
 
        }
817
 
 
818
 
        return TSS_SUCCESS;
819
 
}
820
 
 
821
 
void
822
 
LoadBlob_KEY(UINT64 * offset, BYTE * blob, TCPA_KEY * key)
823
 
{
824
 
        LoadBlob_VERSION(offset, blob, &key->ver);
825
 
        LoadBlob_UINT16(offset, key->keyUsage, blob, "KEY keyUsage");
826
 
        LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags);
827
 
        LoadBlob_BOOL(offset, key->authDataUsage, blob, "KEY authDataUsage");
828
 
        LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms);
829
 
        LoadBlob_UINT32(offset, key->PCRInfoSize, blob, "KEY pcrInfosize");
830
 
        LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo, "KEY PCRInfo");
831
 
        LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey);
832
 
        LoadBlob_UINT32(offset, key->encSize, blob, "KEY encSize");
833
 
        LoadBlob(offset, key->encSize, blob, key->encData, "KEY encData");
834
 
}
835
 
 
836
 
void
837
 
LoadBlob_PUBKEY(UINT64 * offset, BYTE * blob, TCPA_PUBKEY * key)
838
 
{
839
 
        LoadBlob_KEY_PARMS(offset, blob, &(key->algorithmParms));
840
 
        LoadBlob_STORE_PUBKEY(offset, blob, &(key->pubKey));
841
 
}
842
 
 
843
 
TSS_RESULT
844
 
UnloadBlob_PUBKEY(UINT64 * offset, BYTE * blob,
845
 
                  TCPA_PUBKEY * key)
846
 
{
847
 
        TSS_RESULT rc;
848
 
 
849
 
        if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &key->algorithmParms)))
850
 
                return rc;
851
 
        if ((rc = UnloadBlob_STORE_PUBKEY(offset, blob, &key->pubKey))) {
852
 
                free(key->algorithmParms.parms);
853
 
                key->algorithmParms.parms = NULL;
854
 
                key->algorithmParms.parmSize = 0;
855
 
        }
856
 
 
857
 
        return rc;
858
 
}
859
 
 
860
 
void
861
 
LoadBlob_SYMMETRIC_KEY(UINT64 *offset, BYTE *blob, TCPA_SYMMETRIC_KEY *key)
862
 
{
863
 
        LoadBlob_UINT32(offset, key->algId, blob, NULL);
864
 
        LoadBlob_UINT16(offset, key->encScheme, blob, NULL);
865
 
        LoadBlob_UINT16(offset, key->size, blob, NULL);
866
 
 
867
 
        if (key->size > 0) {
868
 
                LoadBlob(offset, key->size, blob, key->data, NULL);
869
 
        } else {
870
 
                key->data = NULL;
871
 
        }
872
 
}
873
 
 
874
 
TSS_RESULT
875
 
UnloadBlob_SYMMETRIC_KEY(UINT64 *offset, BYTE *blob, TCPA_SYMMETRIC_KEY *key)
876
 
{
877
 
        UnloadBlob_UINT32(offset, &key->algId, blob, NULL);
878
 
        UnloadBlob_UINT16(offset, &key->encScheme, blob, NULL);
879
 
        UnloadBlob_UINT16(offset, &key->size, blob, NULL);
880
 
 
881
 
        if (key->size > 0) {
882
 
                key->data = (BYTE *)malloc(key->size);
883
 
                if (key->data == NULL) {
884
 
                        LogError("malloc of %hu bytes failed.", key->size);
885
 
                        key->size = 0;
886
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
887
 
                }
888
 
                UnloadBlob(offset, key->size, blob, key->data, "SYM KEY data");
889
 
        } else {
890
 
                key->data = NULL;
891
 
        }
892
 
 
893
 
        return TSS_SUCCESS;
894
 
}
895
 
 
896
 
TSS_RESULT
897
 
UnloadBlob_PCR_SELECTION(UINT64 * offset, BYTE * blob, TCPA_PCR_SELECTION * pcr)
898
 
{
899
 
        UnloadBlob_UINT16(offset, &pcr->sizeOfSelect, blob, NULL);
900
 
        pcr->pcrSelect = malloc(pcr->sizeOfSelect);
901
 
        if (pcr->pcrSelect == NULL) {
902
 
                LogError("malloc of %hu bytes failed.", pcr->sizeOfSelect);
903
 
                pcr->sizeOfSelect = 0;
904
 
                return TCSERR(TSS_E_OUTOFMEMORY);
905
 
        }
906
 
        UnloadBlob(offset, pcr->sizeOfSelect, blob, pcr->pcrSelect, NULL);
907
 
        return TSS_SUCCESS;
908
 
}
909
 
 
910
 
void
911
 
LoadBlob_PCR_SELECTION(UINT64 * offset, BYTE * blob,
912
 
                       TCPA_PCR_SELECTION pcr)
913
 
{
914
 
        LoadBlob_UINT16(offset, pcr.sizeOfSelect, blob, "PCR SEL sizeOfSel");
915
 
        LoadBlob(offset, pcr.sizeOfSelect, blob, pcr.pcrSelect,
916
 
                 "PCR SEL pcrSel");
917
 
}
918
 
 
919
 
TSS_RESULT
920
 
UnloadBlob_PCR_COMPOSITE(UINT64 *offset, BYTE *blob,
921
 
                         TCPA_PCR_COMPOSITE *out)
922
 
{
923
 
        TSS_RESULT rc;
924
 
 
925
 
        if ((rc = UnloadBlob_PCR_SELECTION(offset, blob, &out->select)))
926
 
                return rc;
927
 
 
928
 
        UnloadBlob_UINT32(offset, &out->valueSize, blob, "PCR COMP valueSize");
929
 
        out->pcrValue = malloc(out->valueSize);
930
 
        if (out->pcrValue == NULL) {
931
 
                LogError("malloc of %u bytes failed.", out->valueSize);
932
 
                out->valueSize = 0;
933
 
                return TCSERR(TSS_E_OUTOFMEMORY);
934
 
        }
935
 
        UnloadBlob(offset, out->valueSize, blob, (BYTE *) out->pcrValue,
936
 
                   "PCR COMP value");
937
 
        return TSS_SUCCESS;
938
 
}
939
 
 
940
 
void
941
 
LoadBlob_PCR_INFO(UINT64 * offset, BYTE * blob, TCPA_PCR_INFO * pcr)
942
 
{
943
 
        LoadBlob_PCR_SELECTION(offset, blob, pcr->pcrSelection);
944
 
        LoadBlob(offset, TCPA_DIGEST_SIZE, blob, pcr->digestAtRelease.digest,
945
 
                 "PCR_INFO digAtRel");
946
 
        LoadBlob(offset, TCPA_DIGEST_SIZE, blob, pcr->digestAtCreation.digest,
947
 
                 "PCR_INFO digAtCreate");
948
 
}
949
 
 
950
 
TSS_RESULT
951
 
UnloadBlob_PCR_INFO(UINT64 * offset, BYTE * blob,
952
 
                    TCPA_PCR_INFO * pcr)
953
 
{
954
 
        TSS_RESULT rc;
955
 
 
956
 
        if ((rc = UnloadBlob_PCR_SELECTION(offset, blob, &pcr->pcrSelection)))
957
 
                return rc;
958
 
        UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, pcr->digestAtRelease.digest, "PCR_INFO digAtRel");
959
 
        UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, pcr->digestAtCreation.digest, "PCR_INFO digAtCreate");
960
 
 
961
 
        return TSS_SUCCESS;
962
 
}
963
 
 
964
 
TSS_RESULT
965
 
UnloadBlob_STORED_DATA(UINT64 * offset, BYTE * blob,
966
 
                       TCPA_STORED_DATA * data)
967
 
{
968
 
        UnloadBlob_VERSION(offset, blob, &data->ver);
969
 
 
970
 
        UnloadBlob_UINT32(offset, &data->sealInfoSize, blob, "seal info size");
971
 
 
972
 
        if (data->sealInfoSize > 0) {
973
 
                data->sealInfo = (BYTE *)calloc(1, data->sealInfoSize);
974
 
                if (data->sealInfo == NULL) {
975
 
                        LogError("malloc of %u bytes failed.", data->sealInfoSize);
976
 
                        data->sealInfoSize = 0;
977
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
978
 
                }
979
 
                UnloadBlob(offset, data->sealInfoSize, blob, data->sealInfo, "seal info");
980
 
        } else {
981
 
                data->sealInfo = NULL;
982
 
        }
983
 
 
984
 
        UnloadBlob_UINT32(offset, &data->encDataSize, blob, "encDataSize");
985
 
 
986
 
        if (data->encDataSize > 0) {
987
 
                data->encData = (BYTE *)calloc(1, data->encDataSize);
988
 
                if (data->encData == NULL) {
989
 
                        LogError("malloc of %u bytes failed.", data->encDataSize);
990
 
                        data->encDataSize = 0;
991
 
                        free(data->sealInfo);
992
 
                        data->sealInfo = NULL;
993
 
                        data->sealInfoSize = 0;
994
 
                        return TCSERR(TSS_E_OUTOFMEMORY);
995
 
                }
996
 
                UnloadBlob(offset, data->encDataSize, blob, data->encData, "encdata");
997
 
        } else {
998
 
                data->encData = NULL;
999
 
        }
1000
 
 
1001
 
        return TSS_SUCCESS;
1002
 
}
1003
 
 
1004
 
void
1005
 
LoadBlob_STORED_DATA(UINT64 * offset, BYTE * blob,
1006
 
                     TCPA_STORED_DATA * data)
1007
 
{
1008
 
        LoadBlob_VERSION(offset, blob, &data->ver);
1009
 
 
1010
 
        LoadBlob_UINT32(offset, data->sealInfoSize, blob, "seal info size");
1011
 
        LoadBlob(offset, data->sealInfoSize, blob, data->sealInfo, "seal info");
1012
 
        LoadBlob_UINT32(offset, data->encDataSize, blob, "encSize");
1013
 
        LoadBlob(offset, data->encDataSize, blob, data->encData, "encData");
1014
 
}
1015
 
 
1016
 
void
1017
 
LoadBlob_KEY_FLAGS(UINT64 * offset, BYTE * blob, TCPA_KEY_FLAGS * flags)
1018
 
{
1019
 
        UINT32 tempFlag = 0;
1020
 
 
1021
 
        if ((*flags) & migratable)
1022
 
                tempFlag |= TSS_FLAG_MIGRATABLE;
1023
 
        if ((*flags) & redirection)
1024
 
                tempFlag |= TSS_FLAG_REDIRECTION;
1025
 
        if ((*flags) & volatileKey)
1026
 
                tempFlag |= TSS_FLAG_VOLATILE;
1027
 
        LoadBlob_UINT32(offset, tempFlag, blob, "Flags");
1028
 
}
1029
 
 
1030
 
void
1031
 
UnloadBlob_KEY_FLAGS(UINT64 * offset, BYTE * blob, TCPA_KEY_FLAGS * flags)
1032
 
{
1033
 
        UINT32 tempFlag = 0;
1034
 
        memset(flags, 0x00, sizeof (TCPA_KEY_FLAGS));
1035
 
 
1036
 
        UnloadBlob_UINT32(offset, &tempFlag, blob, "Flags");
1037
 
 
1038
 
        if (tempFlag & redirection)
1039
 
                *flags |= redirection;
1040
 
        if (tempFlag & migratable)
1041
 
                *flags |= migratable;
1042
 
        if (tempFlag & volatileKey)
1043
 
                *flags |= volatileKey;
1044
 
}
1045
 
 
1046
 
TSS_RESULT
1047
 
UnloadBlob_CERTIFY_INFO(UINT64 * offset, BYTE * blob,
1048
 
                        TCPA_CERTIFY_INFO * certify)
1049
 
{
1050
 
        TSS_RESULT rc;
1051
 
 
1052
 
        LogDebug("Certify Info");
1053
 
        UnloadBlob_VERSION(offset, blob, &certify->version);
1054
 
        UnloadBlob_UINT16(offset, &certify->keyUsage, blob, "usage");
 
354
                UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms);
 
355
        }
 
356
 
 
357
        return TSS_SUCCESS;
 
358
}
 
359
 
 
360
void
 
361
UnloadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags)
 
362
{
 
363
        if (!flags) {
 
364
                UnloadBlob_UINT32(offset, NULL, blob);
 
365
 
 
366
                return;
 
367
        }
 
368
 
 
369
        UnloadBlob_UINT32(offset, flags, blob);
 
370
}
 
371
 
 
372
TSS_RESULT
 
373
UnloadBlob_CERTIFY_INFO(UINT64 *offset, BYTE *blob, TCPA_CERTIFY_INFO *certify)
 
374
{
 
375
        TSS_RESULT rc;
 
376
 
 
377
        if (!certify) {
 
378
                UINT32 size;
 
379
 
 
380
                UnloadBlob_VERSION(offset, blob, NULL);
 
381
                UnloadBlob_UINT16(offset, NULL, blob);
 
382
                UnloadBlob_KEY_FLAGS(offset, blob, NULL);
 
383
                UnloadBlob_BOOL(offset, NULL, blob);
 
384
 
 
385
                if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL)))
 
386
                        return rc;
 
387
 
 
388
                UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
 
389
                UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
 
390
                UnloadBlob_BOOL(offset, NULL, blob);
 
391
                UnloadBlob_UINT32(offset, &size, blob);
 
392
 
 
393
                if (size > 0)
 
394
                        UnloadBlob(offset, size, blob, NULL);
 
395
 
 
396
                return TSS_SUCCESS;
 
397
        }
 
398
 
 
399
        UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&certify->version);
 
400
        UnloadBlob_UINT16(offset, &certify->keyUsage, blob);
1055
401
        UnloadBlob_KEY_FLAGS(offset, blob, &certify->keyFlags);
1056
 
        UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->authDataUsage, blob, "authDatausage");
 
402
        UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->authDataUsage, blob);
1057
403
 
1058
404
        if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &certify->algorithmParms)))
1059
405
                return rc;
1060
406
 
1061
 
        UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, certify->pubkeyDigest.digest, "pubkey digest");
1062
 
        UnloadBlob(offset, TCPA_NONCE_SIZE, blob, certify->data.nonce, "data");
1063
 
        UnloadBlob_BOOL(offset, &certify->parentPCRStatus, blob, "parent pcr status");
1064
 
        UnloadBlob_UINT32(offset, &certify->PCRInfoSize, blob, "pcr info size");
 
407
        UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, certify->pubkeyDigest.digest);
 
408
        UnloadBlob(offset, TCPA_NONCE_SIZE, blob, certify->data.nonce);
 
409
        UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->parentPCRStatus, blob);
 
410
        UnloadBlob_UINT32(offset, &certify->PCRInfoSize, blob);
1065
411
 
1066
412
        if (certify->PCRInfoSize > 0) {
1067
413
                certify->PCRInfo = (BYTE *)malloc(certify->PCRInfoSize);
1073
419
                        certify->algorithmParms.parmSize = 0;
1074
420
                        return TCSERR(TSS_E_OUTOFMEMORY);
1075
421
                }
1076
 
                UnloadBlob(offset, certify->PCRInfoSize, blob, certify->PCRInfo, "pcr info");
 
422
                UnloadBlob(offset, certify->PCRInfoSize, blob, certify->PCRInfo);
1077
423
        } else {
1078
424
                certify->PCRInfo = NULL;
1079
425
        }
1082
428
}
1083
429
 
1084
430
TSS_RESULT
1085
 
UnloadBlob_KEY_HANDLE_LIST(UINT64 * offset,
1086
 
                           BYTE * blob, TCPA_KEY_HANDLE_LIST * list)
 
431
UnloadBlob_KEY_HANDLE_LIST(UINT64 *offset, BYTE *blob, TCPA_KEY_HANDLE_LIST *list)
1087
432
{
1088
433
        UINT16 i;
1089
434
 
1090
 
        UnloadBlob_UINT16(offset, &list->loaded, blob,
1091
 
                          "key handle list: loaded");
1092
 
        if (list->loaded == 0)
1093
 
                return TSS_SUCCESS;
 
435
        if (!list) {
 
436
                UINT16 size;
 
437
 
 
438
                UnloadBlob_UINT16(offset, &size, blob);
 
439
 
 
440
                *offset += (size * sizeof(UINT32));
 
441
 
 
442
                return TSS_SUCCESS;
 
443
        }
 
444
 
 
445
        UnloadBlob_UINT16(offset, &list->loaded, blob);
 
446
        if (list->loaded == 0) {
 
447
                list->handle = NULL;
 
448
                return TSS_SUCCESS;
 
449
        }
 
450
 
1094
451
        list->handle = malloc(list->loaded * sizeof (UINT32));
1095
452
        if (list->handle == NULL) {
1096
453
                LogError("malloc of %zd bytes failed.", list->loaded * sizeof (UINT32));
1098
455
                return TCSERR(TSS_E_OUTOFMEMORY);
1099
456
        }
1100
457
 
1101
 
        for (i = 0; i < list->loaded; i++) {
1102
 
                UnloadBlob_UINT32(offset, &list->handle[i], blob,
1103
 
                                  "key handle list: handle");
1104
 
        }
 
458
        for (i = 0; i < list->loaded; i++)
 
459
                UnloadBlob_UINT32(offset, &list->handle[i], blob);
 
460
 
1105
461
        return TSS_SUCCESS;
1106
462
}
1107
463
 
1108
464
void
1109
 
LoadBlob_UUID(UINT64 * offset, BYTE * blob, TSS_UUID uuid)
1110
 
{
1111
 
        LoadBlob_UINT32(offset, uuid.ulTimeLow, blob, NULL);
1112
 
        LoadBlob_UINT16(offset, uuid.usTimeMid, blob, NULL);
1113
 
        LoadBlob_UINT16(offset, uuid.usTimeHigh, blob, NULL);
1114
 
        LoadBlob_BYTE(offset, uuid.bClockSeqHigh, blob, NULL);
1115
 
        LoadBlob_BYTE(offset, uuid.bClockSeqLow, blob, NULL);
1116
 
        LoadBlob(offset, 6, blob, uuid.rgbNode, NULL);
1117
 
}
1118
 
 
1119
 
void
1120
 
UnloadBlob_UUID(UINT64 * offset, BYTE * blob, TSS_UUID *uuid)
1121
 
{
1122
 
        memset(uuid, 0, sizeof(TSS_UUID));
1123
 
        UnloadBlob_UINT32(offset, &uuid->ulTimeLow, blob, NULL);
1124
 
        UnloadBlob_UINT16(offset, &uuid->usTimeMid, blob, NULL);
1125
 
        UnloadBlob_UINT16(offset, &uuid->usTimeHigh, blob, NULL);
1126
 
        UnloadBlob_BYTE(offset, &uuid->bClockSeqHigh, blob, NULL);
1127
 
        UnloadBlob_BYTE(offset, &uuid->bClockSeqLow, blob, NULL);
1128
 
        UnloadBlob(offset, 6, blob, uuid->rgbNode, NULL);
1129
 
}
1130
 
 
1131
 
void
1132
 
destroy_key_refs(TCPA_KEY *key)
1133
 
{
1134
 
        free(key->algorithmParms.parms);
1135
 
        key->algorithmParms.parms = NULL;
1136
 
        key->algorithmParms.parmSize = 0;
1137
 
 
1138
 
        free(key->pubKey.key);
1139
 
        key->pubKey.key = NULL;
1140
 
        key->pubKey.keyLength = 0;
1141
 
 
1142
 
        free(key->encData);
1143
 
        key->encData = NULL;
1144
 
        key->encSize = 0;
1145
 
 
1146
 
        free(key->PCRInfo);
1147
 
        key->PCRInfo = NULL;
1148
 
        key->PCRInfoSize = 0;
1149
 
}
1150
 
 
1151
 
/* XXX make this a macro */
1152
 
UINT32
1153
 
get_pcr_event_size(TSS_PCR_EVENT *e)
1154
 
{
1155
 
        return (sizeof(TSS_PCR_EVENT) + e->ulEventLength + e->ulPcrValueLength);
1156
 
}
1157
 
 
1158
 
/*
1159
 
 * Hopefully this will make the code clearer since
1160
 
 * OpenSSL returns 1 on success
1161
 
 */
1162
 
#define EVP_SUCCESS 1
1163
 
 
1164
 
TSS_RESULT
1165
 
Hash(UINT32 HashType, UINT32 BufSize, BYTE* Buf, BYTE* Digest)
1166
 
{
1167
 
        EVP_MD_CTX md_ctx;
1168
 
        unsigned int result_size;
1169
 
        int rv;
1170
 
 
1171
 
        switch (HashType) {
1172
 
                case TSS_HASH_SHA1:
1173
 
                        rv = EVP_DigestInit(&md_ctx, EVP_sha1());
1174
 
                        break;
1175
 
                default:
1176
 
                        rv = TSPERR(TSS_E_BAD_PARAMETER);
1177
 
                        goto out;
1178
 
                        break;
1179
 
        }
1180
 
 
1181
 
        if (rv != EVP_SUCCESS) {
1182
 
                rv = TSPERR(TSS_E_INTERNAL_ERROR);
1183
 
                goto out;
1184
 
        }
1185
 
 
1186
 
        rv = EVP_DigestUpdate(&md_ctx, Buf, BufSize);
1187
 
        if (rv != EVP_SUCCESS) {
1188
 
                rv = TSPERR(TSS_E_INTERNAL_ERROR);
1189
 
                goto out;
1190
 
        }
1191
 
 
1192
 
        result_size = EVP_MD_CTX_size(&md_ctx);
1193
 
        rv = EVP_DigestFinal(&md_ctx, Digest, &result_size);
1194
 
        if (rv != EVP_SUCCESS) {
1195
 
                rv = TSPERR(TSS_E_INTERNAL_ERROR);
1196
 
        } else
1197
 
                rv = TSS_SUCCESS;
1198
 
 
1199
 
out:
1200
 
        return rv;
1201
 
}
1202
 
 
1203
 
void
1204
 
get_credential(int type, UINT32 *size, BYTE **cred)
1205
 
{
1206
 
        int rc, fd;
1207
 
        char *path = NULL;
1208
 
        void *file = NULL;
1209
 
        struct stat stat_buf;
1210
 
        size_t file_size;
1211
 
 
1212
 
        switch (type) {
1213
 
                case PLATFORM:
1214
 
                        path = tcsd_options.platform_cred;
1215
 
                        break;
1216
 
                case CONFORMANCE:
1217
 
                        path = tcsd_options.conformance_cred;
1218
 
                        break;
1219
 
                case ENDORSEMENT:
1220
 
                        path = tcsd_options.endorsement_cred;
1221
 
                        break;
1222
 
                default:
1223
 
                        LogDebugFn("Bad credential type");
1224
 
                        break;
1225
 
        }
1226
 
 
1227
 
        if (path == NULL)
1228
 
                goto done;
1229
 
 
1230
 
        if ((fd = open(path, O_RDONLY)) < 0) {
1231
 
                LogError("open(%s): %s", path, strerror(errno));
1232
 
                goto done;
1233
 
        }
1234
 
 
1235
 
        if ((rc = fstat(fd, &stat_buf)) == -1) {
1236
 
                LogError("Error stating credential: %s: %s", path, strerror(errno));
1237
 
                goto done;
1238
 
        }
1239
 
 
1240
 
        file_size = (size_t)stat_buf.st_size;
1241
 
 
1242
 
        LogDebugFn("%s, (%zd bytes)", path, file_size);
1243
 
 
1244
 
        file = mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
1245
 
        if (file == MAP_FAILED) {
1246
 
                LogError("Error reading credential: %s: %s", path, strerror(errno));
1247
 
                close(fd);
1248
 
                goto done;
1249
 
        }
1250
 
        close(fd);
1251
 
 
1252
 
        if ((*cred = malloc(file_size)) == NULL) {
1253
 
                LogError("malloc of %zd bytes failed.", file_size);
1254
 
                munmap(file, file_size);
1255
 
                goto done;
1256
 
        }
1257
 
 
1258
 
        memcpy(*cred, file, file_size);
1259
 
        *size = file_size;
1260
 
        munmap(file, file_size);
1261
 
 
1262
 
        return;
1263
 
done:
1264
 
        *cred = NULL;
1265
 
        *size = 0;
1266
 
}
1267
 
 
1268
 
void
1269
 
free_external_events(UINT32 eventCount, TSS_PCR_EVENT *ppEvents)
1270
 
{
1271
 
        UINT32 j;
1272
 
 
1273
 
        if (!ppEvents)
1274
 
                return;
1275
 
 
1276
 
        for (j = 0; j < eventCount; j++) {
1277
 
                /* This is a fairly heinous hack, but PCR event logs can get really large
1278
 
                 * and without it, there is a real potential to exhaust memory by leaks.
1279
 
                 * The PCR event logs that we pull out of securityfs have had their
1280
 
                 * rgbPcrValue and rgbEvent pointers malloc'd dynamically as the
1281
 
                 * securityfs log was parsed. The other event log lists that are
1282
 
                 * maintained by the TCSD don't need to have this data free'd, since that
1283
 
                 * will happen at shutdown time only. So, for each PCR index that's
1284
 
                 * read from securityfs, we need to free its pointers after that data has
1285
 
                 * been set in the packet to send back to the TSP. */
1286
 
                if ((tcsd_options.kernel_pcrs & (1 << ppEvents[j].ulPcrIndex)) ||
1287
 
                    (tcsd_options.firmware_pcrs & (1 << ppEvents[j].ulPcrIndex))) {
1288
 
                        free(ppEvents[j].rgbPcrValue);
1289
 
                        free(ppEvents[j].rgbEvent);
1290
 
                }
1291
 
        }
1292
 
}
1293
 
 
1294
 
int
1295
 
recv_from_socket(int sock, void *buffer, int size)
1296
 
{
1297
 
        int recv_size = 0, recv_total = 0;
1298
 
 
1299
 
        while (recv_total < size) {
1300
 
                errno = 0;
1301
 
                if ((recv_size = recv(sock, buffer+recv_total, size-recv_total, 0)) <= 0) {
1302
 
                        if (recv_size < 0) {
1303
 
                                if (errno == EINTR)
1304
 
                                        continue;
1305
 
                                LogError("Socket receive connection error: %s.", strerror(errno));
1306
 
                        } else {
1307
 
                                LogDebug("Socket connection closed.");
1308
 
                        }
1309
 
 
1310
 
                        return -1;
1311
 
                }
1312
 
                recv_total += recv_size;
1313
 
        }
1314
 
 
1315
 
        return recv_total;
1316
 
}
1317
 
 
1318
 
int
1319
 
send_to_socket(int sock, void *buffer, int size)
1320
 
{
1321
 
        int send_size = 0, send_total = 0;
1322
 
 
1323
 
        while (send_total < size) {
1324
 
                if ((send_size = send(sock, buffer+send_total, size-send_total, 0)) < 0) {
1325
 
                        LogError("Socket send connection error: %s.", strerror(errno));
1326
 
                        return -1;
1327
 
                }
1328
 
                send_total += send_size;
1329
 
        }
1330
 
 
1331
 
        return send_total;
 
465
LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
 
466
{
 
467
        LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
 
468
}
 
469
 
 
470
void
 
471
UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
 
472
{
 
473
        UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
 
474
}
 
475
 
 
476
void
 
477
LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
 
478
{
 
479
        LoadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
 
480
}
 
481
 
 
482
void
 
483
UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
 
484
{
 
485
        UnloadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
 
486
}
 
487
 
 
488
void
 
489
LoadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
 
490
{
 
491
        LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
 
492
}
 
493
 
 
494
void
 
495
UnloadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
 
496
{
 
497
        UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
1332
498
}
1333
499