1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2012 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * TPM command utility. Runs simple TPM commands. Mostly useful when physical
6*8617a60dSAndroid Build Coastguard Worker * presence has not been locked.
7*8617a60dSAndroid Build Coastguard Worker *
8*8617a60dSAndroid Build Coastguard Worker * The exit code is 0 for success, the TPM error code for TPM errors, and 255
9*8617a60dSAndroid Build Coastguard Worker * for other errors.
10*8617a60dSAndroid Build Coastguard Worker */
11*8617a60dSAndroid Build Coastguard Worker
12*8617a60dSAndroid Build Coastguard Worker #include <inttypes.h>
13*8617a60dSAndroid Build Coastguard Worker #include <stdint.h>
14*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
15*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
16*8617a60dSAndroid Build Coastguard Worker #include <string.h>
17*8617a60dSAndroid Build Coastguard Worker #include <syslog.h>
18*8617a60dSAndroid Build Coastguard Worker
19*8617a60dSAndroid Build Coastguard Worker #include "tlcl.h"
20*8617a60dSAndroid Build Coastguard Worker #include "tpm_error_messages.h"
21*8617a60dSAndroid Build Coastguard Worker #include "tss_constants.h"
22*8617a60dSAndroid Build Coastguard Worker
23*8617a60dSAndroid Build Coastguard Worker #define OTHER_ERROR 255 /* OTHER_ERROR must be the largest uint8_t value. */
24*8617a60dSAndroid Build Coastguard Worker
25*8617a60dSAndroid Build Coastguard Worker #ifdef TPM2_MODE
26*8617a60dSAndroid Build Coastguard Worker #define TPM_MODE_SELECT(_, tpm20_ver) tpm20_ver
27*8617a60dSAndroid Build Coastguard Worker #else
28*8617a60dSAndroid Build Coastguard Worker #define TPM_MODE_SELECT(tpm12_ver, _) tpm12_ver
29*8617a60dSAndroid Build Coastguard Worker #endif
30*8617a60dSAndroid Build Coastguard Worker
31*8617a60dSAndroid Build Coastguard Worker #define TPM_MODE_STRING TPM_MODE_SELECT("1.2", "2.0")
32*8617a60dSAndroid Build Coastguard Worker #define TPM12_NEEDS_PP TPM_MODE_SELECT(" (needs PP)", "")
33*8617a60dSAndroid Build Coastguard Worker #define TPM12_NEEDS_PP_REBOOT TPM_MODE_SELECT(" (needs PP, maybe reboot)", "")
34*8617a60dSAndroid Build Coastguard Worker
35*8617a60dSAndroid Build Coastguard Worker #define TPM20_NOT_IMPLEMENTED_DESCR(descr) \
36*8617a60dSAndroid Build Coastguard Worker descr TPM_MODE_SELECT("", " [not-implemented for TPM2.0]")
37*8617a60dSAndroid Build Coastguard Worker #define TPM20_NOT_IMPLEMENTED_HANDLER(handler) \
38*8617a60dSAndroid Build Coastguard Worker TPM_MODE_SELECT(handler, HandlerNotImplementedForTPM2)
39*8617a60dSAndroid Build Coastguard Worker #define TPM20_NOT_IMPLEMENTED(descr, handler) \
40*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED_DESCR(descr), \
41*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED_HANDLER(handler)
42*8617a60dSAndroid Build Coastguard Worker
43*8617a60dSAndroid Build Coastguard Worker #define TPM20_DOES_NOTHING_DESCR(descr) \
44*8617a60dSAndroid Build Coastguard Worker descr TPM_MODE_SELECT("", " [no-op for TPM2.0]")
45*8617a60dSAndroid Build Coastguard Worker #define TPM20_DOES_NOTHING_HANDLER(handler) \
46*8617a60dSAndroid Build Coastguard Worker TPM_MODE_SELECT(handler, HandlerDoNothingForTPM2)
47*8617a60dSAndroid Build Coastguard Worker #define TPM20_DOES_NOTHING(descr, handler) \
48*8617a60dSAndroid Build Coastguard Worker TPM20_DOES_NOTHING_DESCR(descr), \
49*8617a60dSAndroid Build Coastguard Worker TPM20_DOES_NOTHING_HANDLER(handler)
50*8617a60dSAndroid Build Coastguard Worker
51*8617a60dSAndroid Build Coastguard Worker typedef struct command_record {
52*8617a60dSAndroid Build Coastguard Worker const char* name;
53*8617a60dSAndroid Build Coastguard Worker const char* abbr;
54*8617a60dSAndroid Build Coastguard Worker const char* description;
55*8617a60dSAndroid Build Coastguard Worker uint32_t (*handler)(void);
56*8617a60dSAndroid Build Coastguard Worker } command_record;
57*8617a60dSAndroid Build Coastguard Worker
58*8617a60dSAndroid Build Coastguard Worker /* Set in main, consumed by handler functions below. We use global variables
59*8617a60dSAndroid Build Coastguard Worker * so we can also choose to call Tlcl*() functions directly; they don't take
60*8617a60dSAndroid Build Coastguard Worker * argv/argc.
61*8617a60dSAndroid Build Coastguard Worker */
62*8617a60dSAndroid Build Coastguard Worker int nargs;
63*8617a60dSAndroid Build Coastguard Worker char** args;
64*8617a60dSAndroid Build Coastguard Worker
65*8617a60dSAndroid Build Coastguard Worker /* Converts a string in the form 0x[0-9a-f]+ to a 32-bit value. Returns 0 for
66*8617a60dSAndroid Build Coastguard Worker * success, non-zero for failure.
67*8617a60dSAndroid Build Coastguard Worker */
HexStringToUint32(const char * string,uint32_t * value)68*8617a60dSAndroid Build Coastguard Worker static int HexStringToUint32(const char* string, uint32_t* value) {
69*8617a60dSAndroid Build Coastguard Worker char tail;
70*8617a60dSAndroid Build Coastguard Worker /* strtoul is not as good because it overflows silently */
71*8617a60dSAndroid Build Coastguard Worker const char* format = strncmp(string, "0x", 2) ? "%8x%c" : "0x%8x%c";
72*8617a60dSAndroid Build Coastguard Worker int n = sscanf(string, format, value, &tail);
73*8617a60dSAndroid Build Coastguard Worker return n != 1;
74*8617a60dSAndroid Build Coastguard Worker }
75*8617a60dSAndroid Build Coastguard Worker
76*8617a60dSAndroid Build Coastguard Worker /* Converts a string in the form [0-9a-f]+ to an 8-bit value. Returns 0 for
77*8617a60dSAndroid Build Coastguard Worker * success, non-zero for failure.
78*8617a60dSAndroid Build Coastguard Worker */
HexStringToUint8(const char * string,uint8_t * value)79*8617a60dSAndroid Build Coastguard Worker static int HexStringToUint8(const char* string, uint8_t* value) {
80*8617a60dSAndroid Build Coastguard Worker char* end;
81*8617a60dSAndroid Build Coastguard Worker uint32_t large_value = strtoul(string, &end, 16);
82*8617a60dSAndroid Build Coastguard Worker if (*end != '\0' || large_value > 0xff) {
83*8617a60dSAndroid Build Coastguard Worker return 1;
84*8617a60dSAndroid Build Coastguard Worker }
85*8617a60dSAndroid Build Coastguard Worker *value = large_value;
86*8617a60dSAndroid Build Coastguard Worker return 0;
87*8617a60dSAndroid Build Coastguard Worker }
88*8617a60dSAndroid Build Coastguard Worker
HexStringToArray(const char * string,uint8_t * value,int num_bytes)89*8617a60dSAndroid Build Coastguard Worker static int HexStringToArray(const char* string, uint8_t* value, int num_bytes) {
90*8617a60dSAndroid Build Coastguard Worker int len = strlen(string);
91*8617a60dSAndroid Build Coastguard Worker if (!strncmp(string, "0x", 2)) {
92*8617a60dSAndroid Build Coastguard Worker string += 2;
93*8617a60dSAndroid Build Coastguard Worker len -= 2;
94*8617a60dSAndroid Build Coastguard Worker }
95*8617a60dSAndroid Build Coastguard Worker if (len != num_bytes * 2) {
96*8617a60dSAndroid Build Coastguard Worker return 1;
97*8617a60dSAndroid Build Coastguard Worker }
98*8617a60dSAndroid Build Coastguard Worker for (; len > 0; string += 2, len -= 2, value++) {
99*8617a60dSAndroid Build Coastguard Worker if (sscanf(string, "%2hhx", value) != 1) {
100*8617a60dSAndroid Build Coastguard Worker return 1;
101*8617a60dSAndroid Build Coastguard Worker }
102*8617a60dSAndroid Build Coastguard Worker }
103*8617a60dSAndroid Build Coastguard Worker return 0;
104*8617a60dSAndroid Build Coastguard Worker }
105*8617a60dSAndroid Build Coastguard Worker
106*8617a60dSAndroid Build Coastguard Worker /* TPM error check and reporting. Returns 0 if |result| is 0 (TPM_SUCCESS).
107*8617a60dSAndroid Build Coastguard Worker * Otherwise looks up a TPM error in the error table and prints the error if
108*8617a60dSAndroid Build Coastguard Worker * found. Then returns min(result, OTHER_ERROR) since some error codes, such
109*8617a60dSAndroid Build Coastguard Worker * as TPM_E_RETRY, do not fit in a byte.
110*8617a60dSAndroid Build Coastguard Worker */
ErrorCheck(uint32_t result,const char * cmd)111*8617a60dSAndroid Build Coastguard Worker static uint8_t ErrorCheck(uint32_t result, const char* cmd) {
112*8617a60dSAndroid Build Coastguard Worker uint8_t exit_code = result > OTHER_ERROR ? OTHER_ERROR : result;
113*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
114*8617a60dSAndroid Build Coastguard Worker return 0;
115*8617a60dSAndroid Build Coastguard Worker } else {
116*8617a60dSAndroid Build Coastguard Worker int i;
117*8617a60dSAndroid Build Coastguard Worker int n = sizeof(tpm_error_table) / sizeof(tpm_error_table[0]);
118*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "command \"%s\" failed with code %#x\n", cmd, result);
119*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
120*8617a60dSAndroid Build Coastguard Worker if (tpm_error_table[i].code == result) {
121*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s\n%s\n", tpm_error_table[i].name,
122*8617a60dSAndroid Build Coastguard Worker tpm_error_table[i].description);
123*8617a60dSAndroid Build Coastguard Worker return exit_code;
124*8617a60dSAndroid Build Coastguard Worker }
125*8617a60dSAndroid Build Coastguard Worker }
126*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "the TPM error code is unknown to this program\n");
127*8617a60dSAndroid Build Coastguard Worker return exit_code;
128*8617a60dSAndroid Build Coastguard Worker }
129*8617a60dSAndroid Build Coastguard Worker }
130*8617a60dSAndroid Build Coastguard Worker
131*8617a60dSAndroid Build Coastguard Worker /* Handler functions. These wouldn't exist if C had closures.
132*8617a60dSAndroid Build Coastguard Worker */
HandlerTpmVersion(void)133*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerTpmVersion(void) {
134*8617a60dSAndroid Build Coastguard Worker puts(TPM_MODE_STRING);
135*8617a60dSAndroid Build Coastguard Worker return 0;
136*8617a60dSAndroid Build Coastguard Worker }
137*8617a60dSAndroid Build Coastguard Worker
138*8617a60dSAndroid Build Coastguard Worker /* TODO(apronin): stub for selected flags for TPM2 */
139*8617a60dSAndroid Build Coastguard Worker #ifdef TPM2_MODE
HandlerGetFlags(void)140*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetFlags(void) {
141*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "getflags not implemented for TPM2\n");
142*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
143*8617a60dSAndroid Build Coastguard Worker }
144*8617a60dSAndroid Build Coastguard Worker #else
HandlerGetFlags(void)145*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetFlags(void) {
146*8617a60dSAndroid Build Coastguard Worker uint8_t disabled;
147*8617a60dSAndroid Build Coastguard Worker uint8_t deactivated;
148*8617a60dSAndroid Build Coastguard Worker uint8_t nvlocked;
149*8617a60dSAndroid Build Coastguard Worker uint32_t result = TlclGetFlags(&disabled, &deactivated, &nvlocked);
150*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
151*8617a60dSAndroid Build Coastguard Worker printf("disabled: %d\ndeactivated: %d\nnvlocked: %d\n",
152*8617a60dSAndroid Build Coastguard Worker disabled, deactivated, nvlocked);
153*8617a60dSAndroid Build Coastguard Worker }
154*8617a60dSAndroid Build Coastguard Worker return result;
155*8617a60dSAndroid Build Coastguard Worker }
156*8617a60dSAndroid Build Coastguard Worker #endif
157*8617a60dSAndroid Build Coastguard Worker
158*8617a60dSAndroid Build Coastguard Worker #ifndef TPM2_MODE
HandlerActivate(void)159*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerActivate(void) {
160*8617a60dSAndroid Build Coastguard Worker return TlclSetDeactivated(0);
161*8617a60dSAndroid Build Coastguard Worker }
162*8617a60dSAndroid Build Coastguard Worker
HandlerDeactivate(void)163*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerDeactivate(void) {
164*8617a60dSAndroid Build Coastguard Worker return TlclSetDeactivated(1);
165*8617a60dSAndroid Build Coastguard Worker }
166*8617a60dSAndroid Build Coastguard Worker #endif
167*8617a60dSAndroid Build Coastguard Worker
HandlerDefineSpace(void)168*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerDefineSpace(void) {
169*8617a60dSAndroid Build Coastguard Worker uint32_t index, size, perm;
170*8617a60dSAndroid Build Coastguard Worker int overwrite = 1;
171*8617a60dSAndroid Build Coastguard Worker
172*8617a60dSAndroid Build Coastguard Worker if (nargs != 5 && nargs != 6) {
173*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc def <index> <size> <perm> "
174*8617a60dSAndroid Build Coastguard Worker "[--no-overwrite])\n");
175*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
176*8617a60dSAndroid Build Coastguard Worker }
177*8617a60dSAndroid Build Coastguard Worker
178*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0 ||
179*8617a60dSAndroid Build Coastguard Worker HexStringToUint32(args[3], &size) != 0 ||
180*8617a60dSAndroid Build Coastguard Worker HexStringToUint32(args[4], &perm) != 0) {
181*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index>, <size>, and <perm> must be "
182*8617a60dSAndroid Build Coastguard Worker "32-bit hex (0x[0-9a-f]+)\n");
183*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
184*8617a60dSAndroid Build Coastguard Worker }
185*8617a60dSAndroid Build Coastguard Worker
186*8617a60dSAndroid Build Coastguard Worker if (args[5] && strcmp(args[5], "--no-overwrite") == 0) {
187*8617a60dSAndroid Build Coastguard Worker overwrite = 0;
188*8617a60dSAndroid Build Coastguard Worker }
189*8617a60dSAndroid Build Coastguard Worker
190*8617a60dSAndroid Build Coastguard Worker #ifdef TPM2_MODE
191*8617a60dSAndroid Build Coastguard Worker // For TPM 2.0, DefineSpace will fail if the space already exists, so to
192*8617a60dSAndroid Build Coastguard Worker // support the default 'overwrite' mode, need to undefine the space first.
193*8617a60dSAndroid Build Coastguard Worker if (overwrite) {
194*8617a60dSAndroid Build Coastguard Worker TlclUndefineSpace(index);
195*8617a60dSAndroid Build Coastguard Worker }
196*8617a60dSAndroid Build Coastguard Worker #else /* ifndef TPM2_MODE */
197*8617a60dSAndroid Build Coastguard Worker // For TPM 1.2, we have to check the existing before calling DefineSpace(),
198*8617a60dSAndroid Build Coastguard Worker // since it will automaticly overwrite the existing space by default.
199*8617a60dSAndroid Build Coastguard Worker // Do nothing for TPM 2.0. We rely on DefineSpace() to return the appropriate
200*8617a60dSAndroid Build Coastguard Worker // error code.
201*8617a60dSAndroid Build Coastguard Worker if (!overwrite) {
202*8617a60dSAndroid Build Coastguard Worker uint32_t result , permissions;
203*8617a60dSAndroid Build Coastguard Worker result = TlclGetPermissions(index, &permissions);
204*8617a60dSAndroid Build Coastguard Worker if (!result) {
205*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "The space is existing but --no-overwrite is set.\n");
206*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
207*8617a60dSAndroid Build Coastguard Worker }
208*8617a60dSAndroid Build Coastguard Worker }
209*8617a60dSAndroid Build Coastguard Worker #endif
210*8617a60dSAndroid Build Coastguard Worker
211*8617a60dSAndroid Build Coastguard Worker return TlclDefineSpace(index, perm, size);
212*8617a60dSAndroid Build Coastguard Worker }
213*8617a60dSAndroid Build Coastguard Worker
HandlerUndefineSpace(void)214*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerUndefineSpace(void) {
215*8617a60dSAndroid Build Coastguard Worker uint32_t index;
216*8617a60dSAndroid Build Coastguard Worker if (nargs != 3) {
217*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc undef <index>\n");
218*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
219*8617a60dSAndroid Build Coastguard Worker }
220*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0) {
221*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index> must be "
222*8617a60dSAndroid Build Coastguard Worker "32-bit hex (0x[0-9a-f]+)\n");
223*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
224*8617a60dSAndroid Build Coastguard Worker }
225*8617a60dSAndroid Build Coastguard Worker return TlclUndefineSpace(index);
226*8617a60dSAndroid Build Coastguard Worker }
227*8617a60dSAndroid Build Coastguard Worker
HandlerWrite(void)228*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerWrite(void) {
229*8617a60dSAndroid Build Coastguard Worker uint32_t index, size;
230*8617a60dSAndroid Build Coastguard Worker uint8_t value[TPM_MAX_COMMAND_SIZE];
231*8617a60dSAndroid Build Coastguard Worker char** byteargs;
232*8617a60dSAndroid Build Coastguard Worker int i;
233*8617a60dSAndroid Build Coastguard Worker if (nargs < 3) {
234*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc write <index> [<byte0> <byte1> ...]\n");
235*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
236*8617a60dSAndroid Build Coastguard Worker }
237*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0) {
238*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
239*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
240*8617a60dSAndroid Build Coastguard Worker }
241*8617a60dSAndroid Build Coastguard Worker size = nargs - 3;
242*8617a60dSAndroid Build Coastguard Worker if (size > sizeof(value)) {
243*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "byte array too large\n");
244*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
245*8617a60dSAndroid Build Coastguard Worker }
246*8617a60dSAndroid Build Coastguard Worker
247*8617a60dSAndroid Build Coastguard Worker byteargs = args + 3;
248*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < size; i++) {
249*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint8(byteargs[i], &value[i]) != 0) {
250*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "invalid byte %s, should be [0-9a-f][0-9a-f]?\n",
251*8617a60dSAndroid Build Coastguard Worker byteargs[i]);
252*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
253*8617a60dSAndroid Build Coastguard Worker }
254*8617a60dSAndroid Build Coastguard Worker }
255*8617a60dSAndroid Build Coastguard Worker
256*8617a60dSAndroid Build Coastguard Worker if (size == 0) {
257*8617a60dSAndroid Build Coastguard Worker #ifndef TPM2_MODE
258*8617a60dSAndroid Build Coastguard Worker if (index == TPM_NV_INDEX_LOCK) {
259*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "This would set the nvLocked bit. "
260*8617a60dSAndroid Build Coastguard Worker "Use \"tpmc setnv\" instead.\n");
261*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
262*8617a60dSAndroid Build Coastguard Worker }
263*8617a60dSAndroid Build Coastguard Worker #endif
264*8617a60dSAndroid Build Coastguard Worker printf("warning: zero-length write\n");
265*8617a60dSAndroid Build Coastguard Worker } else {
266*8617a60dSAndroid Build Coastguard Worker printf("writing %d byte%s\n", size, size > 1 ? "s" : "");
267*8617a60dSAndroid Build Coastguard Worker }
268*8617a60dSAndroid Build Coastguard Worker
269*8617a60dSAndroid Build Coastguard Worker return TlclWrite(index, value, size);
270*8617a60dSAndroid Build Coastguard Worker }
271*8617a60dSAndroid Build Coastguard Worker
HandlerPCRRead(void)272*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerPCRRead(void) {
273*8617a60dSAndroid Build Coastguard Worker uint32_t index;
274*8617a60dSAndroid Build Coastguard Worker uint8_t value[TPM_PCR_DIGEST];
275*8617a60dSAndroid Build Coastguard Worker uint32_t result;
276*8617a60dSAndroid Build Coastguard Worker int i;
277*8617a60dSAndroid Build Coastguard Worker if (nargs != 3) {
278*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc pcrread <index>\n");
279*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
280*8617a60dSAndroid Build Coastguard Worker }
281*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0) {
282*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
283*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
284*8617a60dSAndroid Build Coastguard Worker }
285*8617a60dSAndroid Build Coastguard Worker result = TlclPCRRead(index, value, sizeof(value));
286*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
287*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < TPM_PCR_DIGEST; i++) {
288*8617a60dSAndroid Build Coastguard Worker printf("%02x", value[i]);
289*8617a60dSAndroid Build Coastguard Worker }
290*8617a60dSAndroid Build Coastguard Worker printf("\n");
291*8617a60dSAndroid Build Coastguard Worker }
292*8617a60dSAndroid Build Coastguard Worker return result;
293*8617a60dSAndroid Build Coastguard Worker }
294*8617a60dSAndroid Build Coastguard Worker
HandlerPCRExtend(void)295*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerPCRExtend(void) {
296*8617a60dSAndroid Build Coastguard Worker uint32_t index;
297*8617a60dSAndroid Build Coastguard Worker uint8_t value[TPM_PCR_DIGEST];
298*8617a60dSAndroid Build Coastguard Worker if (nargs != 4) {
299*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc pcrextend <index> <extend_hash>\n");
300*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
301*8617a60dSAndroid Build Coastguard Worker }
302*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0) {
303*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
304*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
305*8617a60dSAndroid Build Coastguard Worker }
306*8617a60dSAndroid Build Coastguard Worker if (HexStringToArray(args[3], value, TPM_PCR_DIGEST)) {
307*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<extend_hash> must be a %d-byte hex string\n",
308*8617a60dSAndroid Build Coastguard Worker TPM_PCR_DIGEST);
309*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
310*8617a60dSAndroid Build Coastguard Worker }
311*8617a60dSAndroid Build Coastguard Worker return TlclExtend(index, value, value);
312*8617a60dSAndroid Build Coastguard Worker }
313*8617a60dSAndroid Build Coastguard Worker
HandlerRead(void)314*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerRead(void) {
315*8617a60dSAndroid Build Coastguard Worker uint32_t index, size;
316*8617a60dSAndroid Build Coastguard Worker uint8_t value[4096];
317*8617a60dSAndroid Build Coastguard Worker uint32_t result;
318*8617a60dSAndroid Build Coastguard Worker int i;
319*8617a60dSAndroid Build Coastguard Worker if (nargs != 4) {
320*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc read <index> <size>\n");
321*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
322*8617a60dSAndroid Build Coastguard Worker }
323*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0 ||
324*8617a60dSAndroid Build Coastguard Worker HexStringToUint32(args[3], &size) != 0) {
325*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index> and <size> must be 32-bit hex (0x[0-9a-f]+)\n");
326*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
327*8617a60dSAndroid Build Coastguard Worker }
328*8617a60dSAndroid Build Coastguard Worker if (size > sizeof(value)) {
329*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "size of read (%#x) is too big\n", size);
330*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
331*8617a60dSAndroid Build Coastguard Worker }
332*8617a60dSAndroid Build Coastguard Worker result = TlclRead(index, value, size);
333*8617a60dSAndroid Build Coastguard Worker if (result == 0 && size > 0) {
334*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < size - 1; i++) {
335*8617a60dSAndroid Build Coastguard Worker printf("%x ", value[i]);
336*8617a60dSAndroid Build Coastguard Worker }
337*8617a60dSAndroid Build Coastguard Worker printf("%x\n", value[i]);
338*8617a60dSAndroid Build Coastguard Worker }
339*8617a60dSAndroid Build Coastguard Worker return result;
340*8617a60dSAndroid Build Coastguard Worker }
341*8617a60dSAndroid Build Coastguard Worker
HandlerGetPermissions(void)342*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetPermissions(void) {
343*8617a60dSAndroid Build Coastguard Worker uint32_t index, permissions, result;
344*8617a60dSAndroid Build Coastguard Worker if (nargs != 3) {
345*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc getp <index>\n");
346*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
347*8617a60dSAndroid Build Coastguard Worker }
348*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &index) != 0) {
349*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
350*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
351*8617a60dSAndroid Build Coastguard Worker }
352*8617a60dSAndroid Build Coastguard Worker result = TlclGetPermissions(index, &permissions);
353*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
354*8617a60dSAndroid Build Coastguard Worker printf("space %#x has permissions %#x\n", index, permissions);
355*8617a60dSAndroid Build Coastguard Worker }
356*8617a60dSAndroid Build Coastguard Worker return result;
357*8617a60dSAndroid Build Coastguard Worker }
358*8617a60dSAndroid Build Coastguard Worker
HandlerGetOwnership(void)359*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetOwnership(void) {
360*8617a60dSAndroid Build Coastguard Worker uint8_t owned = 0;
361*8617a60dSAndroid Build Coastguard Worker uint32_t result;
362*8617a60dSAndroid Build Coastguard Worker if (nargs != 2) {
363*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc getownership\n");
364*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
365*8617a60dSAndroid Build Coastguard Worker }
366*8617a60dSAndroid Build Coastguard Worker result = TlclGetOwnership(&owned);
367*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
368*8617a60dSAndroid Build Coastguard Worker printf("Owned: %s\n", owned ? "yes" : "no");
369*8617a60dSAndroid Build Coastguard Worker }
370*8617a60dSAndroid Build Coastguard Worker return result;
371*8617a60dSAndroid Build Coastguard Worker }
372*8617a60dSAndroid Build Coastguard Worker
HandlerGetRandom(void)373*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetRandom(void) {
374*8617a60dSAndroid Build Coastguard Worker uint32_t length, size = 0;
375*8617a60dSAndroid Build Coastguard Worker uint8_t* bytes;
376*8617a60dSAndroid Build Coastguard Worker uint32_t result;
377*8617a60dSAndroid Build Coastguard Worker int i;
378*8617a60dSAndroid Build Coastguard Worker if (nargs != 3) {
379*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc getrandom <size>\n");
380*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
381*8617a60dSAndroid Build Coastguard Worker }
382*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint32(args[2], &length) != 0) {
383*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "<size> must be 32-bit hex (0x[0-9a-f]+)\n");
384*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
385*8617a60dSAndroid Build Coastguard Worker }
386*8617a60dSAndroid Build Coastguard Worker bytes = calloc(1, length);
387*8617a60dSAndroid Build Coastguard Worker if (bytes == NULL) {
388*8617a60dSAndroid Build Coastguard Worker perror("calloc");
389*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
390*8617a60dSAndroid Build Coastguard Worker }
391*8617a60dSAndroid Build Coastguard Worker result = TlclGetRandom(bytes, length, &size);
392*8617a60dSAndroid Build Coastguard Worker if (result == 0 && size > 0) {
393*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < size; i++) {
394*8617a60dSAndroid Build Coastguard Worker printf("%02x", bytes[i]);
395*8617a60dSAndroid Build Coastguard Worker }
396*8617a60dSAndroid Build Coastguard Worker printf("\n");
397*8617a60dSAndroid Build Coastguard Worker }
398*8617a60dSAndroid Build Coastguard Worker free(bytes);
399*8617a60dSAndroid Build Coastguard Worker return result;
400*8617a60dSAndroid Build Coastguard Worker }
401*8617a60dSAndroid Build Coastguard Worker
HandlerGetPermanentFlags(void)402*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetPermanentFlags(void) {
403*8617a60dSAndroid Build Coastguard Worker TPM_PERMANENT_FLAGS pflags;
404*8617a60dSAndroid Build Coastguard Worker uint32_t result = TlclGetPermanentFlags(&pflags);
405*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
406*8617a60dSAndroid Build Coastguard Worker #define P(name) printf("%s %d\n", #name, pflags.name)
407*8617a60dSAndroid Build Coastguard Worker #ifdef TPM2_MODE
408*8617a60dSAndroid Build Coastguard Worker P(ownerAuthSet);
409*8617a60dSAndroid Build Coastguard Worker P(endorsementAuthSet);
410*8617a60dSAndroid Build Coastguard Worker P(lockoutAuthSet);
411*8617a60dSAndroid Build Coastguard Worker P(disableClear);
412*8617a60dSAndroid Build Coastguard Worker P(inLockout);
413*8617a60dSAndroid Build Coastguard Worker P(tpmGeneratedEPS);
414*8617a60dSAndroid Build Coastguard Worker #else
415*8617a60dSAndroid Build Coastguard Worker P(disable);
416*8617a60dSAndroid Build Coastguard Worker P(ownership);
417*8617a60dSAndroid Build Coastguard Worker P(deactivated);
418*8617a60dSAndroid Build Coastguard Worker P(readPubek);
419*8617a60dSAndroid Build Coastguard Worker P(disableOwnerClear);
420*8617a60dSAndroid Build Coastguard Worker P(allowMaintenance);
421*8617a60dSAndroid Build Coastguard Worker P(physicalPresenceLifetimeLock);
422*8617a60dSAndroid Build Coastguard Worker P(physicalPresenceHWEnable);
423*8617a60dSAndroid Build Coastguard Worker P(physicalPresenceCMDEnable);
424*8617a60dSAndroid Build Coastguard Worker P(CEKPUsed);
425*8617a60dSAndroid Build Coastguard Worker P(TPMpost);
426*8617a60dSAndroid Build Coastguard Worker P(TPMpostLock);
427*8617a60dSAndroid Build Coastguard Worker P(FIPS);
428*8617a60dSAndroid Build Coastguard Worker P(Operator);
429*8617a60dSAndroid Build Coastguard Worker P(enableRevokeEK);
430*8617a60dSAndroid Build Coastguard Worker P(nvLocked);
431*8617a60dSAndroid Build Coastguard Worker P(readSRKPub);
432*8617a60dSAndroid Build Coastguard Worker P(tpmEstablished);
433*8617a60dSAndroid Build Coastguard Worker P(maintenanceDone);
434*8617a60dSAndroid Build Coastguard Worker P(disableFullDALogicInfo);
435*8617a60dSAndroid Build Coastguard Worker #endif
436*8617a60dSAndroid Build Coastguard Worker #undef P
437*8617a60dSAndroid Build Coastguard Worker }
438*8617a60dSAndroid Build Coastguard Worker return result;
439*8617a60dSAndroid Build Coastguard Worker }
440*8617a60dSAndroid Build Coastguard Worker
HandlerGetSTClearFlags(void)441*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetSTClearFlags(void) {
442*8617a60dSAndroid Build Coastguard Worker TPM_STCLEAR_FLAGS vflags;
443*8617a60dSAndroid Build Coastguard Worker uint32_t result = TlclGetSTClearFlags(&vflags);
444*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
445*8617a60dSAndroid Build Coastguard Worker #define P(name) printf("%s %d\n", #name, vflags.name)
446*8617a60dSAndroid Build Coastguard Worker #ifdef TPM2_MODE
447*8617a60dSAndroid Build Coastguard Worker P(phEnable);
448*8617a60dSAndroid Build Coastguard Worker P(shEnable);
449*8617a60dSAndroid Build Coastguard Worker P(ehEnable);
450*8617a60dSAndroid Build Coastguard Worker P(phEnableNV);
451*8617a60dSAndroid Build Coastguard Worker P(orderly);
452*8617a60dSAndroid Build Coastguard Worker #else
453*8617a60dSAndroid Build Coastguard Worker P(deactivated);
454*8617a60dSAndroid Build Coastguard Worker P(disableForceClear);
455*8617a60dSAndroid Build Coastguard Worker P(physicalPresence);
456*8617a60dSAndroid Build Coastguard Worker P(physicalPresenceLock);
457*8617a60dSAndroid Build Coastguard Worker P(bGlobalLock);
458*8617a60dSAndroid Build Coastguard Worker #endif
459*8617a60dSAndroid Build Coastguard Worker #undef P
460*8617a60dSAndroid Build Coastguard Worker }
461*8617a60dSAndroid Build Coastguard Worker return result;
462*8617a60dSAndroid Build Coastguard Worker }
463*8617a60dSAndroid Build Coastguard Worker
HandlerSendRaw(void)464*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerSendRaw(void) {
465*8617a60dSAndroid Build Coastguard Worker uint8_t request[4096];
466*8617a60dSAndroid Build Coastguard Worker uint8_t response[4096];
467*8617a60dSAndroid Build Coastguard Worker uint32_t result;
468*8617a60dSAndroid Build Coastguard Worker int size;
469*8617a60dSAndroid Build Coastguard Worker int i;
470*8617a60dSAndroid Build Coastguard Worker if (nargs == 2) {
471*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: tpmc sendraw <hex byte 0> ... <hex byte N>\n");
472*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
473*8617a60dSAndroid Build Coastguard Worker }
474*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < nargs - 2 && i < sizeof(request); i++) {
475*8617a60dSAndroid Build Coastguard Worker if (HexStringToUint8(args[2 + i], &request[i]) != 0) {
476*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "bad byte value \"%s\"\n", args[2 + i]);
477*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
478*8617a60dSAndroid Build Coastguard Worker }
479*8617a60dSAndroid Build Coastguard Worker }
480*8617a60dSAndroid Build Coastguard Worker size = TlclPacketSize(request);
481*8617a60dSAndroid Build Coastguard Worker if (size != i) {
482*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "bad request: size field is %d, but packet has %d bytes\n",
483*8617a60dSAndroid Build Coastguard Worker size, i);
484*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
485*8617a60dSAndroid Build Coastguard Worker }
486*8617a60dSAndroid Build Coastguard Worker bzero(response, sizeof(response));
487*8617a60dSAndroid Build Coastguard Worker result = TlclSendReceive(request, response, sizeof(response));
488*8617a60dSAndroid Build Coastguard Worker if (result != 0) {
489*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "request failed with code %d\n", result);
490*8617a60dSAndroid Build Coastguard Worker }
491*8617a60dSAndroid Build Coastguard Worker size = TlclPacketSize(response);
492*8617a60dSAndroid Build Coastguard Worker if (size < 10 || size > sizeof(response)) {
493*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "unexpected response size %d\n", size);
494*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
495*8617a60dSAndroid Build Coastguard Worker }
496*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < size; i++) {
497*8617a60dSAndroid Build Coastguard Worker printf("0x%02x ", response[i]);
498*8617a60dSAndroid Build Coastguard Worker if (i == size - 1 || (i + 1) % 8 == 0) {
499*8617a60dSAndroid Build Coastguard Worker printf("\n");
500*8617a60dSAndroid Build Coastguard Worker }
501*8617a60dSAndroid Build Coastguard Worker }
502*8617a60dSAndroid Build Coastguard Worker return result;
503*8617a60dSAndroid Build Coastguard Worker }
504*8617a60dSAndroid Build Coastguard Worker
HandlerGetVersion(void)505*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerGetVersion(void) {
506*8617a60dSAndroid Build Coastguard Worker uint32_t vendor;
507*8617a60dSAndroid Build Coastguard Worker uint64_t firmware_version;
508*8617a60dSAndroid Build Coastguard Worker uint8_t vendor_specific[32];
509*8617a60dSAndroid Build Coastguard Worker size_t vendor_specific_size = sizeof(vendor_specific);
510*8617a60dSAndroid Build Coastguard Worker uint32_t result = TlclGetVersion(&vendor, &firmware_version, vendor_specific,
511*8617a60dSAndroid Build Coastguard Worker &vendor_specific_size);
512*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
513*8617a60dSAndroid Build Coastguard Worker printf("vendor %08x\nfirmware_version %016" PRIx64 "\nvendor_specific ",
514*8617a60dSAndroid Build Coastguard Worker vendor, firmware_version);
515*8617a60dSAndroid Build Coastguard Worker size_t n;
516*8617a60dSAndroid Build Coastguard Worker for (n = 0; n < vendor_specific_size; ++n) {
517*8617a60dSAndroid Build Coastguard Worker printf("%02x", vendor_specific[n]);
518*8617a60dSAndroid Build Coastguard Worker }
519*8617a60dSAndroid Build Coastguard Worker printf("\n");
520*8617a60dSAndroid Build Coastguard Worker }
521*8617a60dSAndroid Build Coastguard Worker return result;
522*8617a60dSAndroid Build Coastguard Worker }
523*8617a60dSAndroid Build Coastguard Worker
524*8617a60dSAndroid Build Coastguard Worker #ifndef TPM2_MODE
PrintIFXFirmwarePackage(TPM_IFX_FIRMWAREPACKAGE * firmware_package,const char * prefix)525*8617a60dSAndroid Build Coastguard Worker static void PrintIFXFirmwarePackage(TPM_IFX_FIRMWAREPACKAGE* firmware_package,
526*8617a60dSAndroid Build Coastguard Worker const char* prefix) {
527*8617a60dSAndroid Build Coastguard Worker printf("%s_package_id %08x\n", prefix,
528*8617a60dSAndroid Build Coastguard Worker firmware_package->FwPackageIdentifier);
529*8617a60dSAndroid Build Coastguard Worker printf("%s_version %08x\n", prefix, firmware_package->Version);
530*8617a60dSAndroid Build Coastguard Worker printf("%s_stale_version %08x\n", prefix, firmware_package->StaleVersion);
531*8617a60dSAndroid Build Coastguard Worker }
532*8617a60dSAndroid Build Coastguard Worker
HandlerIFXFieldUpgradeInfo(void)533*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerIFXFieldUpgradeInfo(void) {
534*8617a60dSAndroid Build Coastguard Worker TPM_IFX_FIELDUPGRADEINFO info;
535*8617a60dSAndroid Build Coastguard Worker uint32_t result = TlclIFXFieldUpgradeInfo(&info);
536*8617a60dSAndroid Build Coastguard Worker if (result == 0) {
537*8617a60dSAndroid Build Coastguard Worker printf("max_data_size %u\n", info.wMaxDataSize);
538*8617a60dSAndroid Build Coastguard Worker PrintIFXFirmwarePackage(&info.sBootloaderFirmwarePackage, "bootloader");
539*8617a60dSAndroid Build Coastguard Worker PrintIFXFirmwarePackage(&info.sFirmwarePackages[0], "fw0");
540*8617a60dSAndroid Build Coastguard Worker PrintIFXFirmwarePackage(&info.sFirmwarePackages[1], "fw1");
541*8617a60dSAndroid Build Coastguard Worker printf("status %04x\n", info.wSecurityModuleStatus);
542*8617a60dSAndroid Build Coastguard Worker PrintIFXFirmwarePackage(&info.sProcessFirmwarePackage, "process_fw");
543*8617a60dSAndroid Build Coastguard Worker printf("field_upgrade_counter %u\n", info.wFieldUpgradeCounter);
544*8617a60dSAndroid Build Coastguard Worker }
545*8617a60dSAndroid Build Coastguard Worker return result;
546*8617a60dSAndroid Build Coastguard Worker }
547*8617a60dSAndroid Build Coastguard Worker
HandlerCheckOwnerAuth(void)548*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerCheckOwnerAuth(void) {
549*8617a60dSAndroid Build Coastguard Worker /* Attempt to define an NVRAM space using owner auth. We're using
550*8617a60dSAndroid Build Coastguard Worker * TPM_NV_INDEX_TRIAL, which doesn't actually allocate a space but still
551*8617a60dSAndroid Build Coastguard Worker * performs the owner authorization checks. Thus the return status indicates
552*8617a60dSAndroid Build Coastguard Worker * whether owner authorization was successful or not.
553*8617a60dSAndroid Build Coastguard Worker *
554*8617a60dSAndroid Build Coastguard Worker * The owner_auth value below is the commonly used well-known secret, i.e. the
555*8617a60dSAndroid Build Coastguard Worker * SHA1 hash of 20 zero bytes. This is the owner secret that is effective
556*8617a60dSAndroid Build Coastguard Worker * immediately after taking TPM ownership when we haven't configured a random
557*8617a60dSAndroid Build Coastguard Worker * owner password yet.
558*8617a60dSAndroid Build Coastguard Worker */
559*8617a60dSAndroid Build Coastguard Worker uint8_t owner_auth[TPM_AUTH_DATA_LEN] = {
560*8617a60dSAndroid Build Coastguard Worker 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
561*8617a60dSAndroid Build Coastguard Worker 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f};
562*8617a60dSAndroid Build Coastguard Worker return TlclDefineSpaceEx(owner_auth, sizeof(owner_auth), TPM_NV_INDEX_TRIAL,
563*8617a60dSAndroid Build Coastguard Worker TPM_NV_PER_OWNERWRITE, 1, NULL, 0);
564*8617a60dSAndroid Build Coastguard Worker }
565*8617a60dSAndroid Build Coastguard Worker #endif /* !TPM2_MODE */
566*8617a60dSAndroid Build Coastguard Worker
567*8617a60dSAndroid Build Coastguard Worker #ifdef TPM2_MODE
HandlerDoNothingForTPM2(void)568*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerDoNothingForTPM2(void) {
569*8617a60dSAndroid Build Coastguard Worker return 0;
570*8617a60dSAndroid Build Coastguard Worker }
571*8617a60dSAndroid Build Coastguard Worker
HandlerNotImplementedForTPM2(void)572*8617a60dSAndroid Build Coastguard Worker static uint32_t HandlerNotImplementedForTPM2(void) {
573*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s: not implemented for TPM2.0\n", args[1]);
574*8617a60dSAndroid Build Coastguard Worker exit(OTHER_ERROR);
575*8617a60dSAndroid Build Coastguard Worker }
576*8617a60dSAndroid Build Coastguard Worker #endif
577*8617a60dSAndroid Build Coastguard Worker
578*8617a60dSAndroid Build Coastguard Worker /* Table of TPM commands.
579*8617a60dSAndroid Build Coastguard Worker */
580*8617a60dSAndroid Build Coastguard Worker command_record command_table[] = {
581*8617a60dSAndroid Build Coastguard Worker { "tpmversion", "tpmver", "print TPM version: 1.2 or 2.0",
582*8617a60dSAndroid Build Coastguard Worker HandlerTpmVersion },
583*8617a60dSAndroid Build Coastguard Worker { "getflags", "getf", "read and print the value of selected flags",
584*8617a60dSAndroid Build Coastguard Worker HandlerGetFlags },
585*8617a60dSAndroid Build Coastguard Worker { "startup", "sta", "issue a Startup command", TlclStartup },
586*8617a60dSAndroid Build Coastguard Worker { "selftestfull", "test", "issue a SelfTestFull command", TlclSelfTestFull },
587*8617a60dSAndroid Build Coastguard Worker { "continueselftest", "ctest", "issue a ContinueSelfTest command",
588*8617a60dSAndroid Build Coastguard Worker TlclContinueSelfTest },
589*8617a60dSAndroid Build Coastguard Worker { "assertphysicalpresence", "ppon",
590*8617a60dSAndroid Build Coastguard Worker TPM20_DOES_NOTHING("assert Physical Presence",
591*8617a60dSAndroid Build Coastguard Worker TlclAssertPhysicalPresence) },
592*8617a60dSAndroid Build Coastguard Worker { "physicalpresencecmdenable", "ppcmd",
593*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED("turn on software PP",
594*8617a60dSAndroid Build Coastguard Worker TlclPhysicalPresenceCMDEnable) },
595*8617a60dSAndroid Build Coastguard Worker { "enable", "ena",
596*8617a60dSAndroid Build Coastguard Worker TPM20_DOES_NOTHING("enable the TPM" TPM12_NEEDS_PP,
597*8617a60dSAndroid Build Coastguard Worker TlclSetEnable) },
598*8617a60dSAndroid Build Coastguard Worker { "disable", "dis",
599*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED("disable the TPM" TPM12_NEEDS_PP,
600*8617a60dSAndroid Build Coastguard Worker TlclClearEnable) },
601*8617a60dSAndroid Build Coastguard Worker { "activate", "act",
602*8617a60dSAndroid Build Coastguard Worker TPM20_DOES_NOTHING("activate the TPM" TPM12_NEEDS_PP_REBOOT,
603*8617a60dSAndroid Build Coastguard Worker HandlerActivate) },
604*8617a60dSAndroid Build Coastguard Worker { "deactivate", "deact",
605*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED("deactivate the TPM" TPM12_NEEDS_PP_REBOOT,
606*8617a60dSAndroid Build Coastguard Worker HandlerDeactivate) },
607*8617a60dSAndroid Build Coastguard Worker { "clear", "clr",
608*8617a60dSAndroid Build Coastguard Worker "clear the TPM owner" TPM12_NEEDS_PP,
609*8617a60dSAndroid Build Coastguard Worker TlclForceClear },
610*8617a60dSAndroid Build Coastguard Worker { "setnvlocked", "setnv",
611*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED("set the nvLocked flag permanently (IRREVERSIBLE!)",
612*8617a60dSAndroid Build Coastguard Worker TlclSetNvLocked) },
613*8617a60dSAndroid Build Coastguard Worker { "lockphysicalpresence", "pplock",
614*8617a60dSAndroid Build Coastguard Worker TPM_MODE_SELECT("lock (turn off) PP until reboot",
615*8617a60dSAndroid Build Coastguard Worker "set rollback protection lock for kernel image until reboot"),
616*8617a60dSAndroid Build Coastguard Worker TlclLockPhysicalPresence },
617*8617a60dSAndroid Build Coastguard Worker { "setbgloballock", "block",
618*8617a60dSAndroid Build Coastguard Worker TPM_MODE_SELECT("set the bGlobalLock until reboot",
619*8617a60dSAndroid Build Coastguard Worker "set rollback protection lock for R/W firmware until reboot"),
620*8617a60dSAndroid Build Coastguard Worker TlclSetGlobalLock },
621*8617a60dSAndroid Build Coastguard Worker { "definespace", "def",
622*8617a60dSAndroid Build Coastguard Worker TPM_MODE_SELECT("define a space (def <index> <size> <perm>). ",
623*8617a60dSAndroid Build Coastguard Worker "define a space (def <index> <size> <perm> [--no-overwrite]). ")
624*8617a60dSAndroid Build Coastguard Worker "Default will overwrite if the space is defined.",
625*8617a60dSAndroid Build Coastguard Worker HandlerDefineSpace },
626*8617a60dSAndroid Build Coastguard Worker { "undefinespace", "undef",
627*8617a60dSAndroid Build Coastguard Worker "undefine a space (undef <index>)"
628*8617a60dSAndroid Build Coastguard Worker TPM_MODE_SELECT(" only succeeds when NvLocked is not set", ""),
629*8617a60dSAndroid Build Coastguard Worker HandlerUndefineSpace },
630*8617a60dSAndroid Build Coastguard Worker { "write", "write", "write to a space (write <index> [<byte0> <byte1> ...])",
631*8617a60dSAndroid Build Coastguard Worker HandlerWrite },
632*8617a60dSAndroid Build Coastguard Worker { "read", "read", "read from a space (read <index> <size>)",
633*8617a60dSAndroid Build Coastguard Worker HandlerRead },
634*8617a60dSAndroid Build Coastguard Worker { "pcrread", "pcr", "read from a PCR (pcrread <index>)",
635*8617a60dSAndroid Build Coastguard Worker HandlerPCRRead },
636*8617a60dSAndroid Build Coastguard Worker { "pcrextend", "extend", "extend a PCR (extend <index> <extend_hash>)",
637*8617a60dSAndroid Build Coastguard Worker HandlerPCRExtend },
638*8617a60dSAndroid Build Coastguard Worker { "getownership", "geto", "print state of TPM ownership",
639*8617a60dSAndroid Build Coastguard Worker HandlerGetOwnership },
640*8617a60dSAndroid Build Coastguard Worker { "getpermissions", "getp", "print space permissions (getp <index>)",
641*8617a60dSAndroid Build Coastguard Worker HandlerGetPermissions },
642*8617a60dSAndroid Build Coastguard Worker { "getpermanentflags", "getpf", "print all permanent flags",
643*8617a60dSAndroid Build Coastguard Worker HandlerGetPermanentFlags },
644*8617a60dSAndroid Build Coastguard Worker { "getrandom", "rand", "read bytes from RNG (rand <size>)",
645*8617a60dSAndroid Build Coastguard Worker HandlerGetRandom },
646*8617a60dSAndroid Build Coastguard Worker { "getstclearflags", "getvf", "print all volatile (ST_CLEAR) flags",
647*8617a60dSAndroid Build Coastguard Worker HandlerGetSTClearFlags },
648*8617a60dSAndroid Build Coastguard Worker { "resume", "res", "execute TPM_Startup(ST_STATE)", TlclResume },
649*8617a60dSAndroid Build Coastguard Worker { "savestate", "save", "execute TPM_SaveState", TlclSaveState },
650*8617a60dSAndroid Build Coastguard Worker { "sendraw", "raw", "send a raw request and print raw response",
651*8617a60dSAndroid Build Coastguard Worker HandlerSendRaw },
652*8617a60dSAndroid Build Coastguard Worker { "getversion", "getver", "get TPM vendor and firmware version",
653*8617a60dSAndroid Build Coastguard Worker HandlerGetVersion },
654*8617a60dSAndroid Build Coastguard Worker { "ifxfieldupgradeinfo", "ifxfui",
655*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED("read and print IFX field upgrade info",
656*8617a60dSAndroid Build Coastguard Worker HandlerIFXFieldUpgradeInfo) },
657*8617a60dSAndroid Build Coastguard Worker { "checkownerauth", "chko",
658*8617a60dSAndroid Build Coastguard Worker TPM20_NOT_IMPLEMENTED("Check owner authorization with well-known secret",
659*8617a60dSAndroid Build Coastguard Worker HandlerCheckOwnerAuth) },
660*8617a60dSAndroid Build Coastguard Worker };
661*8617a60dSAndroid Build Coastguard Worker
662*8617a60dSAndroid Build Coastguard Worker static int n_commands = sizeof(command_table) / sizeof(command_table[0]);
663*8617a60dSAndroid Build Coastguard Worker
main(int argc,char * argv[])664*8617a60dSAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
665*8617a60dSAndroid Build Coastguard Worker char *progname;
666*8617a60dSAndroid Build Coastguard Worker uint32_t result;
667*8617a60dSAndroid Build Coastguard Worker
668*8617a60dSAndroid Build Coastguard Worker progname = strrchr(argv[0], '/');
669*8617a60dSAndroid Build Coastguard Worker if (progname)
670*8617a60dSAndroid Build Coastguard Worker progname++;
671*8617a60dSAndroid Build Coastguard Worker else
672*8617a60dSAndroid Build Coastguard Worker progname = argv[0];
673*8617a60dSAndroid Build Coastguard Worker
674*8617a60dSAndroid Build Coastguard Worker if (argc < 2) {
675*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "usage: %s <TPM command> [args]\n or: %s help\n",
676*8617a60dSAndroid Build Coastguard Worker progname, progname);
677*8617a60dSAndroid Build Coastguard Worker return OTHER_ERROR;
678*8617a60dSAndroid Build Coastguard Worker } else {
679*8617a60dSAndroid Build Coastguard Worker command_record* c;
680*8617a60dSAndroid Build Coastguard Worker const char* cmd = argv[1];
681*8617a60dSAndroid Build Coastguard Worker nargs = argc;
682*8617a60dSAndroid Build Coastguard Worker args = argv;
683*8617a60dSAndroid Build Coastguard Worker
684*8617a60dSAndroid Build Coastguard Worker if (strcmp(cmd, "help") == 0) {
685*8617a60dSAndroid Build Coastguard Worker printf("tpmc mode: TPM%s\n", TPM_MODE_STRING);
686*8617a60dSAndroid Build Coastguard Worker printf("%26s %7s %s\n\n", "command", "abbr.", "description");
687*8617a60dSAndroid Build Coastguard Worker for (c = command_table; c < command_table + n_commands; c++) {
688*8617a60dSAndroid Build Coastguard Worker printf("%26s %7s %s\n", c->name, c->abbr, c->description);
689*8617a60dSAndroid Build Coastguard Worker }
690*8617a60dSAndroid Build Coastguard Worker return 0;
691*8617a60dSAndroid Build Coastguard Worker }
692*8617a60dSAndroid Build Coastguard Worker if (!strcmp(cmd, "tpmversion") || !strcmp(cmd, "tpmver")) {
693*8617a60dSAndroid Build Coastguard Worker return HandlerTpmVersion();
694*8617a60dSAndroid Build Coastguard Worker }
695*8617a60dSAndroid Build Coastguard Worker
696*8617a60dSAndroid Build Coastguard Worker result = TlclLibInit();
697*8617a60dSAndroid Build Coastguard Worker if (result) {
698*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "initialization failed with code %d\n", result);
699*8617a60dSAndroid Build Coastguard Worker return result > OTHER_ERROR ? OTHER_ERROR : result;
700*8617a60dSAndroid Build Coastguard Worker }
701*8617a60dSAndroid Build Coastguard Worker
702*8617a60dSAndroid Build Coastguard Worker for (c = command_table; c < command_table + n_commands; c++) {
703*8617a60dSAndroid Build Coastguard Worker if (strcmp(cmd, c->name) == 0 || strcmp(cmd, c->abbr) == 0) {
704*8617a60dSAndroid Build Coastguard Worker return ErrorCheck(c->handler(), cmd);
705*8617a60dSAndroid Build Coastguard Worker }
706*8617a60dSAndroid Build Coastguard Worker }
707*8617a60dSAndroid Build Coastguard Worker
708*8617a60dSAndroid Build Coastguard Worker /* No command matched. */
709*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s: unknown command: %s\n", progname, cmd);
710*8617a60dSAndroid Build Coastguard Worker return OTHER_ERROR;
711*8617a60dSAndroid Build Coastguard Worker }
712*8617a60dSAndroid Build Coastguard Worker }
713