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