xref: /rk3399_rockchip-uboot/cmd/tpm.c (revision 2e192b245ed36a63bab0ef576999a95e23f60ecd)
1*2e192b24SSimon Glass /*
2*2e192b24SSimon Glass  * Copyright (c) 2013 The Chromium OS Authors.
3*2e192b24SSimon Glass  *
4*2e192b24SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
5*2e192b24SSimon Glass  */
6*2e192b24SSimon Glass 
7*2e192b24SSimon Glass #include <common.h>
8*2e192b24SSimon Glass #include <command.h>
9*2e192b24SSimon Glass #include <dm.h>
10*2e192b24SSimon Glass #include <malloc.h>
11*2e192b24SSimon Glass #include <tpm.h>
12*2e192b24SSimon Glass #include <asm/unaligned.h>
13*2e192b24SSimon Glass #include <linux/string.h>
14*2e192b24SSimon Glass 
15*2e192b24SSimon Glass /* Useful constants */
16*2e192b24SSimon Glass enum {
17*2e192b24SSimon Glass 	DIGEST_LENGTH		= 20,
18*2e192b24SSimon Glass 	/* max lengths, valid for RSA keys <= 2048 bits */
19*2e192b24SSimon Glass 	TPM_PUBKEY_MAX_LENGTH	= 288,
20*2e192b24SSimon Glass };
21*2e192b24SSimon Glass 
22*2e192b24SSimon Glass /**
23*2e192b24SSimon Glass  * Print a byte string in hexdecimal format, 16-bytes per line.
24*2e192b24SSimon Glass  *
25*2e192b24SSimon Glass  * @param data		byte string to be printed
26*2e192b24SSimon Glass  * @param count		number of bytes to be printed
27*2e192b24SSimon Glass  */
28*2e192b24SSimon Glass static void print_byte_string(uint8_t *data, size_t count)
29*2e192b24SSimon Glass {
30*2e192b24SSimon Glass 	int i, print_newline = 0;
31*2e192b24SSimon Glass 
32*2e192b24SSimon Glass 	for (i = 0; i < count; i++) {
33*2e192b24SSimon Glass 		printf(" %02x", data[i]);
34*2e192b24SSimon Glass 		print_newline = (i % 16 == 15);
35*2e192b24SSimon Glass 		if (print_newline)
36*2e192b24SSimon Glass 			putc('\n');
37*2e192b24SSimon Glass 	}
38*2e192b24SSimon Glass 	/* Avoid duplicated newline at the end */
39*2e192b24SSimon Glass 	if (!print_newline)
40*2e192b24SSimon Glass 		putc('\n');
41*2e192b24SSimon Glass }
42*2e192b24SSimon Glass 
43*2e192b24SSimon Glass /**
44*2e192b24SSimon Glass  * Convert a text string of hexdecimal values into a byte string.
45*2e192b24SSimon Glass  *
46*2e192b24SSimon Glass  * @param bytes		text string of hexdecimal values with no space
47*2e192b24SSimon Glass  *			between them
48*2e192b24SSimon Glass  * @param data		output buffer for byte string.  The caller has to make
49*2e192b24SSimon Glass  *			sure it is large enough for storing the output.  If
50*2e192b24SSimon Glass  *			NULL is passed, a large enough buffer will be allocated,
51*2e192b24SSimon Glass  *			and the caller must free it.
52*2e192b24SSimon Glass  * @param count_ptr	output variable for the length of byte string
53*2e192b24SSimon Glass  * @return pointer to output buffer
54*2e192b24SSimon Glass  */
55*2e192b24SSimon Glass static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
56*2e192b24SSimon Glass {
57*2e192b24SSimon Glass 	char byte[3];
58*2e192b24SSimon Glass 	size_t count, length;
59*2e192b24SSimon Glass 	int i;
60*2e192b24SSimon Glass 
61*2e192b24SSimon Glass 	if (!bytes)
62*2e192b24SSimon Glass 		return NULL;
63*2e192b24SSimon Glass 	length = strlen(bytes);
64*2e192b24SSimon Glass 	count = length / 2;
65*2e192b24SSimon Glass 
66*2e192b24SSimon Glass 	if (!data)
67*2e192b24SSimon Glass 		data = malloc(count);
68*2e192b24SSimon Glass 	if (!data)
69*2e192b24SSimon Glass 		return NULL;
70*2e192b24SSimon Glass 
71*2e192b24SSimon Glass 	byte[2] = '\0';
72*2e192b24SSimon Glass 	for (i = 0; i < length; i += 2) {
73*2e192b24SSimon Glass 		byte[0] = bytes[i];
74*2e192b24SSimon Glass 		byte[1] = bytes[i + 1];
75*2e192b24SSimon Glass 		data[i / 2] = (uint8_t)simple_strtoul(byte, NULL, 16);
76*2e192b24SSimon Glass 	}
77*2e192b24SSimon Glass 
78*2e192b24SSimon Glass 	if (count_ptr)
79*2e192b24SSimon Glass 		*count_ptr = count;
80*2e192b24SSimon Glass 
81*2e192b24SSimon Glass 	return data;
82*2e192b24SSimon Glass }
83*2e192b24SSimon Glass 
84*2e192b24SSimon Glass /**
85*2e192b24SSimon Glass  * report_return_code() - Report any error and return failure or success
86*2e192b24SSimon Glass  *
87*2e192b24SSimon Glass  * @param return_code	TPM command return code
88*2e192b24SSimon Glass  * @return value of enum command_ret_t
89*2e192b24SSimon Glass  */
90*2e192b24SSimon Glass static int report_return_code(int return_code)
91*2e192b24SSimon Glass {
92*2e192b24SSimon Glass 	if (return_code) {
93*2e192b24SSimon Glass 		printf("Error: %d\n", return_code);
94*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
95*2e192b24SSimon Glass 	} else {
96*2e192b24SSimon Glass 		return CMD_RET_SUCCESS;
97*2e192b24SSimon Glass 	}
98*2e192b24SSimon Glass }
99*2e192b24SSimon Glass 
100*2e192b24SSimon Glass /**
101*2e192b24SSimon Glass  * Return number of values defined by a type string.
102*2e192b24SSimon Glass  *
103*2e192b24SSimon Glass  * @param type_str	type string
104*2e192b24SSimon Glass  * @return number of values of type string
105*2e192b24SSimon Glass  */
106*2e192b24SSimon Glass static int type_string_get_num_values(const char *type_str)
107*2e192b24SSimon Glass {
108*2e192b24SSimon Glass 	return strlen(type_str);
109*2e192b24SSimon Glass }
110*2e192b24SSimon Glass 
111*2e192b24SSimon Glass /**
112*2e192b24SSimon Glass  * Return total size of values defined by a type string.
113*2e192b24SSimon Glass  *
114*2e192b24SSimon Glass  * @param type_str	type string
115*2e192b24SSimon Glass  * @return total size of values of type string, or 0 if type string
116*2e192b24SSimon Glass  *  contains illegal type character.
117*2e192b24SSimon Glass  */
118*2e192b24SSimon Glass static size_t type_string_get_space_size(const char *type_str)
119*2e192b24SSimon Glass {
120*2e192b24SSimon Glass 	size_t size;
121*2e192b24SSimon Glass 
122*2e192b24SSimon Glass 	for (size = 0; *type_str; type_str++) {
123*2e192b24SSimon Glass 		switch (*type_str) {
124*2e192b24SSimon Glass 		case 'b':
125*2e192b24SSimon Glass 			size += 1;
126*2e192b24SSimon Glass 			break;
127*2e192b24SSimon Glass 		case 'w':
128*2e192b24SSimon Glass 			size += 2;
129*2e192b24SSimon Glass 			break;
130*2e192b24SSimon Glass 		case 'd':
131*2e192b24SSimon Glass 			size += 4;
132*2e192b24SSimon Glass 			break;
133*2e192b24SSimon Glass 		default:
134*2e192b24SSimon Glass 			return 0;
135*2e192b24SSimon Glass 		}
136*2e192b24SSimon Glass 	}
137*2e192b24SSimon Glass 
138*2e192b24SSimon Glass 	return size;
139*2e192b24SSimon Glass }
140*2e192b24SSimon Glass 
141*2e192b24SSimon Glass /**
142*2e192b24SSimon Glass  * Allocate a buffer large enough to hold values defined by a type
143*2e192b24SSimon Glass  * string.  The caller has to free the buffer.
144*2e192b24SSimon Glass  *
145*2e192b24SSimon Glass  * @param type_str	type string
146*2e192b24SSimon Glass  * @param count		pointer for storing size of buffer
147*2e192b24SSimon Glass  * @return pointer to buffer or NULL on error
148*2e192b24SSimon Glass  */
149*2e192b24SSimon Glass static void *type_string_alloc(const char *type_str, uint32_t *count)
150*2e192b24SSimon Glass {
151*2e192b24SSimon Glass 	void *data;
152*2e192b24SSimon Glass 	size_t size;
153*2e192b24SSimon Glass 
154*2e192b24SSimon Glass 	size = type_string_get_space_size(type_str);
155*2e192b24SSimon Glass 	if (!size)
156*2e192b24SSimon Glass 		return NULL;
157*2e192b24SSimon Glass 	data = malloc(size);
158*2e192b24SSimon Glass 	if (data)
159*2e192b24SSimon Glass 		*count = size;
160*2e192b24SSimon Glass 
161*2e192b24SSimon Glass 	return data;
162*2e192b24SSimon Glass }
163*2e192b24SSimon Glass 
164*2e192b24SSimon Glass /**
165*2e192b24SSimon Glass  * Pack values defined by a type string into a buffer.  The buffer must have
166*2e192b24SSimon Glass  * large enough space.
167*2e192b24SSimon Glass  *
168*2e192b24SSimon Glass  * @param type_str	type string
169*2e192b24SSimon Glass  * @param values	text strings of values to be packed
170*2e192b24SSimon Glass  * @param data		output buffer of values
171*2e192b24SSimon Glass  * @return 0 on success, non-0 on error
172*2e192b24SSimon Glass  */
173*2e192b24SSimon Glass static int type_string_pack(const char *type_str, char * const values[],
174*2e192b24SSimon Glass 		uint8_t *data)
175*2e192b24SSimon Glass {
176*2e192b24SSimon Glass 	size_t offset;
177*2e192b24SSimon Glass 	uint32_t value;
178*2e192b24SSimon Glass 
179*2e192b24SSimon Glass 	for (offset = 0; *type_str; type_str++, values++) {
180*2e192b24SSimon Glass 		value = simple_strtoul(values[0], NULL, 0);
181*2e192b24SSimon Glass 		switch (*type_str) {
182*2e192b24SSimon Glass 		case 'b':
183*2e192b24SSimon Glass 			data[offset] = value;
184*2e192b24SSimon Glass 			offset += 1;
185*2e192b24SSimon Glass 			break;
186*2e192b24SSimon Glass 		case 'w':
187*2e192b24SSimon Glass 			put_unaligned_be16(value, data + offset);
188*2e192b24SSimon Glass 			offset += 2;
189*2e192b24SSimon Glass 			break;
190*2e192b24SSimon Glass 		case 'd':
191*2e192b24SSimon Glass 			put_unaligned_be32(value, data + offset);
192*2e192b24SSimon Glass 			offset += 4;
193*2e192b24SSimon Glass 			break;
194*2e192b24SSimon Glass 		default:
195*2e192b24SSimon Glass 			return -1;
196*2e192b24SSimon Glass 		}
197*2e192b24SSimon Glass 	}
198*2e192b24SSimon Glass 
199*2e192b24SSimon Glass 	return 0;
200*2e192b24SSimon Glass }
201*2e192b24SSimon Glass 
202*2e192b24SSimon Glass /**
203*2e192b24SSimon Glass  * Read values defined by a type string from a buffer, and write these values
204*2e192b24SSimon Glass  * to environment variables.
205*2e192b24SSimon Glass  *
206*2e192b24SSimon Glass  * @param type_str	type string
207*2e192b24SSimon Glass  * @param data		input buffer of values
208*2e192b24SSimon Glass  * @param vars		names of environment variables
209*2e192b24SSimon Glass  * @return 0 on success, non-0 on error
210*2e192b24SSimon Glass  */
211*2e192b24SSimon Glass static int type_string_write_vars(const char *type_str, uint8_t *data,
212*2e192b24SSimon Glass 		char * const vars[])
213*2e192b24SSimon Glass {
214*2e192b24SSimon Glass 	size_t offset;
215*2e192b24SSimon Glass 	uint32_t value;
216*2e192b24SSimon Glass 
217*2e192b24SSimon Glass 	for (offset = 0; *type_str; type_str++, vars++) {
218*2e192b24SSimon Glass 		switch (*type_str) {
219*2e192b24SSimon Glass 		case 'b':
220*2e192b24SSimon Glass 			value = data[offset];
221*2e192b24SSimon Glass 			offset += 1;
222*2e192b24SSimon Glass 			break;
223*2e192b24SSimon Glass 		case 'w':
224*2e192b24SSimon Glass 			value = get_unaligned_be16(data + offset);
225*2e192b24SSimon Glass 			offset += 2;
226*2e192b24SSimon Glass 			break;
227*2e192b24SSimon Glass 		case 'd':
228*2e192b24SSimon Glass 			value = get_unaligned_be32(data + offset);
229*2e192b24SSimon Glass 			offset += 4;
230*2e192b24SSimon Glass 			break;
231*2e192b24SSimon Glass 		default:
232*2e192b24SSimon Glass 			return -1;
233*2e192b24SSimon Glass 		}
234*2e192b24SSimon Glass 		if (setenv_ulong(*vars, value))
235*2e192b24SSimon Glass 			return -1;
236*2e192b24SSimon Glass 	}
237*2e192b24SSimon Glass 
238*2e192b24SSimon Glass 	return 0;
239*2e192b24SSimon Glass }
240*2e192b24SSimon Glass 
241*2e192b24SSimon Glass static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag,
242*2e192b24SSimon Glass 		int argc, char * const argv[])
243*2e192b24SSimon Glass {
244*2e192b24SSimon Glass 	enum tpm_startup_type mode;
245*2e192b24SSimon Glass 
246*2e192b24SSimon Glass 	if (argc != 2)
247*2e192b24SSimon Glass 		return CMD_RET_USAGE;
248*2e192b24SSimon Glass 	if (!strcasecmp("TPM_ST_CLEAR", argv[1])) {
249*2e192b24SSimon Glass 		mode = TPM_ST_CLEAR;
250*2e192b24SSimon Glass 	} else if (!strcasecmp("TPM_ST_STATE", argv[1])) {
251*2e192b24SSimon Glass 		mode = TPM_ST_STATE;
252*2e192b24SSimon Glass 	} else if (!strcasecmp("TPM_ST_DEACTIVATED", argv[1])) {
253*2e192b24SSimon Glass 		mode = TPM_ST_DEACTIVATED;
254*2e192b24SSimon Glass 	} else {
255*2e192b24SSimon Glass 		printf("Couldn't recognize mode string: %s\n", argv[1]);
256*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
257*2e192b24SSimon Glass 	}
258*2e192b24SSimon Glass 
259*2e192b24SSimon Glass 	return report_return_code(tpm_startup(mode));
260*2e192b24SSimon Glass }
261*2e192b24SSimon Glass 
262*2e192b24SSimon Glass static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
263*2e192b24SSimon Glass 		int argc, char * const argv[])
264*2e192b24SSimon Glass {
265*2e192b24SSimon Glass 	uint32_t index, perm, size;
266*2e192b24SSimon Glass 
267*2e192b24SSimon Glass 	if (argc != 4)
268*2e192b24SSimon Glass 		return CMD_RET_USAGE;
269*2e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
270*2e192b24SSimon Glass 	perm = simple_strtoul(argv[2], NULL, 0);
271*2e192b24SSimon Glass 	size = simple_strtoul(argv[3], NULL, 0);
272*2e192b24SSimon Glass 
273*2e192b24SSimon Glass 	return report_return_code(tpm_nv_define_space(index, perm, size));
274*2e192b24SSimon Glass }
275*2e192b24SSimon Glass 
276*2e192b24SSimon Glass static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
277*2e192b24SSimon Glass 		int argc, char * const argv[])
278*2e192b24SSimon Glass {
279*2e192b24SSimon Glass 	uint32_t index, count, rc;
280*2e192b24SSimon Glass 	void *data;
281*2e192b24SSimon Glass 
282*2e192b24SSimon Glass 	if (argc != 4)
283*2e192b24SSimon Glass 		return CMD_RET_USAGE;
284*2e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
285*2e192b24SSimon Glass 	data = (void *)simple_strtoul(argv[2], NULL, 0);
286*2e192b24SSimon Glass 	count = simple_strtoul(argv[3], NULL, 0);
287*2e192b24SSimon Glass 
288*2e192b24SSimon Glass 	rc = tpm_nv_read_value(index, data, count);
289*2e192b24SSimon Glass 	if (!rc) {
290*2e192b24SSimon Glass 		puts("area content:\n");
291*2e192b24SSimon Glass 		print_byte_string(data, count);
292*2e192b24SSimon Glass 	}
293*2e192b24SSimon Glass 
294*2e192b24SSimon Glass 	return report_return_code(rc);
295*2e192b24SSimon Glass }
296*2e192b24SSimon Glass 
297*2e192b24SSimon Glass static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
298*2e192b24SSimon Glass 		int argc, char * const argv[])
299*2e192b24SSimon Glass {
300*2e192b24SSimon Glass 	uint32_t index, rc;
301*2e192b24SSimon Glass 	size_t count;
302*2e192b24SSimon Glass 	void *data;
303*2e192b24SSimon Glass 
304*2e192b24SSimon Glass 	if (argc != 3)
305*2e192b24SSimon Glass 		return CMD_RET_USAGE;
306*2e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
307*2e192b24SSimon Glass 	data = parse_byte_string(argv[2], NULL, &count);
308*2e192b24SSimon Glass 	if (!data) {
309*2e192b24SSimon Glass 		printf("Couldn't parse byte string %s\n", argv[2]);
310*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
311*2e192b24SSimon Glass 	}
312*2e192b24SSimon Glass 
313*2e192b24SSimon Glass 	rc = tpm_nv_write_value(index, data, count);
314*2e192b24SSimon Glass 	free(data);
315*2e192b24SSimon Glass 
316*2e192b24SSimon Glass 	return report_return_code(rc);
317*2e192b24SSimon Glass }
318*2e192b24SSimon Glass 
319*2e192b24SSimon Glass static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
320*2e192b24SSimon Glass 		int argc, char * const argv[])
321*2e192b24SSimon Glass {
322*2e192b24SSimon Glass 	uint32_t index, rc;
323*2e192b24SSimon Glass 	uint8_t in_digest[20], out_digest[20];
324*2e192b24SSimon Glass 
325*2e192b24SSimon Glass 	if (argc != 3)
326*2e192b24SSimon Glass 		return CMD_RET_USAGE;
327*2e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
328*2e192b24SSimon Glass 	if (!parse_byte_string(argv[2], in_digest, NULL)) {
329*2e192b24SSimon Glass 		printf("Couldn't parse byte string %s\n", argv[2]);
330*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
331*2e192b24SSimon Glass 	}
332*2e192b24SSimon Glass 
333*2e192b24SSimon Glass 	rc = tpm_extend(index, in_digest, out_digest);
334*2e192b24SSimon Glass 	if (!rc) {
335*2e192b24SSimon Glass 		puts("PCR value after execution of the command:\n");
336*2e192b24SSimon Glass 		print_byte_string(out_digest, sizeof(out_digest));
337*2e192b24SSimon Glass 	}
338*2e192b24SSimon Glass 
339*2e192b24SSimon Glass 	return report_return_code(rc);
340*2e192b24SSimon Glass }
341*2e192b24SSimon Glass 
342*2e192b24SSimon Glass static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
343*2e192b24SSimon Glass 		int argc, char * const argv[])
344*2e192b24SSimon Glass {
345*2e192b24SSimon Glass 	uint32_t index, count, rc;
346*2e192b24SSimon Glass 	void *data;
347*2e192b24SSimon Glass 
348*2e192b24SSimon Glass 	if (argc != 4)
349*2e192b24SSimon Glass 		return CMD_RET_USAGE;
350*2e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
351*2e192b24SSimon Glass 	data = (void *)simple_strtoul(argv[2], NULL, 0);
352*2e192b24SSimon Glass 	count = simple_strtoul(argv[3], NULL, 0);
353*2e192b24SSimon Glass 
354*2e192b24SSimon Glass 	rc = tpm_pcr_read(index, data, count);
355*2e192b24SSimon Glass 	if (!rc) {
356*2e192b24SSimon Glass 		puts("Named PCR content:\n");
357*2e192b24SSimon Glass 		print_byte_string(data, count);
358*2e192b24SSimon Glass 	}
359*2e192b24SSimon Glass 
360*2e192b24SSimon Glass 	return report_return_code(rc);
361*2e192b24SSimon Glass }
362*2e192b24SSimon Glass 
363*2e192b24SSimon Glass static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
364*2e192b24SSimon Glass 		int argc, char * const argv[])
365*2e192b24SSimon Glass {
366*2e192b24SSimon Glass 	uint16_t presence;
367*2e192b24SSimon Glass 
368*2e192b24SSimon Glass 	if (argc != 2)
369*2e192b24SSimon Glass 		return CMD_RET_USAGE;
370*2e192b24SSimon Glass 	presence = (uint16_t)simple_strtoul(argv[1], NULL, 0);
371*2e192b24SSimon Glass 
372*2e192b24SSimon Glass 	return report_return_code(tpm_tsc_physical_presence(presence));
373*2e192b24SSimon Glass }
374*2e192b24SSimon Glass 
375*2e192b24SSimon Glass static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
376*2e192b24SSimon Glass 		int argc, char * const argv[])
377*2e192b24SSimon Glass {
378*2e192b24SSimon Glass 	uint32_t count, rc;
379*2e192b24SSimon Glass 	void *data;
380*2e192b24SSimon Glass 
381*2e192b24SSimon Glass 	if (argc != 3)
382*2e192b24SSimon Glass 		return CMD_RET_USAGE;
383*2e192b24SSimon Glass 	data = (void *)simple_strtoul(argv[1], NULL, 0);
384*2e192b24SSimon Glass 	count = simple_strtoul(argv[2], NULL, 0);
385*2e192b24SSimon Glass 
386*2e192b24SSimon Glass 	rc = tpm_read_pubek(data, count);
387*2e192b24SSimon Glass 	if (!rc) {
388*2e192b24SSimon Glass 		puts("pubek value:\n");
389*2e192b24SSimon Glass 		print_byte_string(data, count);
390*2e192b24SSimon Glass 	}
391*2e192b24SSimon Glass 
392*2e192b24SSimon Glass 	return report_return_code(rc);
393*2e192b24SSimon Glass }
394*2e192b24SSimon Glass 
395*2e192b24SSimon Glass static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
396*2e192b24SSimon Glass 		int argc, char * const argv[])
397*2e192b24SSimon Glass {
398*2e192b24SSimon Glass 	uint8_t state;
399*2e192b24SSimon Glass 
400*2e192b24SSimon Glass 	if (argc != 2)
401*2e192b24SSimon Glass 		return CMD_RET_USAGE;
402*2e192b24SSimon Glass 	state = (uint8_t)simple_strtoul(argv[1], NULL, 0);
403*2e192b24SSimon Glass 
404*2e192b24SSimon Glass 	return report_return_code(tpm_physical_set_deactivated(state));
405*2e192b24SSimon Glass }
406*2e192b24SSimon Glass 
407*2e192b24SSimon Glass static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
408*2e192b24SSimon Glass 		int argc, char * const argv[])
409*2e192b24SSimon Glass {
410*2e192b24SSimon Glass 	uint32_t cap_area, sub_cap, rc;
411*2e192b24SSimon Glass 	void *cap;
412*2e192b24SSimon Glass 	size_t count;
413*2e192b24SSimon Glass 
414*2e192b24SSimon Glass 	if (argc != 5)
415*2e192b24SSimon Glass 		return CMD_RET_USAGE;
416*2e192b24SSimon Glass 	cap_area = simple_strtoul(argv[1], NULL, 0);
417*2e192b24SSimon Glass 	sub_cap = simple_strtoul(argv[2], NULL, 0);
418*2e192b24SSimon Glass 	cap = (void *)simple_strtoul(argv[3], NULL, 0);
419*2e192b24SSimon Glass 	count = simple_strtoul(argv[4], NULL, 0);
420*2e192b24SSimon Glass 
421*2e192b24SSimon Glass 	rc = tpm_get_capability(cap_area, sub_cap, cap, count);
422*2e192b24SSimon Glass 	if (!rc) {
423*2e192b24SSimon Glass 		puts("capability information:\n");
424*2e192b24SSimon Glass 		print_byte_string(cap, count);
425*2e192b24SSimon Glass 	}
426*2e192b24SSimon Glass 
427*2e192b24SSimon Glass 	return report_return_code(rc);
428*2e192b24SSimon Glass }
429*2e192b24SSimon Glass 
430*2e192b24SSimon Glass #define TPM_COMMAND_NO_ARG(cmd)				\
431*2e192b24SSimon Glass static int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
432*2e192b24SSimon Glass 		int argc, char * const argv[])		\
433*2e192b24SSimon Glass {							\
434*2e192b24SSimon Glass 	if (argc != 1)					\
435*2e192b24SSimon Glass 		return CMD_RET_USAGE;			\
436*2e192b24SSimon Glass 	return report_return_code(cmd());		\
437*2e192b24SSimon Glass }
438*2e192b24SSimon Glass 
439*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_init)
440*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_self_test_full)
441*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_continue_self_test)
442*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_force_clear)
443*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_physical_enable)
444*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_physical_disable)
445*2e192b24SSimon Glass 
446*2e192b24SSimon Glass static int get_tpm(struct udevice **devp)
447*2e192b24SSimon Glass {
448*2e192b24SSimon Glass 	int rc;
449*2e192b24SSimon Glass 
450*2e192b24SSimon Glass 	rc = uclass_first_device(UCLASS_TPM, devp);
451*2e192b24SSimon Glass 	if (rc) {
452*2e192b24SSimon Glass 		printf("Could not find TPM (ret=%d)\n", rc);
453*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
454*2e192b24SSimon Glass 	}
455*2e192b24SSimon Glass 
456*2e192b24SSimon Glass 	return 0;
457*2e192b24SSimon Glass }
458*2e192b24SSimon Glass 
459*2e192b24SSimon Glass static int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc,
460*2e192b24SSimon Glass 		       char *const argv[])
461*2e192b24SSimon Glass {
462*2e192b24SSimon Glass 	struct udevice *dev;
463*2e192b24SSimon Glass 	char buf[80];
464*2e192b24SSimon Glass 	int rc;
465*2e192b24SSimon Glass 
466*2e192b24SSimon Glass 	rc = get_tpm(&dev);
467*2e192b24SSimon Glass 	if (rc)
468*2e192b24SSimon Glass 		return rc;
469*2e192b24SSimon Glass 	rc = tpm_get_desc(dev, buf, sizeof(buf));
470*2e192b24SSimon Glass 	if (rc < 0) {
471*2e192b24SSimon Glass 		printf("Couldn't get TPM info (%d)\n", rc);
472*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
473*2e192b24SSimon Glass 	}
474*2e192b24SSimon Glass 	printf("%s\n", buf);
475*2e192b24SSimon Glass 
476*2e192b24SSimon Glass 	return 0;
477*2e192b24SSimon Glass }
478*2e192b24SSimon Glass 
479*2e192b24SSimon Glass static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
480*2e192b24SSimon Glass 		int argc, char * const argv[])
481*2e192b24SSimon Glass {
482*2e192b24SSimon Glass 	struct udevice *dev;
483*2e192b24SSimon Glass 	void *command;
484*2e192b24SSimon Glass 	uint8_t response[1024];
485*2e192b24SSimon Glass 	size_t count, response_length = sizeof(response);
486*2e192b24SSimon Glass 	uint32_t rc;
487*2e192b24SSimon Glass 
488*2e192b24SSimon Glass 	command = parse_byte_string(argv[1], NULL, &count);
489*2e192b24SSimon Glass 	if (!command) {
490*2e192b24SSimon Glass 		printf("Couldn't parse byte string %s\n", argv[1]);
491*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
492*2e192b24SSimon Glass 	}
493*2e192b24SSimon Glass 
494*2e192b24SSimon Glass 	rc = get_tpm(&dev);
495*2e192b24SSimon Glass 	if (rc)
496*2e192b24SSimon Glass 		return rc;
497*2e192b24SSimon Glass 
498*2e192b24SSimon Glass 	rc = tpm_xfer(dev, command, count, response, &response_length);
499*2e192b24SSimon Glass 	free(command);
500*2e192b24SSimon Glass 	if (!rc) {
501*2e192b24SSimon Glass 		puts("tpm response:\n");
502*2e192b24SSimon Glass 		print_byte_string(response, response_length);
503*2e192b24SSimon Glass 	}
504*2e192b24SSimon Glass 
505*2e192b24SSimon Glass 	return report_return_code(rc);
506*2e192b24SSimon Glass }
507*2e192b24SSimon Glass 
508*2e192b24SSimon Glass static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
509*2e192b24SSimon Glass 		int argc, char * const argv[])
510*2e192b24SSimon Glass {
511*2e192b24SSimon Glass 	uint32_t index, perm, size;
512*2e192b24SSimon Glass 
513*2e192b24SSimon Glass 	if (argc != 4)
514*2e192b24SSimon Glass 		return CMD_RET_USAGE;
515*2e192b24SSimon Glass 	size = type_string_get_space_size(argv[1]);
516*2e192b24SSimon Glass 	if (!size) {
517*2e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
518*2e192b24SSimon Glass 		return CMD_RET_USAGE;
519*2e192b24SSimon Glass 	}
520*2e192b24SSimon Glass 	index = simple_strtoul(argv[2], NULL, 0);
521*2e192b24SSimon Glass 	perm = simple_strtoul(argv[3], NULL, 0);
522*2e192b24SSimon Glass 
523*2e192b24SSimon Glass 	return report_return_code(tpm_nv_define_space(index, perm, size));
524*2e192b24SSimon Glass }
525*2e192b24SSimon Glass 
526*2e192b24SSimon Glass static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
527*2e192b24SSimon Glass 		int argc, char * const argv[])
528*2e192b24SSimon Glass {
529*2e192b24SSimon Glass 	uint32_t index, count, err;
530*2e192b24SSimon Glass 	void *data;
531*2e192b24SSimon Glass 
532*2e192b24SSimon Glass 	if (argc < 3)
533*2e192b24SSimon Glass 		return CMD_RET_USAGE;
534*2e192b24SSimon Glass 	if (argc != 3 + type_string_get_num_values(argv[1]))
535*2e192b24SSimon Glass 		return CMD_RET_USAGE;
536*2e192b24SSimon Glass 	index = simple_strtoul(argv[2], NULL, 0);
537*2e192b24SSimon Glass 	data = type_string_alloc(argv[1], &count);
538*2e192b24SSimon Glass 	if (!data) {
539*2e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
540*2e192b24SSimon Glass 		return CMD_RET_USAGE;
541*2e192b24SSimon Glass 	}
542*2e192b24SSimon Glass 
543*2e192b24SSimon Glass 	err = tpm_nv_read_value(index, data, count);
544*2e192b24SSimon Glass 	if (!err) {
545*2e192b24SSimon Glass 		if (type_string_write_vars(argv[1], data, argv + 3)) {
546*2e192b24SSimon Glass 			printf("Couldn't write to variables\n");
547*2e192b24SSimon Glass 			err = ~0;
548*2e192b24SSimon Glass 		}
549*2e192b24SSimon Glass 	}
550*2e192b24SSimon Glass 	free(data);
551*2e192b24SSimon Glass 
552*2e192b24SSimon Glass 	return report_return_code(err);
553*2e192b24SSimon Glass }
554*2e192b24SSimon Glass 
555*2e192b24SSimon Glass static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
556*2e192b24SSimon Glass 		int argc, char * const argv[])
557*2e192b24SSimon Glass {
558*2e192b24SSimon Glass 	uint32_t index, count, err;
559*2e192b24SSimon Glass 	void *data;
560*2e192b24SSimon Glass 
561*2e192b24SSimon Glass 	if (argc < 3)
562*2e192b24SSimon Glass 		return CMD_RET_USAGE;
563*2e192b24SSimon Glass 	if (argc != 3 + type_string_get_num_values(argv[1]))
564*2e192b24SSimon Glass 		return CMD_RET_USAGE;
565*2e192b24SSimon Glass 	index = simple_strtoul(argv[2], NULL, 0);
566*2e192b24SSimon Glass 	data = type_string_alloc(argv[1], &count);
567*2e192b24SSimon Glass 	if (!data) {
568*2e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
569*2e192b24SSimon Glass 		return CMD_RET_USAGE;
570*2e192b24SSimon Glass 	}
571*2e192b24SSimon Glass 	if (type_string_pack(argv[1], argv + 3, data)) {
572*2e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
573*2e192b24SSimon Glass 		free(data);
574*2e192b24SSimon Glass 		return CMD_RET_USAGE;
575*2e192b24SSimon Glass 	}
576*2e192b24SSimon Glass 
577*2e192b24SSimon Glass 	err = tpm_nv_write_value(index, data, count);
578*2e192b24SSimon Glass 	free(data);
579*2e192b24SSimon Glass 
580*2e192b24SSimon Glass 	return report_return_code(err);
581*2e192b24SSimon Glass }
582*2e192b24SSimon Glass 
583*2e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
584*2e192b24SSimon Glass 
585*2e192b24SSimon Glass static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag,
586*2e192b24SSimon Glass 		int argc, char * const argv[])
587*2e192b24SSimon Glass {
588*2e192b24SSimon Glass 	uint32_t auth_handle, err;
589*2e192b24SSimon Glass 
590*2e192b24SSimon Glass 	err = tpm_oiap(&auth_handle);
591*2e192b24SSimon Glass 
592*2e192b24SSimon Glass 	return report_return_code(err);
593*2e192b24SSimon Glass }
594*2e192b24SSimon Glass 
595*2e192b24SSimon Glass static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
596*2e192b24SSimon Glass 		int argc, char * const argv[])
597*2e192b24SSimon Glass {
598*2e192b24SSimon Glass 	uint32_t parent_handle, key_len, key_handle, err;
599*2e192b24SSimon Glass 	uint8_t usage_auth[DIGEST_LENGTH];
600*2e192b24SSimon Glass 	void *key;
601*2e192b24SSimon Glass 
602*2e192b24SSimon Glass 	if (argc < 5)
603*2e192b24SSimon Glass 		return CMD_RET_USAGE;
604*2e192b24SSimon Glass 
605*2e192b24SSimon Glass 	parent_handle = simple_strtoul(argv[1], NULL, 0);
606*2e192b24SSimon Glass 	key = (void *)simple_strtoul(argv[2], NULL, 0);
607*2e192b24SSimon Glass 	key_len = simple_strtoul(argv[3], NULL, 0);
608*2e192b24SSimon Glass 	if (strlen(argv[4]) != 2 * DIGEST_LENGTH)
609*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
610*2e192b24SSimon Glass 	parse_byte_string(argv[4], usage_auth, NULL);
611*2e192b24SSimon Glass 
612*2e192b24SSimon Glass 	err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
613*2e192b24SSimon Glass 			&key_handle);
614*2e192b24SSimon Glass 	if (!err)
615*2e192b24SSimon Glass 		printf("Key handle is 0x%x\n", key_handle);
616*2e192b24SSimon Glass 
617*2e192b24SSimon Glass 	return report_return_code(err);
618*2e192b24SSimon Glass }
619*2e192b24SSimon Glass 
620*2e192b24SSimon Glass static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
621*2e192b24SSimon Glass 		int argc, char * const argv[])
622*2e192b24SSimon Glass {
623*2e192b24SSimon Glass 	uint32_t key_handle, err;
624*2e192b24SSimon Glass 	uint8_t usage_auth[DIGEST_LENGTH];
625*2e192b24SSimon Glass 	uint8_t pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
626*2e192b24SSimon Glass 	size_t pub_key_len = sizeof(pub_key_buffer);
627*2e192b24SSimon Glass 
628*2e192b24SSimon Glass 	if (argc < 3)
629*2e192b24SSimon Glass 		return CMD_RET_USAGE;
630*2e192b24SSimon Glass 
631*2e192b24SSimon Glass 	key_handle = simple_strtoul(argv[1], NULL, 0);
632*2e192b24SSimon Glass 	if (strlen(argv[2]) != 2 * DIGEST_LENGTH)
633*2e192b24SSimon Glass 		return CMD_RET_FAILURE;
634*2e192b24SSimon Glass 	parse_byte_string(argv[2], usage_auth, NULL);
635*2e192b24SSimon Glass 
636*2e192b24SSimon Glass 	err = tpm_get_pub_key_oiap(key_handle, usage_auth,
637*2e192b24SSimon Glass 			pub_key_buffer, &pub_key_len);
638*2e192b24SSimon Glass 	if (!err) {
639*2e192b24SSimon Glass 		printf("dump of received pub key structure:\n");
640*2e192b24SSimon Glass 		print_byte_string(pub_key_buffer, pub_key_len);
641*2e192b24SSimon Glass 	}
642*2e192b24SSimon Glass 	return report_return_code(err);
643*2e192b24SSimon Glass }
644*2e192b24SSimon Glass 
645*2e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_end_oiap)
646*2e192b24SSimon Glass 
647*2e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
648*2e192b24SSimon Glass 
649*2e192b24SSimon Glass #define MAKE_TPM_CMD_ENTRY(cmd) \
650*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
651*2e192b24SSimon Glass 
652*2e192b24SSimon Glass static cmd_tbl_t tpm_commands[] = {
653*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
654*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(init, 0, 1,
655*2e192b24SSimon Glass 			do_tpm_init, "", ""),
656*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(startup, 0, 1,
657*2e192b24SSimon Glass 			do_tpm_startup, "", ""),
658*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(self_test_full, 0, 1,
659*2e192b24SSimon Glass 			do_tpm_self_test_full, "", ""),
660*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(continue_self_test, 0, 1,
661*2e192b24SSimon Glass 			do_tpm_continue_self_test, "", ""),
662*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(force_clear, 0, 1,
663*2e192b24SSimon Glass 			do_tpm_force_clear, "", ""),
664*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_enable, 0, 1,
665*2e192b24SSimon Glass 			do_tpm_physical_enable, "", ""),
666*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_disable, 0, 1,
667*2e192b24SSimon Glass 			do_tpm_physical_disable, "", ""),
668*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_define_space, 0, 1,
669*2e192b24SSimon Glass 			do_tpm_nv_define_space, "", ""),
670*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_read_value, 0, 1,
671*2e192b24SSimon Glass 			do_tpm_nv_read_value, "", ""),
672*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_write_value, 0, 1,
673*2e192b24SSimon Glass 			do_tpm_nv_write_value, "", ""),
674*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(extend, 0, 1,
675*2e192b24SSimon Glass 			do_tpm_extend, "", ""),
676*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(pcr_read, 0, 1,
677*2e192b24SSimon Glass 			do_tpm_pcr_read, "", ""),
678*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
679*2e192b24SSimon Glass 			do_tpm_tsc_physical_presence, "", ""),
680*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(read_pubek, 0, 1,
681*2e192b24SSimon Glass 			do_tpm_read_pubek, "", ""),
682*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_set_deactivated, 0, 1,
683*2e192b24SSimon Glass 			do_tpm_physical_set_deactivated, "", ""),
684*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(get_capability, 0, 1,
685*2e192b24SSimon Glass 			do_tpm_get_capability, "", ""),
686*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(raw_transfer, 0, 1,
687*2e192b24SSimon Glass 			do_tpm_raw_transfer, "", ""),
688*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_define, 0, 1,
689*2e192b24SSimon Glass 			do_tpm_nv_define, "", ""),
690*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_read, 0, 1,
691*2e192b24SSimon Glass 			do_tpm_nv_read, "", ""),
692*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_write, 0, 1,
693*2e192b24SSimon Glass 			do_tpm_nv_write, "", ""),
694*2e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
695*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(oiap, 0, 1,
696*2e192b24SSimon Glass 			 do_tpm_oiap, "", ""),
697*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(end_oiap, 0, 1,
698*2e192b24SSimon Glass 			 do_tpm_end_oiap, "", ""),
699*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1,
700*2e192b24SSimon Glass 			 do_tpm_load_key2_oiap, "", ""),
701*2e192b24SSimon Glass 	U_BOOT_CMD_MKENT(get_pub_key_oiap, 0, 1,
702*2e192b24SSimon Glass 			 do_tpm_get_pub_key_oiap, "", ""),
703*2e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
704*2e192b24SSimon Glass };
705*2e192b24SSimon Glass 
706*2e192b24SSimon Glass static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
707*2e192b24SSimon Glass {
708*2e192b24SSimon Glass 	cmd_tbl_t *tpm_cmd;
709*2e192b24SSimon Glass 
710*2e192b24SSimon Glass 	if (argc < 2)
711*2e192b24SSimon Glass 		return CMD_RET_USAGE;
712*2e192b24SSimon Glass 	tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
713*2e192b24SSimon Glass 	if (!tpm_cmd)
714*2e192b24SSimon Glass 		return CMD_RET_USAGE;
715*2e192b24SSimon Glass 
716*2e192b24SSimon Glass 	return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
717*2e192b24SSimon Glass }
718*2e192b24SSimon Glass 
719*2e192b24SSimon Glass U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
720*2e192b24SSimon Glass "Issue a TPM command",
721*2e192b24SSimon Glass "cmd args...\n"
722*2e192b24SSimon Glass "    - Issue TPM command <cmd> with arguments <args...>.\n"
723*2e192b24SSimon Glass "Admin Startup and State Commands:\n"
724*2e192b24SSimon Glass "  info - Show information about the TPM\n"
725*2e192b24SSimon Glass "  init\n"
726*2e192b24SSimon Glass "    - Put TPM into a state where it waits for 'startup' command.\n"
727*2e192b24SSimon Glass "  startup mode\n"
728*2e192b24SSimon Glass "    - Issue TPM_Starup command.  <mode> is one of TPM_ST_CLEAR,\n"
729*2e192b24SSimon Glass "      TPM_ST_STATE, and TPM_ST_DEACTIVATED.\n"
730*2e192b24SSimon Glass "Admin Testing Commands:\n"
731*2e192b24SSimon Glass "  self_test_full\n"
732*2e192b24SSimon Glass "    - Test all of the TPM capabilities.\n"
733*2e192b24SSimon Glass "  continue_self_test\n"
734*2e192b24SSimon Glass "    - Inform TPM that it should complete the self-test.\n"
735*2e192b24SSimon Glass "Admin Opt-in Commands:\n"
736*2e192b24SSimon Glass "  physical_enable\n"
737*2e192b24SSimon Glass "    - Set the PERMANENT disable flag to FALSE using physical presence as\n"
738*2e192b24SSimon Glass "      authorization.\n"
739*2e192b24SSimon Glass "  physical_disable\n"
740*2e192b24SSimon Glass "    - Set the PERMANENT disable flag to TRUE using physical presence as\n"
741*2e192b24SSimon Glass "      authorization.\n"
742*2e192b24SSimon Glass "  physical_set_deactivated 0|1\n"
743*2e192b24SSimon Glass "    - Set deactivated flag.\n"
744*2e192b24SSimon Glass "Admin Ownership Commands:\n"
745*2e192b24SSimon Glass "  force_clear\n"
746*2e192b24SSimon Glass "    - Issue TPM_ForceClear command.\n"
747*2e192b24SSimon Glass "  tsc_physical_presence flags\n"
748*2e192b24SSimon Glass "    - Set TPM device's Physical Presence flags to <flags>.\n"
749*2e192b24SSimon Glass "The Capability Commands:\n"
750*2e192b24SSimon Glass "  get_capability cap_area sub_cap addr count\n"
751*2e192b24SSimon Glass "    - Read <count> bytes of TPM capability indexed by <cap_area> and\n"
752*2e192b24SSimon Glass "      <sub_cap> to memory address <addr>.\n"
753*2e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
754*2e192b24SSimon Glass "Storage functions\n"
755*2e192b24SSimon Glass "  loadkey2_oiap parent_handle key_addr key_len usage_auth\n"
756*2e192b24SSimon Glass "    - loads a key data from memory address <key_addr>, <key_len> bytes\n"
757*2e192b24SSimon Glass "      into TPM using the parent key <parent_handle> with authorization\n"
758*2e192b24SSimon Glass "      <usage_auth> (20 bytes hex string).\n"
759*2e192b24SSimon Glass "  get_pub_key_oiap key_handle usage_auth\n"
760*2e192b24SSimon Glass "    - get the public key portion of a loaded key <key_handle> using\n"
761*2e192b24SSimon Glass "      authorization <usage auth> (20 bytes hex string)\n"
762*2e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
763*2e192b24SSimon Glass "Endorsement Key Handling Commands:\n"
764*2e192b24SSimon Glass "  read_pubek addr count\n"
765*2e192b24SSimon Glass "    - Read <count> bytes of the public endorsement key to memory\n"
766*2e192b24SSimon Glass "      address <addr>\n"
767*2e192b24SSimon Glass "Integrity Collection and Reporting Commands:\n"
768*2e192b24SSimon Glass "  extend index digest_hex_string\n"
769*2e192b24SSimon Glass "    - Add a new measurement to a PCR.  Update PCR <index> with the 20-bytes\n"
770*2e192b24SSimon Glass "      <digest_hex_string>\n"
771*2e192b24SSimon Glass "  pcr_read index addr count\n"
772*2e192b24SSimon Glass "    - Read <count> bytes from PCR <index> to memory address <addr>.\n"
773*2e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
774*2e192b24SSimon Glass "Authorization Sessions\n"
775*2e192b24SSimon Glass "  oiap\n"
776*2e192b24SSimon Glass "    - setup an OIAP session\n"
777*2e192b24SSimon Glass "  end_oiap\n"
778*2e192b24SSimon Glass "    - terminates an active OIAP session\n"
779*2e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
780*2e192b24SSimon Glass "Non-volatile Storage Commands:\n"
781*2e192b24SSimon Glass "  nv_define_space index permission size\n"
782*2e192b24SSimon Glass "    - Establish a space at index <index> with <permission> of <size> bytes.\n"
783*2e192b24SSimon Glass "  nv_read_value index addr count\n"
784*2e192b24SSimon Glass "    - Read <count> bytes from space <index> to memory address <addr>.\n"
785*2e192b24SSimon Glass "  nv_write_value index addr count\n"
786*2e192b24SSimon Glass "    - Write <count> bytes from memory address <addr> to space <index>.\n"
787*2e192b24SSimon Glass "Miscellaneous helper functions:\n"
788*2e192b24SSimon Glass "  raw_transfer byte_string\n"
789*2e192b24SSimon Glass "    - Send a byte string <byte_string> to TPM and print the response.\n"
790*2e192b24SSimon Glass " Non-volatile storage helper functions:\n"
791*2e192b24SSimon Glass "    These helper functions treat a non-volatile space as a non-padded\n"
792*2e192b24SSimon Glass "    sequence of integer values.  These integer values are defined by a type\n"
793*2e192b24SSimon Glass "    string, which is a text string of 'bwd' characters: 'b' means a 8-bit\n"
794*2e192b24SSimon Glass "    value, 'w' 16-bit value, 'd' 32-bit value.  All helper functions take\n"
795*2e192b24SSimon Glass "    a type string as their first argument.\n"
796*2e192b24SSimon Glass "  nv_define type_string index perm\n"
797*2e192b24SSimon Glass "    - Define a space <index> with permission <perm>.\n"
798*2e192b24SSimon Glass "  nv_read types_string index vars...\n"
799*2e192b24SSimon Glass "    - Read from space <index> to environment variables <vars...>.\n"
800*2e192b24SSimon Glass "  nv_write types_string index values...\n"
801*2e192b24SSimon Glass "    - Write to space <index> from values <values...>.\n"
802*2e192b24SSimon Glass );
803