Home | History | Annotate | Download | only in tpm_lite
      1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 /* This program mimicks the TPM usage from read-only firmware.  It exercises
      7  * the TPM functionality needed in the read-only firmware.  It is meant to be
      8  * integrated with the rest of the read-only firmware.  It is also provided as
      9  * a test.
     10  */
     11 
     12 #include <stdio.h>
     13 #include <stdint.h>
     14 #include <stdlib.h>
     15 
     16 #include "tlcl.h"
     17 #include "utility.h"
     18 
     19 /* These index values are used to create NVRAM spaces.  They only need to be
     20  * unique.
     21  */
     22 #define INDEX0 0xda70
     23 #define INDEX1 0xda71
     24 #define INDEX2 0xda72
     25 #define INDEX3 0xda73
     26 
     27 #define INDEX_INITIALIZED 0xda80
     28 
     29 /* This is called once at initialization time.  It may be called again from
     30  * recovery mode to rebuild the spaces if something incomprehensible happened
     31  * and the spaces are gone or messed up.  This is called after TPM_Startup and
     32  * before the spaces are write-locked, so there is a chance that they can be
     33  * recreated (but who knows---if anything can happen, there are plenty of ways
     34  * of making this FUBAR).
     35  */
     36 void InitializeSpaces(void) {
     37   uint32_t zero = 0;
     38   uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
     39 
     40   printf("Initializing spaces\n");
     41   TlclSetNvLocked();  /* useful only the first time */
     42 
     43   TlclDefineSpace(INDEX0, perm, 4);
     44   TlclWrite(INDEX0, (uint8_t *) &zero, 4);
     45   TlclDefineSpace(INDEX1, perm, 4);
     46   TlclWrite(INDEX1, (uint8_t *) &zero, 4);
     47   TlclDefineSpace(INDEX2, perm, 4);
     48   TlclWrite(INDEX2, (uint8_t *) &zero, 4);
     49   TlclDefineSpace(INDEX3, perm, 4);
     50   TlclWrite(INDEX3, (uint8_t *) &zero, 4);
     51 
     52   perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
     53     TPM_NV_PER_PPWRITE;
     54   TlclDefineSpace(INDEX_INITIALIZED, perm, 1);
     55 }
     56 
     57 
     58 void EnterRecoveryMode(void) {
     59   printf("entering recovery mode");
     60   exit(0);
     61 }
     62 
     63 
     64 int main(int argc, char** argv) {
     65   uint8_t c;
     66   uint32_t index_0, index_1, index_2, index_3;
     67 
     68   TlclLibInit();
     69 
     70   TlclStartup();
     71   TlclSelfTestFull();
     72 
     73   TlclAssertPhysicalPresence();
     74 
     75   /* Checks if initialization has completed by trying to read-lock a space
     76    * that's created at the end of initialization.
     77    */
     78   if (TlclRead(INDEX_INITIALIZED, &c, 0) == TPM_E_BADINDEX) {
     79     /* The initialization did not complete.
     80      */
     81     InitializeSpaces();
     82   }
     83 
     84   /* Checks if spaces are OK or messed up.
     85    */
     86   if (TlclRead(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) != TPM_SUCCESS ||
     87       TlclRead(INDEX1, (uint8_t*) &index_1, sizeof(index_1)) != TPM_SUCCESS ||
     88       TlclRead(INDEX2, (uint8_t*) &index_2, sizeof(index_2)) != TPM_SUCCESS ||
     89       TlclRead(INDEX3, (uint8_t*) &index_3, sizeof(index_3)) != TPM_SUCCESS) {
     90     EnterRecoveryMode();
     91   }
     92 
     93   /* Writes space, and locks it.  Then attempts to write again.  I really wish
     94    * I could use the imperative.
     95    */
     96   index_0 += 1;
     97   if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0) != TPM_SUCCESS)) {
     98     error("could not write index 0\n");
     99   }
    100   TlclWriteLock(INDEX0);
    101   if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) == TPM_SUCCESS) {
    102     error("index 0 is not locked\n");
    103   }
    104 
    105   /* Done for now.
    106    */
    107   printf("TEST SUCCEEDED\n");
    108   exit(0);
    109 }
    110