1 /* Copyright 2012 The ChromiumOS Authors
2 * 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
14 #include <assert.h>
15 #include <stdio.h>
16
17 #include "2sysincludes.h"
18 #include "tlcl_internal.h"
19 #include "tpmextras.h"
20 #include "tss_constants.h"
21
22 /* See struct Command below. This structure represent a field in a TPM
23 * command. [name] is the field name. [visible] is 1 if the field is
24 * modified by the run-time. Non-visible fields are initialized at build time
25 * and remain constant. [size] is the field size in bytes. [value] is the
26 * fixed value of non-visible fields.
27 */
28 typedef struct Field {
29 const char* name;
30 int visible;
31 int offset;
32 int size;
33 uint32_t value; /* large enough for all initializers */
34 struct Field* next;
35 } Field;
36
37 /* This structure is used to build (at build time) and manipulate (at firmware
38 * or emulation run time) buffers containing TPM datagrams. [name] is the name
39 * of a TPM command. [size] is the size of the command buffer in bytes, when
40 * known. [max_size] is the maximum size allowed for variable-length commands
41 * (such as Read and Write). [fields] is a link-list of command fields.
42 */
43 typedef struct Command {
44 const char* name;
45 int size;
46 int max_size;
47 Field* fields;
48 struct Command* next;
49 } Command;
50
51 /* Adds a field to a command, and makes its offset visible. The fields must be
52 * added at increasing offsets.
53 */
AddVisibleField(Command * cmd,const char * name,int offset)54 static void AddVisibleField(Command* cmd, const char* name, int offset) {
55 Field* fld = (Field*) calloc(1, sizeof(Field));
56 if (cmd->fields != NULL) {
57 assert(offset > fn->offset);
58 }
59 fld->next = cmd->fields;
60 cmd->fields = fld;
61 fld->name = name;
62 fld->visible = 1;
63 fld->offset = offset;
64 }
65
66 /* Adds a constant field with its value. The fields must be added at
67 * increasing offsets.
68 */
AddInitializedField(Command * cmd,int offset,int size,uint32_t value)69 static void AddInitializedField(Command* cmd, int offset,
70 int size, uint32_t value) {
71 Field* fld = (Field*) calloc(1, sizeof(Field));
72 fld->next = cmd->fields;
73 cmd->fields = fld;
74 fld->name = NULL;
75 fld->visible = 0;
76 fld->size = size;
77 fld->offset = offset;
78 fld->value = value;
79 }
80
81 /* Create a structure representing a TPM command datagram.
82 */
newCommandWithTag(TPM_COMMAND_CODE code,int size,TPM_TAG tag)83 Command* newCommandWithTag(TPM_COMMAND_CODE code, int size, TPM_TAG tag) {
84 Command* cmd = (Command*) calloc(1, sizeof(Command));
85 cmd->size = size;
86 AddInitializedField(cmd, 0, sizeof(TPM_TAG), tag);
87 AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size);
88 AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t),
89 sizeof(TPM_COMMAND_CODE), code);
90 return cmd;
91 }
92
newCommand(TPM_COMMAND_CODE code,int size)93 Command* newCommand(TPM_COMMAND_CODE code, int size) {
94 return newCommandWithTag(code, size, TPM_TAG_RQU_COMMAND);
95 }
96
97 /* BuildXXX builds TPM command XXX.
98 */
BuildDefineSpaceCommand(void)99 Command* BuildDefineSpaceCommand(void) {
100 int nv_data_public = kTpmRequestHeaderLength;
101 int nv_index = nv_data_public + offsetof(TPM_NV_DATA_PUBLIC, nvIndex);
102 int nv_pcr_info_read = nv_data_public +
103 offsetof(TPM_NV_DATA_PUBLIC, pcrInfoRead);
104 int read_locality = nv_pcr_info_read +
105 offsetof(TPM_PCR_INFO_SHORT, localityAtRelease);
106 int nv_pcr_info_write = nv_data_public +
107 offsetof(TPM_NV_DATA_PUBLIC, pcrInfoWrite);
108 int write_locality = nv_pcr_info_write +
109 offsetof(TPM_PCR_INFO_SHORT, localityAtRelease);
110 int nv_permission = nv_data_public +
111 offsetof(TPM_NV_DATA_PUBLIC, permission);
112 int nv_permission_tag =
113 nv_permission + offsetof(TPM_NV_ATTRIBUTES, tag);
114 int nv_permission_attributes =
115 nv_permission + offsetof(TPM_NV_ATTRIBUTES, attributes);
116 int nv_datasize = nv_data_public +
117 offsetof(TPM_NV_DATA_PUBLIC, dataSize);
118
119 int size = kTpmRequestHeaderLength + sizeof(TPM_NV_DATA_PUBLIC) +
120 kEncAuthLength;
121 Command* cmd = newCommand(TPM_ORD_NV_DefineSpace, size);
122 cmd->name = "tpm_nv_definespace_cmd";
123
124 AddVisibleField(cmd, "index", nv_index);
125 AddVisibleField(cmd, "pcr_info_read", nv_pcr_info_read);
126 AddVisibleField(cmd, "pcr_info_write", nv_pcr_info_write);
127 AddVisibleField(cmd, "perm", nv_permission_attributes);
128 AddVisibleField(cmd, "size", nv_datasize);
129
130 AddInitializedField(cmd, nv_data_public, sizeof(uint16_t),
131 TPM_TAG_NV_DATA_PUBLIC);
132 AddInitializedField(cmd, nv_pcr_info_read, sizeof(uint16_t), 3);
133 AddInitializedField(cmd, read_locality, sizeof(TPM_LOCALITY_SELECTION),
134 TPM_ALL_LOCALITIES);
135 AddInitializedField(cmd, nv_pcr_info_write, sizeof(uint16_t), 3);
136 AddInitializedField(cmd, write_locality, sizeof(TPM_LOCALITY_SELECTION),
137 TPM_ALL_LOCALITIES);
138 AddInitializedField(cmd, nv_permission_tag, sizeof(TPM_STRUCTURE_TAG),
139 TPM_TAG_NV_ATTRIBUTES);
140 return cmd;
141 }
142
143 /* BuildXXX builds TPM command XXX.
144 */
BuildWriteCommand(void)145 Command* BuildWriteCommand(void) {
146 Command* cmd = newCommand(TPM_ORD_NV_WriteValue, 0);
147 cmd->name = "tpm_nv_write_cmd";
148 cmd->max_size = TPM_LARGE_ENOUGH_COMMAND_SIZE;
149 AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
150 AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
151 AddVisibleField(cmd, "data", kTpmRequestHeaderLength + 12);
152 return cmd;
153 }
154
BuildReadCommand(void)155 Command* BuildReadCommand(void) {
156 int size = kTpmRequestHeaderLength + kTpmReadInfoLength;
157 Command* cmd = newCommand(TPM_ORD_NV_ReadValue, size);
158 cmd->name = "tpm_nv_read_cmd";
159 AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
160 AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
161 return cmd;
162 }
163
BuildPCRReadCommand(void)164 Command* BuildPCRReadCommand(void) {
165 int size = kTpmRequestHeaderLength + sizeof(uint32_t);
166 Command* cmd = newCommand(TPM_ORD_PcrRead, size);
167 cmd->name = "tpm_pcr_read_cmd";
168 AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
169 return cmd;
170 }
171
BuildPPAssertCommand(void)172 Command* BuildPPAssertCommand(void) {
173 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
174 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
175 cmd->name = "tpm_ppassert_cmd";
176 AddInitializedField(cmd, kTpmRequestHeaderLength,
177 sizeof(TPM_PHYSICAL_PRESENCE),
178 TPM_PHYSICAL_PRESENCE_PRESENT);
179 return cmd;
180 }
181
BuildPPEnableCommand(void)182 Command* BuildPPEnableCommand(void) {
183 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
184 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
185 cmd->name = "tpm_ppenable_cmd";
186 AddInitializedField(cmd, kTpmRequestHeaderLength,
187 sizeof(TPM_PHYSICAL_PRESENCE),
188 TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
189 return cmd;
190 }
191
BuildFinalizePPCommand(void)192 Command* BuildFinalizePPCommand(void) {
193 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
194 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
195 cmd->name = "tpm_finalizepp_cmd";
196 AddInitializedField(cmd, kTpmRequestHeaderLength,
197 sizeof(TPM_PHYSICAL_PRESENCE),
198 TPM_PHYSICAL_PRESENCE_CMD_ENABLE |
199 TPM_PHYSICAL_PRESENCE_HW_DISABLE |
200 TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK);
201 return cmd;
202 }
203
BuildPPLockCommand(void)204 Command* BuildPPLockCommand(void) {
205 int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
206 Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
207 cmd->name = "tpm_pplock_cmd";
208 AddInitializedField(cmd, kTpmRequestHeaderLength,
209 sizeof(TPM_PHYSICAL_PRESENCE),
210 TPM_PHYSICAL_PRESENCE_LOCK);
211 return cmd;
212 }
213
BuildStartupCommand(void)214 Command* BuildStartupCommand(void) {
215 int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
216 Command* cmd = newCommand(TPM_ORD_Startup, size);
217 cmd->name = "tpm_startup_cmd";
218 AddInitializedField(cmd, kTpmRequestHeaderLength,
219 sizeof(TPM_STARTUP_TYPE),
220 TPM_ST_CLEAR);
221 return cmd;
222 }
223
BuildSaveStateCommand(void)224 Command* BuildSaveStateCommand(void) {
225 int size = kTpmRequestHeaderLength;
226 Command* cmd = newCommand(TPM_ORD_SaveState, size);
227 cmd->name = "tpm_savestate_cmd";
228 return cmd;
229 }
230
BuildResumeCommand(void)231 Command* BuildResumeCommand(void) {
232 int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
233 Command* cmd = newCommand(TPM_ORD_Startup, size);
234 cmd->name = "tpm_resume_cmd";
235 AddInitializedField(cmd, kTpmRequestHeaderLength,
236 sizeof(TPM_STARTUP_TYPE),
237 TPM_ST_STATE);
238 return cmd;
239 }
240
BuildSelftestfullCommand(void)241 Command* BuildSelftestfullCommand(void) {
242 int size = kTpmRequestHeaderLength;
243 Command* cmd = newCommand(TPM_ORD_SelfTestFull, size);
244 cmd->name = "tpm_selftestfull_cmd";
245 return cmd;
246 }
247
BuildContinueSelfTestCommand(void)248 Command* BuildContinueSelfTestCommand(void) {
249 int size = kTpmRequestHeaderLength;
250 Command* cmd = newCommand(TPM_ORD_ContinueSelfTest, size);
251 cmd->name = "tpm_continueselftest_cmd";
252 return cmd;
253 }
254
BuildReadPubekCommand(void)255 Command* BuildReadPubekCommand(void) {
256 int size = kTpmRequestHeaderLength + sizeof(TPM_NONCE);
257 Command* cmd = newCommand(TPM_ORD_ReadPubek, size);
258 cmd->name = "tpm_readpubek_cmd";
259 AddVisibleField(cmd, "antiReplay", kTpmRequestHeaderLength);
260 return cmd;
261 }
262
BuildForceClearCommand(void)263 Command* BuildForceClearCommand(void) {
264 int size = kTpmRequestHeaderLength;
265 Command* cmd = newCommand(TPM_ORD_ForceClear, size);
266 cmd->name = "tpm_forceclear_cmd";
267 return cmd;
268 }
269
BuildPhysicalEnableCommand(void)270 Command* BuildPhysicalEnableCommand(void) {
271 int size = kTpmRequestHeaderLength;
272 Command* cmd = newCommand(TPM_ORD_PhysicalEnable, size);
273 cmd->name = "tpm_physicalenable_cmd";
274 return cmd;
275 }
276
BuildPhysicalDisableCommand(void)277 Command* BuildPhysicalDisableCommand(void) {
278 int size = kTpmRequestHeaderLength;
279 Command* cmd = newCommand(TPM_ORD_PhysicalDisable, size);
280 cmd->name = "tpm_physicaldisable_cmd";
281 return cmd;
282 }
283
BuildPhysicalSetDeactivatedCommand(void)284 Command* BuildPhysicalSetDeactivatedCommand(void) {
285 int size = kTpmRequestHeaderLength + sizeof(uint8_t);
286 Command* cmd = newCommand(TPM_ORD_PhysicalSetDeactivated, size);
287 cmd->name = "tpm_physicalsetdeactivated_cmd";
288 AddVisibleField(cmd, "deactivated", kTpmRequestHeaderLength);
289 return cmd;
290 }
291
BuildExtendCommand(void)292 Command* BuildExtendCommand(void) {
293 int size = kTpmRequestHeaderLength + sizeof(uint32_t) + kPcrDigestLength;
294 Command* cmd = newCommand(TPM_ORD_Extend, size);
295 cmd->name = "tpm_extend_cmd";
296 AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
297 AddVisibleField(cmd, "inDigest", kTpmRequestHeaderLength + sizeof(uint32_t));
298 return cmd;
299 }
300
BuildGetFlagsCommand(void)301 Command* BuildGetFlagsCommand(void) {
302 int size = (kTpmRequestHeaderLength +
303 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
304 sizeof(uint32_t) + /* subCapSize */
305 sizeof(uint32_t)); /* subCap */
306
307 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
308 cmd->name = "tpm_getflags_cmd";
309 AddInitializedField(cmd, kTpmRequestHeaderLength,
310 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
311 AddInitializedField(cmd, kTpmRequestHeaderLength +
312 sizeof(TPM_CAPABILITY_AREA),
313 sizeof(uint32_t), sizeof(uint32_t));
314 AddInitializedField(cmd, kTpmRequestHeaderLength +
315 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
316 sizeof(uint32_t), TPM_CAP_FLAG_PERMANENT);
317 return cmd;
318 }
319
BuildGetSTClearFlagsCommand(void)320 Command* BuildGetSTClearFlagsCommand(void) {
321 int size = (kTpmRequestHeaderLength +
322 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
323 sizeof(uint32_t) + /* subCapSize */
324 sizeof(uint32_t)); /* subCap */
325
326 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
327 cmd->name = "tpm_getstclearflags_cmd";
328 AddInitializedField(cmd, kTpmRequestHeaderLength,
329 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
330 AddInitializedField(cmd, kTpmRequestHeaderLength +
331 sizeof(TPM_CAPABILITY_AREA),
332 sizeof(uint32_t), sizeof(uint32_t));
333 AddInitializedField(cmd, kTpmRequestHeaderLength +
334 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
335 sizeof(uint32_t), TPM_CAP_FLAG_VOLATILE);
336 return cmd;
337 }
338
BuildGetSpaceInfoCommand(void)339 Command* BuildGetSpaceInfoCommand(void) {
340 int size = (kTpmRequestHeaderLength +
341 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
342 sizeof(uint32_t) + /* subCapSize */
343 sizeof(uint32_t)); /* subCap */
344
345 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
346 cmd->name = "tpm_getspaceinfo_cmd";
347 AddInitializedField(cmd, kTpmRequestHeaderLength,
348 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_NV_INDEX);
349 AddInitializedField(cmd, kTpmRequestHeaderLength +
350 sizeof(TPM_CAPABILITY_AREA),
351 sizeof(uint32_t), sizeof(uint32_t));
352 AddVisibleField(cmd, "index", kTpmRequestHeaderLength +
353 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t));
354 return cmd;
355 }
356
BuildGetOwnershipCommand(void)357 Command* BuildGetOwnershipCommand(void) {
358 int size = (kTpmRequestHeaderLength +
359 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
360 sizeof(uint32_t) + /* subCapSize */
361 sizeof(uint32_t)); /* subCap */
362
363 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
364 cmd->name = "tpm_getownership_cmd";
365 AddInitializedField(cmd, kTpmRequestHeaderLength,
366 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_PROPERTY);
367 AddInitializedField(cmd, kTpmRequestHeaderLength +
368 sizeof(TPM_CAPABILITY_AREA),
369 sizeof(uint32_t), sizeof(uint32_t));
370 AddInitializedField(cmd, kTpmRequestHeaderLength +
371 sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
372 sizeof(uint32_t), TPM_CAP_PROP_OWNER);
373 return cmd;
374 }
375
BuildGetRandomCommand(void)376 Command* BuildGetRandomCommand(void) {
377 int size = kTpmRequestHeaderLength + sizeof(uint32_t);
378 Command* cmd = newCommand(TPM_ORD_GetRandom, size);
379 cmd->name = "tpm_get_random_cmd";
380 AddVisibleField(cmd, "bytesRequested", kTpmRequestHeaderLength);
381 return cmd;
382 }
383
BuildGetVersionValCommand(void)384 Command* BuildGetVersionValCommand(void) {
385 int size = (kTpmRequestHeaderLength +
386 sizeof(TPM_CAPABILITY_AREA) + /* capArea */
387 sizeof(uint32_t)); /* subCapSize */
388
389 Command* cmd = newCommand(TPM_ORD_GetCapability, size);
390 cmd->name = "tpm_getversionval_cmd";
391 AddInitializedField(cmd, kTpmRequestHeaderLength,
392 sizeof(TPM_CAPABILITY_AREA), TPM_CAP_GET_VERSION_VAL);
393 AddInitializedField(cmd, kTpmRequestHeaderLength +
394 sizeof(TPM_CAPABILITY_AREA),
395 sizeof(uint32_t), 0);
396 return cmd;
397 }
398
BuildIFXFieldUpgradeInfoRequest2Command(void)399 Command* BuildIFXFieldUpgradeInfoRequest2Command(void) {
400 int size = (kTpmRequestHeaderLength +
401 sizeof(TPM_IFX_FieldUpgradeInfoRequest2) +
402 sizeof(uint16_t));
403 Command* cmd = newCommand(TPM_ORD_FieldUpgrade, size);
404 cmd->name = "tpm_ifx_fieldupgradeinforequest2_cmd";
405 AddInitializedField(cmd, kTpmRequestHeaderLength,
406 sizeof(TPM_IFX_FieldUpgradeInfoRequest2),
407 TPM_IFX_FieldUpgradeInfoRequest2);
408 AddInitializedField(cmd, kTpmRequestHeaderLength +
409 sizeof(TPM_IFX_FieldUpgradeInfoRequest2),
410 sizeof(uint16_t), 0);
411 return cmd;
412 }
413
BuildOIAPCommand(void)414 Command* BuildOIAPCommand(void) {
415 int size = kTpmRequestHeaderLength;
416 Command* cmd = newCommand(TPM_ORD_OIAP, size);
417 cmd->name = "tpm_oiap_cmd";
418 return cmd;
419 }
420
BuildOSAPCommand(void)421 Command* BuildOSAPCommand(void) {
422 int size = kTpmRequestHeaderLength + sizeof(uint16_t) + sizeof(uint32_t) +
423 sizeof(TPM_NONCE);
424 Command* cmd = newCommand(TPM_ORD_OSAP, size);
425 cmd->name = "tpm_osap_cmd";
426 AddVisibleField(cmd, "entityType", kTpmRequestHeaderLength);
427 AddVisibleField(cmd, "entityValue",
428 kTpmRequestHeaderLength + sizeof(uint16_t));
429 AddVisibleField(
430 cmd, "nonceOddOSAP",
431 kTpmRequestHeaderLength + sizeof(uint16_t) + sizeof(uint32_t));
432 return cmd;
433 }
434
BuildTakeOwnershipCommand(void)435 Command* BuildTakeOwnershipCommand(void) {
436 Command* cmd = newCommandWithTag(TPM_ORD_TakeOwnership, 624,
437 TPM_TAG_RQU_AUTH1_COMMAND);
438 cmd->name = "tpm_takeownership_cmd";
439 int offset = kTpmRequestHeaderLength;
440 AddInitializedField(cmd, offset, sizeof(uint16_t), TPM_PID_OWNER);
441 offset += sizeof(uint16_t);
442 AddInitializedField(cmd, offset, sizeof(uint32_t), TPM_RSA_2048_LEN);
443 offset += sizeof(uint32_t);
444 AddVisibleField(cmd, "encOwnerAuth", offset);
445 offset += sizeof(uint8_t[TPM_RSA_2048_LEN]);
446 AddInitializedField(cmd, offset, sizeof(uint32_t), TPM_RSA_2048_LEN);
447 offset += sizeof(uint32_t);
448 AddVisibleField(cmd, "encSrkAuth", offset);
449 offset += sizeof(uint8_t[TPM_RSA_2048_LEN]);
450
451 /* The remainder are the srkParams struct TPM_KEY12 contents. */
452 AddInitializedField(cmd, offset, sizeof(uint16_t), TPM_TAG_KEY12);
453 offset += sizeof(uint16_t);
454 AddInitializedField(cmd, offset, sizeof(uint16_t), 0);
455 offset += sizeof(uint16_t);
456 AddInitializedField(cmd, offset, sizeof(uint16_t), TPM_KEY_USAGE_STORAGE);
457 offset += sizeof(uint16_t);
458 AddInitializedField(cmd, offset, sizeof(uint32_t), 0 /* keyFlags */);
459 offset += sizeof(uint32_t);
460 AddInitializedField(cmd, offset, sizeof(uint8_t), TPM_AUTH_ALWAYS);
461 offset += sizeof(uint8_t);
462 AddInitializedField(cmd, offset, sizeof(uint32_t), TPM_ALG_RSA);
463 offset += sizeof(uint32_t);
464 AddInitializedField(cmd, offset, sizeof(uint16_t),
465 TPM_ES_RSAESOAEP_SHA1_MGF1);
466 offset += sizeof(uint16_t);
467 AddInitializedField(cmd, offset, sizeof(uint16_t), TPM_SS_NONE);
468 offset += sizeof(uint16_t);
469 AddInitializedField(cmd, offset, sizeof(uint32_t),
470 3 * sizeof(uint32_t) /* algorithmParams.parmSize */);
471 offset += sizeof(uint32_t);
472 AddInitializedField(cmd, offset, sizeof(uint32_t),
473 2048 /* algorithmParms.parms.keyLength */);
474 offset += sizeof(uint32_t);
475 AddInitializedField(cmd, offset, sizeof(uint32_t),
476 2 /* algorithmParms.parms.numPrimes */);
477 offset += sizeof(uint32_t);
478 AddInitializedField(cmd, offset, sizeof(uint32_t),
479 0 /* algorithmParms.parms.exponentSize */);
480 offset += sizeof(uint32_t);
481 AddInitializedField(cmd, offset, sizeof(uint32_t), 0 /* PCRInfoSize */);
482 offset += sizeof(uint32_t);
483 AddInitializedField(cmd, offset, sizeof(uint32_t), 0 /* pubkey.keyLength */);
484 offset += sizeof(uint32_t);
485 AddInitializedField(cmd, offset, sizeof(uint32_t), 0 /* encDataSize */);
486 offset += sizeof(uint32_t);
487
488 /* Allocate space for the auth block. */
489 offset += kTpmRequestAuthBlockLength;
490
491 assert(offset == cmd->size);
492
493 return cmd;
494 }
495
BuildCreateDelegationFamilyCommand(void)496 Command* BuildCreateDelegationFamilyCommand(void) {
497 int size = kTpmRequestHeaderLength + 3 * sizeof(uint32_t) + sizeof(uint8_t);
498 Command* cmd = newCommand(TPM_ORD_Delegate_Manage, size);
499 cmd->name = "tpm_create_delegation_family_cmd";
500 AddInitializedField(cmd, kTpmRequestHeaderLength, sizeof(uint32_t),
501 0 /* familyID */);
502 AddInitializedField(cmd, kTpmRequestHeaderLength + sizeof(uint32_t),
503 sizeof(uint32_t), TPM_FAMILY_CREATE);
504 AddInitializedField(cmd, kTpmRequestHeaderLength + 2 * sizeof(uint32_t),
505 sizeof(uint32_t), sizeof(uint8_t) /* opDataSize */);
506 AddVisibleField(cmd, "familyLabel",
507 kTpmRequestHeaderLength + 3 * sizeof(uint32_t));
508 return cmd;
509 }
510
BuildReadDelegationFamilyTableCommand(void)511 Command* BuildReadDelegationFamilyTableCommand(void) {
512 Command* cmd =
513 newCommand(TPM_ORD_Delegate_ReadTable, kTpmRequestHeaderLength);
514 cmd->name = "tpm_delegate_read_table_cmd";
515 return cmd;
516 }
517
518 /* Output the fields of a structure.
519 */
OutputFields(Field * fld)520 void OutputFields(Field* fld) {
521 /*
522 * Field order is reversed.
523 */
524 if (fld != NULL) {
525 OutputFields(fld->next);
526 if (fld->visible) {
527 printf(" uint16_t %s;\n", fld->name);
528 }
529 }
530 }
531
532 /* Outputs a structure initializer.
533 */
OutputBytes_(Command * cmd,Field * fld)534 int OutputBytes_(Command* cmd, Field* fld) {
535 int cursor = 0;
536 int i;
537 /*
538 * Field order is reversed.
539 */
540 if (fld != NULL) {
541 cursor = OutputBytes_(cmd, fld->next);
542 } else {
543 return 0;
544 }
545 if (!fld->visible) {
546 /*
547 * Catch up missing fields.
548 */
549 assert(fld->offset >= cursor);
550 for (i = 0; i < fld->offset - cursor; i++) {
551 printf("0, ");
552 }
553 cursor = fld->offset;
554 switch (fld->size) {
555 case 1:
556 printf("%#x, ", fld->value);
557 cursor += 1;
558 break;
559 case 2:
560 printf("%#x, %#x, ", fld->value >> 8, fld->value & 0xff);
561 cursor += 2;
562 break;
563 case 4:
564 printf("%#x, %#x, %#x, %#x, ", fld->value >> 24,
565 (fld->value >> 16) & 0xff,
566 (fld->value >> 8) & 0xff,
567 fld->value & 0xff);
568 cursor += 4;
569 break;
570 default:
571 fprintf(stderr, "invalid field size %d\n", fld->size);
572 exit(1);
573 break;
574 }
575 }
576 return cursor;
577 }
578
579 /* Helper to output a structure initializer.
580 */
OutputBytes(Command * cmd)581 void OutputBytes(Command* cmd) {
582 (void) OutputBytes_(cmd, cmd->fields);
583 }
584
OutputFieldPointers(Command * cmd,Field * fld)585 void OutputFieldPointers(Command* cmd, Field* fld) {
586 if (fld == NULL) {
587 return;
588 } else {
589 OutputFieldPointers(cmd, fld->next);
590 if (fld->visible) {
591 printf("%d, ", fld->offset);
592 }
593 }
594 }
595
596 /* Outputs the structure initializers for all commands.
597 */
OutputCommands(Command * cmd)598 void OutputCommands(Command* cmd) {
599 if (cmd == NULL) {
600 return;
601 } else {
602 printf("const struct s_%s{\n uint8_t buffer[%d];\n",
603 cmd->name, cmd->size == 0 ? cmd->max_size : cmd->size);
604 OutputFields(cmd->fields);
605 printf("} %s = {{", cmd->name);
606 OutputBytes(cmd);
607 printf("},\n");
608 OutputFieldPointers(cmd, cmd->fields);
609 printf("};\n\n");
610 }
611 OutputCommands(cmd->next);
612 }
613
614 Command* (*builders[])(void) = {
615 BuildDefineSpaceCommand,
616 BuildWriteCommand,
617 BuildReadCommand,
618 BuildPCRReadCommand,
619 BuildPPAssertCommand,
620 BuildPPEnableCommand,
621 BuildPPLockCommand,
622 BuildFinalizePPCommand,
623 BuildStartupCommand,
624 BuildSaveStateCommand,
625 BuildResumeCommand,
626 BuildSelftestfullCommand,
627 BuildContinueSelfTestCommand,
628 BuildReadPubekCommand,
629 BuildForceClearCommand,
630 BuildPhysicalDisableCommand,
631 BuildPhysicalEnableCommand,
632 BuildPhysicalSetDeactivatedCommand,
633 BuildGetFlagsCommand,
634 BuildGetSTClearFlagsCommand,
635 BuildGetSpaceInfoCommand,
636 BuildGetOwnershipCommand,
637 BuildGetRandomCommand,
638 BuildExtendCommand,
639 BuildGetVersionValCommand,
640 BuildIFXFieldUpgradeInfoRequest2Command,
641 BuildOIAPCommand,
642 BuildOSAPCommand,
643 BuildTakeOwnershipCommand,
644 BuildCreateDelegationFamilyCommand,
645 BuildReadDelegationFamilyTableCommand,
646 };
647
FreeFields(Field * fld)648 static void FreeFields(Field* fld) {
649 if (fld != NULL) {
650 Field* next_field = fld->next;
651 free(fld);
652 FreeFields(next_field);
653 }
654 }
655
FreeCommands(Command * cmd)656 static void FreeCommands(Command* cmd) {
657 if (cmd != NULL) {
658 Command* next_command = cmd->next;
659 FreeFields(cmd->fields);
660 free(cmd);
661 FreeCommands(next_command);
662 }
663 }
664
main(void)665 int main(void) {
666 Command* commands = NULL;
667 int i;
668 for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) {
669 Command* cmd = builders[i]();
670 cmd->next = commands;
671 commands = cmd;
672 }
673
674 printf("/* This file is automatically generated */\n\n");
675 OutputCommands(commands);
676 printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO));
677
678 FreeCommands(commands);
679 return 0;
680 }
681