Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 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 | * |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 16 | * Exit status always 0. Prints "reboot" to request reboot, "fail" for errors, |
| 17 | * "success" when everything worked. |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 18 | */ |
| 19 | |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 20 | #include <stdio.h> |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 21 | #include <syslog.h> |
| 22 | |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 23 | #include "tlcl.h" |
| 24 | |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 25 | int main(int argc, char* argv[]) { |
| 26 | uint32_t result; |
| 27 | uint8_t disable, deactivated; |
| 28 | int pri = LOG_USER | LOG_ERR; |
| 29 | |
| 30 | TlclLibInit(); |
| 31 | TlclStartup(); /* ignore result */ |
Luigi Semenzato | d7bff87 | 2010-08-12 09:26:50 -0700 | [diff] [blame] | 32 | |
| 33 | /* On the dogfood device, GetFlags causes an assertion failure because the |
| 34 | * device uses an older TPM which is not compatible with the current spec. |
| 35 | * We take advantage of this to cause the program to exit and not run the |
| 36 | * self test again (which takes 1 second). |
| 37 | */ |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 38 | result = TlclGetFlags(NULL, NULL, NULL); |
Luigi Semenzato | d7bff87 | 2010-08-12 09:26:50 -0700 | [diff] [blame] | 39 | |
| 40 | result = TlclSelfTestFull(); |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 41 | if (result != 0) { |
Luigi Semenzato | d7bff87 | 2010-08-12 09:26:50 -0700 | [diff] [blame] | 42 | syslog(pri, "TPM selftest failed with code 0x%x\n", result); |
| 43 | printf("fail\n"); |
| 44 | return 0; |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 45 | } |
Luigi Semenzato | d7bff87 | 2010-08-12 09:26:50 -0700 | [diff] [blame] | 46 | |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 47 | /* Optional one-time enabling of TPM. */ |
| 48 | result = TlclAssertPhysicalPresence(); |
| 49 | if (result != 0) { |
| 50 | syslog(pri, "TPM assertpp failed with code 0x%x\n", result); |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 51 | printf("fail\n"); |
| 52 | return 0; |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 53 | } |
| 54 | result = TlclGetFlags(&disable, &deactivated, NULL); |
| 55 | if (result != 0) { |
| 56 | syslog(pri, "TPM getflags failed with code 0x%x\n", result); |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 57 | printf("fail\n"); |
| 58 | return 0; |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 59 | } |
| 60 | if (disable) { |
| 61 | result = TlclSetEnable(); |
| 62 | if (result != 0) { |
| 63 | syslog(pri, "TPM physical enable failed with code 0x%x\n", result); |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 64 | printf("fail\n"); |
| 65 | return 0; |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 66 | } |
| 67 | } |
| 68 | if (deactivated) { |
| 69 | result = TlclSetDeactivated(0); |
| 70 | if (result != 0) { |
| 71 | syslog(pri, "TPM physical activate failed with code 0x%x\n", result); |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 72 | printf("fail\n"); |
| 73 | } else { |
| 74 | printf("reboot\n"); |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 75 | } |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 76 | return 0; /* needs reboot */ |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 77 | } |
Luigi Semenzato | f37fdf5 | 2010-08-04 17:13:08 -0700 | [diff] [blame] | 78 | printf("success\n"); |
Luigi Semenzato | fda9488 | 2010-08-04 11:51:13 -0700 | [diff] [blame] | 79 | return 0; |
| 80 | } |