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