139f66114c03639715cb88774255f066a2d942557Randall Spangler/* Copyright (c) 2010 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 mimicks the TPM usage from read-only firmware.  It exercises
739f66114c03639715cb88774255f066a2d942557Randall Spangler * the TPM functionality needed in the read-only firmware.  It is meant to be
839f66114c03639715cb88774255f066a2d942557Randall Spangler * integrated with the rest of the read-only firmware.  It is also provided as
939f66114c03639715cb88774255f066a2d942557Randall Spangler * a test.
1039f66114c03639715cb88774255f066a2d942557Randall Spangler */
1139f66114c03639715cb88774255f066a2d942557Randall Spangler
1239f66114c03639715cb88774255f066a2d942557Randall Spangler#include <stdio.h>
1339f66114c03639715cb88774255f066a2d942557Randall Spangler#include <stdint.h>
1439f66114c03639715cb88774255f066a2d942557Randall Spangler#include <stdlib.h>
1539f66114c03639715cb88774255f066a2d942557Randall Spangler
1639f66114c03639715cb88774255f066a2d942557Randall Spangler#include "tlcl.h"
1739f66114c03639715cb88774255f066a2d942557Randall Spangler#include "utility.h"
1839f66114c03639715cb88774255f066a2d942557Randall Spangler
1939f66114c03639715cb88774255f066a2d942557Randall Spangler/* These index values are used to create NVRAM spaces.  They only need to be
2039f66114c03639715cb88774255f066a2d942557Randall Spangler * unique.
2139f66114c03639715cb88774255f066a2d942557Randall Spangler */
2239f66114c03639715cb88774255f066a2d942557Randall Spangler#define INDEX0 0xda70
2339f66114c03639715cb88774255f066a2d942557Randall Spangler#define INDEX1 0xda71
2439f66114c03639715cb88774255f066a2d942557Randall Spangler#define INDEX2 0xda72
2539f66114c03639715cb88774255f066a2d942557Randall Spangler#define INDEX3 0xda73
2639f66114c03639715cb88774255f066a2d942557Randall Spangler
2739f66114c03639715cb88774255f066a2d942557Randall Spangler#define INDEX_INITIALIZED 0xda80
2839f66114c03639715cb88774255f066a2d942557Randall Spangler
2939f66114c03639715cb88774255f066a2d942557Randall Spangler/* This is called once at initialization time.  It may be called again from
3039f66114c03639715cb88774255f066a2d942557Randall Spangler * recovery mode to rebuild the spaces if something incomprehensible happened
3139f66114c03639715cb88774255f066a2d942557Randall Spangler * and the spaces are gone or messed up.  This is called after TPM_Startup and
3239f66114c03639715cb88774255f066a2d942557Randall Spangler * before the spaces are write-locked, so there is a chance that they can be
3339f66114c03639715cb88774255f066a2d942557Randall Spangler * recreated (but who knows---if anything can happen, there are plenty of ways
3439f66114c03639715cb88774255f066a2d942557Randall Spangler * of making this FUBAR).
3539f66114c03639715cb88774255f066a2d942557Randall Spangler */
3639f66114c03639715cb88774255f066a2d942557Randall Spanglervoid InitializeSpaces(void) {
3739f66114c03639715cb88774255f066a2d942557Randall Spangler  uint32_t zero = 0;
3839f66114c03639715cb88774255f066a2d942557Randall Spangler  uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
3939f66114c03639715cb88774255f066a2d942557Randall Spangler
4039f66114c03639715cb88774255f066a2d942557Randall Spangler  printf("Initializing spaces\n");
4139f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclSetNvLocked();  /* useful only the first time */
4239f66114c03639715cb88774255f066a2d942557Randall Spangler
4339f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclDefineSpace(INDEX0, perm, 4);
4439f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclWrite(INDEX0, (uint8_t *) &zero, 4);
4539f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclDefineSpace(INDEX1, perm, 4);
4639f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclWrite(INDEX1, (uint8_t *) &zero, 4);
4739f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclDefineSpace(INDEX2, perm, 4);
4839f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclWrite(INDEX2, (uint8_t *) &zero, 4);
4939f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclDefineSpace(INDEX3, perm, 4);
5039f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclWrite(INDEX3, (uint8_t *) &zero, 4);
5139f66114c03639715cb88774255f066a2d942557Randall Spangler
5239f66114c03639715cb88774255f066a2d942557Randall Spangler  perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
5339f66114c03639715cb88774255f066a2d942557Randall Spangler    TPM_NV_PER_PPWRITE;
5439f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclDefineSpace(INDEX_INITIALIZED, perm, 1);
5539f66114c03639715cb88774255f066a2d942557Randall Spangler}
5639f66114c03639715cb88774255f066a2d942557Randall Spangler
5739f66114c03639715cb88774255f066a2d942557Randall Spangler
5839f66114c03639715cb88774255f066a2d942557Randall Spanglervoid EnterRecoveryMode(void) {
5939f66114c03639715cb88774255f066a2d942557Randall Spangler  printf("entering recovery mode");
6039f66114c03639715cb88774255f066a2d942557Randall Spangler  exit(0);
6139f66114c03639715cb88774255f066a2d942557Randall Spangler}
6239f66114c03639715cb88774255f066a2d942557Randall Spangler
6339f66114c03639715cb88774255f066a2d942557Randall Spangler
6439f66114c03639715cb88774255f066a2d942557Randall Spanglerint main(int argc, char** argv) {
6539f66114c03639715cb88774255f066a2d942557Randall Spangler  uint8_t c;
6639f66114c03639715cb88774255f066a2d942557Randall Spangler  uint32_t index_0, index_1, index_2, index_3;
6739f66114c03639715cb88774255f066a2d942557Randall Spangler
6839f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclLibInit();
6939f66114c03639715cb88774255f066a2d942557Randall Spangler
7039f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclStartup();
713e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler  TlclSelfTestFull();
7239f66114c03639715cb88774255f066a2d942557Randall Spangler
7339f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclAssertPhysicalPresence();
7439f66114c03639715cb88774255f066a2d942557Randall Spangler
7539f66114c03639715cb88774255f066a2d942557Randall Spangler  /* Checks if initialization has completed by trying to read-lock a space
7639f66114c03639715cb88774255f066a2d942557Randall Spangler   * that's created at the end of initialization.
7739f66114c03639715cb88774255f066a2d942557Randall Spangler   */
7839f66114c03639715cb88774255f066a2d942557Randall Spangler  if (TlclRead(INDEX_INITIALIZED, &c, 0) == TPM_E_BADINDEX) {
7939f66114c03639715cb88774255f066a2d942557Randall Spangler    /* The initialization did not complete.
8039f66114c03639715cb88774255f066a2d942557Randall Spangler     */
8139f66114c03639715cb88774255f066a2d942557Randall Spangler    InitializeSpaces();
8239f66114c03639715cb88774255f066a2d942557Randall Spangler  }
8339f66114c03639715cb88774255f066a2d942557Randall Spangler
8439f66114c03639715cb88774255f066a2d942557Randall Spangler  /* Checks if spaces are OK or messed up.
8539f66114c03639715cb88774255f066a2d942557Randall Spangler   */
8639f66114c03639715cb88774255f066a2d942557Randall Spangler  if (TlclRead(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) != TPM_SUCCESS ||
8739f66114c03639715cb88774255f066a2d942557Randall Spangler      TlclRead(INDEX1, (uint8_t*) &index_1, sizeof(index_1)) != TPM_SUCCESS ||
8839f66114c03639715cb88774255f066a2d942557Randall Spangler      TlclRead(INDEX2, (uint8_t*) &index_2, sizeof(index_2)) != TPM_SUCCESS ||
8939f66114c03639715cb88774255f066a2d942557Randall Spangler      TlclRead(INDEX3, (uint8_t*) &index_3, sizeof(index_3)) != TPM_SUCCESS) {
9039f66114c03639715cb88774255f066a2d942557Randall Spangler    EnterRecoveryMode();
9139f66114c03639715cb88774255f066a2d942557Randall Spangler  }
9239f66114c03639715cb88774255f066a2d942557Randall Spangler
9339f66114c03639715cb88774255f066a2d942557Randall Spangler  /* Writes space, and locks it.  Then attempts to write again.  I really wish
9439f66114c03639715cb88774255f066a2d942557Randall Spangler   * I could use the imperative.
9539f66114c03639715cb88774255f066a2d942557Randall Spangler   */
9639f66114c03639715cb88774255f066a2d942557Randall Spangler  index_0 += 1;
9739f66114c03639715cb88774255f066a2d942557Randall Spangler  if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0) != TPM_SUCCESS)) {
9839f66114c03639715cb88774255f066a2d942557Randall Spangler    error("could not write index 0\n");
9939f66114c03639715cb88774255f066a2d942557Randall Spangler  }
10039f66114c03639715cb88774255f066a2d942557Randall Spangler  TlclWriteLock(INDEX0);
10139f66114c03639715cb88774255f066a2d942557Randall Spangler  if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) == TPM_SUCCESS) {
10239f66114c03639715cb88774255f066a2d942557Randall Spangler    error("index 0 is not locked\n");
10339f66114c03639715cb88774255f066a2d942557Randall Spangler  }
10439f66114c03639715cb88774255f066a2d942557Randall Spangler
10539f66114c03639715cb88774255f066a2d942557Randall Spangler  /* Done for now.
10639f66114c03639715cb88774255f066a2d942557Randall Spangler   */
107a7e19cffbee540a130d16b3b93ebfe250a774358Luigi Semenzato  printf("TEST SUCCEEDED\n");
10839f66114c03639715cb88774255f066a2d942557Randall Spangler  exit(0);
10939f66114c03639715cb88774255f066a2d942557Randall Spangler}
110