/* 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.
 */

/* Exhaustive testing for correctness and integrity of TPM locking code from
 * all interesting initial conditions.
 *
 * This program iterates through a large number of initial states of the TPM at
 * power on, and executes the code related to initialing the TPM and managing
 * the anti-rollback indices.
 *
 * This program must be run on a system with "TPM-agnostic" BIOS: that is, the
 * system must have a TPM (as of this date, the emulator isn't good enough,
 * because it doesn't support bGlobalLock), but the firmware should not issue a
 * TPM_Startup.  In addition, the TPM drivers must be loaded (tpm_tis, tpm, and
 * tpm_bios) but tcsd should NOT be running.  However, tcsd must be installed,
 * as well as the command tpm_takeownership from the TPM tools, and tpm-nvtool
 * from third-party/tpm.
 *
 * This program must be run as root.  It issues multiple reboots, saving and
 * restoring the state from a file.  Typically it works in two phases: on one
 * reboot it sets the TPM to a certain state, and in the next reboot it runs
 * the test.
 *
 * This program may take a long time to complete.
 *
 * A companion upstart file rbtest.conf contains test setup instructions.  Look
 * around for it.
 */

#include "rollback_index.h"
#include "tlcl.h"
#include "tss_constants.h"
#include "utility.h"

#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>

#define RETURN_ON_FAILURE(tpm_command) do {             \
    uint32_t result;                                    \
    if ((result = (tpm_command)) != TPM_SUCCESS) {      \
      return result;                                    \
    }                                                   \
  } while (0)

#define WRITE_BUCKET_NV_INDEX 0x1050
#define STATEPATH "/var/spool/rbtest.state"
#define TPM_ANY_FAILURE (-1)

#define TPM_MAX_NV_WRITE_NOOWNER 64
#define MAX_NV_WRITES_AT_BOOT 18         /* see comment below */
#define INITIALIZATION_NV_WRITES 11      /* see below */

const int high_writecount = TPM_MAX_NV_WRITE_NOOWNER;
/* The -1 below is to make sure there is at least one case when we don't hit
 * the write limit.  It is probably unnecessary, but we pay this cost to avoid
 * an off-by-one error.
 */
const int low_writecount = TPM_MAX_NV_WRITE_NOOWNER - MAX_NV_WRITES_AT_BOOT - 1;
const int low_writecount_when_initialized = TPM_MAX_NV_WRITE_NOOWNER
  - MAX_NV_WRITES_AT_BOOT + INITIALIZATION_NV_WRITES;

/*
 * This structure contains all TPM states of interest, and other testing
 * states.  It is saved and restored from a file across all reboots.
 *
 * OWNED/UNOWNED
 * ACTIVATED/DEACTIVATED
 * ENABLED/DISABLED
 * WRITE COUNT
 *
 * The write count tests hitting the write limit with an unowned TPM.  After
 * resetting the TPM we reset the write count to zero, then we perform
 * |writecount| writes to bring the count to the desired number.
 *
 * Low write counts are not interesting, because we know they cannot cause the
 * code to hit the limit during a single boot.  There are a total of N
 * SafeWrite and SafeDefineSpace call sites, where N = MAX_NV_WRITES_AT_BOOT.
 * Every call site can be reached at most once at every boot (there are no
 * loops or multiple nested calls).  So we only need to test N + 1 different
 * initial values of the NVRAM write count (between 64 - (N + 1)) and 64).
 *
 * A number of calls happen at initialization, so when the TPM_IS_INITIALIZED
 * space exists, we only need to start checking at TPM_MAX_NV_WRITE_NOOWNER -
 * MAX_NV_WRITES_AT_BOOT + INITIALIZATION_NV_WRITES.
 *
 * TPM_IS_INITIALIZED space exists/does not exist
 * KERNEL_MUST_USE_BACKUP = 0 or 1
 * KERNEL_VERSIONS exists/does not
 * KERNEL_VERSIONS space has wrong permissions
 * KERNEL_VERSIONS does not contain the replacement-prevention value
 * KERNEL_VERSIONS and KERNEL_VERSIONS_BACKUP are the same/are not
 * DEVELOPER_MODE_NV_INDEX = 0 or 1
 *
 * developer switch on/off
 * recovery switch on/off
 */

typedef struct RBTState {
  /* Internal testing state */
  int advancing;  /* this is 1 if we are setting the TPM to the next initial
                     state, 0 if we are running the test. */

  /* TPM state */
  int writecount;
  int owned;
  int disable;
  int deactivated;
  int TPM_IS_INITIALIZED_exists;
  int KERNEL_MUST_USE_BACKUP;
  int KERNEL_VERSIONS_exists;
  int KERNEL_VERSIONS_wrong_permissions;
  int KERNEL_VERSIONS_wrong_value;
  int KERNEL_VERSIONS_same_as_backup;
  int DEVELOPER_MODE;   /* content of DEVELOPER_MODE space */
  int developer;        /* setting of developer mode switch */
  int recovery;         /* booting in recovery mode */
} RBTState;

RBTState RBTS;

/* Set to 1 if the TPM was cleared in this run, to avoid clearing it again
 * before we set the write count.
 */
int tpm_was_just_cleared = 0;

const char* RBTS_format =
  "advancing=%d, owned=%d, disable=%d, activated=%d, "
  "writecount=%d, TII_exists=%d, KMUB=%d, "
  "KV_exists=%d, KV_wp=%d, KV_wv=%d, KV_sab=%d, DM=%d, dm=%d, rm=%d";

static void Log(const char* format, ...) {
  va_list ap;
  va_start(ap, format);
  vsyslog(LOG_INFO, format, ap);
  va_end(ap);
  va_start(ap, format);
  vfprintf(stderr, format, ap);
  va_end(ap);
  fprintf(stderr, "\n");
}

static void reboot(void) {
  int status;
  Log("requesting reboot");
  status = system("/sbin/reboot");
  if (status != 0) {
    Log("reboot failed with status %d", status);
    exit(1);
  }
}

static uint32_t SafeWrite(uint32_t index, uint8_t* data, uint32_t length) {
  uint32_t result = TlclWrite(index, data, length);
  if (result == TPM_E_MAXNVWRITES) {
    RETURN_ON_FAILURE(TPMClearAndReenable());
    result = TlclWrite(index, data, length);
    tpm_was_just_cleared = 0;
  }
  return result;
}

static uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
  uint32_t result = TlclDefineSpace(index, perm, size);
  if (result == TPM_E_MAXNVWRITES) {
    RETURN_ON_FAILURE(TPMClearAndReenable());
    result = TlclDefineSpace(index, perm, size);
    tpm_was_just_cleared = 0;
  }
  return result;
}

static void RollbackTest_SaveState(FILE* file) {
  rewind(file);
  fprintf(file, RBTS_format,
          RBTS.advancing,
          RBTS.owned,
          RBTS.disable,
          RBTS.deactivated,
          RBTS.writecount,
          RBTS.TPM_IS_INITIALIZED_exists,
          RBTS.KERNEL_MUST_USE_BACKUP,
          RBTS.KERNEL_VERSIONS_exists,
          RBTS.KERNEL_VERSIONS_wrong_permissions,
          RBTS.KERNEL_VERSIONS_wrong_value,
          RBTS.KERNEL_VERSIONS_same_as_backup,
          RBTS.DEVELOPER_MODE,
          RBTS.developer,
          RBTS.recovery);
}

static void RollbackTest_RestoreState(FILE* file) {
  if (fscanf(file, RBTS_format,
             &RBTS.advancing,
             &RBTS.owned,
             &RBTS.disable,
             &RBTS.deactivated,
             &RBTS.writecount,
             &RBTS.TPM_IS_INITIALIZED_exists,
             &RBTS.KERNEL_MUST_USE_BACKUP,
             &RBTS.KERNEL_VERSIONS_exists,
             &RBTS.KERNEL_VERSIONS_wrong_permissions,
             &RBTS.KERNEL_VERSIONS_wrong_value,
             &RBTS.KERNEL_VERSIONS_same_as_backup,
             &RBTS.DEVELOPER_MODE,
             &RBTS.developer,
             &RBTS.recovery) != sizeof(RBTS)/sizeof(int)) {
    Log("failed to restore state");
    exit(1);
  }
}

static void RollbackTest_LogState(void) {
  Log(RBTS_format,
      RBTS.advancing,
      RBTS.owned,
      RBTS.disable,
      RBTS.deactivated,
      RBTS.writecount,
      RBTS.TPM_IS_INITIALIZED_exists,
      RBTS.KERNEL_MUST_USE_BACKUP,
      RBTS.KERNEL_VERSIONS_exists,
      RBTS.KERNEL_VERSIONS_wrong_permissions,
      RBTS.KERNEL_VERSIONS_wrong_value,
      RBTS.KERNEL_VERSIONS_same_as_backup,
      RBTS.DEVELOPER_MODE,
      RBTS.developer,
      RBTS.recovery);
}

/* Executes a TPM command from the shell.
 */
static void RollbackTest_TPMShellCommand(char* command) {
  int status;
  TlclCloseDevice();
  status = system("/usr/sbin/tcsd");
  if (status != 0) {
    Log("could not start tcsd");
    exit(1);
  }
  status = system("/usr/bin/sleep 0.1");
  status = system(command);
  if (status != 0) {
    Log("command %s returned 0x%x", command, status);
    exit(1);
  }
  status = system("/usr/bin/pkill tcsd");
  if (status != 0) {
    Log("could not kill tcsd, status 0x%x", status);
    exit(1);
  }
  status = system("/usr/bin/sleep 0.1");
  TlclOpenDevice();
}

/* Sets or clears ownership.
 */
static uint32_t RollbackTest_SetOwnership(int ownership) {
  if (ownership) {
    /* Requesting owned state */
    int owned = TlclIsOwned();
    if (!owned) {
      Log("acquiring ownership");
      RollbackTest_TPMShellCommand("/usr/sbin/tpm_takeownership -y -z");
      Log("ownership acquired");
    }
  } else {
    /* Requesting unowned state */
    Log("clearing TPM");
    RETURN_ON_FAILURE(TPMClearAndReenable());
    tpm_was_just_cleared = 1;
  }
  return TPM_SUCCESS;
}

/* Removes a space.  This is a huge pain, because spaces can be removed only
 * when the TPM is owned.
 */
static uint32_t RollbackTest_RemoveSpace(uint32_t index) {
  char command[1024];
  RollbackTest_SetOwnership(1);
  snprintf(command, sizeof(command),
           "/usr/bin/tpm-nvtool --release --index 0x%x --owner_password \"\"",
           index);
  Log("releasing space %x with command: %s", index, command);
  RollbackTest_TPMShellCommand(command);
  Log("space %x released", index);
  return TPM_SUCCESS;
}

/* Checks if the TPM is disabled/deactivated, and optionally enables/activates.
 * Does not disable/deactivate here because it might interfere with other
 * operations.
 */
static uint32_t RollbackTest_PartiallyAdjustFlags(uint8_t* disable,
                                                  uint8_t* deactivated) {
  RETURN_ON_FAILURE(TlclGetFlags(disable, deactivated));

  if (*deactivated && !RBTS.deactivated) {
    /* Needs to enable before we can activate. */
    RETURN_ON_FAILURE(TlclSetEnable());
    *disable = 0;
    /* Needs to reboot after activating. */
    RETURN_ON_FAILURE(TlclSetDeactivated(0));
    reboot();
  }
  /* We disable and deactivate at the end, if needed. */

  if (*disable && !RBTS.disable) {
    RETURN_ON_FAILURE(TlclSetEnable());
  }
  return TPM_SUCCESS;
}

/* Removes or creates the TPM_IS_INITIALIZED space.
 */
static uint32_t RollbackTest_AdjustIsInitialized(void) {
  int initialized;
  RETURN_ON_FAILURE(GetSpacesInitialized(&initialized));
  if (RBTS.TPM_IS_INITIALIZED_exists && !initialized) {
    RETURN_ON_FAILURE(SafeDefineSpace(TPM_IS_INITIALIZED_NV_INDEX,
                                      TPM_NV_PER_PPWRITE, sizeof(uint32_t)));
  }
  if (!RBTS.TPM_IS_INITIALIZED_exists && initialized) {
    RETURN_ON_FAILURE(RollbackTest_RemoveSpace(TPM_IS_INITIALIZED_NV_INDEX));
  }
  return TPM_SUCCESS;
}

/* Sets or clears KERNEL_MUST_USE_BACKUP.
 */
static uint32_t RollbackTest_AdjustMustUseBackup(void) {
  uint32_t must_use_backup;
  RETURN_ON_FAILURE(TlclRead(KERNEL_MUST_USE_BACKUP_NV_INDEX,
                             (uint8_t*) &must_use_backup,
                             sizeof(must_use_backup)));
  if (RBTS.KERNEL_MUST_USE_BACKUP != must_use_backup) {
    RETURN_ON_FAILURE(SafeWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX,
                                (uint8_t*) &must_use_backup,
                                sizeof(must_use_backup)));
  }
  return TPM_SUCCESS;
}

/* Adjusts KERNEL_VERSIONS space.
 */
static uint32_t RollbackTest_AdjustKernelVersions(int* wrong_value) {
  uint8_t kdata[KERNEL_SPACE_SIZE];
  int exists;
  uint32_t result;

  result = TlclRead(KERNEL_VERSIONS_NV_INDEX, kdata, sizeof(kdata));
  if (result != TPM_SUCCESS && result != TPM_E_BADINDEX) {
    return result;
  }
  *wrong_value = Memcmp(kdata + sizeof(uint32_t), KERNEL_SPACE_UID,
                        KERNEL_SPACE_UID_SIZE);     /* for later use */
  exists = result == TPM_SUCCESS;
  if (RBTS.KERNEL_VERSIONS_exists && !exists) {
    RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_VERSIONS_NV_INDEX,
                                      TPM_NV_PER_PPWRITE, KERNEL_SPACE_SIZE));
  }
  if (!RBTS.KERNEL_VERSIONS_exists && exists) {
    RETURN_ON_FAILURE(RollbackTest_RemoveSpace(KERNEL_VERSIONS_NV_INDEX));
  }
  return TPM_SUCCESS;
}

/* Adjusts permissions of KERNEL_VERSIONS space.  Updates |wrong_value| to
 * reflect that currently the space contains the wrong value (i.e. does not
 * contain the GRWL identifier).
 */
static uint32_t RollbackTest_AdjustKernelPermissions(int* wrong_value) {
  uint32_t perms;

  /* Wrong permissions */
  RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_VERSIONS_NV_INDEX, &perms));
  if (RBTS.KERNEL_VERSIONS_wrong_permissions && perms == TPM_NV_PER_PPWRITE) {
    /* Redefines with wrong permissions. */
    RETURN_ON_FAILURE(RollbackTest_RemoveSpace(KERNEL_VERSIONS_NV_INDEX));
    RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_VERSIONS_NV_INDEX,
                                      TPM_NV_PER_PPWRITE |
                                      TPM_NV_PER_GLOBALLOCK,
                                      KERNEL_SPACE_SIZE));
    *wrong_value = 1;
  }
  if (!RBTS.KERNEL_VERSIONS_wrong_permissions &&
      perms != TPM_NV_PER_PPWRITE) {
    /* Redefines with right permissions. */
    RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_VERSIONS_NV_INDEX,
                                      TPM_NV_PER_PPWRITE, 0));
    RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_VERSIONS_NV_INDEX,
                                      TPM_NV_PER_PPWRITE,
                                      KERNEL_SPACE_SIZE));
    *wrong_value = 1;
  }
  return TPM_SUCCESS;
}

static uint32_t RollbackTest_AdjustKernelValue(int wrong_value) {
  if (!RBTS.KERNEL_VERSIONS_wrong_value && wrong_value) {
    RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_NV_INDEX,
                                KERNEL_SPACE_INIT_DATA, KERNEL_SPACE_SIZE));
  }
  if (RBTS.KERNEL_VERSIONS_wrong_value && !wrong_value) {
    RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_NV_INDEX,
                                (uint8_t*) "mickey mouse",
                                KERNEL_SPACE_SIZE));
  }
  return TPM_SUCCESS;
}

/* Adjusts value of KERNEL_VERSIONS_BACKUP space.
 */
static uint32_t RollbackTest_AdjustKernelBackup(void) {
  /* Same as backup */
  uint32_t kv, kvbackup;
  RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX,
                             (uint8_t*) &kv, sizeof(kv)));
  RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_BACKUP_NV_INDEX,
                             (uint8_t*) &kvbackup, sizeof(kvbackup)));
  if (RBTS.KERNEL_VERSIONS_same_as_backup && kv != kvbackup) {
    kvbackup = kv;
    RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX,
                                (uint8_t*) &kvbackup, sizeof(kvbackup)));
  }
  if (!RBTS.KERNEL_VERSIONS_same_as_backup && kv == kvbackup) {
    kvbackup = kv + 1;
    RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX,
                                (uint8_t*) &kvbackup, sizeof(kvbackup)));
  }
  return TPM_SUCCESS;
}

/* Adjust the value in the developer mode transition space.
 */
static uint32_t RollbackTest_AdjustDeveloperMode(void) {
  uint32_t dev;
  /* Developer mode transitions */
  RETURN_ON_FAILURE(TlclRead(DEVELOPER_MODE_NV_INDEX,
                             (uint8_t*) &dev, sizeof(dev)));

  if (RBTS.developer != dev) {
    dev = RBTS.developer;
    RETURN_ON_FAILURE(SafeWrite(DEVELOPER_MODE_NV_INDEX,
                                (uint8_t*) &dev, sizeof(dev)));
  }
  return TPM_SUCCESS;
}

/* Changes the unowned write count.
 */
static uint32_t RollbackTest_AdjustWriteCount(void) {
  int i;
  if (!RBTS.owned) {
    /* Sets the unowned write count, but only if we think that it will make a
     * difference for the test. In other words: we're trying to reduce the
     * number if initial states with some reasoning that we hope is correct.
     */
    if (RBTS.writecount > low_writecount) {
      if (!tpm_was_just_cleared) {
        /* Unknown write count: must clear the TPM to reset to 0 */
        RETURN_ON_FAILURE(TPMClearAndReenable());
      }
      for (i = 0; i < RBTS.writecount; i++) {
        /* Changes the value to ensure that the TPM won't optimize away
         * writes.
         */
        uint8_t b = (uint8_t) i;
        RETURN_ON_FAILURE(SafeWrite(WRITE_BUCKET_NV_INDEX, &b, 1));
      }
    }
  }
  return TPM_SUCCESS;
}

/* Sets the TPM to the right state for the next test run.
 *
 * Functionally correct ordering is tricky.  Optimal ordering is even trickier
 * (no claim to this).  May succeed only partially and require a reboot to
 * continue (if the TPM was deactivated at boot).
 */
static uint32_t RollbackTest_SetTPMState(int initialize) {
  uint8_t disable, deactivated;
  int wrong_value = 0;

  /* Initializes if needed */
  if (initialize) {
    TlclLibInit();
    /* Don't worry if we're already started. */
    (void) TlclStartup();
    RETURN_ON_FAILURE(TlclContinueSelfTest());
    RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
  }

  RETURN_ON_FAILURE(RollbackTest_PartiallyAdjustFlags(&disable, &deactivated));
  RETURN_ON_FAILURE(RollbackTest_AdjustIsInitialized());
  RETURN_ON_FAILURE(RollbackTest_AdjustMustUseBackup());
  RETURN_ON_FAILURE(RollbackTest_AdjustKernelVersions(&wrong_value));

  if (RBTS.KERNEL_VERSIONS_exists) {
    /* Adjusting these states only makes sense when the kernel versions space
     * exists. */
    RETURN_ON_FAILURE(RollbackTest_AdjustKernelPermissions(&wrong_value));
    RETURN_ON_FAILURE(RollbackTest_AdjustKernelValue(wrong_value));
    RETURN_ON_FAILURE(RollbackTest_AdjustKernelBackup());
  }

  RETURN_ON_FAILURE(RollbackTest_AdjustDeveloperMode());
  RETURN_ON_FAILURE(RollbackTest_SetOwnership(RBTS.owned));
  /* Do not remove spaces between SetOwnership and AdjustWriteCount, as that
   * might change the ownership state.  Also do not issue any writes from now
   * on, because AdjustWriteCount tries to avoid unneccessary clears, and after
   * that, any writes will obviously change the write count.
   */
  RETURN_ON_FAILURE(RollbackTest_AdjustWriteCount());

  /* Finally, disables and/or deactivates.  Must deactivate before disabling
   */
  if (!deactivated && RBTS.deactivated) {
    RETURN_ON_FAILURE(TlclSetDeactivated(1));
  }
  /* It's better to do this last, even though most commands we use work with
   * the TPM disabled.
   */
  if (!disable && RBTS.disable) {
    RETURN_ON_FAILURE(TlclClearEnable());
  }
  return TPM_SUCCESS;
}

#define ADVANCE(rbts_field, min, max) do { \
    if (RBTS.rbts_field == max) {          \
      RBTS.rbts_field = min;               \
    } else {                               \
      RBTS.rbts_field++;                   \
      return 0;                            \
    }                                      \
  } while (0)

#define ADVANCEB(field) ADVANCE(field, 0, 1)

static int RollbackTest_AdvanceState(void) {
  /* This is a generalized counter.  It advances an element of the RTBS
   * structure, and when it hits its maximum value, it resets the element and
   * moves on to the next element, similar to the way a decimal counter
   * increases each digit from 0 to 9 and back to 0 with a carry.
   *
   * Tip: put the expensive state changes at the end.
   */
  ADVANCEB(developer);
  ADVANCEB(recovery);
  ADVANCEB(TPM_IS_INITIALIZED_exists);
  ADVANCEB(KERNEL_MUST_USE_BACKUP);
  if (RBTS.owned) {
    ADVANCEB(KERNEL_VERSIONS_exists);
    ADVANCEB(KERNEL_VERSIONS_wrong_permissions);
    ADVANCEB(KERNEL_VERSIONS_wrong_value);
    ADVANCEB(KERNEL_VERSIONS_same_as_backup);
  }
  ADVANCEB(DEVELOPER_MODE);
  /* The writecount is meaningful only when the TPM is not owned. */
  if (!RBTS.owned) {
    ADVANCE(writecount, low_writecount, high_writecount);
    if (RBTS.TPM_IS_INITIALIZED_exists) {
      /* We don't have to go through the full range in this case. */
      if (RBTS.writecount < low_writecount_when_initialized) {
        RBTS.writecount = low_writecount_when_initialized;
      }
    }
  }
  ADVANCEB(deactivated);
  ADVANCEB(disable);
  ADVANCEB(owned);
  if (RBTS.owned == 0) {
    /* overflow */
    return 1;
  }
  return 0;
}

static void RollbackTest_InitializeState(void) {
  FILE* file = fopen(STATEPATH, "w");
  if (file == NULL) {
    fprintf(stderr, "could not open %s for writing\n", STATEPATH);
    exit(1);
  }
  RBTS.writecount = low_writecount;
  RollbackTest_SaveState(file);
}

uint32_t RollbackTest_Test(void) {
  uint16_t key_version, version;

  if (RBTS.recovery) {
    if (RBTS.developer) {
      /* Developer Recovery mode */
      RETURN_ON_FAILURE(RollbackKernelRecovery(1));
    } else {
      /* Normal Recovery mode */
      RETURN_ON_FAILURE(RollbackKernelRecovery(0));
    }
  } else {
    if (RBTS.developer) {
      /* Developer mode */
      key_version = 0;
      version = 0;
      RETURN_ON_FAILURE(RollbackFirmwareSetup(1));
      RETURN_ON_FAILURE(RollbackFirmwareLock());
    } else {
      /* Normal mode */
      key_version = 0;
      version = 0;
      RETURN_ON_FAILURE(RollbackFirmwareSetup(0));
      RETURN_ON_FAILURE(RollbackFirmwareLock());
      RETURN_ON_FAILURE(RollbackKernelRead(&key_version, &version));
      RETURN_ON_FAILURE(RollbackKernelWrite(key_version, version));
      RETURN_ON_FAILURE(RollbackKernelLock());
    }
  }
  return TPM_SUCCESS;
}

/* One-time call to create the WRITE_BUCKET space.
 */
static uint32_t RollbackTest_InitializeTPM(void) {
  TlclLibInit();
  RETURN_ON_FAILURE(TlclStartup());
  RETURN_ON_FAILURE(TlclContinueSelfTest());
  RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
  RETURN_ON_FAILURE(SafeDefineSpace(WRITE_BUCKET_NV_INDEX,
                                    TPM_NV_PER_PPWRITE, 1));
  RETURN_ON_FAILURE(RollbackTest_SetTPMState(0));
  return TPM_SUCCESS;
}

static void RollbackTest_Initialize(void) {
  Log("initializing");
  RollbackTest_InitializeState();
  if (RollbackTest_InitializeTPM() != TPM_SUCCESS) {
    Log("couldn't initialize TPM");
    exit(1);
  }
}

/* Advances the desired TPM state and sets the TPM to the new state.
 */
static void RollbackTest_Advance(FILE* file) {
  uint32_t result;
  Log("advancing state");
  if (RollbackTest_AdvanceState()) {
    Log("done");
    exit(0);
  }
  result = RollbackTest_SetTPMState(1);
  if (result == TPM_SUCCESS) {
    RBTS.advancing = 0;
    RollbackTest_SaveState(file);
    reboot();
  } else {
    Log("SetTPMState failed with 0x%x\n", result);
    exit(1);
  }
}

/* Performs the test for the current TPM state, and verify that the outcome
 * matches the expectations.
 */
static void RollbackTest_RunOneTest(FILE* file) {
  uint32_t result;
  uint32_t expected_result = TPM_SUCCESS;

  if (!RBTS.KERNEL_VERSIONS_exists ||
      RBTS.KERNEL_VERSIONS_wrong_permissions ||
      RBTS.KERNEL_VERSIONS_wrong_value) {
    expected_result = TPM_E_CORRUPTED_STATE;
  }

  if (!RBTS.KERNEL_VERSIONS_exists && !RBTS.TPM_IS_INITIALIZED_exists) {
    /* The space will be recreated */
    expected_result = TPM_SUCCESS;
  }

  if ((!RBTS.TPM_IS_INITIALIZED_exists || !RBTS.KERNEL_VERSIONS_exists)
      && RBTS.owned) {
    /* Cannot create spaces without owner authorization */
    expected_result = TPM_E_OWNER_SET;
  }

  if (RBTS.TPM_IS_INITIALIZED_exists && !RBTS.KERNEL_VERSIONS_exists) {
    expected_result = TPM_ANY_FAILURE;
  }

  result = RollbackTest_Test();

  if (result == expected_result ||
      (result != TPM_SUCCESS && expected_result == TPM_ANY_FAILURE)) {
    Log("test succeeded with 0x%x\n", result);
    RBTS.advancing = 1;
    RollbackTest_SaveState(file);
    reboot();
  } else {
    Log("test failed with 0x%x, expecting 0x%x\n", result, expected_result);
    exit(1);
  }
}

static FILE* RollbackTest_OpenState(void) {
  FILE* file = fopen(STATEPATH, "r+");
  if (file == NULL) {
    Log("%s could not be opened", STATEPATH);
    exit(1);
  }
  return file;
}

/* Sync saved state with TPM state.
 */
static void RollbackTest_Sync(void) {
  FILE *file = RollbackTest_OpenState();
  uint32_t result;
  RollbackTest_RestoreState(file);
  Log("Syncing state");
  result = RollbackTest_SetTPMState(1);
  if (result != TPM_SUCCESS) {
    Log("Sync failed with %x", result);
    exit(1);
  }
}

/* Runs one testing iteration and advances the testing state.
 */
static void RollbackTest_Run(void) {
  FILE* file = RollbackTest_OpenState();
  RollbackTest_RestoreState(file);
  RollbackTest_LogState();
  if (RBTS.advancing) {
    RollbackTest_Advance(file);
  } else {
    RollbackTest_RunOneTest(file);
  }
}

int main(int argc, char** argv) {

  openlog("rbtest", LOG_CONS | LOG_PERROR, LOG_USER);

  if (geteuid() != 0) {
    fprintf(stderr, "rollback-test: must run as root\n");
    exit(1);
  }

  if (argc == 2 && strcmp(argv[1], "initialize") == 0) {
    RollbackTest_Initialize();
  } else if (argc == 2 && strcmp(argv[1], "sync") == 0) {
    RollbackTest_Sync();
  } else if (argc == 1) {
    RollbackTest_Run();
  } else {
    fprintf(stderr, "usage: rollback-test [ initialize ]\n");
    exit(1);
  }
  return 0;
}
