blob: 882562b09dac51791baeb7d537eb58b094b54c41 [file] [log] [blame]
Kees Cookf0605cb2012-02-29 16:09:14 -08001/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Randall Spangler39f66112010-07-14 09:10:23 -07002 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6/* This program generates partially filled TPM datagrams and other compile-time
7 * constants (e.g. structure sizes and offsets). Compile this file---and ONLY
8 * this file---with -fpack-struct. We take advantage of the fact that the
9 * (packed) TPM structures layout (mostly) match the TPM request and response
10 * datagram layout. When they don't completely match, some fixing is necessary
11 * (see PCR_SELECTION_FIX below).
12 */
13
Gaurav Shah553d00e2010-07-19 19:22:10 -070014#include <assert.h>
Randall Spangler39f66112010-07-14 09:10:23 -070015#include <stddef.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <tss/tcs.h>
19
Luigi Semenzato5896b962010-08-25 07:16:03 -070020#include "sysincludes.h"
Randall Spangler39f66112010-07-14 09:10:23 -070021#include "tlcl_internal.h"
22#include "tpmextras.h"
Randall Spangler39f66112010-07-14 09:10:23 -070023
24/* See struct Command below. This structure represent a field in a TPM
25 * command. [name] is the field name. [visible] is 1 if the field is
26 * modified by the run-time. Non-visible fields are initialized at build time
27 * and remain constant. [size] is the field size in bytes. [value] is the
28 * fixed value of non-visible fields.
29 */
30typedef struct Field {
31 const char* name;
32 int visible;
33 int offset;
34 int size;
35 uint32_t value; /* large enough for all initializers */
36 struct Field* next;
37} Field;
38
39/* This structure is used to build (at build time) and manipulate (at firmware
40 * or emulation run time) buffers containing TPM datagrams. [name] is the name
41 * of a TPM command. [size] is the size of the command buffer in bytes, when
42 * known. [max_size] is the maximum size allowed for variable-length commands
43 * (such as Read and Write). [fields] is a link-list of command fields.
44 */
45typedef struct Command {
46 const char* name;
47 int size;
48 int max_size;
49 Field* fields;
50 struct Command* next;
51} Command;
52
53/* Adds a field to a command, and makes its offset visible. The fields must be
54 * added at increasing offsets.
55 */
56static void AddVisibleField(Command* cmd, const char* name, int offset) {
Luigi Semenzatod6acfd42013-01-08 16:23:11 -080057 Field* fld = (Field*) calloc(1, sizeof(Field));
Randall Spangler39f66112010-07-14 09:10:23 -070058 if (cmd->fields != NULL) {
Randall Spangler39f66112010-07-14 09:10:23 -070059 assert(offset > fn->offset);
60 }
61 fld->next = cmd->fields;
62 cmd->fields = fld;
63 fld->name = name;
64 fld->visible = 1;
65 fld->offset = offset;
66}
67
68/* Adds a constant field with its value. The fields must be added at
69 * increasing offsets.
70 */
71static void AddInitializedField(Command* cmd, int offset,
72 int size, uint32_t value) {
Luigi Semenzatod6acfd42013-01-08 16:23:11 -080073 Field* fld = (Field*) calloc(1, sizeof(Field));
Randall Spangler39f66112010-07-14 09:10:23 -070074 fld->next = cmd->fields;
75 cmd->fields = fld;
76 fld->name = NULL;
77 fld->visible = 0;
78 fld->size = size;
79 fld->offset = offset;
80 fld->value = value;
81}
82
83/* Create a structure representing a TPM command datagram.
84 */
85Command* newCommand(TPM_COMMAND_CODE code, int size) {
Luigi Semenzatod6acfd42013-01-08 16:23:11 -080086 Command* cmd = (Command*) calloc(1, sizeof(Command));
Randall Spangler39f66112010-07-14 09:10:23 -070087 cmd->size = size;
88 AddInitializedField(cmd, 0, sizeof(TPM_TAG), TPM_TAG_RQU_COMMAND);
89 AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size);
90 AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t),
91 sizeof(TPM_COMMAND_CODE), code);
92 return cmd;
93}
94
95/* The TPM_PCR_SELECTION structure in /usr/include/tss/tpm.h contains a pointer
96 * instead of an array[3] of bytes, so we need to adjust sizes and offsets
97 * accordingly.
98 */
99#define PCR_SELECTION_FIX (3 - sizeof(char *))
100
101/* BuildXXX builds TPM command XXX.
102 */
103Command* BuildDefineSpaceCommand(void) {
104 int nv_data_public = kTpmRequestHeaderLength;
105 int nv_index = nv_data_public + offsetof(TPM_NV_DATA_PUBLIC, nvIndex);
106 int nv_pcr_info_read = nv_data_public +
107 offsetof(TPM_NV_DATA_PUBLIC, pcrInfoRead);
108 /*
109 * Here we need to carefully add PCR_SELECTION_FIX (or twice that much) in
110 * all the places where the offset calculation would be wrong without it.
111 * The mismatch occurs in the TPM_PCR_SELECTION structure, and it must be
112 * accounted for in all the structures that include it, directly or
113 * indirectly.
114 */
115 int read_locality = nv_pcr_info_read +
116 offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
117 int nv_pcr_info_write = nv_data_public +
118 offsetof(TPM_NV_DATA_PUBLIC, pcrInfoWrite) + PCR_SELECTION_FIX;
119 int write_locality = nv_pcr_info_write +
120 offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
121 int nv_permission = nv_data_public +
122 offsetof(TPM_NV_DATA_PUBLIC, permission) + 2 * PCR_SELECTION_FIX;
123 int nv_permission_tag =
124 nv_permission + offsetof(TPM_NV_ATTRIBUTES, tag);
125 int nv_permission_attributes =
126 nv_permission + offsetof(TPM_NV_ATTRIBUTES, attributes);
127 int nv_datasize = nv_data_public +
128 offsetof(TPM_NV_DATA_PUBLIC, dataSize) + 2 * PCR_SELECTION_FIX;
129
130 int size = kTpmRequestHeaderLength + sizeof(TPM_NV_DATA_PUBLIC) +
131 2 * PCR_SELECTION_FIX + kEncAuthLength;
132 Command* cmd = newCommand(TPM_ORD_NV_DefineSpace, size);
133 cmd->name = "tpm_nv_definespace_cmd";
134
135 AddVisibleField(cmd, "index", nv_index);
136 AddVisibleField(cmd, "perm", nv_permission_attributes);
137 AddVisibleField(cmd, "size", nv_datasize);
138
139 AddInitializedField(cmd, nv_data_public, sizeof(uint16_t),
140 TPM_TAG_NV_DATA_PUBLIC);
141 AddInitializedField(cmd, nv_pcr_info_read, sizeof(uint16_t), 3);
142 AddInitializedField(cmd, read_locality, sizeof(TPM_LOCALITY_SELECTION),
143 TPM_ALL_LOCALITIES);
144 AddInitializedField(cmd, nv_pcr_info_write, sizeof(uint16_t), 3);
145 AddInitializedField(cmd, write_locality, sizeof(TPM_LOCALITY_SELECTION),
146 TPM_ALL_LOCALITIES);
147 AddInitializedField(cmd, nv_permission_tag, sizeof(TPM_STRUCTURE_TAG),
148 TPM_TAG_NV_ATTRIBUTES);
149 return cmd;
150}
151
152/* BuildXXX builds TPM command XXX.
153 */
154Command* BuildWriteCommand(void) {
155 Command* cmd = newCommand(TPM_ORD_NV_WriteValue, 0);
156 cmd->name = "tpm_nv_write_cmd";
157 cmd->max_size = TPM_LARGE_ENOUGH_COMMAND_SIZE;
158 AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
159 AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
160 AddVisibleField(cmd, "data", kTpmRequestHeaderLength + 12);
161 return cmd;
162}
163
164Command* BuildReadCommand(void) {
165 int size = kTpmRequestHeaderLength + kTpmReadInfoLength;
166 Command* cmd = newCommand(TPM_ORD_NV_ReadValue, size);
167 cmd->name = "tpm_nv_read_cmd";
168 AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
169 AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
170 return cmd;
171}
172
Kees Cook946370d2012-01-09 14:17:40 -0800173Command* BuildPCRReadCommand(void) {
174 int size = kTpmRequestHeaderLength + sizeof(uint32_t);
175 Command* cmd = newCommand(TPM_ORD_PcrRead, size);
176 cmd->name = "tpm_pcr_read_cmd";
177 AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
178 return cmd;
179}
180
Randall Spangler39f66112010-07-14 09:10:23 -0700181Command* BuildPPAssertCommand(void) {
182 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
183 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
184 cmd->name = "tpm_ppassert_cmd";
185 AddInitializedField(cmd, kTpmRequestHeaderLength,
186 sizeof(TPM_PHYSICAL_PRESENCE),
187 TPM_PHYSICAL_PRESENCE_PRESENT);
188 return cmd;
189}
190
Luigi Semenzato1d83dd12010-08-30 10:23:43 -0700191Command* BuildPPEnableCommand(void) {
192 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
193 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
194 cmd->name = "tpm_ppenable_cmd";
195 AddInitializedField(cmd, kTpmRequestHeaderLength,
196 sizeof(TPM_PHYSICAL_PRESENCE),
197 TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
198 return cmd;
199}
200
Luigi Semenzato377557f2010-08-31 13:20:53 -0700201Command* BuildFinalizePPCommand(void) {
202 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
203 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
204 cmd->name = "tpm_finalizepp_cmd";
205 AddInitializedField(cmd, kTpmRequestHeaderLength,
206 sizeof(TPM_PHYSICAL_PRESENCE),
207 TPM_PHYSICAL_PRESENCE_CMD_ENABLE |
208 TPM_PHYSICAL_PRESENCE_HW_DISABLE |
209 TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK);
210 return cmd;
211}
212
Randall Spangler39f66112010-07-14 09:10:23 -0700213Command* BuildPPLockCommand(void) {
214 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
215 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
216 cmd->name = "tpm_pplock_cmd";
217 AddInitializedField(cmd, kTpmRequestHeaderLength,
218 sizeof(TPM_PHYSICAL_PRESENCE),
219 TPM_PHYSICAL_PRESENCE_LOCK);
220 return cmd;
221}
222
223Command* BuildStartupCommand(void) {
Luigi Semenzato3da063e2010-08-31 14:31:30 -0700224 int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
Randall Spangler39f66112010-07-14 09:10:23 -0700225 Command* cmd = newCommand(TPM_ORD_Startup, size);
226 cmd->name = "tpm_startup_cmd";
227 AddInitializedField(cmd, kTpmRequestHeaderLength,
228 sizeof(TPM_STARTUP_TYPE),
229 TPM_ST_CLEAR);
230 return cmd;
231}
232
Luigi Semenzato54992f92011-03-16 10:56:48 -0700233Command* BuildSaveStateCommand(void) {
234 int size = kTpmRequestHeaderLength;
235 Command* cmd = newCommand(TPM_ORD_SaveState, size);
236 cmd->name = "tpm_savestate_cmd";
237 return cmd;
238}
239
Luigi Semenzato3da063e2010-08-31 14:31:30 -0700240Command* BuildResumeCommand(void) {
241 int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
242 Command* cmd = newCommand(TPM_ORD_Startup, size);
243 cmd->name = "tpm_resume_cmd";
244 AddInitializedField(cmd, kTpmRequestHeaderLength,
245 sizeof(TPM_STARTUP_TYPE),
246 TPM_ST_STATE);
247 return cmd;
248}
249
Randall Spangler39f66112010-07-14 09:10:23 -0700250Command* BuildSelftestfullCommand(void) {
251 int size = kTpmRequestHeaderLength;
252 Command* cmd = newCommand(TPM_ORD_SelfTestFull, size);
253 cmd->name = "tpm_selftestfull_cmd";
254 return cmd;
255}
256
257Command* BuildContinueSelfTestCommand(void) {
258 int size = kTpmRequestHeaderLength;
259 Command* cmd = newCommand(TPM_ORD_ContinueSelfTest, size);
260 cmd->name = "tpm_continueselftest_cmd";
261 return cmd;
262}
263
264Command* BuildReadPubekCommand(void) {
265 int size = kTpmRequestHeaderLength + sizeof(TPM_NONCE);
266 Command* cmd = newCommand(TPM_ORD_ReadPubek, size);
267 cmd->name = "tpm_readpubek_cmd";
268 return cmd;
269}
270
271Command* BuildForceClearCommand(void) {
272 int size = kTpmRequestHeaderLength;
273 Command* cmd = newCommand(TPM_ORD_ForceClear, size);
274 cmd->name = "tpm_forceclear_cmd";
275 return cmd;
276}
277
278Command* BuildPhysicalEnableCommand(void) {
279 int size = kTpmRequestHeaderLength;
280 Command* cmd = newCommand(TPM_ORD_PhysicalEnable, size);
281 cmd->name = "tpm_physicalenable_cmd";
282 return cmd;
283}
284
285Command* BuildPhysicalDisableCommand(void) {
286 int size = kTpmRequestHeaderLength;
287 Command* cmd = newCommand(TPM_ORD_PhysicalDisable, size);
288 cmd->name = "tpm_physicaldisable_cmd";
289 return cmd;
290}
291
292Command* BuildPhysicalSetDeactivatedCommand(void) {
293 int size = kTpmRequestHeaderLength + sizeof(uint8_t);
294 Command* cmd = newCommand(TPM_ORD_PhysicalSetDeactivated, size);
295 cmd->name = "tpm_physicalsetdeactivated_cmd";
296 AddVisibleField(cmd, "deactivated", kTpmRequestHeaderLength);
297 return cmd;
298}
299
300Command* BuildExtendCommand(void) {
301 int size = kTpmRequestHeaderLength + sizeof(uint32_t) + kPcrDigestLength;
302 Command* cmd = newCommand(TPM_ORD_Extend, size);
303 cmd->name = "tpm_extend_cmd";
304 AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
305 AddVisibleField(cmd, "inDigest", kTpmRequestHeaderLength + sizeof(uint32_t));
306 return cmd;
307}
308
309Command* BuildGetFlagsCommand(void) {
310 int size = (kTpmRequestHeaderLength +
311 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
312 sizeof(uint32_t) + /* subCapSize */
313 sizeof(uint32_t)); /* subCap */
314
315 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
316 cmd->name = "tpm_getflags_cmd";
317 AddInitializedField(cmd, kTpmRequestHeaderLength,
318 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
319 AddInitializedField(cmd, kTpmRequestHeaderLength +
320 sizeof(TPM_CAPABILITY_AREA),
321 sizeof(uint32_t), sizeof(uint32_t));
322 AddInitializedField(cmd, kTpmRequestHeaderLength +
323 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
324 sizeof(uint32_t), TPM_CAP_FLAG_PERMANENT);
325 return cmd;
326}
327
Luigi Semenzato5896b962010-08-25 07:16:03 -0700328Command* BuildGetSTClearFlagsCommand(void) {
329 int size = (kTpmRequestHeaderLength +
330 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
331 sizeof(uint32_t) + /* subCapSize */
332 sizeof(uint32_t)); /* subCap */
333
334 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
335 cmd->name = "tpm_getstclearflags_cmd";
336 AddInitializedField(cmd, kTpmRequestHeaderLength,
337 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
338 AddInitializedField(cmd, kTpmRequestHeaderLength +
339 sizeof(TPM_CAPABILITY_AREA),
340 sizeof(uint32_t), sizeof(uint32_t));
341 AddInitializedField(cmd, kTpmRequestHeaderLength +
342 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
343 sizeof(uint32_t), TPM_CAP_FLAG_VOLATILE);
344 return cmd;
345}
346
Randall Spangler39f66112010-07-14 09:10:23 -0700347Command* BuildGetPermissionsCommand(void) {
348 int size = (kTpmRequestHeaderLength +
349 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
350 sizeof(uint32_t) + /* subCapSize */
351 sizeof(uint32_t)); /* subCap */
352
353 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
354 cmd->name = "tpm_getpermissions_cmd";
355 AddInitializedField(cmd, kTpmRequestHeaderLength,
356 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_NV_INDEX);
357 AddInitializedField(cmd, kTpmRequestHeaderLength +
358 sizeof(TPM_CAPABILITY_AREA),
359 sizeof(uint32_t), sizeof(uint32_t));
360 AddVisibleField(cmd, "index", kTpmRequestHeaderLength +
361 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t));
362 return cmd;
363}
364
Kees Cook8b6da262012-06-07 13:48:26 -0700365Command* BuildGetOwnershipCommand(void) {
366 int size = (kTpmRequestHeaderLength +
367 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
368 sizeof(uint32_t) + /* subCapSize */
369 sizeof(uint32_t)); /* subCap */
370
371 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
372 cmd->name = "tpm_getownership_cmd";
373 AddInitializedField(cmd, kTpmRequestHeaderLength,
374 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_PROPERTY);
375 AddInitializedField(cmd, kTpmRequestHeaderLength +
376 sizeof(TPM_CAPABILITY_AREA),
377 sizeof(uint32_t), sizeof(uint32_t));
378 AddInitializedField(cmd, kTpmRequestHeaderLength +
379 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
380 sizeof(uint32_t), TPM_CAP_PROP_OWNER);
381 return cmd;
382}
383
Kees Cookf0605cb2012-02-29 16:09:14 -0800384Command* BuildGetRandomCommand(void) {
385 int size = kTpmRequestHeaderLength + sizeof(uint32_t);
386 Command* cmd = newCommand(TPM_ORD_GetRandom, size);
387 cmd->name = "tpm_get_random_cmd";
388 AddVisibleField(cmd, "bytesRequested", kTpmRequestHeaderLength);
389 return cmd;
390}
391
Randall Spangler39f66112010-07-14 09:10:23 -0700392/* Output the fields of a structure.
393 */
394void OutputFields(Field* fld) {
395 /*
396 * Field order is reversed.
397 */
398 if (fld != NULL) {
399 OutputFields(fld->next);
400 if (fld->visible) {
Gaurav Shah553d00e2010-07-19 19:22:10 -0700401 printf(" uint16_t %s;\n", fld->name);
Randall Spangler39f66112010-07-14 09:10:23 -0700402 }
403 }
404}
405
406/* Outputs a structure initializer.
407 */
408int OutputBytes_(Command* cmd, Field* fld) {
409 int cursor = 0;
410 int i;
411 /*
412 * Field order is reversed.
413 */
414 if (fld != NULL) {
415 cursor = OutputBytes_(cmd, fld->next);
416 } else {
417 return 0;
418 }
419 if (!fld->visible) {
420 /*
421 * Catch up missing fields.
422 */
423 assert(fld->offset >= cursor);
424 for (i = 0; i < fld->offset - cursor; i++) {
425 printf("0, ");
426 }
427 cursor = fld->offset;
428 switch (fld->size) {
429 case 1:
430 printf("0x%x, ", fld->value);
431 cursor += 1;
432 break;
433 case 2:
434 printf("0x%x, 0x%x, ", fld->value >> 8, fld->value & 0xff);
435 cursor += 2;
436 break;
437 case 4:
438 printf("0x%x, 0x%x, 0x%x, 0x%x, ", fld->value >> 24,
439 (fld->value >> 16) & 0xff,
440 (fld->value >> 8) & 0xff,
441 fld->value & 0xff);
442 cursor += 4;
443 break;
444 default:
Gaurav Shah553d00e2010-07-19 19:22:10 -0700445 fprintf(stderr, "invalid field size %d\n", fld->size);
446 exit(1);
Randall Spangler39f66112010-07-14 09:10:23 -0700447 break;
448 }
449 }
450 return cursor;
451}
452
453/* Helper to output a structure initializer.
454 */
455void OutputBytes(Command* cmd) {
456 (void) OutputBytes_(cmd, cmd->fields);
457}
458
459void OutputFieldPointers(Command* cmd, Field* fld) {
460 if (fld == NULL) {
461 return;
462 } else {
463 OutputFieldPointers(cmd, fld->next);
464 if (fld->visible) {
Gaurav Shah553d00e2010-07-19 19:22:10 -0700465 printf("%d, ", fld->offset);
Randall Spangler39f66112010-07-14 09:10:23 -0700466 }
467 }
468}
469
470/* Outputs the structure initializers for all commands.
471 */
472void OutputCommands(Command* cmd) {
473 if (cmd == NULL) {
474 return;
475 } else {
Luigi Semenzato89a02c12010-08-31 15:49:56 -0700476 printf("const struct s_%s{\n uint8_t buffer[%d];\n",
Gaurav Shah553d00e2010-07-19 19:22:10 -0700477 cmd->name, cmd->size == 0 ? cmd->max_size : cmd->size);
Randall Spangler39f66112010-07-14 09:10:23 -0700478 OutputFields(cmd->fields);
479 printf("} %s = {{", cmd->name);
480 OutputBytes(cmd);
481 printf("},\n");
482 OutputFieldPointers(cmd, cmd->fields);
483 printf("};\n\n");
484 }
485 OutputCommands(cmd->next);
486}
487
488Command* (*builders[])(void) = {
489 BuildDefineSpaceCommand,
490 BuildWriteCommand,
491 BuildReadCommand,
Kees Cook946370d2012-01-09 14:17:40 -0800492 BuildPCRReadCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700493 BuildPPAssertCommand,
Luigi Semenzato1d83dd12010-08-30 10:23:43 -0700494 BuildPPEnableCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700495 BuildPPLockCommand,
Luigi Semenzato377557f2010-08-31 13:20:53 -0700496 BuildFinalizePPCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700497 BuildStartupCommand,
Luigi Semenzato54992f92011-03-16 10:56:48 -0700498 BuildSaveStateCommand,
Luigi Semenzato3da063e2010-08-31 14:31:30 -0700499 BuildResumeCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700500 BuildSelftestfullCommand,
501 BuildContinueSelfTestCommand,
502 BuildReadPubekCommand,
503 BuildForceClearCommand,
504 BuildPhysicalDisableCommand,
505 BuildPhysicalEnableCommand,
506 BuildPhysicalSetDeactivatedCommand,
507 BuildGetFlagsCommand,
Luigi Semenzato5896b962010-08-25 07:16:03 -0700508 BuildGetSTClearFlagsCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700509 BuildGetPermissionsCommand,
Kees Cook8b6da262012-06-07 13:48:26 -0700510 BuildGetOwnershipCommand,
Kees Cookf0605cb2012-02-29 16:09:14 -0800511 BuildGetRandomCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700512 BuildExtendCommand,
513};
514
515static void FreeFields(Field* fld) {
516 if (fld != NULL) {
517 Field* next_field = fld->next;
Gaurav Shah553d00e2010-07-19 19:22:10 -0700518 free(fld);
Randall Spangler39f66112010-07-14 09:10:23 -0700519 FreeFields(next_field);
520 }
521}
522
523static void FreeCommands(Command* cmd) {
524 if (cmd != NULL) {
525 Command* next_command = cmd->next;
Randall Spangler39f66112010-07-14 09:10:23 -0700526 FreeFields(cmd->fields);
Luigi Semenzatod6acfd42013-01-08 16:23:11 -0800527 free(cmd);
Randall Spangler39f66112010-07-14 09:10:23 -0700528 FreeCommands(next_command);
529 }
530}
531
532int main(void) {
533 Command* commands = NULL;
534 int i;
535 for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) {
536 Command* cmd = builders[i]();
537 cmd->next = commands;
538 commands = cmd;
539 }
540
541 printf("/* This file is automatically generated */\n\n");
542 OutputCommands(commands);
543 printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO));
544 printf("const int kNvDataPublicPermissionsOffset = %d;\n",
545 (int) (offsetof(TPM_NV_DATA_PUBLIC, permission) +
546 2 * PCR_SELECTION_FIX +
547 offsetof(TPM_NV_ATTRIBUTES, attributes)));
548
549 FreeCommands(commands);
550 return 0;
551}