/* 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 mimicks the TPM usage from read-only firmware.  It exercises
 * the TPM functionality needed in the read-only firmware.  It is meant to be
 * integrated with the rest of the read-only firmware.  It is also provided as
 * a test.
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#include "tlcl.h"

/* These index values are used to create NVRAM spaces.  They only need to be
 * unique.
 */
#define INDEX0 0xda70
#define INDEX1 0xda71
#define INDEX2 0xda72
#define INDEX3 0xda73

#define INDEX_INITIALIZED 0xda80

/* This is called once at initialization time.  It may be called again from
 * recovery mode to rebuild the spaces if something incomprehensible happened
 * and the spaces are gone or messed up.  This is called after TPM_Startup and
 * before the spaces are write-locked, so there is a chance that they can be
 * recreated (but who knows---if anything can happen, there are plenty of ways
 * of making this FUBAR).
 */
void InitializeSpaces(void) {
	uint32_t zero = 0;
	uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;

	printf("Initializing spaces\n");
	TlclSetNvLocked();  /* useful only the first time */

	TlclDefineSpace(INDEX0, perm, 4);
	TlclWrite(INDEX0, (uint8_t *) &zero, 4);
	TlclDefineSpace(INDEX1, perm, 4);
	TlclWrite(INDEX1, (uint8_t *) &zero, 4);
	TlclDefineSpace(INDEX2, perm, 4);
	TlclWrite(INDEX2, (uint8_t *) &zero, 4);
	TlclDefineSpace(INDEX3, perm, 4);
	TlclWrite(INDEX3, (uint8_t *) &zero, 4);

	perm = (TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
		TPM_NV_PER_PPWRITE);
	TlclDefineSpace(INDEX_INITIALIZED, perm, 1);
}


void EnterRecoveryMode(void) {
	printf("entering recovery mode");
	exit(0);
}


int main(int argc, char** argv) {
	uint8_t c;
	uint32_t index_0, index_1, index_2, index_3;

	TlclLibInit();

	TlclStartup();
	TlclSelfTestFull();

	TlclAssertPhysicalPresence();

	/* Checks if initialization has completed by trying to read-lock a space
	 * that's created at the end of initialization.
	 */
	if (TlclRead(INDEX_INITIALIZED, &c, 0) == TPM_E_BADINDEX) {
		/* The initialization did not complete.
		*/
		InitializeSpaces();
	}

	/* Checks if spaces are OK or messed up.
	 */
	if (TlclRead(INDEX0, (uint8_t*) &index_0,
		     sizeof(index_0)) != TPM_SUCCESS ||
	    TlclRead(INDEX1, (uint8_t*) &index_1,
		     sizeof(index_1)) != TPM_SUCCESS ||
	    TlclRead(INDEX2, (uint8_t*) &index_2,
		     sizeof(index_2)) != TPM_SUCCESS ||
	    TlclRead(INDEX3, (uint8_t*) &index_3,
		     sizeof(index_3)) != TPM_SUCCESS) {
		EnterRecoveryMode();
	}

	/* Writes space, and locks it.  Then attempts to write again.  I really wish
	 * I could use the imperative.
	 */
	index_0 += 1;
	if (TlclWrite(INDEX0, (uint8_t*) &index_0,
		      sizeof(index_0) != TPM_SUCCESS)) {
		error("could not write index 0\n");
	}
	TlclWriteLock(INDEX0);
	if (TlclWrite(INDEX0, (uint8_t*) &index_0,
		      sizeof(index_0)) == TPM_SUCCESS) {
		error("index 0 is not locked\n");
	}

	/* Done for now.
	 */
	printf("TEST SUCCEEDED\n");
	exit(0);
}
