1f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
239f66114c03639715cb88774255f066a2d942557Randall Spangler * Use of this source code is governed by a BSD-style license that can be
339f66114c03639715cb88774255f066a2d942557Randall Spangler * found in the LICENSE file.
439f66114c03639715cb88774255f066a2d942557Randall Spangler */
539f66114c03639715cb88774255f066a2d942557Randall Spangler
639f66114c03639715cb88774255f066a2d942557Randall Spangler/* This program generates partially filled TPM datagrams and other compile-time
739f66114c03639715cb88774255f066a2d942557Randall Spangler * constants (e.g. structure sizes and offsets).  Compile this file---and ONLY
839f66114c03639715cb88774255f066a2d942557Randall Spangler * this file---with -fpack-struct.  We take advantage of the fact that the
939f66114c03639715cb88774255f066a2d942557Randall Spangler * (packed) TPM structures layout (mostly) match the TPM request and response
1039f66114c03639715cb88774255f066a2d942557Randall Spangler * datagram layout.  When they don't completely match, some fixing is necessary
1139f66114c03639715cb88774255f066a2d942557Randall Spangler * (see PCR_SELECTION_FIX below).
1239f66114c03639715cb88774255f066a2d942557Randall Spangler */
1339f66114c03639715cb88774255f066a2d942557Randall Spangler
14553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah#include <assert.h>
1539f66114c03639715cb88774255f066a2d942557Randall Spangler#include <stddef.h>
1639f66114c03639715cb88774255f066a2d942557Randall Spangler#include <stdio.h>
1739f66114c03639715cb88774255f066a2d942557Randall Spangler#include <stdlib.h>
1839f66114c03639715cb88774255f066a2d942557Randall Spangler#include <tss/tcs.h>
1939f66114c03639715cb88774255f066a2d942557Randall Spangler
205896b9664d088699e246de964a7c374af663a34eLuigi Semenzato#include "sysincludes.h"
2139f66114c03639715cb88774255f066a2d942557Randall Spangler#include "tlcl_internal.h"
2239f66114c03639715cb88774255f066a2d942557Randall Spangler#include "tpmextras.h"
2339f66114c03639715cb88774255f066a2d942557Randall Spangler
2439f66114c03639715cb88774255f066a2d942557Randall Spangler/* See struct Command below.  This structure represent a field in a TPM
2539f66114c03639715cb88774255f066a2d942557Randall Spangler * command.  [name] is the field name.  [visible] is 1 if the field is
2639f66114c03639715cb88774255f066a2d942557Randall Spangler * modified by the run-time.  Non-visible fields are initialized at build time
2739f66114c03639715cb88774255f066a2d942557Randall Spangler * and remain constant.  [size] is the field size in bytes.  [value] is the
2839f66114c03639715cb88774255f066a2d942557Randall Spangler * fixed value of non-visible fields.
2939f66114c03639715cb88774255f066a2d942557Randall Spangler */
3039f66114c03639715cb88774255f066a2d942557Randall Spanglertypedef struct Field {
3139f66114c03639715cb88774255f066a2d942557Randall Spangler  const char* name;
3239f66114c03639715cb88774255f066a2d942557Randall Spangler  int visible;
3339f66114c03639715cb88774255f066a2d942557Randall Spangler  int offset;
3439f66114c03639715cb88774255f066a2d942557Randall Spangler  int size;
3539f66114c03639715cb88774255f066a2d942557Randall Spangler  uint32_t value;     /* large enough for all initializers */
3639f66114c03639715cb88774255f066a2d942557Randall Spangler  struct Field* next;
3739f66114c03639715cb88774255f066a2d942557Randall Spangler} Field;
3839f66114c03639715cb88774255f066a2d942557Randall Spangler
3939f66114c03639715cb88774255f066a2d942557Randall Spangler/* This structure is used to build (at build time) and manipulate (at firmware
4039f66114c03639715cb88774255f066a2d942557Randall Spangler * or emulation run time) buffers containing TPM datagrams.  [name] is the name
4139f66114c03639715cb88774255f066a2d942557Randall Spangler * of a TPM command.  [size] is the size of the command buffer in bytes, when
4239f66114c03639715cb88774255f066a2d942557Randall Spangler * known.  [max_size] is the maximum size allowed for variable-length commands
4339f66114c03639715cb88774255f066a2d942557Randall Spangler * (such as Read and Write).  [fields] is a link-list of command fields.
4439f66114c03639715cb88774255f066a2d942557Randall Spangler */
4539f66114c03639715cb88774255f066a2d942557Randall Spanglertypedef struct Command {
4639f66114c03639715cb88774255f066a2d942557Randall Spangler  const char* name;
4739f66114c03639715cb88774255f066a2d942557Randall Spangler  int size;
4839f66114c03639715cb88774255f066a2d942557Randall Spangler  int max_size;
4939f66114c03639715cb88774255f066a2d942557Randall Spangler  Field* fields;
5039f66114c03639715cb88774255f066a2d942557Randall Spangler  struct Command* next;
5139f66114c03639715cb88774255f066a2d942557Randall Spangler} Command;
5239f66114c03639715cb88774255f066a2d942557Randall Spangler
5339f66114c03639715cb88774255f066a2d942557Randall Spangler/* Adds a field to a command, and makes its offset visible.  The fields must be
5439f66114c03639715cb88774255f066a2d942557Randall Spangler * added at increasing offsets.
5539f66114c03639715cb88774255f066a2d942557Randall Spangler */
5639f66114c03639715cb88774255f066a2d942557Randall Spanglerstatic void AddVisibleField(Command* cmd, const char* name, int offset) {
57d6acfd441d70c0083276a9eed0d89f06bce1d4e6Luigi Semenzato  Field* fld = (Field*) calloc(1, sizeof(Field));
5839f66114c03639715cb88774255f066a2d942557Randall Spangler  if (cmd->fields != NULL) {
5939f66114c03639715cb88774255f066a2d942557Randall Spangler    assert(offset > fn->offset);
6039f66114c03639715cb88774255f066a2d942557Randall Spangler  }
6139f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->next = cmd->fields;
6239f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->fields = fld;
6339f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->name = name;
6439f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->visible = 1;
6539f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->offset = offset;
6639f66114c03639715cb88774255f066a2d942557Randall Spangler}
6739f66114c03639715cb88774255f066a2d942557Randall Spangler
6839f66114c03639715cb88774255f066a2d942557Randall Spangler/* Adds a constant field with its value.  The fields must be added at
6939f66114c03639715cb88774255f066a2d942557Randall Spangler * increasing offsets.
7039f66114c03639715cb88774255f066a2d942557Randall Spangler */
7139f66114c03639715cb88774255f066a2d942557Randall Spanglerstatic void AddInitializedField(Command* cmd, int offset,
7239f66114c03639715cb88774255f066a2d942557Randall Spangler                                int size, uint32_t value) {
73d6acfd441d70c0083276a9eed0d89f06bce1d4e6Luigi Semenzato  Field* fld = (Field*) calloc(1, sizeof(Field));
7439f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->next = cmd->fields;
7539f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->fields = fld;
7639f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->name = NULL;
7739f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->visible = 0;
7839f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->size = size;
7939f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->offset = offset;
8039f66114c03639715cb88774255f066a2d942557Randall Spangler  fld->value = value;
8139f66114c03639715cb88774255f066a2d942557Randall Spangler}
8239f66114c03639715cb88774255f066a2d942557Randall Spangler
8339f66114c03639715cb88774255f066a2d942557Randall Spangler/* Create a structure representing a TPM command datagram.
8439f66114c03639715cb88774255f066a2d942557Randall Spangler */
8539f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* newCommand(TPM_COMMAND_CODE code, int size) {
86d6acfd441d70c0083276a9eed0d89f06bce1d4e6Luigi Semenzato  Command* cmd = (Command*) calloc(1, sizeof(Command));
8739f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->size = size;
8839f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, 0, sizeof(TPM_TAG), TPM_TAG_RQU_COMMAND);
8939f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size);
9039f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t),
9139f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_COMMAND_CODE), code);
9239f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
9339f66114c03639715cb88774255f066a2d942557Randall Spangler}
9439f66114c03639715cb88774255f066a2d942557Randall Spangler
9539f66114c03639715cb88774255f066a2d942557Randall Spangler/* The TPM_PCR_SELECTION structure in /usr/include/tss/tpm.h contains a pointer
9639f66114c03639715cb88774255f066a2d942557Randall Spangler * instead of an array[3] of bytes, so we need to adjust sizes and offsets
9739f66114c03639715cb88774255f066a2d942557Randall Spangler * accordingly.
9839f66114c03639715cb88774255f066a2d942557Randall Spangler */
9939f66114c03639715cb88774255f066a2d942557Randall Spangler#define PCR_SELECTION_FIX (3 - sizeof(char *))
10039f66114c03639715cb88774255f066a2d942557Randall Spangler
10139f66114c03639715cb88774255f066a2d942557Randall Spangler/* BuildXXX builds TPM command XXX.
10239f66114c03639715cb88774255f066a2d942557Randall Spangler */
10339f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildDefineSpaceCommand(void) {
10439f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_data_public = kTpmRequestHeaderLength;
10539f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_index = nv_data_public + offsetof(TPM_NV_DATA_PUBLIC, nvIndex);
10639f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_pcr_info_read = nv_data_public +
10739f66114c03639715cb88774255f066a2d942557Randall Spangler    offsetof(TPM_NV_DATA_PUBLIC, pcrInfoRead);
10839f66114c03639715cb88774255f066a2d942557Randall Spangler  /*
10939f66114c03639715cb88774255f066a2d942557Randall Spangler   * Here we need to carefully add PCR_SELECTION_FIX (or twice that much) in
11039f66114c03639715cb88774255f066a2d942557Randall Spangler   * all the places where the offset calculation would be wrong without it.
11139f66114c03639715cb88774255f066a2d942557Randall Spangler   * The mismatch occurs in the TPM_PCR_SELECTION structure, and it must be
11239f66114c03639715cb88774255f066a2d942557Randall Spangler   * accounted for in all the structures that include it, directly or
11339f66114c03639715cb88774255f066a2d942557Randall Spangler   * indirectly.
11439f66114c03639715cb88774255f066a2d942557Randall Spangler   */
11539f66114c03639715cb88774255f066a2d942557Randall Spangler  int read_locality = nv_pcr_info_read +
11639f66114c03639715cb88774255f066a2d942557Randall Spangler    offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
11739f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_pcr_info_write = nv_data_public +
11839f66114c03639715cb88774255f066a2d942557Randall Spangler    offsetof(TPM_NV_DATA_PUBLIC, pcrInfoWrite) + PCR_SELECTION_FIX;
11939f66114c03639715cb88774255f066a2d942557Randall Spangler  int write_locality = nv_pcr_info_write +
12039f66114c03639715cb88774255f066a2d942557Randall Spangler    offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
12139f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_permission = nv_data_public +
12239f66114c03639715cb88774255f066a2d942557Randall Spangler    offsetof(TPM_NV_DATA_PUBLIC, permission) + 2 * PCR_SELECTION_FIX;
12339f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_permission_tag =
12439f66114c03639715cb88774255f066a2d942557Randall Spangler    nv_permission + offsetof(TPM_NV_ATTRIBUTES, tag);
12539f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_permission_attributes =
12639f66114c03639715cb88774255f066a2d942557Randall Spangler    nv_permission + offsetof(TPM_NV_ATTRIBUTES, attributes);
12739f66114c03639715cb88774255f066a2d942557Randall Spangler  int nv_datasize = nv_data_public +
12839f66114c03639715cb88774255f066a2d942557Randall Spangler    offsetof(TPM_NV_DATA_PUBLIC, dataSize) + 2 * PCR_SELECTION_FIX;
12939f66114c03639715cb88774255f066a2d942557Randall Spangler
13039f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + sizeof(TPM_NV_DATA_PUBLIC) +
13139f66114c03639715cb88774255f066a2d942557Randall Spangler    2 * PCR_SELECTION_FIX + kEncAuthLength;
13239f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_NV_DefineSpace, size);
13339f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_nv_definespace_cmd";
13439f66114c03639715cb88774255f066a2d942557Randall Spangler
13539f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "index", nv_index);
13639f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "perm", nv_permission_attributes);
13739f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "size", nv_datasize);
13839f66114c03639715cb88774255f066a2d942557Randall Spangler
13939f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, nv_data_public, sizeof(uint16_t),
14039f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_TAG_NV_DATA_PUBLIC);
14139f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, nv_pcr_info_read, sizeof(uint16_t), 3);
14239f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, read_locality, sizeof(TPM_LOCALITY_SELECTION),
14339f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_ALL_LOCALITIES);
14439f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, nv_pcr_info_write, sizeof(uint16_t), 3);
14539f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, write_locality, sizeof(TPM_LOCALITY_SELECTION),
14639f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_ALL_LOCALITIES);
14739f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, nv_permission_tag, sizeof(TPM_STRUCTURE_TAG),
14839f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_TAG_NV_ATTRIBUTES);
14939f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
15039f66114c03639715cb88774255f066a2d942557Randall Spangler}
15139f66114c03639715cb88774255f066a2d942557Randall Spangler
15239f66114c03639715cb88774255f066a2d942557Randall Spangler/* BuildXXX builds TPM command XXX.
15339f66114c03639715cb88774255f066a2d942557Randall Spangler */
15439f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildWriteCommand(void) {
15539f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_NV_WriteValue, 0);
15639f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_nv_write_cmd";
15739f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->max_size = TPM_LARGE_ENOUGH_COMMAND_SIZE;
15839f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
15939f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
16039f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "data", kTpmRequestHeaderLength + 12);
16139f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
16239f66114c03639715cb88774255f066a2d942557Randall Spangler}
16339f66114c03639715cb88774255f066a2d942557Randall Spangler
16439f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildReadCommand(void) {
16539f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + kTpmReadInfoLength;
16639f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_NV_ReadValue, size);
16739f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_nv_read_cmd";
16839f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
16939f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
17039f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
17139f66114c03639715cb88774255f066a2d942557Randall Spangler}
17239f66114c03639715cb88774255f066a2d942557Randall Spangler
173946370d012a809bba833ff9d37fe0ce86af09860Kees CookCommand* BuildPCRReadCommand(void) {
174946370d012a809bba833ff9d37fe0ce86af09860Kees Cook  int size = kTpmRequestHeaderLength + sizeof(uint32_t);
175946370d012a809bba833ff9d37fe0ce86af09860Kees Cook  Command* cmd = newCommand(TPM_ORD_PcrRead, size);
176946370d012a809bba833ff9d37fe0ce86af09860Kees Cook  cmd->name = "tpm_pcr_read_cmd";
177946370d012a809bba833ff9d37fe0ce86af09860Kees Cook  AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
178946370d012a809bba833ff9d37fe0ce86af09860Kees Cook  return cmd;
179946370d012a809bba833ff9d37fe0ce86af09860Kees Cook}
180946370d012a809bba833ff9d37fe0ce86af09860Kees Cook
18139f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildPPAssertCommand(void) {
18239f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
18339f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
18439f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_ppassert_cmd";
18539f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength,
18639f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_PHYSICAL_PRESENCE),
18739f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_PHYSICAL_PRESENCE_PRESENT);
18839f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
18939f66114c03639715cb88774255f066a2d942557Randall Spangler}
19039f66114c03639715cb88774255f066a2d942557Randall Spangler
1911d83dd1ba5b825407a8e17972c54577d14ba173dLuigi SemenzatoCommand* BuildPPEnableCommand(void) {
1921d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
1931d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
1941d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato  cmd->name = "tpm_ppenable_cmd";
1951d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato  AddInitializedField(cmd, kTpmRequestHeaderLength,
1961d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato                      sizeof(TPM_PHYSICAL_PRESENCE),
1971d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato                      TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
1981d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato  return cmd;
1991d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato}
2001d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato
201377557fcb260c9b41abc36ebba5759336436e59cLuigi SemenzatoCommand* BuildFinalizePPCommand(void) {
202377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
203377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
204377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato  cmd->name = "tpm_finalizepp_cmd";
205377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato  AddInitializedField(cmd, kTpmRequestHeaderLength,
206377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato                      sizeof(TPM_PHYSICAL_PRESENCE),
207377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato                      TPM_PHYSICAL_PRESENCE_CMD_ENABLE |
208377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato                      TPM_PHYSICAL_PRESENCE_HW_DISABLE |
209377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato                      TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK);
210377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato  return cmd;
211377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato}
212377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato
21339f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildPPLockCommand(void) {
21439f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
21539f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
21639f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_pplock_cmd";
21739f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength,
21839f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_PHYSICAL_PRESENCE),
21939f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_PHYSICAL_PRESENCE_LOCK);
22039f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
22139f66114c03639715cb88774255f066a2d942557Randall Spangler}
22239f66114c03639715cb88774255f066a2d942557Randall Spangler
22339f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildStartupCommand(void) {
2243da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
22539f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_Startup, size);
22639f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_startup_cmd";
22739f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength,
22839f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_STARTUP_TYPE),
22939f66114c03639715cb88774255f066a2d942557Randall Spangler                      TPM_ST_CLEAR);
23039f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
23139f66114c03639715cb88774255f066a2d942557Randall Spangler}
23239f66114c03639715cb88774255f066a2d942557Randall Spangler
23354992f9d3379c4b048d8da6171f0e578b2db4facLuigi SemenzatoCommand* BuildSaveStateCommand(void) {
23454992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato  int size = kTpmRequestHeaderLength;
23554992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato  Command* cmd = newCommand(TPM_ORD_SaveState, size);
23654992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato  cmd->name = "tpm_savestate_cmd";
23754992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato  return cmd;
23854992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato}
23954992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato
2403da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi SemenzatoCommand* BuildResumeCommand(void) {
2413da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  int size = kTpmRequestHeaderLength + sizeof(TPM_STARTUP_TYPE);
2423da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  Command* cmd = newCommand(TPM_ORD_Startup, size);
2433da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  cmd->name = "tpm_resume_cmd";
2443da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  AddInitializedField(cmd, kTpmRequestHeaderLength,
2453da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato                      sizeof(TPM_STARTUP_TYPE),
2463da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato                      TPM_ST_STATE);
2473da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  return cmd;
2483da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato}
2493da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato
25039f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildSelftestfullCommand(void) {
25139f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength;
25239f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_SelfTestFull, size);
25339f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_selftestfull_cmd";
25439f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
25539f66114c03639715cb88774255f066a2d942557Randall Spangler}
25639f66114c03639715cb88774255f066a2d942557Randall Spangler
25739f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildContinueSelfTestCommand(void) {
25839f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength;
25939f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_ContinueSelfTest, size);
26039f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_continueselftest_cmd";
26139f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
26239f66114c03639715cb88774255f066a2d942557Randall Spangler}
26339f66114c03639715cb88774255f066a2d942557Randall Spangler
26439f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildReadPubekCommand(void) {
26539f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + sizeof(TPM_NONCE);
26639f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_ReadPubek, size);
26739f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_readpubek_cmd";
26839f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
26939f66114c03639715cb88774255f066a2d942557Randall Spangler}
27039f66114c03639715cb88774255f066a2d942557Randall Spangler
27139f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildForceClearCommand(void) {
27239f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength;
27339f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_ForceClear, size);
27439f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_forceclear_cmd";
27539f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
27639f66114c03639715cb88774255f066a2d942557Randall Spangler}
27739f66114c03639715cb88774255f066a2d942557Randall Spangler
27839f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildPhysicalEnableCommand(void) {
27939f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength;
28039f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_PhysicalEnable, size);
28139f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_physicalenable_cmd";
28239f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
28339f66114c03639715cb88774255f066a2d942557Randall Spangler}
28439f66114c03639715cb88774255f066a2d942557Randall Spangler
28539f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildPhysicalDisableCommand(void) {
28639f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength;
28739f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_PhysicalDisable, size);
28839f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_physicaldisable_cmd";
28939f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
29039f66114c03639715cb88774255f066a2d942557Randall Spangler}
29139f66114c03639715cb88774255f066a2d942557Randall Spangler
29239f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildPhysicalSetDeactivatedCommand(void) {
29339f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + sizeof(uint8_t);
29439f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_PhysicalSetDeactivated, size);
29539f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_physicalsetdeactivated_cmd";
29639f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "deactivated", kTpmRequestHeaderLength);
29739f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
29839f66114c03639715cb88774255f066a2d942557Randall Spangler}
29939f66114c03639715cb88774255f066a2d942557Randall Spangler
30039f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildExtendCommand(void) {
30139f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = kTpmRequestHeaderLength + sizeof(uint32_t) + kPcrDigestLength;
30239f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_Extend, size);
30339f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_extend_cmd";
30439f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
30539f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "inDigest", kTpmRequestHeaderLength + sizeof(uint32_t));
30639f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
30739f66114c03639715cb88774255f066a2d942557Randall Spangler}
30839f66114c03639715cb88774255f066a2d942557Randall Spangler
30939f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildGetFlagsCommand(void) {
31039f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = (kTpmRequestHeaderLength +
31139f66114c03639715cb88774255f066a2d942557Randall Spangler              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
31239f66114c03639715cb88774255f066a2d942557Randall Spangler              sizeof(uint32_t) +              /* subCapSize */
31339f66114c03639715cb88774255f066a2d942557Randall Spangler              sizeof(uint32_t));              /* subCap */
31439f66114c03639715cb88774255f066a2d942557Randall Spangler
31539f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
31639f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_getflags_cmd";
31739f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength,
31839f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
31939f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength +
32039f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_CAPABILITY_AREA),
32139f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(uint32_t), sizeof(uint32_t));
32239f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength +
32339f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
32439f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(uint32_t), TPM_CAP_FLAG_PERMANENT);
32539f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
32639f66114c03639715cb88774255f066a2d942557Randall Spangler}
32739f66114c03639715cb88774255f066a2d942557Randall Spangler
3285896b9664d088699e246de964a7c374af663a34eLuigi SemenzatoCommand* BuildGetSTClearFlagsCommand(void) {
3295896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  int size = (kTpmRequestHeaderLength +
3305896b9664d088699e246de964a7c374af663a34eLuigi Semenzato              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
3315896b9664d088699e246de964a7c374af663a34eLuigi Semenzato              sizeof(uint32_t) +              /* subCapSize */
3325896b9664d088699e246de964a7c374af663a34eLuigi Semenzato              sizeof(uint32_t));              /* subCap */
3335896b9664d088699e246de964a7c374af663a34eLuigi Semenzato
3345896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
3355896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  cmd->name = "tpm_getstclearflags_cmd";
3365896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  AddInitializedField(cmd, kTpmRequestHeaderLength,
3375896b9664d088699e246de964a7c374af663a34eLuigi Semenzato                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
3385896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  AddInitializedField(cmd, kTpmRequestHeaderLength +
3395896b9664d088699e246de964a7c374af663a34eLuigi Semenzato                      sizeof(TPM_CAPABILITY_AREA),
3405896b9664d088699e246de964a7c374af663a34eLuigi Semenzato                      sizeof(uint32_t), sizeof(uint32_t));
3415896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  AddInitializedField(cmd, kTpmRequestHeaderLength +
3425896b9664d088699e246de964a7c374af663a34eLuigi Semenzato                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
3435896b9664d088699e246de964a7c374af663a34eLuigi Semenzato                      sizeof(uint32_t), TPM_CAP_FLAG_VOLATILE);
3445896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  return cmd;
3455896b9664d088699e246de964a7c374af663a34eLuigi Semenzato}
3465896b9664d088699e246de964a7c374af663a34eLuigi Semenzato
34739f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* BuildGetPermissionsCommand(void) {
34839f66114c03639715cb88774255f066a2d942557Randall Spangler  int size = (kTpmRequestHeaderLength +
34939f66114c03639715cb88774255f066a2d942557Randall Spangler              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
35039f66114c03639715cb88774255f066a2d942557Randall Spangler              sizeof(uint32_t) +              /* subCapSize */
35139f66114c03639715cb88774255f066a2d942557Randall Spangler              sizeof(uint32_t));              /* subCap */
35239f66114c03639715cb88774255f066a2d942557Randall Spangler
35339f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
35439f66114c03639715cb88774255f066a2d942557Randall Spangler  cmd->name = "tpm_getpermissions_cmd";
35539f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength,
35639f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_NV_INDEX);
35739f66114c03639715cb88774255f066a2d942557Randall Spangler  AddInitializedField(cmd, kTpmRequestHeaderLength +
35839f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(TPM_CAPABILITY_AREA),
35939f66114c03639715cb88774255f066a2d942557Randall Spangler                      sizeof(uint32_t), sizeof(uint32_t));
36039f66114c03639715cb88774255f066a2d942557Randall Spangler  AddVisibleField(cmd, "index", kTpmRequestHeaderLength +
36139f66114c03639715cb88774255f066a2d942557Randall Spangler                  sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t));
36239f66114c03639715cb88774255f066a2d942557Randall Spangler  return cmd;
36339f66114c03639715cb88774255f066a2d942557Randall Spangler}
36439f66114c03639715cb88774255f066a2d942557Randall Spangler
3658b6da26a6e5978a43233f7a43c7bab5889d3817aKees CookCommand* BuildGetOwnershipCommand(void) {
3668b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  int size = (kTpmRequestHeaderLength +
3678b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
3688b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook              sizeof(uint32_t) +              /* subCapSize */
3698b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook              sizeof(uint32_t));              /* subCap */
3708b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook
3718b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
3728b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  cmd->name = "tpm_getownership_cmd";
3738b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  AddInitializedField(cmd, kTpmRequestHeaderLength,
3748b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_PROPERTY);
3758b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  AddInitializedField(cmd, kTpmRequestHeaderLength +
3768b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook                      sizeof(TPM_CAPABILITY_AREA),
3778b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook                      sizeof(uint32_t), sizeof(uint32_t));
3788b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  AddInitializedField(cmd, kTpmRequestHeaderLength +
3798b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
3808b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook                      sizeof(uint32_t), TPM_CAP_PROP_OWNER);
3818b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  return cmd;
3828b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook}
3838b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook
384f0605cbdc36f58829a908a3333e438c565c8c7afKees CookCommand* BuildGetRandomCommand(void) {
385f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook  int size = kTpmRequestHeaderLength + sizeof(uint32_t);
386f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook  Command* cmd = newCommand(TPM_ORD_GetRandom, size);
387f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook  cmd->name = "tpm_get_random_cmd";
388f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook  AddVisibleField(cmd, "bytesRequested", kTpmRequestHeaderLength);
389f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook  return cmd;
390f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook}
391f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook
39239f66114c03639715cb88774255f066a2d942557Randall Spangler/* Output the fields of a structure.
39339f66114c03639715cb88774255f066a2d942557Randall Spangler */
39439f66114c03639715cb88774255f066a2d942557Randall Spanglervoid OutputFields(Field* fld) {
39539f66114c03639715cb88774255f066a2d942557Randall Spangler  /*
39639f66114c03639715cb88774255f066a2d942557Randall Spangler   * Field order is reversed.
39739f66114c03639715cb88774255f066a2d942557Randall Spangler   */
39839f66114c03639715cb88774255f066a2d942557Randall Spangler  if (fld != NULL) {
39939f66114c03639715cb88774255f066a2d942557Randall Spangler    OutputFields(fld->next);
40039f66114c03639715cb88774255f066a2d942557Randall Spangler    if (fld->visible) {
401553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah      printf("  uint16_t %s;\n", fld->name);
40239f66114c03639715cb88774255f066a2d942557Randall Spangler    }
40339f66114c03639715cb88774255f066a2d942557Randall Spangler  }
40439f66114c03639715cb88774255f066a2d942557Randall Spangler}
40539f66114c03639715cb88774255f066a2d942557Randall Spangler
40639f66114c03639715cb88774255f066a2d942557Randall Spangler/* Outputs a structure initializer.
40739f66114c03639715cb88774255f066a2d942557Randall Spangler */
40839f66114c03639715cb88774255f066a2d942557Randall Spanglerint OutputBytes_(Command* cmd, Field* fld) {
40939f66114c03639715cb88774255f066a2d942557Randall Spangler  int cursor = 0;
41039f66114c03639715cb88774255f066a2d942557Randall Spangler  int i;
41139f66114c03639715cb88774255f066a2d942557Randall Spangler  /*
41239f66114c03639715cb88774255f066a2d942557Randall Spangler   * Field order is reversed.
41339f66114c03639715cb88774255f066a2d942557Randall Spangler   */
41439f66114c03639715cb88774255f066a2d942557Randall Spangler  if (fld != NULL) {
41539f66114c03639715cb88774255f066a2d942557Randall Spangler    cursor = OutputBytes_(cmd, fld->next);
41639f66114c03639715cb88774255f066a2d942557Randall Spangler  } else {
41739f66114c03639715cb88774255f066a2d942557Randall Spangler    return 0;
41839f66114c03639715cb88774255f066a2d942557Randall Spangler  }
41939f66114c03639715cb88774255f066a2d942557Randall Spangler  if (!fld->visible) {
42039f66114c03639715cb88774255f066a2d942557Randall Spangler    /*
42139f66114c03639715cb88774255f066a2d942557Randall Spangler     * Catch up missing fields.
42239f66114c03639715cb88774255f066a2d942557Randall Spangler     */
42339f66114c03639715cb88774255f066a2d942557Randall Spangler    assert(fld->offset >= cursor);
42439f66114c03639715cb88774255f066a2d942557Randall Spangler    for (i = 0; i < fld->offset - cursor; i++) {
42539f66114c03639715cb88774255f066a2d942557Randall Spangler      printf("0, ");
42639f66114c03639715cb88774255f066a2d942557Randall Spangler    }
42739f66114c03639715cb88774255f066a2d942557Randall Spangler    cursor = fld->offset;
42839f66114c03639715cb88774255f066a2d942557Randall Spangler    switch (fld->size) {
42939f66114c03639715cb88774255f066a2d942557Randall Spangler    case 1:
43039f66114c03639715cb88774255f066a2d942557Randall Spangler      printf("0x%x, ", fld->value);
43139f66114c03639715cb88774255f066a2d942557Randall Spangler      cursor += 1;
43239f66114c03639715cb88774255f066a2d942557Randall Spangler      break;
43339f66114c03639715cb88774255f066a2d942557Randall Spangler    case 2:
43439f66114c03639715cb88774255f066a2d942557Randall Spangler      printf("0x%x, 0x%x, ", fld->value >> 8, fld->value & 0xff);
43539f66114c03639715cb88774255f066a2d942557Randall Spangler      cursor += 2;
43639f66114c03639715cb88774255f066a2d942557Randall Spangler      break;
43739f66114c03639715cb88774255f066a2d942557Randall Spangler    case 4:
43839f66114c03639715cb88774255f066a2d942557Randall Spangler      printf("0x%x, 0x%x, 0x%x, 0x%x, ", fld->value >> 24,
43939f66114c03639715cb88774255f066a2d942557Randall Spangler             (fld->value >> 16) & 0xff,
44039f66114c03639715cb88774255f066a2d942557Randall Spangler             (fld->value >> 8) & 0xff,
44139f66114c03639715cb88774255f066a2d942557Randall Spangler             fld->value & 0xff);
44239f66114c03639715cb88774255f066a2d942557Randall Spangler      cursor += 4;
44339f66114c03639715cb88774255f066a2d942557Randall Spangler      break;
44439f66114c03639715cb88774255f066a2d942557Randall Spangler    default:
445553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah      fprintf(stderr, "invalid field size %d\n", fld->size);
446553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah      exit(1);
44739f66114c03639715cb88774255f066a2d942557Randall Spangler      break;
44839f66114c03639715cb88774255f066a2d942557Randall Spangler    }
44939f66114c03639715cb88774255f066a2d942557Randall Spangler  }
45039f66114c03639715cb88774255f066a2d942557Randall Spangler  return cursor;
45139f66114c03639715cb88774255f066a2d942557Randall Spangler}
45239f66114c03639715cb88774255f066a2d942557Randall Spangler
45339f66114c03639715cb88774255f066a2d942557Randall Spangler/* Helper to output a structure initializer.
45439f66114c03639715cb88774255f066a2d942557Randall Spangler */
45539f66114c03639715cb88774255f066a2d942557Randall Spanglervoid OutputBytes(Command* cmd) {
45639f66114c03639715cb88774255f066a2d942557Randall Spangler  (void) OutputBytes_(cmd, cmd->fields);
45739f66114c03639715cb88774255f066a2d942557Randall Spangler}
45839f66114c03639715cb88774255f066a2d942557Randall Spangler
45939f66114c03639715cb88774255f066a2d942557Randall Spanglervoid OutputFieldPointers(Command* cmd, Field* fld) {
46039f66114c03639715cb88774255f066a2d942557Randall Spangler  if (fld == NULL) {
46139f66114c03639715cb88774255f066a2d942557Randall Spangler    return;
46239f66114c03639715cb88774255f066a2d942557Randall Spangler  } else {
46339f66114c03639715cb88774255f066a2d942557Randall Spangler    OutputFieldPointers(cmd, fld->next);
46439f66114c03639715cb88774255f066a2d942557Randall Spangler    if (fld->visible) {
465553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah      printf("%d, ", fld->offset);
46639f66114c03639715cb88774255f066a2d942557Randall Spangler    }
46739f66114c03639715cb88774255f066a2d942557Randall Spangler  }
46839f66114c03639715cb88774255f066a2d942557Randall Spangler}
46939f66114c03639715cb88774255f066a2d942557Randall Spangler
47039f66114c03639715cb88774255f066a2d942557Randall Spangler/* Outputs the structure initializers for all commands.
47139f66114c03639715cb88774255f066a2d942557Randall Spangler */
47239f66114c03639715cb88774255f066a2d942557Randall Spanglervoid OutputCommands(Command* cmd) {
47339f66114c03639715cb88774255f066a2d942557Randall Spangler  if (cmd == NULL) {
47439f66114c03639715cb88774255f066a2d942557Randall Spangler    return;
47539f66114c03639715cb88774255f066a2d942557Randall Spangler  } else {
47689a02c194f1b6da0de7f98784d85e6827c3a1aecLuigi Semenzato    printf("const struct s_%s{\n  uint8_t buffer[%d];\n",
477553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah           cmd->name, cmd->size == 0 ? cmd->max_size : cmd->size);
47839f66114c03639715cb88774255f066a2d942557Randall Spangler    OutputFields(cmd->fields);
47939f66114c03639715cb88774255f066a2d942557Randall Spangler    printf("} %s = {{", cmd->name);
48039f66114c03639715cb88774255f066a2d942557Randall Spangler    OutputBytes(cmd);
48139f66114c03639715cb88774255f066a2d942557Randall Spangler    printf("},\n");
48239f66114c03639715cb88774255f066a2d942557Randall Spangler    OutputFieldPointers(cmd, cmd->fields);
48339f66114c03639715cb88774255f066a2d942557Randall Spangler    printf("};\n\n");
48439f66114c03639715cb88774255f066a2d942557Randall Spangler  }
48539f66114c03639715cb88774255f066a2d942557Randall Spangler  OutputCommands(cmd->next);
48639f66114c03639715cb88774255f066a2d942557Randall Spangler}
48739f66114c03639715cb88774255f066a2d942557Randall Spangler
48839f66114c03639715cb88774255f066a2d942557Randall SpanglerCommand* (*builders[])(void) = {
48939f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildDefineSpaceCommand,
49039f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildWriteCommand,
49139f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildReadCommand,
492946370d012a809bba833ff9d37fe0ce86af09860Kees Cook  BuildPCRReadCommand,
49339f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildPPAssertCommand,
4941d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato  BuildPPEnableCommand,
49539f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildPPLockCommand,
496377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato  BuildFinalizePPCommand,
49739f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildStartupCommand,
49854992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato  BuildSaveStateCommand,
4993da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato  BuildResumeCommand,
50039f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildSelftestfullCommand,
50139f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildContinueSelfTestCommand,
50239f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildReadPubekCommand,
50339f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildForceClearCommand,
50439f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildPhysicalDisableCommand,
50539f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildPhysicalEnableCommand,
50639f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildPhysicalSetDeactivatedCommand,
50739f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildGetFlagsCommand,
5085896b9664d088699e246de964a7c374af663a34eLuigi Semenzato  BuildGetSTClearFlagsCommand,
50939f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildGetPermissionsCommand,
5108b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook  BuildGetOwnershipCommand,
511f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook  BuildGetRandomCommand,
51239f66114c03639715cb88774255f066a2d942557Randall Spangler  BuildExtendCommand,
51339f66114c03639715cb88774255f066a2d942557Randall Spangler};
51439f66114c03639715cb88774255f066a2d942557Randall Spangler
51539f66114c03639715cb88774255f066a2d942557Randall Spanglerstatic void FreeFields(Field* fld) {
51639f66114c03639715cb88774255f066a2d942557Randall Spangler  if (fld != NULL) {
51739f66114c03639715cb88774255f066a2d942557Randall Spangler    Field* next_field = fld->next;
518553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah    free(fld);
51939f66114c03639715cb88774255f066a2d942557Randall Spangler    FreeFields(next_field);
52039f66114c03639715cb88774255f066a2d942557Randall Spangler  }
52139f66114c03639715cb88774255f066a2d942557Randall Spangler}
52239f66114c03639715cb88774255f066a2d942557Randall Spangler
52339f66114c03639715cb88774255f066a2d942557Randall Spanglerstatic void FreeCommands(Command* cmd) {
52439f66114c03639715cb88774255f066a2d942557Randall Spangler  if (cmd != NULL) {
52539f66114c03639715cb88774255f066a2d942557Randall Spangler    Command* next_command = cmd->next;
52639f66114c03639715cb88774255f066a2d942557Randall Spangler    FreeFields(cmd->fields);
527d6acfd441d70c0083276a9eed0d89f06bce1d4e6Luigi Semenzato    free(cmd);
52839f66114c03639715cb88774255f066a2d942557Randall Spangler    FreeCommands(next_command);
52939f66114c03639715cb88774255f066a2d942557Randall Spangler  }
53039f66114c03639715cb88774255f066a2d942557Randall Spangler}
53139f66114c03639715cb88774255f066a2d942557Randall Spangler
53239f66114c03639715cb88774255f066a2d942557Randall Spanglerint main(void) {
53339f66114c03639715cb88774255f066a2d942557Randall Spangler  Command* commands = NULL;
53439f66114c03639715cb88774255f066a2d942557Randall Spangler  int i;
53539f66114c03639715cb88774255f066a2d942557Randall Spangler  for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) {
53639f66114c03639715cb88774255f066a2d942557Randall Spangler    Command* cmd = builders[i]();
53739f66114c03639715cb88774255f066a2d942557Randall Spangler    cmd->next = commands;
53839f66114c03639715cb88774255f066a2d942557Randall Spangler    commands = cmd;
53939f66114c03639715cb88774255f066a2d942557Randall Spangler  }
54039f66114c03639715cb88774255f066a2d942557Randall Spangler
54139f66114c03639715cb88774255f066a2d942557Randall Spangler  printf("/* This file is automatically generated */\n\n");
54239f66114c03639715cb88774255f066a2d942557Randall Spangler  OutputCommands(commands);
54339f66114c03639715cb88774255f066a2d942557Randall Spangler  printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO));
54439f66114c03639715cb88774255f066a2d942557Randall Spangler  printf("const int kNvDataPublicPermissionsOffset = %d;\n",
54539f66114c03639715cb88774255f066a2d942557Randall Spangler         (int) (offsetof(TPM_NV_DATA_PUBLIC, permission) +
54639f66114c03639715cb88774255f066a2d942557Randall Spangler                2 * PCR_SELECTION_FIX +
54739f66114c03639715cb88774255f066a2d942557Randall Spangler                offsetof(TPM_NV_ATTRIBUTES, attributes)));
54839f66114c03639715cb88774255f066a2d942557Randall Spangler
54939f66114c03639715cb88774255f066a2d942557Randall Spangler  FreeCommands(commands);
55039f66114c03639715cb88774255f066a2d942557Randall Spangler  return 0;
55139f66114c03639715cb88774255f066a2d942557Randall Spangler}
552