/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* This program generates partially filled TPM datagrams and other compile-time
 * constants (e.g. structure sizes and offsets).  Compile this file---and ONLY
 * this file---with -fpack-struct.  We take advantage of the fact that the
 * (packed) TPM structures layout (mostly) match the TPM request and response
 * datagram layout.  When they don't completely match, some fixing is necessary
 * (see PCR_SELECTION_FIX below).
 */

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <tss/tcs.h>

#include "tlcl.h"
#include "tlcl_internal.h"
#include "tpmextras.h"

/* See struct Command below.  This structure represent a field in a TPM
 * command.  [name] is the field name.  [visible] is true if the field is
 * modified by the run-time.  Non-visible fields are initialized at build time
 * and remain constant.  [size] is the field size in bytes.  [value] is the
 * fixed value of non-visible fields.
 */
typedef struct Field {
  const char* name;
  bool visible;
  int offset;
  int size;
  uint32_t value;     /* large enough for all initializers */
  struct Field* next;
} Field;

/* This structure is used to build (at build time) and manipulate (at firmware
 * or emulation run time) buffers containing TPM datagrams.  [name] is the name
 * of a TPM command.  [size] is the size of the command buffer in bytes, when
 * known.  [max_size] is the maximum size allowed for variable-length commands
 * (such as Read and Write).  [fields] is a link-list of command fields.
 */
typedef struct Command {
  const char* name;
  int size;
  int max_size;
  Field* fields;
  struct Command* next;
} Command;

/* Adds a field to a command, and makes its offset visible.  The fields must be
 * added at increasing offsets.
 */
static void AddVisibleField(Command* cmd, const char* name, int offset) {
  Field* fld = (Field*) malloc(sizeof(Field));
  if (cmd->fields != NULL) {
    Field* fn = cmd->fields;
    assert(offset > fn->offset);
  }
  fld->next = cmd->fields;
  cmd->fields = fld;
  fld->name = name;
  fld->visible = true;
  fld->offset = offset;
}

/* Adds a constant field with its value.  The fields must be added at
 * increasing offsets.
 */
static void AddInitializedField(Command* cmd, int offset,
                                int size, uint32_t value) {
  Field* fld = (Field*) malloc(sizeof(Field));
  fld->next = cmd->fields;
  cmd->fields = fld;
  fld->name = NULL;
  fld->visible = false;
  fld->size = size;
  fld->offset = offset;
  fld->value = value;
}

/* Create a structure representing a TPM command datagram.
 */
Command* newCommand(TPM_COMMAND_CODE code, int size) {
  Command* cmd = (Command*) malloc(sizeof(Command));
  cmd->size = size;
  AddInitializedField(cmd, 0, sizeof(TPM_TAG), TPM_TAG_RQU_COMMAND);
  AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size);
  AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t),
                      sizeof(TPM_COMMAND_CODE), code);
  return cmd;
}

/* The TPM_PCR_SELECTION structure in /usr/include/tss/tpm.h contains a pointer
 * instead of an array[3] of bytes, so we need to adjust sizes and offsets
 * accordingly.
 */
#define PCR_SELECTION_FIX (3 - sizeof(char *))

/* BuildXXX builds TPM command XXX.
 */
Command* BuildDefineSpaceCommand(void) {
  int nv_data_public = kTpmRequestHeaderLength;
  int nv_index = nv_data_public + offsetof(TPM_NV_DATA_PUBLIC, nvIndex);
  int nv_pcr_info_read = nv_data_public +
    offsetof(TPM_NV_DATA_PUBLIC, pcrInfoRead);
  /*
   * Here we need to carefully add PCR_SELECTION_FIX (or twice that much) in
   * all the places where the offset calculation would be wrong without it.
   * The mismatch occurs in the TPM_PCR_SELECTION structure, and it must be
   * accounted for in all the structures that include it, directly or
   * indirectly.
   */
  int read_locality = nv_pcr_info_read +
    offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
  int nv_pcr_info_write = nv_data_public +
    offsetof(TPM_NV_DATA_PUBLIC, pcrInfoWrite) + PCR_SELECTION_FIX;
  int write_locality = nv_pcr_info_write +
    offsetof(TPM_PCR_INFO_SHORT, localityAtRelease) + PCR_SELECTION_FIX;
  int nv_permission = nv_data_public +
    offsetof(TPM_NV_DATA_PUBLIC, permission) + 2 * PCR_SELECTION_FIX;
  int nv_permission_tag =
    nv_permission + offsetof(TPM_NV_ATTRIBUTES, tag);
  int nv_permission_attributes =
    nv_permission + offsetof(TPM_NV_ATTRIBUTES, attributes);
  int nv_datasize = nv_data_public +
    offsetof(TPM_NV_DATA_PUBLIC, dataSize) + 2 * PCR_SELECTION_FIX;

  int size = kTpmRequestHeaderLength + sizeof(TPM_NV_DATA_PUBLIC) +
    2 * PCR_SELECTION_FIX + kEncAuthLength;
  Command* cmd = newCommand(TPM_ORD_NV_DefineSpace, size);
  cmd->name = "tpm_nv_definespace_cmd";

  AddVisibleField(cmd, "index", nv_index);
  AddVisibleField(cmd, "perm", nv_permission_attributes);
  AddVisibleField(cmd, "size", nv_datasize);

  AddInitializedField(cmd, nv_data_public, sizeof(uint16_t),
                      TPM_TAG_NV_DATA_PUBLIC);
  AddInitializedField(cmd, nv_pcr_info_read, sizeof(uint16_t), 3);
  AddInitializedField(cmd, read_locality, sizeof(TPM_LOCALITY_SELECTION),
                      TPM_ALL_LOCALITIES);
  AddInitializedField(cmd, nv_pcr_info_write, sizeof(uint16_t), 3);
  AddInitializedField(cmd, write_locality, sizeof(TPM_LOCALITY_SELECTION),
                      TPM_ALL_LOCALITIES);
  AddInitializedField(cmd, nv_permission_tag, sizeof(TPM_STRUCTURE_TAG),
                      TPM_TAG_NV_ATTRIBUTES);
  return cmd;
}

/* BuildXXX builds TPM command XXX.
 */
Command* BuildWriteCommand(void) {
  Command* cmd = newCommand(TPM_ORD_NV_WriteValue, 0);
  cmd->name = "tpm_nv_write_cmd";
  cmd->max_size = TPM_LARGE_ENOUGH_COMMAND_SIZE;
  AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
  AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
  AddVisibleField(cmd, "data", kTpmRequestHeaderLength + 12);
  return cmd;
}

Command* BuildReadCommand(void) {
  int size = kTpmRequestHeaderLength + kTpmReadInfoLength;
  Command* cmd = newCommand(TPM_ORD_NV_ReadValue, size);
  cmd->name = "tpm_nv_read_cmd";
  AddVisibleField(cmd, "index", kTpmRequestHeaderLength);
  AddVisibleField(cmd, "length", kTpmRequestHeaderLength + 8);
  return cmd;
}

Command* BuildPPAssertCommand(void) {
  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
  cmd->name = "tpm_ppassert_cmd";
  AddInitializedField(cmd, kTpmRequestHeaderLength,
                      sizeof(TPM_PHYSICAL_PRESENCE),
                      TPM_PHYSICAL_PRESENCE_PRESENT);
  return cmd;
}

Command* BuildPPLockCommand(void) {
  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
  Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
  cmd->name = "tpm_pplock_cmd";
  AddInitializedField(cmd, kTpmRequestHeaderLength,
                      sizeof(TPM_PHYSICAL_PRESENCE),
                      TPM_PHYSICAL_PRESENCE_LOCK);
  return cmd;
}

Command* BuildStartupCommand(void) {
  int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
  Command* cmd = newCommand(TPM_ORD_Startup, size);
  cmd->name = "tpm_startup_cmd";
  AddInitializedField(cmd, kTpmRequestHeaderLength,
                      sizeof(TPM_STARTUP_TYPE),
                      TPM_ST_CLEAR);
  return cmd;
}

Command* BuildSelftestfullCommand(void) {
  int size = kTpmRequestHeaderLength;
  Command* cmd = newCommand(TPM_ORD_SelfTestFull, size);
  cmd->name = "tpm_selftestfull_cmd";
  return cmd;
}

Command* BuildContinueSelfTestCommand(void) {
  int size = kTpmRequestHeaderLength;
  Command* cmd = newCommand(TPM_ORD_ContinueSelfTest, size);
  cmd->name = "tpm_continueselftest_cmd";
  return cmd;
}

Command* BuildReadPubekCommand(void) {
  int size = kTpmRequestHeaderLength + sizeof(TPM_NONCE);
  Command* cmd = newCommand(TPM_ORD_ReadPubek, size);
  cmd->name = "tpm_readpubek_cmd";
  return cmd;  
}

Command* BuildForceClearCommand(void) {
  int size = kTpmRequestHeaderLength;
  Command* cmd = newCommand(TPM_ORD_ForceClear, size);
  cmd->name = "tpm_forceclear_cmd";
  return cmd;  
}

Command* BuildPhysicalEnableCommand(void) {
  int size = kTpmRequestHeaderLength;
  Command* cmd = newCommand(TPM_ORD_PhysicalEnable, size);
  cmd->name = "tpm_physicalenable_cmd";
  return cmd;  
}

Command* BuildPhysicalSetDeactivatedCommand(void) {
  int size = kTpmRequestHeaderLength + sizeof(uint8_t);
  Command* cmd = newCommand(TPM_ORD_PhysicalSetDeactivated, size);
  cmd->name = "tpm_physicalsetdeactivated_cmd";
  AddVisibleField(cmd, "deactivated", kTpmRequestHeaderLength);
  return cmd;  
}

Command* BuildExtendCommand(void) {
  int size = kTpmRequestHeaderLength + sizeof(uint32_t) + kPcrDigestLength;
  Command* cmd = newCommand(TPM_ORD_Extend, size);
  cmd->name = "tpm_extend_cmd";
  AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength);
  AddVisibleField(cmd, "inDigest", kTpmRequestHeaderLength + sizeof(uint32_t));
  return cmd;  
}

Command* BuildGetCapabilityCommand(void) {
  int size = (kTpmRequestHeaderLength +
              sizeof(TPM_CAPABILITY_AREA) +   /* capArea */
              sizeof(uint32_t) +              /* subCapSize */
              sizeof(uint32_t));               /* subCap */
    
  Command* cmd = newCommand(TPM_ORD_GetCapability, size);
  cmd->name = "tpm_getcapability_cmd";
  AddInitializedField(cmd, kTpmRequestHeaderLength,
                      sizeof(TPM_CAPABILITY_AREA), TPM_CAP_FLAG);
  AddInitializedField(cmd, kTpmRequestHeaderLength +
                      sizeof(TPM_CAPABILITY_AREA),
                      sizeof(uint32_t), sizeof(uint32_t));
  AddInitializedField(cmd, kTpmRequestHeaderLength +
                      sizeof(TPM_CAPABILITY_AREA) + sizeof(uint32_t),
                      sizeof(uint32_t), TPM_CAP_FLAG_PERMANENT);
  return cmd;  
}

/* Output the fields of a structure.
 */
void OutputFields(Field* fld) {
  /*
   * Field order is reversed.
   */
  if (fld != NULL) {
    OutputFields(fld->next);
    if (fld->visible) {
      printf("  uint8_t* %s;\n", fld->name);
    }
  }
}

/* Outputs a structure initializer.
 */
int OutputBytes_(Command* cmd, Field* fld) {
  int cursor = 0;
  int i;
  /*
   * Field order is reversed.
   */
  if (fld != NULL) {
    cursor = OutputBytes_(cmd, fld->next);
  } else {
    return 0;
  }
  if (!fld->visible) {
    /*
     * Catch up missing fields.
     */
    assert(fld->offset >= cursor);
    for (i = 0; i < fld->offset - cursor; i++) {
      printf("0, ");
    }
    cursor = fld->offset;
    switch (fld->size) {
    case 1:
      printf("0x%x, ", fld->value);
      cursor += 1;
      break;
    case 2:
      printf("0x%x, 0x%x, ", fld->value >> 8, fld->value & 0xff);
      cursor += 2;
      break;
    case 4:
      printf("0x%x, 0x%x, 0x%x, 0x%x, ", fld->value >> 24,
             (fld->value >> 16) & 0xff, 
             (fld->value >> 8) & 0xff, 
             fld->value & 0xff);
      cursor += 4;
      break;
    default:
      error("invalid field size %d\n", fld->size);
      break;
    }
  }
  return cursor;
}

/* Helper to output a structure initializer.
 */
void OutputBytes(Command* cmd) {
  (void) OutputBytes_(cmd, cmd->fields);
}

void OutputFieldPointers(Command* cmd, Field* fld) {
  if (fld == NULL) {
    return;
  } else {
    OutputFieldPointers(cmd, fld->next);
    if (fld->visible) {
      printf("%s.buffer + %d, ", cmd->name, fld->offset);
    }
  }
}

/* Outputs the structure initializers for all commands.
 */
void OutputCommands(Command* cmd) {
  if (cmd == NULL) {
    return;
  } else {
    printf("struct {\n  uint8_t buffer[%d];\n",
           cmd->size == 0 ? cmd->max_size : cmd->size);
    OutputFields(cmd->fields);
    printf("} %s = {{", cmd->name);
    OutputBytes(cmd);
    printf("},\n");
    OutputFieldPointers(cmd, cmd->fields);
    printf("};\n\n");
  }
  OutputCommands(cmd->next);
}

Command* (*builders[])(void) = {
  BuildDefineSpaceCommand,
  BuildWriteCommand,
  BuildReadCommand,
  BuildPPAssertCommand,
  BuildPPLockCommand,
  BuildStartupCommand,
  BuildSelftestfullCommand,
  BuildContinueSelfTestCommand,
  BuildReadPubekCommand,
  BuildForceClearCommand,
  BuildPhysicalEnableCommand,
  BuildPhysicalSetDeactivatedCommand,
  BuildGetCapabilityCommand,
  BuildExtendCommand,
};

static void FreeFields(Field* fld) {
  if (fld != NULL) {
    Field* next_field = fld->next;
    free(fld);
    FreeFields(next_field);
  }
}

static void FreeCommands(Command* cmd) {
  if (cmd != NULL) {
    Command* next_command = cmd->next;
    free(cmd);
    FreeFields(cmd->fields);
    FreeCommands(next_command);
  }
}

int main(void) {
  Command* commands = NULL;
  int i;
  for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) {
    Command* cmd = builders[i]();
    cmd->next = commands;
    commands = cmd;
  }

  printf("/* This file is automatically generated */\n\n");
  OutputCommands(commands);
  printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO));

  FreeCommands(commands);
  return 0;
}
