~ubuntu-branches/ubuntu/karmic/trousers/karmic

« back to all changes in this revision

Viewing changes to src/tcs/tcs_pbg.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-2007
 
8
 *
 
9
 */
 
10
 
 
11
 
 
12
#include <stdlib.h>
 
13
#include <stdio.h>
 
14
#include <stdarg.h>
 
15
#include <string.h>
 
16
#include <unistd.h>
 
17
#include <sys/types.h>
 
18
#include <sys/stat.h>
 
19
#include <sys/mman.h>
 
20
#include <fcntl.h>
 
21
#include <errno.h>
 
22
 
 
23
#include "trousers/tss.h"
 
24
#include "trousers_types.h"
 
25
#include "tcs_tsp.h"
 
26
#include "tcs_utils.h"
 
27
#include "tcs_int_literals.h"
 
28
#include "capabilities.h"
 
29
#include "tcsps.h"
 
30
#include "tcslog.h"
 
31
 
 
32
 
 
33
#define TSS_TPM_RSP_BLOB_AUTH_LEN       (sizeof(TPM_NONCE) + sizeof(TPM_DIGEST) + sizeof(TPM_BOOL))
 
34
 
 
35
TSS_RESULT
 
36
tpm_rsp_parse(TPM_COMMAND_CODE ordinal, BYTE *b, UINT32 len, ...)
 
37
{
 
38
        TSS_RESULT result = TSS_SUCCESS;
 
39
        UINT64 offset1, offset2;
 
40
        va_list ap;
 
41
 
 
42
        DBG_ASSERT(ordinal);
 
43
        DBG_ASSERT(b);
 
44
 
 
45
        va_start(ap, len);
 
46
 
 
47
        switch (ordinal) {
 
48
        case TPM_ORD_ExecuteTransport:
 
49
        {
 
50
                UINT32 *val1 = va_arg(ap, UINT32 *);
 
51
                UINT32 *val2 = va_arg(ap, UINT32 *);
 
52
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
53
                BYTE **blob1 = va_arg(ap, BYTE **);
 
54
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
55
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
56
                va_end(ap);
 
57
 
 
58
                if (auth1 && auth2) {
 
59
                        offset1 = offset2 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
 
60
                        UnloadBlob_Auth(&offset1, b, auth1);
 
61
                        UnloadBlob_Auth(&offset1, b, auth2);
 
62
                } else if (auth1) {
 
63
                        offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
64
                        UnloadBlob_Auth(&offset1, b, auth1);
 
65
                } else if (auth2) {
 
66
                        offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
67
                        UnloadBlob_Auth(&offset1, b, auth2);
 
68
                } else
 
69
                        offset2 = len;
 
70
 
 
71
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
72
                if (val1)
 
73
                        UnloadBlob_UINT32(&offset1, val1, b);
 
74
                if (val2)
 
75
                        UnloadBlob_UINT32(&offset1, val2, b);
 
76
 
 
77
                *len1 = offset2 - offset1;
 
78
                if (*len1) {
 
79
                        if ((*blob1 = malloc(*len1)) == NULL) {
 
80
                                LogError("malloc of %u bytes failed", *len1);
 
81
                                return TCSERR(TSS_E_OUTOFMEMORY);
 
82
                        }
 
83
                        UnloadBlob(&offset1, *len1, b, *blob1);
 
84
                } else
 
85
                        *blob1 = NULL;
 
86
 
 
87
                break;
 
88
        }
 
89
        /* TPM BLOB: TPM_CURRENT_TICKS, UINT32, BLOB, optional AUTH */
 
90
        case TPM_ORD_TickStampBlob:
 
91
        {
 
92
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
93
                BYTE **blob1 = va_arg(ap, BYTE **);
 
94
                UINT32 *len2 = va_arg(ap, UINT32 *);
 
95
                BYTE **blob2 = va_arg(ap, BYTE **);
 
96
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
97
                va_end(ap);
 
98
 
 
99
                if (!len1 || !blob1 || !len2 || !blob2) {
 
100
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
101
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
102
                }
 
103
 
 
104
                if (auth1) {
 
105
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
106
                        UnloadBlob_Auth(&offset1, b, auth1);
 
107
                }
 
108
 
 
109
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
110
                UnloadBlob_CURRENT_TICKS(&offset2, b, NULL);
 
111
                *len1 = (UINT32)offset2 - offset1;
 
112
 
 
113
                if ((*blob1 = malloc(*len1)) == NULL) {
 
114
                        LogError("malloc of %u bytes failed", *len1);
 
115
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
116
                }
 
117
 
 
118
                UnloadBlob(&offset1, *len1, b, *blob1);
 
119
                UnloadBlob_UINT32(&offset1, len2, b);
 
120
 
 
121
                if ((*blob2 = malloc(*len2)) == NULL) {
 
122
                        LogError("malloc of %u bytes failed", *len2);
 
123
                        free(*blob1);
 
124
                        *blob1 = NULL;
 
125
                        *len1 = 0;
 
126
                        *len2 = 0;
 
127
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
128
                }
 
129
                UnloadBlob(&offset1, *len2, b, *blob2);
 
130
 
 
131
                break;
 
132
        }
 
133
        /* TPM BLOB: TPM_PCR_COMPOSITE, UINT32, BLOB, 1 optional AUTH
 
134
         * return UINT32*, BYTE**, UINT32*, BYTE**, 1 optional AUTH */
 
135
        case TPM_ORD_Quote:
 
136
        {
 
137
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
138
                BYTE **blob1 = va_arg(ap, BYTE **);
 
139
                UINT32 *len2 = va_arg(ap, UINT32 *);
 
140
                BYTE **blob2 = va_arg(ap, BYTE **);
 
141
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
142
                va_end(ap);
 
143
 
 
144
                if (!len1 || !blob1 || !len2 || !blob2) {
 
145
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
146
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
147
                }
 
148
 
 
149
                if (auth1) {
 
150
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
151
                        UnloadBlob_Auth(&offset1, b, auth1);
 
152
                }
 
153
 
 
154
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
155
                UnloadBlob_PCR_COMPOSITE(&offset2, b, NULL);
 
156
                *len1 = offset2 - offset1;
 
157
 
 
158
                if ((*blob1 = malloc(*len1)) == NULL) {
 
159
                        LogError("malloc of %u bytes failed", *len1);
 
160
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
161
                }
 
162
                UnloadBlob(&offset1, *len1, b, *blob1);
 
163
                UnloadBlob_UINT32(&offset1, len2, b);
 
164
 
 
165
                if ((*blob2 = malloc(*len2)) == NULL) {
 
166
                        LogError("malloc of %u bytes failed", *len2);
 
167
                        free(*blob1);
 
168
                        *blob1 = NULL;
 
169
                        *len1 = 0;
 
170
                        *len2 = 0;
 
171
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
172
                }
 
173
                UnloadBlob(&offset1, *len2, b, *blob2);
 
174
 
 
175
                break;
 
176
        }
 
177
        /* TPM BLOB: TPM_PCR_INFO_SHORT, (UINT32, BLOB,) UINT32, BLOB, 1 optional AUTH */
 
178
        case TPM_ORD_Quote2:
 
179
        {
 
180
                UINT32 *len1 = va_arg(ap, UINT32 *); /* pcrDataSizeOut */
 
181
                BYTE **blob1 = va_arg(ap, BYTE **);  /* pcrDataOut */
 
182
                TSS_BOOL *addVersion = va_arg(ap, TSS_BOOL *); /* addVersion */
 
183
                UINT32 *len2 = va_arg(ap, UINT32 *); /* versionInfoSize */
 
184
                BYTE **blob2 = va_arg(ap, BYTE **);  /* versionInfo */
 
185
                UINT32 *len3 = va_arg(ap, UINT32 *); /* sigSize */
 
186
                BYTE **blob3 = va_arg(ap, BYTE **);  /* sig */
 
187
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *); /* privAuth */
 
188
                va_end(ap);
 
189
 
 
190
                if (!len1 || !blob1 || !len2 || !blob2 || !len3 || !blob3 || !addVersion) {
 
191
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
192
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
193
                }
 
194
 
 
195
                if (auth1) {
 
196
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
197
                        UnloadBlob_Auth(&offset1, b, auth1);
 
198
                }
 
199
 
 
200
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
201
                /* Adjust the offset to take the TPM_PCR_INFO_SHORT size:
 
202
                 * need to allocate this size into blob1
 
203
                 */
 
204
                UnloadBlob_PCR_INFO_SHORT(&offset2, b, NULL);
 
205
 
 
206
                /* Get the size of the TSS_TPM_INFO_SHORT
 
207
                 * and copy it into blob1 */
 
208
                *len1 = offset2 - offset1;
 
209
                LogDebugFn("QUOTE2 Core: PCR_INFO_SHORT is %u size", *len1);
 
210
                if ((*blob1 = malloc(*len1)) == NULL) {
 
211
                        LogError("malloc of %u bytes failed", *len1);
 
212
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
213
                }
 
214
                UnloadBlob(&offset1, *len1, b, *blob1); /* TPM_PCR_INFO_SHORT */
 
215
 
 
216
                UnloadBlob_UINT32(&offset1, len2,b); /* versionInfoSize */
 
217
                LogDebugFn("QUOTE2 Core: versionInfoSize=%u", *len2);
 
218
                if ((*blob2 = malloc(*len2)) == NULL) {
 
219
                        LogError("malloc of %u bytes failed", *len2);
 
220
                        free(*blob1);
 
221
                        *blob1 = NULL;
 
222
                        *len1 = 0;
 
223
                        *len2 = 0;
 
224
                        *len3 = 0;
 
225
                        *blob3 = NULL;
 
226
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
227
                }
 
228
                UnloadBlob(&offset1, *len2, b, *blob2);
 
229
 
 
230
                /* Take the sigSize */
 
231
                UnloadBlob_UINT32(&offset1, len3, b);
 
232
                LogDebugFn("QUOTE2 Core: sigSize=%u", *len3);
 
233
                /* sig */
 
234
                if ((*blob3 = malloc(*len3)) == NULL) {
 
235
                        LogError("malloc of %u bytes failed", *len3);
 
236
                        free(*blob1);
 
237
                        *blob1 = NULL;
 
238
                        if (*len2 > 0){
 
239
                                free(*blob2);
 
240
                                *blob2 = NULL;
 
241
                        }
 
242
                        *len1 = 0;
 
243
                        *len2 = 0;
 
244
                        *len3 = 0;
 
245
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
246
                }
 
247
                UnloadBlob(&offset1, *len3, b, *blob3);
 
248
                break;
 
249
        }
 
250
        /* TPM BLOB: TPM_CERTIFY_INFO, UINT32, BLOB, 2 optional AUTHs
 
251
         * return UINT32*, BYTE**, UINT32*, BYTE**, 2 optional AUTHs */
 
252
        case TPM_ORD_CertifyKey:
 
253
        {
 
254
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
255
                BYTE **blob1 = va_arg(ap, BYTE **);
 
256
                UINT32 *len2 = va_arg(ap, UINT32 *);
 
257
                BYTE **blob2 = va_arg(ap, BYTE **);
 
258
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
259
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
260
                va_end(ap);
 
261
 
 
262
                if (!len1 || !blob1 || !len2 || !blob2) {
 
263
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
264
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
265
                }
 
266
 
 
267
                if (auth1 && auth2) {
 
268
                        offset1 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
 
269
                        UnloadBlob_Auth(&offset1, b, auth1);
 
270
                        UnloadBlob_Auth(&offset1, b, auth2);
 
271
                } else if (auth1) {
 
272
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
273
                        UnloadBlob_Auth(&offset1, b, auth1);
 
274
                } else if (auth2) {
 
275
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
276
                        UnloadBlob_Auth(&offset1, b, auth2);
 
277
                }
 
278
 
 
279
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
280
                UnloadBlob_CERTIFY_INFO(&offset2, b, NULL);
 
281
                *len1 = offset2 - offset1;
 
282
 
 
283
                if ((*blob1 = malloc(*len1)) == NULL) {
 
284
                        LogError("malloc of %u bytes failed", *len1);
 
285
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
286
                }
 
287
                UnloadBlob(&offset1, *len1, b, *blob1);
 
288
                UnloadBlob_UINT32(&offset1, len2, b);
 
289
 
 
290
                if ((*blob2 = malloc(*len2)) == NULL) {
 
291
                        LogError("malloc of %u bytes failed", *len2);
 
292
                        free(*blob1);
 
293
                        *blob1 = NULL;
 
294
                        *len1 = 0;
 
295
                        *len2 = 0;
 
296
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
297
                }
 
298
                UnloadBlob(&offset1, *len2, b, *blob2);
 
299
 
 
300
                break;
 
301
        }
 
302
        /* TPM_BLOB: TPM_COUNTER_VALUE, DIGEST, DIGEST, UINT32, BLOB, optional AUTH
 
303
         * return: UINT32*, BYTE**, DIGEST*, DIGEST*, UINT32*, BYTE**, optional AUTH */
 
304
        case TPM_ORD_GetAuditDigestSigned:
 
305
        {
 
306
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
307
                BYTE **blob1 = va_arg(ap, BYTE **);
 
308
                TPM_DIGEST *digest1 = va_arg(ap, TPM_DIGEST *);
 
309
                TPM_DIGEST *digest2 = va_arg(ap, TPM_DIGEST *);
 
310
                UINT32 *len2 = va_arg(ap, UINT32 *);
 
311
                BYTE **blob2 = va_arg(ap, BYTE **);
 
312
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
313
                va_end(ap);
 
314
 
 
315
                if (!digest1 || !digest2 || !len1 || !blob1 || !len2 || !blob2) {
 
316
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
317
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
318
                }
 
319
 
 
320
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
321
                UnloadBlob_COUNTER_VALUE(&offset2, b, NULL);
 
322
                *len1 = offset2 - offset1;
 
323
 
 
324
                if ((*blob1 = malloc(*len1)) == NULL) {
 
325
                        LogError("malloc of %u bytes failed", *len1);
 
326
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
327
                }
 
328
                UnloadBlob(&offset1, *len1, b, *blob1);
 
329
 
 
330
                UnloadBlob_DIGEST(&offset1, b, digest1);
 
331
                UnloadBlob_DIGEST(&offset1, b, digest2);
 
332
                UnloadBlob_UINT32(&offset1, len2, b);
 
333
 
 
334
                if ((*blob2 = malloc(*len2)) == NULL) {
 
335
                        LogError("malloc of %u bytes failed", *len2);
 
336
                        free(*blob1);
 
337
                        *blob1 = NULL;
 
338
                        *len1 = 0;
 
339
                        *len2 = 0;
 
340
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
341
                }
 
342
                UnloadBlob(&offset1, *len2, b, *blob2);
 
343
 
 
344
                if (auth1)
 
345
                        UnloadBlob_Auth(&offset1, b, auth1);
 
346
 
 
347
                break;
 
348
        }
 
349
        /* TPM_BLOB: TPM_COUNTER_VALUE, DIGEST, BOOL, UINT32, BLOB
 
350
         * return: DIGEST*, UINT32*, BYTE**, BOOL, UINT32*, BYTE** */
 
351
        case TPM_ORD_GetAuditDigest:
 
352
        {
 
353
                TPM_DIGEST *digest1 = va_arg(ap, TPM_DIGEST *);
 
354
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
355
                BYTE **blob1 = va_arg(ap, BYTE **);
 
356
                TSS_BOOL *bool1 = va_arg(ap, TSS_BOOL *);
 
357
                UINT32 *len2 = va_arg(ap, UINT32 *);
 
358
                BYTE **blob2 = va_arg(ap, BYTE **);
 
359
                va_end(ap);
 
360
 
 
361
                if (!digest1 || !len1 || !blob1 || !len2 || !blob2 || !bool1) {
 
362
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
363
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
364
                }
 
365
 
 
366
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
367
                UnloadBlob_COUNTER_VALUE(&offset2, b, NULL);
 
368
                *len1 = offset2 - offset1;
 
369
 
 
370
                if ((*blob1 = malloc(*len1)) == NULL) {
 
371
                        LogError("malloc of %u bytes failed", *len1);
 
372
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
373
                }
 
374
                UnloadBlob(&offset1, *len1, b, *blob1);
 
375
 
 
376
                UnloadBlob_DIGEST(&offset1, b, digest1);
 
377
                UnloadBlob_BOOL(&offset1, bool1, b);
 
378
                UnloadBlob_UINT32(&offset1, len2, b);
 
379
 
 
380
                if ((*blob2 = malloc(*len2)) == NULL) {
 
381
                        LogError("malloc of %u bytes failed", *len2);
 
382
                        free(*blob1);
 
383
                        *blob1 = NULL;
 
384
                        *len1 = 0;
 
385
                        *len2 = 0;
 
386
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
387
                }
 
388
                UnloadBlob(&offset1, *len2, b, *blob2);
 
389
 
 
390
                break;
 
391
        }
 
392
        /* optional UINT32, TPM_COUNTER_VALUE, optional AUTH */
 
393
        case TPM_ORD_ReadCounter:
 
394
        case TPM_ORD_CreateCounter:
 
395
        case TPM_ORD_IncrementCounter:
 
396
        {
 
397
                UINT32 *val1 = va_arg(ap, UINT32 *);
 
398
                TPM_COUNTER_VALUE *ctr = va_arg(ap, TPM_COUNTER_VALUE *);
 
399
                TPM_AUTH * auth1 = va_arg(ap, TPM_AUTH *);
 
400
                va_end(ap);
 
401
 
 
402
                if (!ctr) {
 
403
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
404
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
405
                }
 
406
 
 
407
                if (auth1) {
 
408
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
409
                        UnloadBlob_Auth(&offset1, b, auth1);
 
410
                }
 
411
 
 
412
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
413
                if (val1)
 
414
                        UnloadBlob_UINT32(&offset1, val1, b);
 
415
                UnloadBlob_COUNTER_VALUE(&offset1, b, ctr);
 
416
 
 
417
                break;
 
418
        }
 
419
        /* TPM BLOB: UINT32, BLOB, UINT32, BLOB, optional AUTH, optional AUTH */
 
420
        case TPM_ORD_CreateMaintenanceArchive:
 
421
        case TPM_ORD_CreateMigrationBlob:
 
422
        case TPM_ORD_Delegate_ReadTable:
 
423
        case TPM_ORD_CMK_CreateBlob:
 
424
        {
 
425
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
426
                BYTE **blob1 = va_arg(ap, BYTE **);
 
427
                UINT32 *len2 = va_arg(ap, UINT32 *);
 
428
                BYTE **blob2 = va_arg(ap, BYTE **);
 
429
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
430
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
431
                va_end(ap);
 
432
 
 
433
                if (!len1 || !blob1 || !len2 || !blob2) {
 
434
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
435
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
436
                }
 
437
 
 
438
                if (auth1 && auth2) {
 
439
                        offset1 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
 
440
                        UnloadBlob_Auth(&offset1, b, auth1);
 
441
                        UnloadBlob_Auth(&offset1, b, auth2);
 
442
                } else if (auth1) {
 
443
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
444
                        UnloadBlob_Auth(&offset1, b, auth1);
 
445
                } else if (auth2) {
 
446
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
447
                        UnloadBlob_Auth(&offset1, b, auth2);
 
448
                }
 
449
 
 
450
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
451
                UnloadBlob_UINT32(&offset1, len1, b);
 
452
                if ((*blob1 = malloc(*len1)) == NULL) {
 
453
                        LogError("malloc of %u bytes failed", *len1);
 
454
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
455
                }
 
456
 
 
457
                UnloadBlob(&offset1, *len1, b, *blob1);
 
458
 
 
459
                UnloadBlob_UINT32(&offset1, len2, b);
 
460
                if ((*blob2 = malloc(*len2)) == NULL) {
 
461
                        LogError("malloc of %u bytes failed", *len2);
 
462
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
463
                }
 
464
 
 
465
                UnloadBlob(&offset1, *len2, b, *blob2);
 
466
 
 
467
                break;
 
468
        }
 
469
        /* TPM BLOB: BLOB, optional AUTH, AUTH
 
470
         * return:   UINT32 *, BYTE **, optional AUTH, AUTH */
 
471
        case TPM_ORD_ActivateIdentity:
 
472
        {
 
473
                UINT32 *len1 = va_arg(ap, UINT32 *);
 
474
                BYTE **blob1 = va_arg(ap, BYTE **);
 
475
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
476
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
477
                va_end(ap);
 
478
 
 
479
                if (!len1 || !blob1 || !auth2) {
 
480
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
481
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
482
                }
 
483
 
 
484
                if (auth1 && auth2) {
 
485
                        offset1 = offset2 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
 
486
                        UnloadBlob_Auth(&offset1, b, auth1);
 
487
                        UnloadBlob_Auth(&offset1, b, auth2);
 
488
                } else if (auth2) {
 
489
                        offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
490
                        UnloadBlob_Auth(&offset1, b, auth2);
 
491
                } else
 
492
                        offset2 = len;
 
493
 
 
494
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
495
                offset2 -= TSS_TPM_TXBLOB_HDR_LEN;
 
496
                if ((*blob1 = malloc(offset2)) == NULL) {
 
497
                        LogError("malloc of %zd bytes failed", (size_t)offset2);
 
498
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
499
                }
 
500
                *len1 = offset2;
 
501
                UnloadBlob(&offset1, *len1, b, *blob1);
 
502
 
 
503
                break;
 
504
        }
 
505
        /* TPM BLOB: TPM_KEY, UINT32, BLOB, optional AUTH, AUTH
 
506
         * return:   UINT32 *, BYTE **, UINT32 *, BYTE **, optional AUTH, AUTH */
 
507
        case TPM_ORD_MakeIdentity:
 
508
        {
 
509
                UINT32 *len1, *len2;
 
510
                BYTE **blob1, **blob2;
 
511
                TPM_AUTH *auth1, *auth2;
 
512
 
 
513
                len1 = va_arg(ap, UINT32 *);
 
514
                blob1 = va_arg(ap, BYTE **);
 
515
                len2 = va_arg(ap, UINT32 *);
 
516
                blob2 = va_arg(ap, BYTE **);
 
517
                auth1 = va_arg(ap, TPM_AUTH *);
 
518
                auth2 = va_arg(ap, TPM_AUTH *);
 
519
                va_end(ap);
 
520
 
 
521
                if (!len1 || !blob1 || !len2 || !blob2 || !auth2) {
 
522
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
523
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
524
                }
 
525
 
 
526
                offset1 = offset2 = TSS_TPM_TXBLOB_HDR_LEN;
 
527
                UnloadBlob_TSS_KEY(&offset1, b, NULL);
 
528
                offset1 -= TSS_TPM_TXBLOB_HDR_LEN;
 
529
 
 
530
                if ((*blob1 = malloc(offset1)) == NULL) {
 
531
                        LogError("malloc of %zd bytes failed", (size_t)offset1);
 
532
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
533
                }
 
534
                *len1 = offset1;
 
535
 
 
536
                UnloadBlob(&offset2, offset1, b, *blob1);
 
537
 
 
538
                /* offset2 points to the stuff after the key */
 
539
                UnloadBlob_UINT32(&offset2, len2, b);
 
540
 
 
541
                if ((*blob2 = malloc(*len2)) == NULL) {
 
542
                        LogError("malloc of %u bytes failed", *len2);
 
543
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
544
                }
 
545
 
 
546
                UnloadBlob(&offset2, *len2, b, *blob2);
 
547
 
 
548
                if (auth1)
 
549
                        UnloadBlob_Auth(&offset2, b, auth1);
 
550
                UnloadBlob_Auth(&offset2, b, auth2);
 
551
 
 
552
                break;
 
553
        }
 
554
        /* 1 TPM_VERSION, 2 UINT32s, 1 optional AUTH */
 
555
        case TPM_ORD_GetCapabilityOwner:
 
556
        {
 
557
                TPM_VERSION *ver1 = va_arg(ap, TPM_VERSION *);
 
558
                UINT32 *data1 = va_arg(ap, UINT32 *);
 
559
                UINT32 *data2 = va_arg(ap, UINT32 *);
 
560
                TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
 
561
                va_end(ap);
 
562
 
 
563
                if (!data1 || !data2 || !ver1) {
 
564
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
565
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
566
                }
 
567
 
 
568
                if (auth) {
 
569
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
570
                        UnloadBlob_Auth(&offset1, b, auth);
 
571
                }
 
572
 
 
573
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
574
                UnloadBlob_VERSION(&offset1, b, ver1);
 
575
                UnloadBlob_UINT32(&offset1, data1, b);
 
576
                UnloadBlob_UINT32(&offset1, data2, b);
 
577
                break;
 
578
        }
 
579
        /* TPM BLOB: 1 UINT32, 1 BLOB, 2 optional AUTHs
 
580
         * return: UINT32 *, BYTE**, 2 optional AUTHs */
 
581
        case TPM_ORD_Sign:
 
582
        case TPM_ORD_GetTestResult:
 
583
        case TPM_ORD_CertifySelfTest:
 
584
        case TPM_ORD_Unseal:
 
585
        case TPM_ORD_GetRandom:
 
586
        case TPM_ORD_DAA_Join:
 
587
        case TPM_ORD_DAA_Sign:
 
588
        case TPM_ORD_ChangeAuth:
 
589
        case TPM_ORD_GetCapability:
 
590
        case TPM_ORD_UnBind:
 
591
        case TPM_ORD_LoadMaintenanceArchive:
 
592
        case TPM_ORD_ConvertMigrationBlob:
 
593
        case TPM_ORD_NV_ReadValue:
 
594
        case TPM_ORD_NV_ReadValueAuth:
 
595
        case TPM_ORD_Delegate_Manage:
 
596
        case TPM_ORD_Delegate_CreateKeyDelegation:
 
597
        case TPM_ORD_Delegate_CreateOwnerDelegation:
 
598
        case TPM_ORD_Delegate_UpdateVerification:
 
599
        case TPM_ORD_CMK_ConvertMigration:
 
600
        {
 
601
                UINT32 *data_len = va_arg(ap, UINT32 *);
 
602
                BYTE **data = va_arg(ap, BYTE **);
 
603
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
604
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
605
                va_end(ap);
 
606
 
 
607
                if (!data || !data_len) {
 
608
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
609
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
610
                }
 
611
 
 
612
                if (auth1 && auth2) {
 
613
                        offset1 = len - (2 * TSS_TPM_RSP_BLOB_AUTH_LEN);
 
614
                        UnloadBlob_Auth(&offset1, b, auth1);
 
615
                        UnloadBlob_Auth(&offset1, b, auth2);
 
616
                } else if (auth1) {
 
617
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
618
                        UnloadBlob_Auth(&offset1, b, auth1);
 
619
                } else if (auth2) {
 
620
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
621
                        UnloadBlob_Auth(&offset1, b, auth2);
 
622
                }
 
623
 
 
624
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
625
                UnloadBlob_UINT32(&offset1, data_len, b);
 
626
                if ((*data = malloc(*data_len)) == NULL) {
 
627
                        LogError("malloc of %u bytes failed", *data_len);
 
628
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
629
                }
 
630
 
 
631
                UnloadBlob(&offset1, *data_len, b, *data);
 
632
                break;
 
633
        }
 
634
        /* TPM BLOB: 1 BLOB, 1 optional AUTH
 
635
         * return: UINT32 *, BYTE**, 1 optional AUTH*/
 
636
        case TPM_ORD_GetTicks:
 
637
        case TPM_ORD_Seal:
 
638
        case TPM_ORD_Sealx:
 
639
        case TPM_ORD_FieldUpgrade:
 
640
        case TPM_ORD_CreateWrapKey:
 
641
        case TPM_ORD_GetPubKey:
 
642
        case TPM_ORD_OwnerReadPubek:
 
643
        case TPM_ORD_OwnerReadInternalPub:
 
644
        case TPM_ORD_AuthorizeMigrationKey:
 
645
        case TPM_ORD_TakeOwnership:
 
646
        case TPM_ORD_CMK_CreateKey:
 
647
        {
 
648
                UINT32 *data_len = va_arg(ap, UINT32 *);
 
649
                BYTE **data = va_arg(ap, BYTE **);
 
650
                TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
 
651
                va_end(ap);
 
652
 
 
653
                if (!data || !data_len) {
 
654
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
655
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
656
                }
 
657
 
 
658
                /* remove the auth data from the back end of the data */
 
659
                if (auth) {
 
660
                        offset1 = offset2 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
661
                        UnloadBlob_Auth(&offset1, b, auth);
 
662
                } else
 
663
                        offset2 = len;
 
664
 
 
665
                /* everything after the header is returned as the blob */
 
666
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
667
                offset2 -= offset1;
 
668
                if ((*data = malloc((size_t)offset2)) == NULL) {
 
669
                        LogError("malloc of %zd bytes failed", (size_t)offset2);
 
670
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
671
                }
 
672
 
 
673
                memcpy(*data, &b[offset1], offset2);
 
674
                *data_len = offset2;
 
675
                break;
 
676
        }
 
677
        /* TPM BLOB: BLOB, optional DIGEST */
 
678
        case TPM_ORD_CreateEndorsementKeyPair:
 
679
        case TPM_ORD_ReadPubek:
 
680
        {
 
681
                UINT32 *data_len = va_arg(ap, UINT32 *);
 
682
                BYTE **data = va_arg(ap, BYTE **);
 
683
                BYTE *digest1 = va_arg(ap, BYTE *);
 
684
                va_end(ap);
 
685
 
 
686
                if (!data || !data_len) {
 
687
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
688
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
689
                }
 
690
 
 
691
                if (digest1) {
 
692
                        offset1 = offset2 = len - TPM_DIGEST_SIZE;
 
693
                        memcpy(digest1, &b[offset2], TPM_DIGEST_SIZE);
 
694
                } else
 
695
                        offset2 = len;
 
696
 
 
697
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
698
                offset2 -= offset1;
 
699
                if ((*data = malloc((size_t)offset2)) == NULL) {
 
700
                        LogError("malloc of %zd bytes failed", (size_t)offset2);
 
701
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
702
                }
 
703
 
 
704
                UnloadBlob(&offset1, offset2, b, *data);
 
705
                *data_len = offset2;
 
706
                break;
 
707
        }
 
708
        /* TPM BLOB: BLOB, DIGEST, DIGEST
 
709
         * return: UINT32 *, BYTE**, DIGEST, DIGEST */
 
710
        case TPM_ORD_CreateRevocableEK:
 
711
        {
 
712
                UINT32 *data_len = va_arg(ap, UINT32 *);
 
713
                BYTE **data = va_arg(ap, BYTE **);
 
714
                BYTE *digest1 = va_arg(ap, BYTE *);
 
715
                BYTE *digest2 = va_arg(ap, BYTE *);
 
716
                va_end(ap);
 
717
 
 
718
                if (!data || !data_len || !digest1 || !digest2) {
 
719
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
720
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
721
                }
 
722
 
 
723
                offset2 = len - TPM_DIGEST_SIZE;
 
724
                memcpy(digest2, &b[offset2], TPM_DIGEST_SIZE);
 
725
 
 
726
                offset2 -= TPM_DIGEST_SIZE;
 
727
                memcpy(digest1, &b[offset2], TPM_DIGEST_SIZE);
 
728
 
 
729
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
730
                offset2 -= offset1;
 
731
                if ((*data = malloc((size_t)offset2)) == NULL) {
 
732
                        LogError("malloc of %zd bytes failed", (size_t)offset2);
 
733
                        return TCSERR(TSS_E_OUTOFMEMORY);
 
734
                }
 
735
 
 
736
                UnloadBlob(&offset1, offset2, b, *data);
 
737
                *data_len = offset2;
 
738
                break;
 
739
        }
 
740
        /* 1 UINT32, 1 optional AUTH */
 
741
        case TPM_ORD_LoadKey:
 
742
        case TPM_ORD_LoadKey2:
 
743
        {
 
744
                UINT32 *handle;
 
745
                TPM_AUTH *auth;
 
746
 
 
747
                handle = va_arg(ap, UINT32 *);
 
748
                auth = va_arg(ap, TPM_AUTH *);
 
749
                va_end(ap);
 
750
 
 
751
                if (!handle) {
 
752
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
753
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
754
                }
 
755
 
 
756
                if (auth) {
 
757
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
758
                        UnloadBlob_Auth(&offset1, b, auth);
 
759
                }
 
760
 
 
761
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
762
                UnloadBlob_UINT32(&offset1, handle, b);
 
763
                break;
 
764
        }
 
765
        /* 1 optional UINT32, 1 20 byte value */
 
766
        case TPM_ORD_DirRead:
 
767
        case TPM_ORD_OIAP:
 
768
        case TPM_ORD_LoadManuMaintPub:
 
769
        case TPM_ORD_ReadManuMaintPub:
 
770
        case TPM_ORD_Extend:
 
771
        case TPM_ORD_PcrRead:
 
772
        {
 
773
                UINT32 *handle = va_arg(ap, UINT32 *);
 
774
                BYTE *nonce = va_arg(ap, BYTE *);
 
775
                va_end(ap);
 
776
 
 
777
                if (!nonce) {
 
778
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
779
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
780
                }
 
781
 
 
782
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
783
                if (handle)
 
784
                        UnloadBlob_UINT32(&offset1, handle, b);
 
785
                UnloadBlob(&offset1, TPM_NONCE_SIZE, b, nonce);
 
786
                break;
 
787
        }
 
788
        /* 1 UINT32, 2 20 byte values */
 
789
        case TPM_ORD_OSAP:
 
790
        case TPM_ORD_DSAP:
 
791
        {
 
792
                UINT32 *handle = va_arg(ap, UINT32 *);
 
793
                BYTE *nonce1 = va_arg(ap, BYTE *);
 
794
                BYTE *nonce2 = va_arg(ap, BYTE *);
 
795
                va_end(ap);
 
796
 
 
797
                if (!handle || !nonce1 || !nonce2) {
 
798
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
799
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
800
                }
 
801
 
 
802
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
803
                UnloadBlob_UINT32(&offset1, handle, b);
 
804
                UnloadBlob(&offset1, TPM_NONCE_SIZE, b, nonce1);
 
805
                UnloadBlob(&offset1, TPM_NONCE_SIZE, b, nonce2);
 
806
                break;
 
807
        }
 
808
        /* 1 20 byte value, 1 optional AUTH */
 
809
        case TPM_ORD_CMK_ApproveMA:
 
810
        case TPM_ORD_CMK_CreateTicket:
 
811
        {
 
812
                BYTE *hmac1 = va_arg(ap, BYTE *);
 
813
                TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
 
814
                va_end(ap);
 
815
 
 
816
                if (!hmac1) {
 
817
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
818
                        return TCSERR(TSS_E_INTERNAL_ERROR);
 
819
                }
 
820
 
 
821
                offset1 = TSS_TPM_TXBLOB_HDR_LEN;
 
822
                UnloadBlob(&offset1, TPM_SHA1_160_HASH_LEN, b, hmac1);
 
823
                if (auth) {
 
824
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
825
                        UnloadBlob_Auth(&offset1, b, auth);
 
826
                }
 
827
                break;
 
828
        }
 
829
        /* 1 optional AUTH */
 
830
        case TPM_ORD_DisablePubekRead:
 
831
        case TPM_ORD_DirWriteAuth:
 
832
        case TPM_ORD_ReleaseCounter:
 
833
        case TPM_ORD_ReleaseCounterOwner:
 
834
        case TPM_ORD_ChangeAuthOwner:
 
835
        case TPM_ORD_SetCapability:
 
836
        case TPM_ORD_SetOrdinalAuditStatus:
 
837
        case TPM_ORD_ResetLockValue:
 
838
        case TPM_ORD_SetRedirection:
 
839
        case TPM_ORD_DisableOwnerClear:
 
840
        case TPM_ORD_OwnerSetDisable:
 
841
        case TPM_ORD_SetTempDeactivated:
 
842
        case TPM_ORD_KillMaintenanceFeature:
 
843
        case TPM_ORD_NV_DefineSpace:
 
844
        case TPM_ORD_NV_WriteValue:
 
845
        case TPM_ORD_NV_WriteValueAuth:
 
846
        case TPM_ORD_OwnerClear:
 
847
        case TPM_ORD_Delegate_LoadOwnerDelegation:
 
848
        case TPM_ORD_CMK_SetRestrictions:
 
849
        case TPM_ORD_FlushSpecific:
 
850
        case TPM_ORD_KeyControlOwner:
 
851
        {
 
852
                TPM_AUTH *auth = va_arg(ap, TPM_AUTH *);
 
853
                va_end(ap);
 
854
 
 
855
                if (auth) {
 
856
                        offset1 = len - TSS_TPM_RSP_BLOB_AUTH_LEN;
 
857
                        UnloadBlob_Auth(&offset1, b, auth);
 
858
                }
 
859
                break;
 
860
        }
 
861
        default:
 
862
                LogError("Unknown ordinal: 0x%x", ordinal);
 
863
                result = TCSERR(TSS_E_INTERNAL_ERROR);
 
864
                break;
 
865
        }
 
866
 
 
867
        return result;
 
868
}
 
869
 
 
870
/* XXX optimize these cases by always passing in lengths for blobs, no more "20 byte values" */
 
871
TSS_RESULT
 
872
tpm_rqu_build(TPM_COMMAND_CODE ordinal, UINT64 *outOffset, BYTE *out_blob, ...)
 
873
{
 
874
        TSS_RESULT result = TCSERR(TSS_E_INTERNAL_ERROR);
 
875
        va_list ap;
 
876
 
 
877
        DBG_ASSERT(ordinal);
 
878
        DBG_ASSERT(outOffset);
 
879
        DBG_ASSERT(out_blob);
 
880
 
 
881
        va_start(ap, out_blob);
 
882
 
 
883
        switch (ordinal) {
 
884
        /* 1 UINT16, 1 UINT32, 1 20 bytes value, 1 UINT32, 1 BLOB */
 
885
        case TPM_ORD_DSAP:
 
886
        {
 
887
                UINT16 val1 = va_arg(ap, int);
 
888
                UINT32 handle1 = va_arg(ap, UINT32);
 
889
                BYTE *digest1 = va_arg(ap, BYTE *);
 
890
                UINT32 in_len1 = va_arg(ap, UINT32);
 
891
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
892
                va_end(ap);
 
893
 
 
894
                if (!digest1 || !in_blob1) {
 
895
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
896
                        break;
 
897
                }
 
898
 
 
899
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
900
                LoadBlob_UINT16(outOffset, val1, out_blob);
 
901
                LoadBlob_UINT32(outOffset, handle1, out_blob);
 
902
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
903
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
904
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
905
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
906
 
 
907
                result = TSS_SUCCESS;
 
908
                break;
 
909
        }
 
910
        /* 1 BOOL, 1 UINT32, 1 BLOB, 1 20 byte value, 1 AUTH */
 
911
        case TPM_ORD_Delegate_CreateOwnerDelegation:
 
912
        {
 
913
                TSS_BOOL bool1 = va_arg(ap, int);
 
914
                UINT32 in_len1 = va_arg(ap, UINT32);
 
915
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
916
                BYTE *digest1 = va_arg(ap, BYTE *);
 
917
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
918
                va_end(ap);
 
919
 
 
920
                if (!in_len1 || !in_blob1 || !digest1) {
 
921
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
922
                        break;
 
923
                }
 
924
 
 
925
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
926
                LoadBlob_BOOL(outOffset, bool1, out_blob);
 
927
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
928
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
929
                if (auth1) {
 
930
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
931
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
932
                } else
 
933
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
934
 
 
935
                result = TSS_SUCCESS;
 
936
                break;
 
937
        }
 
938
        /* 2 UINT32's, 1 BLOB, 1 20 byte value, 1 AUTH */
 
939
        case TPM_ORD_Delegate_CreateKeyDelegation:
 
940
        {
 
941
                UINT32 keyslot1 = va_arg(ap, UINT32);
 
942
                UINT32 in_len1 = va_arg(ap, UINT32);
 
943
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
944
                BYTE *digest1 = va_arg(ap, BYTE *);
 
945
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
946
                va_end(ap);
 
947
 
 
948
                if (!keyslot1 || !in_len1 || !in_blob1 || !digest1) {
 
949
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
950
                        break;
 
951
                }
 
952
 
 
953
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
954
                LoadBlob_UINT32(outOffset, keyslot1, out_blob);
 
955
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
956
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
957
                if (auth1) {
 
958
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
959
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
960
                } else
 
961
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
962
 
 
963
                result = TSS_SUCCESS;
 
964
                break;
 
965
        }
 
966
        /* 3 UINT32's, 1 BLOB, 2 AUTHs */
 
967
        case TPM_ORD_ExecuteTransport:
 
968
        {
 
969
                UINT32 ord1 = va_arg(ap, UINT32);
 
970
                UINT32 *keyslot1 = va_arg(ap, UINT32 *);
 
971
                UINT32 *keyslot2 = va_arg(ap, UINT32 *);
 
972
                UINT32 in_len1 = va_arg(ap, UINT32);
 
973
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
974
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
975
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
976
                va_end(ap);
 
977
 
 
978
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
979
                if (keyslot1)
 
980
                        LoadBlob_UINT32(outOffset, *keyslot1, out_blob);
 
981
                if (keyslot2)
 
982
                        LoadBlob_UINT32(outOffset, *keyslot2, out_blob);
 
983
                //LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
984
                if (in_blob1)
 
985
                        LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
986
 
 
987
                if (auth1 && auth2) {
 
988
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
989
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
990
                        LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ord1, out_blob);
 
991
                } else if (auth1) {
 
992
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
993
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ord1, out_blob);
 
994
                } else if (auth2) {
 
995
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
996
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ord1, out_blob);
 
997
                } else {
 
998
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ord1, out_blob);
 
999
                }
 
1000
 
 
1001
                result = TSS_SUCCESS;
 
1002
                break;
 
1003
        }
 
1004
        /* 1 UINT32, 1 UINT16, 1 BLOB, 1 UINT32, 1 BLOB, 1 options AUTH, 1 AUTH */
 
1005
        case TPM_ORD_CreateMigrationBlob:
 
1006
        {
 
1007
                UINT32 keyslot1 = va_arg(ap, UINT32);
 
1008
                UINT16 type1 = va_arg(ap, int);
 
1009
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1010
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1011
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1012
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1013
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1014
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
1015
                va_end(ap);
 
1016
 
 
1017
                if (!in_blob1 || !in_blob2 || !auth2) {
 
1018
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1019
                        break;
 
1020
                }
 
1021
 
 
1022
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1023
                LoadBlob_UINT32(outOffset, keyslot1, out_blob);
 
1024
                LoadBlob_UINT16(outOffset, type1, out_blob);
 
1025
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1026
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
1027
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1028
                if (auth1) {
 
1029
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1030
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1031
                        LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
 
1032
                } else {
 
1033
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1034
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1035
                }
 
1036
 
 
1037
                result = TSS_SUCCESS;
 
1038
                break;
 
1039
        }
 
1040
        /* 1 UINT32, 1 UINT16, 1 20 byte value, 1 UINT16, 1 UINT32, 1 BLOB, 2 AUTHs */
 
1041
        case TPM_ORD_ChangeAuth:
 
1042
        {
 
1043
                UINT32 keyslot1 = va_arg(ap, UINT32);
 
1044
                UINT16 proto1 = va_arg(ap, int);
 
1045
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1046
                UINT16 entity1 = va_arg(ap, int);
 
1047
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1048
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1049
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1050
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
1051
                va_end(ap);
 
1052
 
 
1053
                if (!digest1 || !in_blob1 || !auth1 || !auth2) {
 
1054
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1055
                        break;
 
1056
                }
 
1057
 
 
1058
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1059
                LoadBlob_UINT32(outOffset, keyslot1, out_blob);
 
1060
                LoadBlob_UINT16(outOffset, proto1, out_blob);
 
1061
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1062
                LoadBlob_UINT16(outOffset, entity1, out_blob);
 
1063
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1064
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1065
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1066
                LoadBlob_Auth(outOffset, out_blob, auth2);
 
1067
                LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
 
1068
 
 
1069
                result = TSS_SUCCESS;
 
1070
                break;
 
1071
        }
 
1072
        /* 2 DIGEST/ENCAUTH's, 1 UINT32, 1 BLOB, 1 optional AUTH, 1 AUTH */
 
1073
        case TPM_ORD_MakeIdentity:
 
1074
        {
 
1075
                BYTE *dig1, *dig2, *blob1;
 
1076
                UINT32 len1;
 
1077
                TPM_AUTH *auth1, *auth2;
 
1078
 
 
1079
                dig1 = va_arg(ap, BYTE *);
 
1080
                dig2 = va_arg(ap, BYTE *);
 
1081
                len1 = va_arg(ap, UINT32);
 
1082
                blob1 = va_arg(ap, BYTE *);
 
1083
                auth1 = va_arg(ap, TPM_AUTH *);
 
1084
                auth2 = va_arg(ap, TPM_AUTH *);
 
1085
                va_end(ap);
 
1086
 
 
1087
                if (!dig1 || !dig2 || !blob1 || !auth2) {
 
1088
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1089
                        break;
 
1090
                }
 
1091
 
 
1092
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1093
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, dig1);
 
1094
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, dig2);
 
1095
                LoadBlob(outOffset, len1, out_blob, blob1);
 
1096
                if (auth1) {
 
1097
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1098
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1099
                        LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
 
1100
                } else {
 
1101
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1102
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1103
                }
 
1104
 
 
1105
                result = TSS_SUCCESS;
 
1106
                break;
 
1107
        }
 
1108
        /* 3 UINT32's, 1 BLOB, 1 optional AUTH */
 
1109
        case TPM_ORD_NV_WriteValue:
 
1110
        case TPM_ORD_NV_WriteValueAuth:
 
1111
        case TPM_ORD_Delegate_Manage:
 
1112
        {
 
1113
                UINT32 i = va_arg(ap, UINT32);
 
1114
                UINT32 j = va_arg(ap, UINT32);
 
1115
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1116
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1117
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1118
                va_end(ap);
 
1119
 
 
1120
                if (!in_blob1) {
 
1121
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1122
                        break;
 
1123
                }
 
1124
 
 
1125
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1126
                LoadBlob_UINT32(outOffset, i, out_blob);
 
1127
                LoadBlob_UINT32(outOffset, j, out_blob);
 
1128
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1129
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1130
                if (auth1) {
 
1131
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1132
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1133
                } else {
 
1134
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1135
                }
 
1136
 
 
1137
                result = TSS_SUCCESS;
 
1138
                break;
 
1139
        }
 
1140
        /* 3 UINT32's, 1 optional AUTH */
 
1141
        case TPM_ORD_NV_ReadValue:
 
1142
        case TPM_ORD_NV_ReadValueAuth:
 
1143
        case TPM_ORD_SetRedirection:
 
1144
        {
 
1145
                UINT32 i = va_arg(ap, UINT32);
 
1146
                UINT32 j = va_arg(ap, UINT32);
 
1147
                UINT32 k = va_arg(ap, UINT32);
 
1148
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1149
                va_end(ap);
 
1150
 
 
1151
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1152
                LoadBlob_UINT32(outOffset, i, out_blob);
 
1153
                LoadBlob_UINT32(outOffset, j, out_blob);
 
1154
                LoadBlob_UINT32(outOffset, k, out_blob);
 
1155
                if (auth1) {
 
1156
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1157
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1158
                } else {
 
1159
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1160
                }
 
1161
 
 
1162
                result = TSS_SUCCESS;
 
1163
                break;
 
1164
        }
 
1165
        /* 1 20 byte value, 1 UINT32, 1 BLOB */
 
1166
        case TPM_ORD_CreateEndorsementKeyPair:
 
1167
        {
 
1168
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1169
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1170
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1171
                va_end(ap);
 
1172
 
 
1173
                if (!digest1 || !in_blob1) {
 
1174
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1175
                        break;
 
1176
                }
 
1177
 
 
1178
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1179
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1180
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1181
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1182
 
 
1183
                result = TSS_SUCCESS;
 
1184
                break;
 
1185
        }
 
1186
        /* 1 20 byte value, 1 UINT32, 1 BLOB, 1 BOOL, 1 20 byte value */
 
1187
        case TPM_ORD_CreateRevocableEK:
 
1188
        {
 
1189
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1190
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1191
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1192
                TSS_BOOL in_bool1 = va_arg(ap, int);
 
1193
                BYTE *digest2 = va_arg(ap, BYTE *);
 
1194
                va_end(ap);
 
1195
 
 
1196
                if (!digest1 || !in_blob1 || !digest2) {
 
1197
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1198
                        break;
 
1199
                }
 
1200
 
 
1201
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1202
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1203
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1204
                LoadBlob_BOOL(outOffset, in_bool1, out_blob);
 
1205
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
 
1206
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1207
 
 
1208
                result = TSS_SUCCESS;
 
1209
                break;
 
1210
        }
 
1211
        /* 1 20 byte value */
 
1212
        case TPM_ORD_RevokeTrust:
 
1213
        {
 
1214
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1215
                va_end(ap);
 
1216
 
 
1217
                if (!digest1) {
 
1218
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1219
                        break;
 
1220
                }
 
1221
 
 
1222
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1223
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1224
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1225
 
 
1226
                result = TSS_SUCCESS;
 
1227
                break;
 
1228
        }
 
1229
        /* 1 20 byte value, 1 UINT32, 1 BLOB, 1 AUTH */
 
1230
        case TPM_ORD_CreateCounter:
 
1231
        {
 
1232
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1233
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1234
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1235
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1236
                va_end(ap);
 
1237
 
 
1238
                if (!digest1 || !in_blob1 || !auth1) {
 
1239
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1240
                        break;
 
1241
                }
 
1242
 
 
1243
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1244
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1245
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1246
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1247
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1248
 
 
1249
                result = TSS_SUCCESS;
 
1250
                break;
 
1251
        }
 
1252
        /* 1 UINT32, 1 BYTE, 1 UINT32, 1 BLOB, 1 UINT32, 1 BLOB, 1 AUTH */
 
1253
        case TPM_ORD_DAA_Sign:
 
1254
        case TPM_ORD_DAA_Join:
 
1255
        {
 
1256
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1257
                BYTE stage1 = va_arg(ap, int);
 
1258
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1259
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1260
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1261
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1262
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1263
                va_end(ap);
 
1264
 
 
1265
                if (!keySlot1 || !in_blob1 || !auth1) {
 
1266
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1267
                        break;
 
1268
                }
 
1269
 
 
1270
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1271
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1272
                LoadBlob_BOOL(outOffset, stage1, out_blob);
 
1273
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1274
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1275
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
1276
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1277
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1278
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1279
 
 
1280
                result = TSS_SUCCESS;
 
1281
                break;
 
1282
        }
 
1283
        /* 2 UINT32's, 1 BLOB, 1 UINT32, 1 BLOB, 1 optional AUTH */
 
1284
        case TPM_ORD_ConvertMigrationBlob:
 
1285
        case TPM_ORD_SetCapability:
 
1286
        {
 
1287
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1288
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1289
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1290
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1291
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1292
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1293
                va_end(ap);
 
1294
 
 
1295
                if (!keySlot1 || !in_blob1 || !in_blob2) {
 
1296
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1297
                        break;
 
1298
                }
 
1299
 
 
1300
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1301
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1302
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1303
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1304
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
1305
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1306
                if (auth1) {
 
1307
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1308
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1309
                } else {
 
1310
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1311
                }
 
1312
 
 
1313
                result = TSS_SUCCESS;
 
1314
                break;
 
1315
        }
 
1316
        /* 2 UINT32's, 1 20 byte value, 2 optional AUTHs */
 
1317
        case TPM_ORD_CertifyKey:
 
1318
        {
 
1319
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1320
                UINT32 keySlot2 = va_arg(ap, UINT32);
 
1321
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1322
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1323
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
1324
                va_end(ap);
 
1325
 
 
1326
                if (!keySlot1 || !keySlot2 || !digest1) {
 
1327
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1328
                        break;
 
1329
                }
 
1330
 
 
1331
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1332
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1333
                LoadBlob_UINT32(outOffset, keySlot2, out_blob);
 
1334
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1335
                if (auth1 && auth2) {
 
1336
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1337
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1338
                        LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
 
1339
                } else if (auth1) {
 
1340
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1341
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1342
                } else if (auth2) {
 
1343
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1344
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1345
                } else {
 
1346
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1347
                }
 
1348
 
 
1349
                result = TSS_SUCCESS;
 
1350
                break;
 
1351
        }
 
1352
        /* 2 UINT32's, 1 BLOB, 1 optional AUTH */
 
1353
        case TPM_ORD_Delegate_LoadOwnerDelegation:
 
1354
        case TPM_ORD_GetCapability:
 
1355
        case TPM_ORD_UnBind:
 
1356
        case TPM_ORD_Sign:
 
1357
        {
 
1358
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1359
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1360
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1361
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1362
                va_end(ap);
 
1363
 
 
1364
                if (in_len1 && !in_blob1) {
 
1365
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1366
                        break;
 
1367
                }
 
1368
 
 
1369
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1370
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1371
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1372
                if (in_len1)
 
1373
                        LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1374
                if (auth1) {
 
1375
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1376
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1377
                } else {
 
1378
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1379
                }
 
1380
 
 
1381
                result = TSS_SUCCESS;
 
1382
                break;
 
1383
        }
 
1384
        /* 1 UINT32, 1 20 byte value, 1 UINT32, 1 optional BLOB, 1 UINT32, 1 BLOB, 1 AUTH */
 
1385
        case TPM_ORD_Seal:
 
1386
        case TPM_ORD_Sealx:
 
1387
        {
 
1388
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1389
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1390
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1391
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1392
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1393
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1394
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1395
                va_end(ap);
 
1396
 
 
1397
                if (!keySlot1 || !in_blob2 || !auth1) {
 
1398
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1399
                        break;
 
1400
                }
 
1401
 
 
1402
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1403
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1404
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1405
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1406
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1407
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
1408
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1409
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1410
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1411
 
 
1412
                result = TSS_SUCCESS;
 
1413
                break;
 
1414
        }
 
1415
        /* 2 UINT32's, 1 BLOB, 1 optional AUTH, 1 AUTH */
 
1416
        case TPM_ORD_ActivateIdentity:
 
1417
        {
 
1418
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1419
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1420
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1421
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1422
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
1423
                va_end(ap);
 
1424
 
 
1425
                if (!keySlot1 || !in_blob1 || !auth2) {
 
1426
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1427
                        break;
 
1428
                }
 
1429
 
 
1430
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1431
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1432
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1433
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1434
                if (auth1) {
 
1435
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1436
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1437
                        LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
 
1438
                } else {
 
1439
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1440
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1441
                }
 
1442
 
 
1443
                result = TSS_SUCCESS;
 
1444
                break;
 
1445
        }
 
1446
        /* 1 UINT32, 1 20-byte blob, 1 BLOB, 1 optional AUTH */
 
1447
        case TPM_ORD_Quote:
 
1448
        {
 
1449
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1450
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1451
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1452
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1453
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1454
                va_end(ap);
 
1455
 
 
1456
                if (!keySlot1 || !digest1 || !in_blob1) {
 
1457
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1458
                        break;
 
1459
                }
 
1460
 
 
1461
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1462
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1463
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1464
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1465
 
 
1466
                if (auth1) {
 
1467
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1468
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1469
                } else
 
1470
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1471
 
 
1472
                result = TSS_SUCCESS;
 
1473
                break;
 
1474
        }
 
1475
        /* 1 UINT32, 1 20-byte blob, 1 BLOB, 1 BOOL, 1 optional AUTH */
 
1476
        case TPM_ORD_Quote2:
 
1477
        {
 
1478
                /* Input vars */
 
1479
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1480
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1481
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1482
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1483
                TSS_BOOL* addVersion = va_arg(ap,TSS_BOOL *);
 
1484
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1485
                va_end(ap);
 
1486
 
 
1487
                if (!keySlot1 || !digest1 || !in_blob1 || !addVersion) {
 
1488
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1489
                        break;
 
1490
                }
 
1491
 
 
1492
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1493
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1494
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1495
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1496
 
 
1497
                /* Load the addVersion Bool */
 
1498
                LoadBlob_BOOL(outOffset,*addVersion,out_blob);
 
1499
 
 
1500
                if (auth1) {
 
1501
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1502
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1503
                } else
 
1504
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1505
 
 
1506
                result = TSS_SUCCESS;
 
1507
                break;
 
1508
        }
 
1509
        /* 1 UINT32, 2 20-byte blobs, 1 BLOB, 1 optional AUTH */
 
1510
        case TPM_ORD_CreateWrapKey:
 
1511
        {
 
1512
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1513
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1514
                BYTE *digest2 = va_arg(ap, BYTE *);
 
1515
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1516
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1517
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1518
                va_end(ap);
 
1519
 
 
1520
                if (!keySlot1 || !digest1 || !digest2 || !in_blob1) {
 
1521
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1522
                        break;
 
1523
                }
 
1524
 
 
1525
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1526
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1527
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1528
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
 
1529
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1530
                if (auth1) {
 
1531
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1532
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1533
                } else
 
1534
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1535
 
 
1536
                result = TSS_SUCCESS;
 
1537
                break;
 
1538
        }
 
1539
        /* 2 BLOBs, 1 optional AUTH */
 
1540
        case TPM_ORD_NV_DefineSpace:
 
1541
        case TPM_ORD_LoadManuMaintPub:
 
1542
        {
 
1543
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1544
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1545
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1546
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1547
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1548
                va_end(ap);
 
1549
 
 
1550
                if (!in_blob1 || !in_blob2) {
 
1551
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1552
                        break;
 
1553
                }
 
1554
 
 
1555
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1556
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1557
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1558
                if (auth1) {
 
1559
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1560
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1561
                } else {
 
1562
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1563
                }
 
1564
 
 
1565
                result = TSS_SUCCESS;
 
1566
                break;
 
1567
        }
 
1568
        /* 1 UINT32, 2 20-byte blobs, 1 optional AUTH */
 
1569
        case TPM_ORD_TickStampBlob:
 
1570
        {
 
1571
                UINT32 keySlot1 = va_arg(ap, UINT32);
 
1572
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1573
                BYTE *digest2 = va_arg(ap, BYTE *);
 
1574
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1575
                va_end(ap);
 
1576
 
 
1577
                if (!keySlot1 || !digest1 || !digest2) {
 
1578
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1579
                        break;
 
1580
                }
 
1581
 
 
1582
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1583
                LoadBlob_UINT32(outOffset, keySlot1, out_blob);
 
1584
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1585
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
 
1586
 
 
1587
                if (auth1) {
 
1588
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1589
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1590
                } else
 
1591
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1592
 
 
1593
                result = TSS_SUCCESS;
 
1594
                break;
 
1595
        }
 
1596
        /* 1 BLOB */
 
1597
        case TPM_ORD_ReadManuMaintPub:
 
1598
        case TPM_ORD_ReadPubek:
 
1599
        case TPM_ORD_PCR_Reset:
 
1600
        case TPM_ORD_SetOperatorAuth:
 
1601
        {
 
1602
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1603
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1604
                va_end(ap);
 
1605
 
 
1606
                if (!in_blob1) {
 
1607
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1608
                        break;
 
1609
                }
 
1610
 
 
1611
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1612
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1613
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1614
 
 
1615
                result = TSS_SUCCESS;
 
1616
                break;
 
1617
        }
 
1618
        /* 1 UINT32, 1 BLOB, 2 optional AUTHs */
 
1619
        case TPM_ORD_LoadKey:
 
1620
        case TPM_ORD_LoadKey2:
 
1621
        case TPM_ORD_DirWriteAuth:
 
1622
        case TPM_ORD_CertifySelfTest:
 
1623
        case TPM_ORD_Unseal:
 
1624
        case TPM_ORD_Extend:
 
1625
        case TPM_ORD_StirRandom:
 
1626
        case TPM_ORD_LoadMaintenanceArchive: /* XXX */
 
1627
        case TPM_ORD_FieldUpgrade:
 
1628
        case TPM_ORD_Delegate_UpdateVerification:
 
1629
        case TPM_ORD_Delegate_VerifyDelegation:
 
1630
        {
 
1631
                UINT32 val1 = va_arg(ap, UINT32);
 
1632
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1633
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1634
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1635
                TPM_AUTH *auth2 = va_arg(ap, TPM_AUTH *);
 
1636
                va_end(ap);
 
1637
 
 
1638
                if (in_len1 && !in_blob1) {
 
1639
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1640
                        break;
 
1641
                }
 
1642
 
 
1643
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1644
                LoadBlob_UINT32(outOffset, val1, out_blob);
 
1645
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1646
                if (auth1 && auth2) {
 
1647
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1648
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1649
                        LoadBlob_Header(TPM_TAG_RQU_AUTH2_COMMAND, *outOffset, ordinal, out_blob);
 
1650
                } else if (auth1) {
 
1651
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1652
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1653
                } else if (auth2) {
 
1654
                        LoadBlob_Auth(outOffset, out_blob, auth2);
 
1655
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1656
                } else {
 
1657
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1658
                }
 
1659
 
 
1660
                result = TSS_SUCCESS;
 
1661
                break;
 
1662
        }
 
1663
        /* 1 UINT16, 1 BLOB, 1 AUTH */
 
1664
        case TPM_ORD_AuthorizeMigrationKey:
 
1665
        {
 
1666
                UINT16 scheme1 = va_arg(ap, int);
 
1667
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1668
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1669
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1670
                va_end(ap);
 
1671
 
 
1672
                if (!in_blob1 || !auth1) {
 
1673
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1674
                        break;
 
1675
                }
 
1676
 
 
1677
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1678
                LoadBlob_UINT16(outOffset, scheme1, out_blob);
 
1679
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1680
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1681
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1682
 
 
1683
                result = TSS_SUCCESS;
 
1684
                break;
 
1685
        }
 
1686
        /* 1 UINT16, 1 UINT32, 1 BLOB, 1 UINT32, 2 BLOBs, 1 AUTH */
 
1687
        case TPM_ORD_TakeOwnership:
 
1688
        {
 
1689
                UINT16 scheme1 = va_arg(ap, int);
 
1690
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1691
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1692
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1693
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1694
                UINT32 in_len3 = va_arg(ap, UINT32);
 
1695
                BYTE *in_blob3 = va_arg(ap, BYTE *);
 
1696
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1697
                va_end(ap);
 
1698
 
 
1699
                if (!in_blob1 || !in_blob2 || !in_blob3 || !auth1) {
 
1700
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1701
                        break;
 
1702
                }
 
1703
 
 
1704
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1705
                LoadBlob_UINT16(outOffset, scheme1, out_blob);
 
1706
                LoadBlob_UINT32(outOffset, in_len1, out_blob);
 
1707
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1708
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
1709
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1710
                LoadBlob(outOffset, in_len3, out_blob, in_blob3);
 
1711
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1712
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1713
 
 
1714
                result = TSS_SUCCESS;
 
1715
                break;
 
1716
        }
 
1717
        /* 1 UINT32, 1 BOOL, 1 20 byte value, 1 optional AUTH */
 
1718
        case TPM_ORD_GetAuditDigestSigned:
 
1719
        {
 
1720
                UINT32 keyslot1 = va_arg(ap, UINT32);
 
1721
                TSS_BOOL bool1 = va_arg(ap, int);
 
1722
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1723
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1724
                va_end(ap);
 
1725
 
 
1726
                if (!digest1) {
 
1727
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1728
                        break;
 
1729
                }
 
1730
 
 
1731
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1732
                LoadBlob_UINT32(outOffset, keyslot1, out_blob);
 
1733
                LoadBlob_BOOL(outOffset, bool1, out_blob);
 
1734
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1735
 
 
1736
                if (auth1) {
 
1737
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1738
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1739
                } else {
 
1740
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1741
                }
 
1742
 
 
1743
                result = TSS_SUCCESS;
 
1744
                break;
 
1745
        }
 
1746
        /* 1 UINT16, 1 UINT32, 1 20 byte value */
 
1747
        case TPM_ORD_OSAP:
 
1748
        {
 
1749
                UINT16 type1 = va_arg(ap, int);
 
1750
                UINT32 value1 = va_arg(ap, UINT32);
 
1751
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1752
                va_end(ap);
 
1753
 
 
1754
                if (!digest1) {
 
1755
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1756
                        break;
 
1757
                }
 
1758
 
 
1759
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1760
                LoadBlob_UINT16(outOffset, type1, out_blob);
 
1761
                LoadBlob_UINT32(outOffset, value1, out_blob);
 
1762
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1763
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1764
 
 
1765
                result = TSS_SUCCESS;
 
1766
                break;
 
1767
        }
 
1768
        /* 1 UINT16, 1 20 byte value, 1 UINT16, 1 AUTH */
 
1769
        case TPM_ORD_ChangeAuthOwner:
 
1770
        {
 
1771
                UINT16 type1 = va_arg(ap, int);
 
1772
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1773
                UINT16 type2 = va_arg(ap, int);
 
1774
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1775
                va_end(ap);
 
1776
 
 
1777
                if (!digest1 || !auth1) {
 
1778
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1779
                        break;
 
1780
                }
 
1781
 
 
1782
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1783
                LoadBlob_UINT16(outOffset, type1, out_blob);
 
1784
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1785
                LoadBlob_UINT16(outOffset, type2, out_blob);
 
1786
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1787
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1788
 
 
1789
                result = TSS_SUCCESS;
 
1790
                break;
 
1791
        }
 
1792
        /* 1 UINT32, 1 BOOL, 1 AUTH */
 
1793
        case TPM_ORD_SetOrdinalAuditStatus:
 
1794
        {
 
1795
                UINT32 ord1 = va_arg(ap, UINT32);
 
1796
                TSS_BOOL bool1 = va_arg(ap, int);
 
1797
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1798
                va_end(ap);
 
1799
 
 
1800
                if (!auth1) {
 
1801
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1802
                        break;
 
1803
                }
 
1804
 
 
1805
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1806
                LoadBlob_UINT32(outOffset, ord1, out_blob);
 
1807
                LoadBlob_BOOL(outOffset, bool1, out_blob);
 
1808
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
1809
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1810
 
 
1811
                result = TSS_SUCCESS;
 
1812
                break;
 
1813
        }
 
1814
        /* 1 BOOL, 1 optional AUTH */
 
1815
        case TPM_ORD_OwnerSetDisable:
 
1816
        case TPM_ORD_PhysicalSetDeactivated:
 
1817
        case TPM_ORD_CreateMaintenanceArchive:
 
1818
        case TPM_ORD_SetOwnerInstall:
 
1819
        {
 
1820
                TSS_BOOL bool1 = va_arg(ap, int);
 
1821
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1822
                va_end(ap);
 
1823
 
 
1824
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1825
                LoadBlob_BOOL(outOffset, bool1, out_blob);
 
1826
                if (auth1) {
 
1827
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1828
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1829
                } else {
 
1830
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1831
                }
 
1832
 
 
1833
                result = TSS_SUCCESS;
 
1834
                break;
 
1835
        }
 
1836
        /* 1 optional AUTH */
 
1837
        case TPM_ORD_OwnerClear:
 
1838
        case TPM_ORD_DisablePubekRead:
 
1839
        case TPM_ORD_GetCapabilityOwner:
 
1840
        case TPM_ORD_ResetLockValue:
 
1841
        case TPM_ORD_DisableOwnerClear:
 
1842
        case TPM_ORD_SetTempDeactivated:
 
1843
        case TPM_ORD_OIAP:
 
1844
        case TPM_ORD_OwnerReadPubek:
 
1845
        case TPM_ORD_SelfTestFull:
 
1846
        case TPM_ORD_GetTicks:
 
1847
        case TPM_ORD_GetTestResult:
 
1848
        case TPM_ORD_KillMaintenanceFeature:
 
1849
        case TPM_ORD_Delegate_ReadTable:
 
1850
        case TPM_ORD_PhysicalEnable:
 
1851
        case TPM_ORD_DisableForceClear:
 
1852
        case TPM_ORD_ForceClear:
 
1853
        {
 
1854
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1855
                va_end(ap);
 
1856
 
 
1857
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1858
                if (auth1) {
 
1859
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1860
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1861
                } else {
 
1862
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1863
                }
 
1864
 
 
1865
                result = TSS_SUCCESS;
 
1866
                break;
 
1867
        }
 
1868
        /* 1 UINT32, 1 optional AUTH */
 
1869
        case TPM_ORD_OwnerReadInternalPub:
 
1870
        case TPM_ORD_GetPubKey:
 
1871
        case TPM_ORD_ReleaseCounterOwner:
 
1872
        case TPM_ORD_ReleaseCounter:
 
1873
        case TPM_ORD_IncrementCounter:
 
1874
        case TPM_ORD_PcrRead:
 
1875
        case TPM_ORD_DirRead:
 
1876
        case TPM_ORD_ReadCounter:
 
1877
        case TPM_ORD_Terminate_Handle:
 
1878
        case TPM_ORD_GetAuditDigest:
 
1879
        case TPM_ORD_GetRandom:
 
1880
        case TPM_ORD_CMK_SetRestrictions:
 
1881
        {
 
1882
                UINT32 i = va_arg(ap, UINT32);
 
1883
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1884
                va_end(ap);
 
1885
 
 
1886
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1887
                LoadBlob_UINT32(outOffset, i, out_blob);
 
1888
                if (auth1) {
 
1889
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1890
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1891
                } else {
 
1892
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1893
                }
 
1894
 
 
1895
                result = TSS_SUCCESS;
 
1896
                break;
 
1897
        }
 
1898
        /* 1 20 byte value, 1 optional AUTH */
 
1899
        case TPM_ORD_CMK_ApproveMA:
 
1900
        {
 
1901
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1902
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1903
                va_end(ap);
 
1904
 
 
1905
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1906
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1907
                if (auth1) {
 
1908
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1909
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1910
                } else {
 
1911
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1912
                }
 
1913
 
 
1914
                result = TSS_SUCCESS;
 
1915
                break;
 
1916
        }
 
1917
        /* 1 UINT16 only */
 
1918
        case TSC_ORD_PhysicalPresence:
 
1919
        {
 
1920
                UINT16 i = va_arg(ap, int);
 
1921
                va_end(ap);
 
1922
 
 
1923
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1924
                LoadBlob_UINT16(outOffset, i, out_blob);
 
1925
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1926
 
 
1927
                result = TSS_SUCCESS;
 
1928
                break;
 
1929
        }
 
1930
        /* 1 UINT32, 1 20 byte value, 1 BLOB, 2 20 byte values, 1 optional AUTH */
 
1931
        case TPM_ORD_CMK_CreateKey:
 
1932
        {
 
1933
                UINT32 key1 = va_arg(ap, UINT32);
 
1934
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1935
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1936
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1937
                BYTE *digest2 = va_arg(ap, BYTE *);
 
1938
                BYTE *digest3 = va_arg(ap, BYTE *);
 
1939
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1940
                va_end(ap);
 
1941
 
 
1942
                if (!digest1 || !in_blob1 || !digest2 || !digest3) {
 
1943
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1944
                        break;
 
1945
                }
 
1946
 
 
1947
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1948
                LoadBlob_UINT32(outOffset, key1, out_blob);
 
1949
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1950
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1951
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest2);
 
1952
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest3);
 
1953
                if (auth1) {
 
1954
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1955
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1956
                } else {
 
1957
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1958
                }
 
1959
 
 
1960
                result = TSS_SUCCESS;
 
1961
                break;
 
1962
        }
 
1963
        /* 1 BLOB, 1 20 byte value, 1 UINT32, 1 BLOB, 1 optional AUTH */
 
1964
        case TPM_ORD_CMK_CreateTicket:
 
1965
        {
 
1966
                UINT32 in_len1 = va_arg(ap, UINT32);
 
1967
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
1968
                BYTE *digest1 = va_arg(ap, BYTE *);
 
1969
                UINT32 in_len2 = va_arg(ap, UINT32);
 
1970
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
1971
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
1972
                va_end(ap);
 
1973
 
 
1974
                if (!digest1 || !in_blob1 || !in_blob2) {
 
1975
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
1976
                        break;
 
1977
                }
 
1978
 
 
1979
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
1980
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
1981
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
1982
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
1983
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
1984
                if (auth1) {
 
1985
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
1986
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
1987
                } else {
 
1988
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
1989
                }
 
1990
 
 
1991
                result = TSS_SUCCESS;
 
1992
                break;
 
1993
        }
 
1994
        /* 1 UINT32, 1 UINT16, 1 BLOB, 1 20 byte value, 4 x (1 UINT32, 1 BLOB), 1 optional AUTH */
 
1995
        case TPM_ORD_CMK_CreateBlob:
 
1996
        {
 
1997
                UINT32 in_key1 = va_arg(ap, UINT32);
 
1998
                UINT16 i = va_arg(ap, int);
 
1999
                UINT32 in_len1 = va_arg(ap, UINT32);
 
2000
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
2001
                BYTE *digest1 = va_arg(ap, BYTE *);
 
2002
                UINT32 in_len2 = va_arg(ap, UINT32);
 
2003
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
2004
                UINT32 in_len3 = va_arg(ap, UINT32);
 
2005
                BYTE *in_blob3 = va_arg(ap, BYTE *);
 
2006
                UINT32 in_len4 = va_arg(ap, UINT32);
 
2007
                BYTE *in_blob4 = va_arg(ap, BYTE *);
 
2008
                UINT32 in_len5 = va_arg(ap, UINT32);
 
2009
                BYTE *in_blob5 = va_arg(ap, BYTE *);
 
2010
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
2011
                va_end(ap);
 
2012
 
 
2013
                if (!digest1 || !in_blob1 || !in_blob2 || !in_blob3 || !in_blob4 || !in_blob5) {
 
2014
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
2015
                        break;
 
2016
                }
 
2017
 
 
2018
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
2019
                LoadBlob_UINT32(outOffset, in_key1, out_blob);
 
2020
                LoadBlob_UINT16(outOffset, i, out_blob);
 
2021
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
2022
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
2023
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
2024
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
2025
                LoadBlob_UINT32(outOffset, in_len3, out_blob);
 
2026
                LoadBlob(outOffset, in_len3, out_blob, in_blob3);
 
2027
                LoadBlob_UINT32(outOffset, in_len4, out_blob);
 
2028
                LoadBlob(outOffset, in_len4, out_blob, in_blob4);
 
2029
                LoadBlob_UINT32(outOffset, in_len5, out_blob);
 
2030
                LoadBlob(outOffset, in_len5, out_blob, in_blob5);
 
2031
                if (auth1) {
 
2032
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
2033
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
2034
                } else {
 
2035
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
2036
                }
 
2037
 
 
2038
                result = TSS_SUCCESS;
 
2039
                break;
 
2040
        }
 
2041
        /* 1 UINT32, 1 60 byte value, 1 20 byte value, 1 BLOB, 2 x (1 UINT32, 1 BLOB), 1 optional AUTH */
 
2042
        case TPM_ORD_CMK_ConvertMigration:
 
2043
        {
 
2044
                UINT32 key1 = va_arg(ap, UINT32);
 
2045
                BYTE *cmkauth1 = va_arg(ap, BYTE *);
 
2046
                BYTE *digest1 = va_arg(ap, BYTE *);
 
2047
                UINT32 in_len1 = va_arg(ap, UINT32);
 
2048
                BYTE *in_blob1 = va_arg(ap, BYTE *);
 
2049
                UINT32 in_len2 = va_arg(ap, UINT32);
 
2050
                BYTE *in_blob2 = va_arg(ap, BYTE *);
 
2051
                UINT32 in_len3 = va_arg(ap, UINT32);
 
2052
                BYTE *in_blob3 = va_arg(ap, BYTE *);
 
2053
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
2054
                va_end(ap);
 
2055
 
 
2056
                if (!cmkauth1 || !digest1 || !in_blob1 || !in_blob2 || !in_blob3) {
 
2057
                        LogError("Internal error for ordinal 0x%x", ordinal);
 
2058
                        break;
 
2059
                }
 
2060
 
 
2061
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
2062
                LoadBlob_UINT32(outOffset, key1, out_blob);
 
2063
                LoadBlob(outOffset, 3 * TPM_SHA1_160_HASH_LEN, out_blob, cmkauth1);
 
2064
                LoadBlob(outOffset, TPM_SHA1_160_HASH_LEN, out_blob, digest1);
 
2065
                LoadBlob(outOffset, in_len1, out_blob, in_blob1);
 
2066
                LoadBlob_UINT32(outOffset, in_len2, out_blob);
 
2067
                LoadBlob(outOffset, in_len2, out_blob, in_blob2);
 
2068
                LoadBlob_UINT32(outOffset, in_len3, out_blob);
 
2069
                LoadBlob(outOffset, in_len3, out_blob, in_blob3);
 
2070
                if (auth1) {
 
2071
                        LoadBlob_Auth(outOffset, out_blob, auth1);
 
2072
                        LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
2073
                } else {
 
2074
                        LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
2075
                }
 
2076
 
 
2077
                result = TSS_SUCCESS;
 
2078
                break;
 
2079
        }
 
2080
        case TPM_ORD_FlushSpecific:
 
2081
        {
 
2082
                UINT32 val1 = va_arg(ap, UINT32);
 
2083
                UINT32 val2 = va_arg(ap, UINT32);
 
2084
                va_end(ap);
 
2085
 
 
2086
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
2087
                LoadBlob_UINT32(outOffset, val1, out_blob);
 
2088
                LoadBlob_UINT32(outOffset, val2, out_blob);
 
2089
                LoadBlob_Header(TPM_TAG_RQU_COMMAND, *outOffset, ordinal, out_blob);
 
2090
 
 
2091
                result = TSS_SUCCESS;
 
2092
                break;
 
2093
        }
 
2094
        /* 1 UINT32, 1 BLOB, 1 UINT32, 1 BOOL, 1 AUTH */
 
2095
        case TPM_ORD_KeyControlOwner:
 
2096
        {
 
2097
                UINT32 i = va_arg(ap, UINT32);
 
2098
                UINT32 len1 = va_arg(ap, UINT32);
 
2099
                BYTE *blob1 = va_arg(ap, BYTE *);
 
2100
                UINT32 j = va_arg(ap, UINT32);
 
2101
                TSS_BOOL bool1 = va_arg(ap, int);
 
2102
                TPM_AUTH *auth1 = va_arg(ap, TPM_AUTH *);
 
2103
                va_end(ap);
 
2104
 
 
2105
                *outOffset += TSS_TPM_TXBLOB_HDR_LEN;
 
2106
                LoadBlob_UINT32(outOffset, i, out_blob);
 
2107
                LoadBlob(outOffset, len1, out_blob, blob1);
 
2108
                LoadBlob_UINT32(outOffset, j, out_blob);
 
2109
                LoadBlob_BOOL(outOffset, bool1, out_blob);
 
2110
                LoadBlob_Auth(outOffset, out_blob, auth1);
 
2111
                LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, *outOffset, ordinal, out_blob);
 
2112
 
 
2113
                result = TSS_SUCCESS;
 
2114
                break;
 
2115
        }
 
2116
        default:
 
2117
                LogError("Unknown ordinal: 0x%x", ordinal);
 
2118
                break;
 
2119
        }
 
2120
 
 
2121
        return result;
 
2122
}