Home | History | Annotate | Download | only in utility
      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  * Temporary fix for running the TPM selftest and other essential
      6  * intializations that we forgot to put in the BIOS.
      7  *
      8  * This works in a very specific situation: we assume TPM_Startup has been
      9  * executed, but we don't know if the self test has run.  On a ST TPM version
     10  * 1.2.7.0, GetCapabilities fails before the self test has run, so we use that
     11  * to check if we need to run it.
     12  *
     13  * This also enables the TPM if it is disabled, and activates it if it is
     14  * deactivated.
     15  *
     16  * Exit status always 0.  Prints "reboot" to request reboot, "fail" for errors,
     17  * "success" when everything worked.
     18  */
     19 
     20 #include <stdint.h>
     21 #include <stdio.h>
     22 #include <syslog.h>
     23 
     24 #include "tlcl.h"
     25 
     26 int main(int argc, char* argv[]) {
     27   uint32_t result;
     28   uint8_t disable, deactivated;
     29   int pri = LOG_USER | LOG_ERR;
     30 
     31   TlclLibInit();
     32   TlclStartup();        /* ignore result */
     33 
     34   /* On the dogfood device, GetFlags causes an assertion failure because the
     35    * device uses an older TPM which is not compatible with the current spec.
     36    * We take advantage of this to cause the program to exit and not run the
     37    * self test again (which takes 1 second).
     38    */
     39   result = TlclGetFlags(NULL, NULL, NULL);
     40 
     41   result = TlclSelfTestFull();
     42   if (result != 0) {
     43     syslog(pri, "TPM selftest failed with code 0x%x\n", result);
     44     printf("fail\n");
     45     return 0;
     46   }
     47 
     48   /* Optional one-time enabling of TPM. */
     49   result = TlclAssertPhysicalPresence();
     50   if (result != 0) {
     51     syslog(pri, "TPM assertpp failed with code 0x%x\n", result);
     52     printf("fail\n");
     53     return 0;
     54   }
     55   result = TlclGetFlags(&disable, &deactivated, NULL);
     56   if (result != 0) {
     57     syslog(pri, "TPM getflags failed with code 0x%x\n", result);
     58     printf("fail\n");
     59     return 0;
     60   }
     61   if (disable) {
     62     result = TlclSetEnable();
     63     if (result != 0) {
     64       syslog(pri, "TPM physical enable failed with code 0x%x\n", result);
     65       printf("fail\n");
     66       return 0;
     67     }
     68   }
     69   if (deactivated) {
     70     result = TlclSetDeactivated(0);
     71     if (result != 0) {
     72       syslog(pri, "TPM physical activate failed with code 0x%x\n", result);
     73       printf("fail\n");
     74     } else {
     75       printf("reboot\n");
     76     }
     77     return 0; /* needs reboot */
     78   }
     79   printf("success\n");
     80   return 0;
     81 }
     82