blob: 99ec4a5e5f241c0699c343723e4ff82cc4f8ae61 [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 <stdio.h>
Randall Spangler39f66112010-07-14 09:10:23 -070016
Joel Kitching0b3ce462019-06-14 14:52:41 +080017#include "2sysincludes.h"
Randall Spangler39f66112010-07-14 09:10:23 -070018#include "tlcl_internal.h"
19#include "tpmextras.h"
Luigi Semenzatob472d9c2015-04-28 11:12:18 -070020#include "tss_constants.h"
Randall Spangler39f66112010-07-14 09:10:23 -070021
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 */
28typedef 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 */
43typedef 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 */
54static void AddVisibleField(Command* cmd, const char* name, int offset) {
Luigi Semenzatod6acfd42013-01-08 16:23:11 -080055 Field* fld = (Field*) calloc(1, sizeof(Field));
Randall Spangler39f66112010-07-14 09:10:23 -070056 if (cmd->fields != NULL) {
Randall Spangler39f66112010-07-14 09:10:23 -070057 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 */
69static void AddInitializedField(Command* cmd, int offset,
70 int size, uint32_t value) {
Luigi Semenzatod6acfd42013-01-08 16:23:11 -080071 Field* fld = (Field*) calloc(1, sizeof(Field));
Randall Spangler39f66112010-07-14 09:10:23 -070072 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 */
Mattias Nisslerac2286e2017-11-27 15:35:10 +010083Command* newCommandWithTag(TPM_COMMAND_CODE code, int size, TPM_TAG tag) {
Luigi Semenzatod6acfd42013-01-08 16:23:11 -080084 Command* cmd = (Command*) calloc(1, sizeof(Command));
Randall Spangler39f66112010-07-14 09:10:23 -070085 cmd->size = size;
Mattias Nisslerac2286e2017-11-27 15:35:10 +010086 AddInitializedField(cmd, 0, sizeof(TPM_TAG), tag);
Randall Spangler39f66112010-07-14 09:10:23 -070087 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
Mattias Nisslerac2286e2017-11-27 15:35:10 +010093Command* newCommand(TPM_COMMAND_CODE code, int size) {
94 return newCommandWithTag(code, size, TPM_TAG_RQU_COMMAND);
95}
96
Randall Spangler39f66112010-07-14 09:10:23 -070097/* BuildXXX builds TPM command XXX.
98 */
99Command* 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);
Randall Spangler39f66112010-07-14 09:10:23 -0700104 int read_locality = nv_pcr_info_read +
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100105 offsetof(TPM_PCR_INFO_SHORT, localityAtRelease);
Randall Spangler39f66112010-07-14 09:10:23 -0700106 int nv_pcr_info_write = nv_data_public +
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100107 offsetof(TPM_NV_DATA_PUBLIC, pcrInfoWrite);
Randall Spangler39f66112010-07-14 09:10:23 -0700108 int write_locality = nv_pcr_info_write +
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100109 offsetof(TPM_PCR_INFO_SHORT, localityAtRelease);
Randall Spangler39f66112010-07-14 09:10:23 -0700110 int nv_permission = nv_data_public +
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100111 offsetof(TPM_NV_DATA_PUBLIC, permission);
Randall Spangler39f66112010-07-14 09:10:23 -0700112 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 +
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100117 offsetof(TPM_NV_DATA_PUBLIC, dataSize);
Randall Spangler39f66112010-07-14 09:10:23 -0700118
119 int size = kTpmRequestHeaderLength + sizeof(TPM_NV_DATA_PUBLIC) +
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100120 kEncAuthLength;
Randall Spangler39f66112010-07-14 09:10:23 -0700121 Command* cmd = newCommand(TPM_ORD_NV_DefineSpace, size);
122 cmd->name = "tpm_nv_definespace_cmd";
123
124 AddVisibleField(cmd, "index", nv_index);
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100125 AddVisibleField(cmd, "pcr_info_read", nv_pcr_info_read);
126 AddVisibleField(cmd, "pcr_info_write", nv_pcr_info_write);
Randall Spangler39f66112010-07-14 09:10:23 -0700127 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 */
145Command* 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
155Command* 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
Kees Cook946370d2012-01-09 14:17:40 -0800164Command* 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
Randall Spangler39f66112010-07-14 09:10:23 -0700172Command* 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
Luigi Semenzato1d83dd12010-08-30 10:23:43 -0700182Command* 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
Luigi Semenzato377557f2010-08-31 13:20:53 -0700192Command* 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
Randall Spangler39f66112010-07-14 09:10:23 -0700204Command* 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
214Command* BuildStartupCommand(void) {
Luigi Semenzato3da063e2010-08-31 14:31:30 -0700215 int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
Randall Spangler39f66112010-07-14 09:10:23 -0700216 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
Luigi Semenzato54992f92011-03-16 10:56:48 -0700224Command* 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
Luigi Semenzato3da063e2010-08-31 14:31:30 -0700231Command* 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
Randall Spangler39f66112010-07-14 09:10:23 -0700241Command* 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
248Command* 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
255Command* BuildReadPubekCommand(void) {
256 int size = kTpmRequestHeaderLength + sizeof(TPM_NONCE);
257 Command* cmd = newCommand(TPM_ORD_ReadPubek, size);
258 cmd->name = "tpm_readpubek_cmd";
Mattias Nissler163b4122017-11-21 12:17:03 +0100259 AddVisibleField(cmd, "antiReplay", kTpmRequestHeaderLength);
Randall Spangler39f66112010-07-14 09:10:23 -0700260 return cmd;
261}
262
263Command* 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
270Command* 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
277Command* 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
284Command* 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
292Command* 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
301Command* 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
Luigi Semenzato5896b962010-08-25 07:16:03 -0700320Command* 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
Mattias Nisslerdc060ac2017-12-05 16:27:42 +0100339Command* BuildGetSpaceInfoCommand(void) {
Randall Spangler39f66112010-07-14 09:10:23 -0700340 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);
Mattias Nisslerdc060ac2017-12-05 16:27:42 +0100346 cmd->name = "tpm_getspaceinfo_cmd";
Randall Spangler39f66112010-07-14 09:10:23 -0700347 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
Kees Cook8b6da262012-06-07 13:48:26 -0700357Command* 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
Kees Cookf0605cb2012-02-29 16:09:14 -0800376Command* 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
Mattias Nissler2a7e9b82017-07-10 13:46:20 +0200384Command* 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
Mattias Nisslerb2b39702017-07-07 10:26:43 +0200399Command* 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
Mattias Nisslerac2286e2017-11-27 15:35:10 +0100414Command* 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
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100421Command* 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
Mattias Nisslerac2286e2017-11-27 15:35:10 +0100435Command* 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
Mattias Nissler2e626202017-12-08 14:13:25 +0100496Command* 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
511Command* 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
Randall Spangler39f66112010-07-14 09:10:23 -0700518/* Output the fields of a structure.
519 */
520void OutputFields(Field* fld) {
521 /*
522 * Field order is reversed.
523 */
524 if (fld != NULL) {
525 OutputFields(fld->next);
526 if (fld->visible) {
Gaurav Shah553d00e2010-07-19 19:22:10 -0700527 printf(" uint16_t %s;\n", fld->name);
Randall Spangler39f66112010-07-14 09:10:23 -0700528 }
529 }
530}
531
532/* Outputs a structure initializer.
533 */
534int 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:
Joel Kitching3c477452019-10-04 17:46:29 +0800556 printf("%#x, ", fld->value);
Randall Spangler39f66112010-07-14 09:10:23 -0700557 cursor += 1;
558 break;
559 case 2:
Joel Kitching3c477452019-10-04 17:46:29 +0800560 printf("%#x, %#x, ", fld->value >> 8, fld->value & 0xff);
Randall Spangler39f66112010-07-14 09:10:23 -0700561 cursor += 2;
562 break;
563 case 4:
Joel Kitching3c477452019-10-04 17:46:29 +0800564 printf("%#x, %#x, %#x, %#x, ", fld->value >> 24,
Randall Spangler39f66112010-07-14 09:10:23 -0700565 (fld->value >> 16) & 0xff,
566 (fld->value >> 8) & 0xff,
567 fld->value & 0xff);
568 cursor += 4;
569 break;
570 default:
Gaurav Shah553d00e2010-07-19 19:22:10 -0700571 fprintf(stderr, "invalid field size %d\n", fld->size);
572 exit(1);
Randall Spangler39f66112010-07-14 09:10:23 -0700573 break;
574 }
575 }
576 return cursor;
577}
578
579/* Helper to output a structure initializer.
580 */
581void OutputBytes(Command* cmd) {
582 (void) OutputBytes_(cmd, cmd->fields);
583}
584
585void OutputFieldPointers(Command* cmd, Field* fld) {
586 if (fld == NULL) {
587 return;
588 } else {
589 OutputFieldPointers(cmd, fld->next);
590 if (fld->visible) {
Gaurav Shah553d00e2010-07-19 19:22:10 -0700591 printf("%d, ", fld->offset);
Randall Spangler39f66112010-07-14 09:10:23 -0700592 }
593 }
594}
595
596/* Outputs the structure initializers for all commands.
597 */
598void OutputCommands(Command* cmd) {
599 if (cmd == NULL) {
600 return;
601 } else {
Luigi Semenzato89a02c12010-08-31 15:49:56 -0700602 printf("const struct s_%s{\n uint8_t buffer[%d];\n",
Gaurav Shah553d00e2010-07-19 19:22:10 -0700603 cmd->name, cmd->size == 0 ? cmd->max_size : cmd->size);
Randall Spangler39f66112010-07-14 09:10:23 -0700604 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
614Command* (*builders[])(void) = {
615 BuildDefineSpaceCommand,
616 BuildWriteCommand,
617 BuildReadCommand,
Kees Cook946370d2012-01-09 14:17:40 -0800618 BuildPCRReadCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700619 BuildPPAssertCommand,
Luigi Semenzato1d83dd12010-08-30 10:23:43 -0700620 BuildPPEnableCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700621 BuildPPLockCommand,
Luigi Semenzato377557f2010-08-31 13:20:53 -0700622 BuildFinalizePPCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700623 BuildStartupCommand,
Luigi Semenzato54992f92011-03-16 10:56:48 -0700624 BuildSaveStateCommand,
Luigi Semenzato3da063e2010-08-31 14:31:30 -0700625 BuildResumeCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700626 BuildSelftestfullCommand,
627 BuildContinueSelfTestCommand,
628 BuildReadPubekCommand,
629 BuildForceClearCommand,
630 BuildPhysicalDisableCommand,
631 BuildPhysicalEnableCommand,
632 BuildPhysicalSetDeactivatedCommand,
633 BuildGetFlagsCommand,
Luigi Semenzato5896b962010-08-25 07:16:03 -0700634 BuildGetSTClearFlagsCommand,
Mattias Nisslerdc060ac2017-12-05 16:27:42 +0100635 BuildGetSpaceInfoCommand,
Kees Cook8b6da262012-06-07 13:48:26 -0700636 BuildGetOwnershipCommand,
Kees Cookf0605cb2012-02-29 16:09:14 -0800637 BuildGetRandomCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700638 BuildExtendCommand,
Mattias Nissler2a7e9b82017-07-10 13:46:20 +0200639 BuildGetVersionValCommand,
Mattias Nisslerb2b39702017-07-07 10:26:43 +0200640 BuildIFXFieldUpgradeInfoRequest2Command,
Mattias Nisslerac2286e2017-11-27 15:35:10 +0100641 BuildOIAPCommand,
Mattias Nisslerbc5b2db2017-12-05 16:27:42 +0100642 BuildOSAPCommand,
Mattias Nisslerac2286e2017-11-27 15:35:10 +0100643 BuildTakeOwnershipCommand,
Mattias Nissler2e626202017-12-08 14:13:25 +0100644 BuildCreateDelegationFamilyCommand,
645 BuildReadDelegationFamilyTableCommand,
Randall Spangler39f66112010-07-14 09:10:23 -0700646};
647
648static void FreeFields(Field* fld) {
649 if (fld != NULL) {
650 Field* next_field = fld->next;
Gaurav Shah553d00e2010-07-19 19:22:10 -0700651 free(fld);
Randall Spangler39f66112010-07-14 09:10:23 -0700652 FreeFields(next_field);
653 }
654}
655
656static void FreeCommands(Command* cmd) {
657 if (cmd != NULL) {
658 Command* next_command = cmd->next;
Randall Spangler39f66112010-07-14 09:10:23 -0700659 FreeFields(cmd->fields);
Luigi Semenzatod6acfd42013-01-08 16:23:11 -0800660 free(cmd);
Randall Spangler39f66112010-07-14 09:10:23 -0700661 FreeCommands(next_command);
662 }
663}
664
665int 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));
Randall Spangler39f66112010-07-14 09:10:23 -0700677
678 FreeCommands(commands);
679 return 0;
680}