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