xref: /rk3399_rockchip-uboot/cmd/tpm.c (revision 3f603cbbb8e175e545d6037a783e1ef82bab30f9)
12e192b24SSimon Glass /*
22e192b24SSimon Glass  * Copyright (c) 2013 The Chromium OS Authors.
32e192b24SSimon Glass  *
42e192b24SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
52e192b24SSimon Glass  */
62e192b24SSimon Glass 
72e192b24SSimon Glass #include <common.h>
82e192b24SSimon Glass #include <command.h>
92e192b24SSimon Glass #include <dm.h>
102e192b24SSimon Glass #include <malloc.h>
112e192b24SSimon Glass #include <tpm.h>
122e192b24SSimon Glass #include <asm/unaligned.h>
132e192b24SSimon Glass #include <linux/string.h>
142e192b24SSimon Glass 
152e192b24SSimon Glass /* Useful constants */
162e192b24SSimon Glass enum {
172e192b24SSimon Glass 	DIGEST_LENGTH		= 20,
182e192b24SSimon Glass 	/* max lengths, valid for RSA keys <= 2048 bits */
192e192b24SSimon Glass 	TPM_PUBKEY_MAX_LENGTH	= 288,
202e192b24SSimon Glass };
212e192b24SSimon Glass 
222e192b24SSimon Glass /**
232e192b24SSimon Glass  * Print a byte string in hexdecimal format, 16-bytes per line.
242e192b24SSimon Glass  *
252e192b24SSimon Glass  * @param data		byte string to be printed
262e192b24SSimon Glass  * @param count		number of bytes to be printed
272e192b24SSimon Glass  */
282e192b24SSimon Glass static void print_byte_string(uint8_t *data, size_t count)
292e192b24SSimon Glass {
302e192b24SSimon Glass 	int i, print_newline = 0;
312e192b24SSimon Glass 
322e192b24SSimon Glass 	for (i = 0; i < count; i++) {
332e192b24SSimon Glass 		printf(" %02x", data[i]);
342e192b24SSimon Glass 		print_newline = (i % 16 == 15);
352e192b24SSimon Glass 		if (print_newline)
362e192b24SSimon Glass 			putc('\n');
372e192b24SSimon Glass 	}
382e192b24SSimon Glass 	/* Avoid duplicated newline at the end */
392e192b24SSimon Glass 	if (!print_newline)
402e192b24SSimon Glass 		putc('\n');
412e192b24SSimon Glass }
422e192b24SSimon Glass 
432e192b24SSimon Glass /**
442e192b24SSimon Glass  * Convert a text string of hexdecimal values into a byte string.
452e192b24SSimon Glass  *
462e192b24SSimon Glass  * @param bytes		text string of hexdecimal values with no space
472e192b24SSimon Glass  *			between them
482e192b24SSimon Glass  * @param data		output buffer for byte string.  The caller has to make
492e192b24SSimon Glass  *			sure it is large enough for storing the output.  If
502e192b24SSimon Glass  *			NULL is passed, a large enough buffer will be allocated,
512e192b24SSimon Glass  *			and the caller must free it.
522e192b24SSimon Glass  * @param count_ptr	output variable for the length of byte string
532e192b24SSimon Glass  * @return pointer to output buffer
542e192b24SSimon Glass  */
552e192b24SSimon Glass static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
562e192b24SSimon Glass {
572e192b24SSimon Glass 	char byte[3];
582e192b24SSimon Glass 	size_t count, length;
592e192b24SSimon Glass 	int i;
602e192b24SSimon Glass 
612e192b24SSimon Glass 	if (!bytes)
622e192b24SSimon Glass 		return NULL;
632e192b24SSimon Glass 	length = strlen(bytes);
642e192b24SSimon Glass 	count = length / 2;
652e192b24SSimon Glass 
662e192b24SSimon Glass 	if (!data)
672e192b24SSimon Glass 		data = malloc(count);
682e192b24SSimon Glass 	if (!data)
692e192b24SSimon Glass 		return NULL;
702e192b24SSimon Glass 
712e192b24SSimon Glass 	byte[2] = '\0';
722e192b24SSimon Glass 	for (i = 0; i < length; i += 2) {
732e192b24SSimon Glass 		byte[0] = bytes[i];
742e192b24SSimon Glass 		byte[1] = bytes[i + 1];
752e192b24SSimon Glass 		data[i / 2] = (uint8_t)simple_strtoul(byte, NULL, 16);
762e192b24SSimon Glass 	}
772e192b24SSimon Glass 
782e192b24SSimon Glass 	if (count_ptr)
792e192b24SSimon Glass 		*count_ptr = count;
802e192b24SSimon Glass 
812e192b24SSimon Glass 	return data;
822e192b24SSimon Glass }
832e192b24SSimon Glass 
842e192b24SSimon Glass /**
852e192b24SSimon Glass  * report_return_code() - Report any error and return failure or success
862e192b24SSimon Glass  *
872e192b24SSimon Glass  * @param return_code	TPM command return code
882e192b24SSimon Glass  * @return value of enum command_ret_t
892e192b24SSimon Glass  */
902e192b24SSimon Glass static int report_return_code(int return_code)
912e192b24SSimon Glass {
922e192b24SSimon Glass 	if (return_code) {
932e192b24SSimon Glass 		printf("Error: %d\n", return_code);
942e192b24SSimon Glass 		return CMD_RET_FAILURE;
952e192b24SSimon Glass 	} else {
962e192b24SSimon Glass 		return CMD_RET_SUCCESS;
972e192b24SSimon Glass 	}
982e192b24SSimon Glass }
992e192b24SSimon Glass 
1002e192b24SSimon Glass /**
1012e192b24SSimon Glass  * Return number of values defined by a type string.
1022e192b24SSimon Glass  *
1032e192b24SSimon Glass  * @param type_str	type string
1042e192b24SSimon Glass  * @return number of values of type string
1052e192b24SSimon Glass  */
1062e192b24SSimon Glass static int type_string_get_num_values(const char *type_str)
1072e192b24SSimon Glass {
1082e192b24SSimon Glass 	return strlen(type_str);
1092e192b24SSimon Glass }
1102e192b24SSimon Glass 
1112e192b24SSimon Glass /**
1122e192b24SSimon Glass  * Return total size of values defined by a type string.
1132e192b24SSimon Glass  *
1142e192b24SSimon Glass  * @param type_str	type string
1152e192b24SSimon Glass  * @return total size of values of type string, or 0 if type string
1162e192b24SSimon Glass  *  contains illegal type character.
1172e192b24SSimon Glass  */
1182e192b24SSimon Glass static size_t type_string_get_space_size(const char *type_str)
1192e192b24SSimon Glass {
1202e192b24SSimon Glass 	size_t size;
1212e192b24SSimon Glass 
1222e192b24SSimon Glass 	for (size = 0; *type_str; type_str++) {
1232e192b24SSimon Glass 		switch (*type_str) {
1242e192b24SSimon Glass 		case 'b':
1252e192b24SSimon Glass 			size += 1;
1262e192b24SSimon Glass 			break;
1272e192b24SSimon Glass 		case 'w':
1282e192b24SSimon Glass 			size += 2;
1292e192b24SSimon Glass 			break;
1302e192b24SSimon Glass 		case 'd':
1312e192b24SSimon Glass 			size += 4;
1322e192b24SSimon Glass 			break;
1332e192b24SSimon Glass 		default:
1342e192b24SSimon Glass 			return 0;
1352e192b24SSimon Glass 		}
1362e192b24SSimon Glass 	}
1372e192b24SSimon Glass 
1382e192b24SSimon Glass 	return size;
1392e192b24SSimon Glass }
1402e192b24SSimon Glass 
1412e192b24SSimon Glass /**
1422e192b24SSimon Glass  * Allocate a buffer large enough to hold values defined by a type
1432e192b24SSimon Glass  * string.  The caller has to free the buffer.
1442e192b24SSimon Glass  *
1452e192b24SSimon Glass  * @param type_str	type string
1462e192b24SSimon Glass  * @param count		pointer for storing size of buffer
1472e192b24SSimon Glass  * @return pointer to buffer or NULL on error
1482e192b24SSimon Glass  */
1492e192b24SSimon Glass static void *type_string_alloc(const char *type_str, uint32_t *count)
1502e192b24SSimon Glass {
1512e192b24SSimon Glass 	void *data;
1522e192b24SSimon Glass 	size_t size;
1532e192b24SSimon Glass 
1542e192b24SSimon Glass 	size = type_string_get_space_size(type_str);
1552e192b24SSimon Glass 	if (!size)
1562e192b24SSimon Glass 		return NULL;
1572e192b24SSimon Glass 	data = malloc(size);
1582e192b24SSimon Glass 	if (data)
1592e192b24SSimon Glass 		*count = size;
1602e192b24SSimon Glass 
1612e192b24SSimon Glass 	return data;
1622e192b24SSimon Glass }
1632e192b24SSimon Glass 
1642e192b24SSimon Glass /**
1652e192b24SSimon Glass  * Pack values defined by a type string into a buffer.  The buffer must have
1662e192b24SSimon Glass  * large enough space.
1672e192b24SSimon Glass  *
1682e192b24SSimon Glass  * @param type_str	type string
1692e192b24SSimon Glass  * @param values	text strings of values to be packed
1702e192b24SSimon Glass  * @param data		output buffer of values
1712e192b24SSimon Glass  * @return 0 on success, non-0 on error
1722e192b24SSimon Glass  */
1732e192b24SSimon Glass static int type_string_pack(const char *type_str, char * const values[],
1742e192b24SSimon Glass 		uint8_t *data)
1752e192b24SSimon Glass {
1762e192b24SSimon Glass 	size_t offset;
1772e192b24SSimon Glass 	uint32_t value;
1782e192b24SSimon Glass 
1792e192b24SSimon Glass 	for (offset = 0; *type_str; type_str++, values++) {
1802e192b24SSimon Glass 		value = simple_strtoul(values[0], NULL, 0);
1812e192b24SSimon Glass 		switch (*type_str) {
1822e192b24SSimon Glass 		case 'b':
1832e192b24SSimon Glass 			data[offset] = value;
1842e192b24SSimon Glass 			offset += 1;
1852e192b24SSimon Glass 			break;
1862e192b24SSimon Glass 		case 'w':
1872e192b24SSimon Glass 			put_unaligned_be16(value, data + offset);
1882e192b24SSimon Glass 			offset += 2;
1892e192b24SSimon Glass 			break;
1902e192b24SSimon Glass 		case 'd':
1912e192b24SSimon Glass 			put_unaligned_be32(value, data + offset);
1922e192b24SSimon Glass 			offset += 4;
1932e192b24SSimon Glass 			break;
1942e192b24SSimon Glass 		default:
1952e192b24SSimon Glass 			return -1;
1962e192b24SSimon Glass 		}
1972e192b24SSimon Glass 	}
1982e192b24SSimon Glass 
1992e192b24SSimon Glass 	return 0;
2002e192b24SSimon Glass }
2012e192b24SSimon Glass 
2022e192b24SSimon Glass /**
2032e192b24SSimon Glass  * Read values defined by a type string from a buffer, and write these values
2042e192b24SSimon Glass  * to environment variables.
2052e192b24SSimon Glass  *
2062e192b24SSimon Glass  * @param type_str	type string
2072e192b24SSimon Glass  * @param data		input buffer of values
2082e192b24SSimon Glass  * @param vars		names of environment variables
2092e192b24SSimon Glass  * @return 0 on success, non-0 on error
2102e192b24SSimon Glass  */
2112e192b24SSimon Glass static int type_string_write_vars(const char *type_str, uint8_t *data,
2122e192b24SSimon Glass 		char * const vars[])
2132e192b24SSimon Glass {
2142e192b24SSimon Glass 	size_t offset;
2152e192b24SSimon Glass 	uint32_t value;
2162e192b24SSimon Glass 
2172e192b24SSimon Glass 	for (offset = 0; *type_str; type_str++, vars++) {
2182e192b24SSimon Glass 		switch (*type_str) {
2192e192b24SSimon Glass 		case 'b':
2202e192b24SSimon Glass 			value = data[offset];
2212e192b24SSimon Glass 			offset += 1;
2222e192b24SSimon Glass 			break;
2232e192b24SSimon Glass 		case 'w':
2242e192b24SSimon Glass 			value = get_unaligned_be16(data + offset);
2252e192b24SSimon Glass 			offset += 2;
2262e192b24SSimon Glass 			break;
2272e192b24SSimon Glass 		case 'd':
2282e192b24SSimon Glass 			value = get_unaligned_be32(data + offset);
2292e192b24SSimon Glass 			offset += 4;
2302e192b24SSimon Glass 			break;
2312e192b24SSimon Glass 		default:
2322e192b24SSimon Glass 			return -1;
2332e192b24SSimon Glass 		}
2342e192b24SSimon Glass 		if (setenv_ulong(*vars, value))
2352e192b24SSimon Glass 			return -1;
2362e192b24SSimon Glass 	}
2372e192b24SSimon Glass 
2382e192b24SSimon Glass 	return 0;
2392e192b24SSimon Glass }
2402e192b24SSimon Glass 
2412e192b24SSimon Glass static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag,
2422e192b24SSimon Glass 		int argc, char * const argv[])
2432e192b24SSimon Glass {
2442e192b24SSimon Glass 	enum tpm_startup_type mode;
2452e192b24SSimon Glass 
2462e192b24SSimon Glass 	if (argc != 2)
2472e192b24SSimon Glass 		return CMD_RET_USAGE;
2482e192b24SSimon Glass 	if (!strcasecmp("TPM_ST_CLEAR", argv[1])) {
2492e192b24SSimon Glass 		mode = TPM_ST_CLEAR;
2502e192b24SSimon Glass 	} else if (!strcasecmp("TPM_ST_STATE", argv[1])) {
2512e192b24SSimon Glass 		mode = TPM_ST_STATE;
2522e192b24SSimon Glass 	} else if (!strcasecmp("TPM_ST_DEACTIVATED", argv[1])) {
2532e192b24SSimon Glass 		mode = TPM_ST_DEACTIVATED;
2542e192b24SSimon Glass 	} else {
2552e192b24SSimon Glass 		printf("Couldn't recognize mode string: %s\n", argv[1]);
2562e192b24SSimon Glass 		return CMD_RET_FAILURE;
2572e192b24SSimon Glass 	}
2582e192b24SSimon Glass 
2592e192b24SSimon Glass 	return report_return_code(tpm_startup(mode));
2602e192b24SSimon Glass }
2612e192b24SSimon Glass 
2622e192b24SSimon Glass static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
2632e192b24SSimon Glass 		int argc, char * const argv[])
2642e192b24SSimon Glass {
2652e192b24SSimon Glass 	uint32_t index, perm, size;
2662e192b24SSimon Glass 
2672e192b24SSimon Glass 	if (argc != 4)
2682e192b24SSimon Glass 		return CMD_RET_USAGE;
2692e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
2702e192b24SSimon Glass 	perm = simple_strtoul(argv[2], NULL, 0);
2712e192b24SSimon Glass 	size = simple_strtoul(argv[3], NULL, 0);
2722e192b24SSimon Glass 
2732e192b24SSimon Glass 	return report_return_code(tpm_nv_define_space(index, perm, size));
2742e192b24SSimon Glass }
2752e192b24SSimon Glass 
2762e192b24SSimon Glass static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
2772e192b24SSimon Glass 		int argc, char * const argv[])
2782e192b24SSimon Glass {
2792e192b24SSimon Glass 	uint32_t index, count, rc;
2802e192b24SSimon Glass 	void *data;
2812e192b24SSimon Glass 
2822e192b24SSimon Glass 	if (argc != 4)
2832e192b24SSimon Glass 		return CMD_RET_USAGE;
2842e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
2852e192b24SSimon Glass 	data = (void *)simple_strtoul(argv[2], NULL, 0);
2862e192b24SSimon Glass 	count = simple_strtoul(argv[3], NULL, 0);
2872e192b24SSimon Glass 
2882e192b24SSimon Glass 	rc = tpm_nv_read_value(index, data, count);
2892e192b24SSimon Glass 	if (!rc) {
2902e192b24SSimon Glass 		puts("area content:\n");
2912e192b24SSimon Glass 		print_byte_string(data, count);
2922e192b24SSimon Glass 	}
2932e192b24SSimon Glass 
2942e192b24SSimon Glass 	return report_return_code(rc);
2952e192b24SSimon Glass }
2962e192b24SSimon Glass 
2972e192b24SSimon Glass static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
2982e192b24SSimon Glass 		int argc, char * const argv[])
2992e192b24SSimon Glass {
3002e192b24SSimon Glass 	uint32_t index, rc;
3012e192b24SSimon Glass 	size_t count;
3022e192b24SSimon Glass 	void *data;
3032e192b24SSimon Glass 
3042e192b24SSimon Glass 	if (argc != 3)
3052e192b24SSimon Glass 		return CMD_RET_USAGE;
3062e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
3072e192b24SSimon Glass 	data = parse_byte_string(argv[2], NULL, &count);
3082e192b24SSimon Glass 	if (!data) {
3092e192b24SSimon Glass 		printf("Couldn't parse byte string %s\n", argv[2]);
3102e192b24SSimon Glass 		return CMD_RET_FAILURE;
3112e192b24SSimon Glass 	}
3122e192b24SSimon Glass 
3132e192b24SSimon Glass 	rc = tpm_nv_write_value(index, data, count);
3142e192b24SSimon Glass 	free(data);
3152e192b24SSimon Glass 
3162e192b24SSimon Glass 	return report_return_code(rc);
3172e192b24SSimon Glass }
3182e192b24SSimon Glass 
3192e192b24SSimon Glass static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
3202e192b24SSimon Glass 		int argc, char * const argv[])
3212e192b24SSimon Glass {
3222e192b24SSimon Glass 	uint32_t index, rc;
3232e192b24SSimon Glass 	uint8_t in_digest[20], out_digest[20];
3242e192b24SSimon Glass 
3252e192b24SSimon Glass 	if (argc != 3)
3262e192b24SSimon Glass 		return CMD_RET_USAGE;
3272e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
3282e192b24SSimon Glass 	if (!parse_byte_string(argv[2], in_digest, NULL)) {
3292e192b24SSimon Glass 		printf("Couldn't parse byte string %s\n", argv[2]);
3302e192b24SSimon Glass 		return CMD_RET_FAILURE;
3312e192b24SSimon Glass 	}
3322e192b24SSimon Glass 
3332e192b24SSimon Glass 	rc = tpm_extend(index, in_digest, out_digest);
3342e192b24SSimon Glass 	if (!rc) {
3352e192b24SSimon Glass 		puts("PCR value after execution of the command:\n");
3362e192b24SSimon Glass 		print_byte_string(out_digest, sizeof(out_digest));
3372e192b24SSimon Glass 	}
3382e192b24SSimon Glass 
3392e192b24SSimon Glass 	return report_return_code(rc);
3402e192b24SSimon Glass }
3412e192b24SSimon Glass 
3422e192b24SSimon Glass static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
3432e192b24SSimon Glass 		int argc, char * const argv[])
3442e192b24SSimon Glass {
3452e192b24SSimon Glass 	uint32_t index, count, rc;
3462e192b24SSimon Glass 	void *data;
3472e192b24SSimon Glass 
3482e192b24SSimon Glass 	if (argc != 4)
3492e192b24SSimon Glass 		return CMD_RET_USAGE;
3502e192b24SSimon Glass 	index = simple_strtoul(argv[1], NULL, 0);
3512e192b24SSimon Glass 	data = (void *)simple_strtoul(argv[2], NULL, 0);
3522e192b24SSimon Glass 	count = simple_strtoul(argv[3], NULL, 0);
3532e192b24SSimon Glass 
3542e192b24SSimon Glass 	rc = tpm_pcr_read(index, data, count);
3552e192b24SSimon Glass 	if (!rc) {
3562e192b24SSimon Glass 		puts("Named PCR content:\n");
3572e192b24SSimon Glass 		print_byte_string(data, count);
3582e192b24SSimon Glass 	}
3592e192b24SSimon Glass 
3602e192b24SSimon Glass 	return report_return_code(rc);
3612e192b24SSimon Glass }
3622e192b24SSimon Glass 
3632e192b24SSimon Glass static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
3642e192b24SSimon Glass 		int argc, char * const argv[])
3652e192b24SSimon Glass {
3662e192b24SSimon Glass 	uint16_t presence;
3672e192b24SSimon Glass 
3682e192b24SSimon Glass 	if (argc != 2)
3692e192b24SSimon Glass 		return CMD_RET_USAGE;
3702e192b24SSimon Glass 	presence = (uint16_t)simple_strtoul(argv[1], NULL, 0);
3712e192b24SSimon Glass 
3722e192b24SSimon Glass 	return report_return_code(tpm_tsc_physical_presence(presence));
3732e192b24SSimon Glass }
3742e192b24SSimon Glass 
3752e192b24SSimon Glass static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
3762e192b24SSimon Glass 		int argc, char * const argv[])
3772e192b24SSimon Glass {
3782e192b24SSimon Glass 	uint32_t count, rc;
3792e192b24SSimon Glass 	void *data;
3802e192b24SSimon Glass 
3812e192b24SSimon Glass 	if (argc != 3)
3822e192b24SSimon Glass 		return CMD_RET_USAGE;
3832e192b24SSimon Glass 	data = (void *)simple_strtoul(argv[1], NULL, 0);
3842e192b24SSimon Glass 	count = simple_strtoul(argv[2], NULL, 0);
3852e192b24SSimon Glass 
3862e192b24SSimon Glass 	rc = tpm_read_pubek(data, count);
3872e192b24SSimon Glass 	if (!rc) {
3882e192b24SSimon Glass 		puts("pubek value:\n");
3892e192b24SSimon Glass 		print_byte_string(data, count);
3902e192b24SSimon Glass 	}
3912e192b24SSimon Glass 
3922e192b24SSimon Glass 	return report_return_code(rc);
3932e192b24SSimon Glass }
3942e192b24SSimon Glass 
3952e192b24SSimon Glass static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
3962e192b24SSimon Glass 		int argc, char * const argv[])
3972e192b24SSimon Glass {
3982e192b24SSimon Glass 	uint8_t state;
3992e192b24SSimon Glass 
4002e192b24SSimon Glass 	if (argc != 2)
4012e192b24SSimon Glass 		return CMD_RET_USAGE;
4022e192b24SSimon Glass 	state = (uint8_t)simple_strtoul(argv[1], NULL, 0);
4032e192b24SSimon Glass 
4042e192b24SSimon Glass 	return report_return_code(tpm_physical_set_deactivated(state));
4052e192b24SSimon Glass }
4062e192b24SSimon Glass 
4072e192b24SSimon Glass static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
4082e192b24SSimon Glass 		int argc, char * const argv[])
4092e192b24SSimon Glass {
4102e192b24SSimon Glass 	uint32_t cap_area, sub_cap, rc;
4112e192b24SSimon Glass 	void *cap;
4122e192b24SSimon Glass 	size_t count;
4132e192b24SSimon Glass 
4142e192b24SSimon Glass 	if (argc != 5)
4152e192b24SSimon Glass 		return CMD_RET_USAGE;
4162e192b24SSimon Glass 	cap_area = simple_strtoul(argv[1], NULL, 0);
4172e192b24SSimon Glass 	sub_cap = simple_strtoul(argv[2], NULL, 0);
4182e192b24SSimon Glass 	cap = (void *)simple_strtoul(argv[3], NULL, 0);
4192e192b24SSimon Glass 	count = simple_strtoul(argv[4], NULL, 0);
4202e192b24SSimon Glass 
4212e192b24SSimon Glass 	rc = tpm_get_capability(cap_area, sub_cap, cap, count);
4222e192b24SSimon Glass 	if (!rc) {
4232e192b24SSimon Glass 		puts("capability information:\n");
4242e192b24SSimon Glass 		print_byte_string(cap, count);
4252e192b24SSimon Glass 	}
4262e192b24SSimon Glass 
4272e192b24SSimon Glass 	return report_return_code(rc);
4282e192b24SSimon Glass }
4292e192b24SSimon Glass 
4302e192b24SSimon Glass #define TPM_COMMAND_NO_ARG(cmd)				\
4312e192b24SSimon Glass static int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
4322e192b24SSimon Glass 		int argc, char * const argv[])		\
4332e192b24SSimon Glass {							\
4342e192b24SSimon Glass 	if (argc != 1)					\
4352e192b24SSimon Glass 		return CMD_RET_USAGE;			\
4362e192b24SSimon Glass 	return report_return_code(cmd());		\
4372e192b24SSimon Glass }
4382e192b24SSimon Glass 
4392e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_init)
4402e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_self_test_full)
4412e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_continue_self_test)
4422e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_force_clear)
4432e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_physical_enable)
4442e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_physical_disable)
4452e192b24SSimon Glass 
4462e192b24SSimon Glass static int get_tpm(struct udevice **devp)
4472e192b24SSimon Glass {
4482e192b24SSimon Glass 	int rc;
4492e192b24SSimon Glass 
450*3f603cbbSSimon Glass 	rc = uclass_first_device_err(UCLASS_TPM, devp);
451*3f603cbbSSimon Glass 	if (rc) {
4522e192b24SSimon Glass 		printf("Could not find TPM (ret=%d)\n", rc);
4532e192b24SSimon Glass 		return CMD_RET_FAILURE;
4542e192b24SSimon Glass 	}
4552e192b24SSimon Glass 
4562e192b24SSimon Glass 	return 0;
4572e192b24SSimon Glass }
4582e192b24SSimon Glass 
4592e192b24SSimon Glass static int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc,
4602e192b24SSimon Glass 		       char *const argv[])
4612e192b24SSimon Glass {
4622e192b24SSimon Glass 	struct udevice *dev;
4632e192b24SSimon Glass 	char buf[80];
4642e192b24SSimon Glass 	int rc;
4652e192b24SSimon Glass 
4662e192b24SSimon Glass 	rc = get_tpm(&dev);
4672e192b24SSimon Glass 	if (rc)
4682e192b24SSimon Glass 		return rc;
4692e192b24SSimon Glass 	rc = tpm_get_desc(dev, buf, sizeof(buf));
4702e192b24SSimon Glass 	if (rc < 0) {
4712e192b24SSimon Glass 		printf("Couldn't get TPM info (%d)\n", rc);
4722e192b24SSimon Glass 		return CMD_RET_FAILURE;
4732e192b24SSimon Glass 	}
4742e192b24SSimon Glass 	printf("%s\n", buf);
4752e192b24SSimon Glass 
4762e192b24SSimon Glass 	return 0;
4772e192b24SSimon Glass }
4782e192b24SSimon Glass 
4792e192b24SSimon Glass static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
4802e192b24SSimon Glass 		int argc, char * const argv[])
4812e192b24SSimon Glass {
4822e192b24SSimon Glass 	struct udevice *dev;
4832e192b24SSimon Glass 	void *command;
4842e192b24SSimon Glass 	uint8_t response[1024];
4852e192b24SSimon Glass 	size_t count, response_length = sizeof(response);
4862e192b24SSimon Glass 	uint32_t rc;
4872e192b24SSimon Glass 
4882e192b24SSimon Glass 	command = parse_byte_string(argv[1], NULL, &count);
4892e192b24SSimon Glass 	if (!command) {
4902e192b24SSimon Glass 		printf("Couldn't parse byte string %s\n", argv[1]);
4912e192b24SSimon Glass 		return CMD_RET_FAILURE;
4922e192b24SSimon Glass 	}
4932e192b24SSimon Glass 
4942e192b24SSimon Glass 	rc = get_tpm(&dev);
4952e192b24SSimon Glass 	if (rc)
4962e192b24SSimon Glass 		return rc;
4972e192b24SSimon Glass 
4982e192b24SSimon Glass 	rc = tpm_xfer(dev, command, count, response, &response_length);
4992e192b24SSimon Glass 	free(command);
5002e192b24SSimon Glass 	if (!rc) {
5012e192b24SSimon Glass 		puts("tpm response:\n");
5022e192b24SSimon Glass 		print_byte_string(response, response_length);
5032e192b24SSimon Glass 	}
5042e192b24SSimon Glass 
5052e192b24SSimon Glass 	return report_return_code(rc);
5062e192b24SSimon Glass }
5072e192b24SSimon Glass 
5082e192b24SSimon Glass static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
5092e192b24SSimon Glass 		int argc, char * const argv[])
5102e192b24SSimon Glass {
5112e192b24SSimon Glass 	uint32_t index, perm, size;
5122e192b24SSimon Glass 
5132e192b24SSimon Glass 	if (argc != 4)
5142e192b24SSimon Glass 		return CMD_RET_USAGE;
5152e192b24SSimon Glass 	size = type_string_get_space_size(argv[1]);
5162e192b24SSimon Glass 	if (!size) {
5172e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
5182e192b24SSimon Glass 		return CMD_RET_USAGE;
5192e192b24SSimon Glass 	}
5202e192b24SSimon Glass 	index = simple_strtoul(argv[2], NULL, 0);
5212e192b24SSimon Glass 	perm = simple_strtoul(argv[3], NULL, 0);
5222e192b24SSimon Glass 
5232e192b24SSimon Glass 	return report_return_code(tpm_nv_define_space(index, perm, size));
5242e192b24SSimon Glass }
5252e192b24SSimon Glass 
5262e192b24SSimon Glass static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
5272e192b24SSimon Glass 		int argc, char * const argv[])
5282e192b24SSimon Glass {
5292e192b24SSimon Glass 	uint32_t index, count, err;
5302e192b24SSimon Glass 	void *data;
5312e192b24SSimon Glass 
5322e192b24SSimon Glass 	if (argc < 3)
5332e192b24SSimon Glass 		return CMD_RET_USAGE;
5342e192b24SSimon Glass 	if (argc != 3 + type_string_get_num_values(argv[1]))
5352e192b24SSimon Glass 		return CMD_RET_USAGE;
5362e192b24SSimon Glass 	index = simple_strtoul(argv[2], NULL, 0);
5372e192b24SSimon Glass 	data = type_string_alloc(argv[1], &count);
5382e192b24SSimon Glass 	if (!data) {
5392e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
5402e192b24SSimon Glass 		return CMD_RET_USAGE;
5412e192b24SSimon Glass 	}
5422e192b24SSimon Glass 
5432e192b24SSimon Glass 	err = tpm_nv_read_value(index, data, count);
5442e192b24SSimon Glass 	if (!err) {
5452e192b24SSimon Glass 		if (type_string_write_vars(argv[1], data, argv + 3)) {
5462e192b24SSimon Glass 			printf("Couldn't write to variables\n");
5472e192b24SSimon Glass 			err = ~0;
5482e192b24SSimon Glass 		}
5492e192b24SSimon Glass 	}
5502e192b24SSimon Glass 	free(data);
5512e192b24SSimon Glass 
5522e192b24SSimon Glass 	return report_return_code(err);
5532e192b24SSimon Glass }
5542e192b24SSimon Glass 
5552e192b24SSimon Glass static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
5562e192b24SSimon Glass 		int argc, char * const argv[])
5572e192b24SSimon Glass {
5582e192b24SSimon Glass 	uint32_t index, count, err;
5592e192b24SSimon Glass 	void *data;
5602e192b24SSimon Glass 
5612e192b24SSimon Glass 	if (argc < 3)
5622e192b24SSimon Glass 		return CMD_RET_USAGE;
5632e192b24SSimon Glass 	if (argc != 3 + type_string_get_num_values(argv[1]))
5642e192b24SSimon Glass 		return CMD_RET_USAGE;
5652e192b24SSimon Glass 	index = simple_strtoul(argv[2], NULL, 0);
5662e192b24SSimon Glass 	data = type_string_alloc(argv[1], &count);
5672e192b24SSimon Glass 	if (!data) {
5682e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
5692e192b24SSimon Glass 		return CMD_RET_USAGE;
5702e192b24SSimon Glass 	}
5712e192b24SSimon Glass 	if (type_string_pack(argv[1], argv + 3, data)) {
5722e192b24SSimon Glass 		printf("Couldn't parse arguments\n");
5732e192b24SSimon Glass 		free(data);
5742e192b24SSimon Glass 		return CMD_RET_USAGE;
5752e192b24SSimon Glass 	}
5762e192b24SSimon Glass 
5772e192b24SSimon Glass 	err = tpm_nv_write_value(index, data, count);
5782e192b24SSimon Glass 	free(data);
5792e192b24SSimon Glass 
5802e192b24SSimon Glass 	return report_return_code(err);
5812e192b24SSimon Glass }
5822e192b24SSimon Glass 
5832e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
5842e192b24SSimon Glass 
5852e192b24SSimon Glass static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag,
5862e192b24SSimon Glass 		int argc, char * const argv[])
5872e192b24SSimon Glass {
5882e192b24SSimon Glass 	uint32_t auth_handle, err;
5892e192b24SSimon Glass 
5902e192b24SSimon Glass 	err = tpm_oiap(&auth_handle);
5912e192b24SSimon Glass 
5922e192b24SSimon Glass 	return report_return_code(err);
5932e192b24SSimon Glass }
5942e192b24SSimon Glass 
5952e192b24SSimon Glass static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
5962e192b24SSimon Glass 		int argc, char * const argv[])
5972e192b24SSimon Glass {
5982e192b24SSimon Glass 	uint32_t parent_handle, key_len, key_handle, err;
5992e192b24SSimon Glass 	uint8_t usage_auth[DIGEST_LENGTH];
6002e192b24SSimon Glass 	void *key;
6012e192b24SSimon Glass 
6022e192b24SSimon Glass 	if (argc < 5)
6032e192b24SSimon Glass 		return CMD_RET_USAGE;
6042e192b24SSimon Glass 
6052e192b24SSimon Glass 	parent_handle = simple_strtoul(argv[1], NULL, 0);
6062e192b24SSimon Glass 	key = (void *)simple_strtoul(argv[2], NULL, 0);
6072e192b24SSimon Glass 	key_len = simple_strtoul(argv[3], NULL, 0);
6082e192b24SSimon Glass 	if (strlen(argv[4]) != 2 * DIGEST_LENGTH)
6092e192b24SSimon Glass 		return CMD_RET_FAILURE;
6102e192b24SSimon Glass 	parse_byte_string(argv[4], usage_auth, NULL);
6112e192b24SSimon Glass 
6122e192b24SSimon Glass 	err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
6132e192b24SSimon Glass 			&key_handle);
6142e192b24SSimon Glass 	if (!err)
6152e192b24SSimon Glass 		printf("Key handle is 0x%x\n", key_handle);
6162e192b24SSimon Glass 
6172e192b24SSimon Glass 	return report_return_code(err);
6182e192b24SSimon Glass }
6192e192b24SSimon Glass 
6202e192b24SSimon Glass static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
6212e192b24SSimon Glass 		int argc, char * const argv[])
6222e192b24SSimon Glass {
6232e192b24SSimon Glass 	uint32_t key_handle, err;
6242e192b24SSimon Glass 	uint8_t usage_auth[DIGEST_LENGTH];
6252e192b24SSimon Glass 	uint8_t pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
6262e192b24SSimon Glass 	size_t pub_key_len = sizeof(pub_key_buffer);
6272e192b24SSimon Glass 
6282e192b24SSimon Glass 	if (argc < 3)
6292e192b24SSimon Glass 		return CMD_RET_USAGE;
6302e192b24SSimon Glass 
6312e192b24SSimon Glass 	key_handle = simple_strtoul(argv[1], NULL, 0);
6322e192b24SSimon Glass 	if (strlen(argv[2]) != 2 * DIGEST_LENGTH)
6332e192b24SSimon Glass 		return CMD_RET_FAILURE;
6342e192b24SSimon Glass 	parse_byte_string(argv[2], usage_auth, NULL);
6352e192b24SSimon Glass 
6362e192b24SSimon Glass 	err = tpm_get_pub_key_oiap(key_handle, usage_auth,
6372e192b24SSimon Glass 			pub_key_buffer, &pub_key_len);
6382e192b24SSimon Glass 	if (!err) {
6392e192b24SSimon Glass 		printf("dump of received pub key structure:\n");
6402e192b24SSimon Glass 		print_byte_string(pub_key_buffer, pub_key_len);
6412e192b24SSimon Glass 	}
6422e192b24SSimon Glass 	return report_return_code(err);
6432e192b24SSimon Glass }
6442e192b24SSimon Glass 
6452e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_end_oiap)
6462e192b24SSimon Glass 
6472e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
6482e192b24SSimon Glass 
6492e192b24SSimon Glass #define MAKE_TPM_CMD_ENTRY(cmd) \
6502e192b24SSimon Glass 	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
6512e192b24SSimon Glass 
6522e192b24SSimon Glass static cmd_tbl_t tpm_commands[] = {
6532e192b24SSimon Glass 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
6542e192b24SSimon Glass 	U_BOOT_CMD_MKENT(init, 0, 1,
6552e192b24SSimon Glass 			do_tpm_init, "", ""),
6562e192b24SSimon Glass 	U_BOOT_CMD_MKENT(startup, 0, 1,
6572e192b24SSimon Glass 			do_tpm_startup, "", ""),
6582e192b24SSimon Glass 	U_BOOT_CMD_MKENT(self_test_full, 0, 1,
6592e192b24SSimon Glass 			do_tpm_self_test_full, "", ""),
6602e192b24SSimon Glass 	U_BOOT_CMD_MKENT(continue_self_test, 0, 1,
6612e192b24SSimon Glass 			do_tpm_continue_self_test, "", ""),
6622e192b24SSimon Glass 	U_BOOT_CMD_MKENT(force_clear, 0, 1,
6632e192b24SSimon Glass 			do_tpm_force_clear, "", ""),
6642e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_enable, 0, 1,
6652e192b24SSimon Glass 			do_tpm_physical_enable, "", ""),
6662e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_disable, 0, 1,
6672e192b24SSimon Glass 			do_tpm_physical_disable, "", ""),
6682e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_define_space, 0, 1,
6692e192b24SSimon Glass 			do_tpm_nv_define_space, "", ""),
6702e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_read_value, 0, 1,
6712e192b24SSimon Glass 			do_tpm_nv_read_value, "", ""),
6722e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_write_value, 0, 1,
6732e192b24SSimon Glass 			do_tpm_nv_write_value, "", ""),
6742e192b24SSimon Glass 	U_BOOT_CMD_MKENT(extend, 0, 1,
6752e192b24SSimon Glass 			do_tpm_extend, "", ""),
6762e192b24SSimon Glass 	U_BOOT_CMD_MKENT(pcr_read, 0, 1,
6772e192b24SSimon Glass 			do_tpm_pcr_read, "", ""),
6782e192b24SSimon Glass 	U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
6792e192b24SSimon Glass 			do_tpm_tsc_physical_presence, "", ""),
6802e192b24SSimon Glass 	U_BOOT_CMD_MKENT(read_pubek, 0, 1,
6812e192b24SSimon Glass 			do_tpm_read_pubek, "", ""),
6822e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_set_deactivated, 0, 1,
6832e192b24SSimon Glass 			do_tpm_physical_set_deactivated, "", ""),
6842e192b24SSimon Glass 	U_BOOT_CMD_MKENT(get_capability, 0, 1,
6852e192b24SSimon Glass 			do_tpm_get_capability, "", ""),
6862e192b24SSimon Glass 	U_BOOT_CMD_MKENT(raw_transfer, 0, 1,
6872e192b24SSimon Glass 			do_tpm_raw_transfer, "", ""),
6882e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_define, 0, 1,
6892e192b24SSimon Glass 			do_tpm_nv_define, "", ""),
6902e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_read, 0, 1,
6912e192b24SSimon Glass 			do_tpm_nv_read, "", ""),
6922e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_write, 0, 1,
6932e192b24SSimon Glass 			do_tpm_nv_write, "", ""),
6942e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
6952e192b24SSimon Glass 	U_BOOT_CMD_MKENT(oiap, 0, 1,
6962e192b24SSimon Glass 			 do_tpm_oiap, "", ""),
6972e192b24SSimon Glass 	U_BOOT_CMD_MKENT(end_oiap, 0, 1,
6982e192b24SSimon Glass 			 do_tpm_end_oiap, "", ""),
6992e192b24SSimon Glass 	U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1,
7002e192b24SSimon Glass 			 do_tpm_load_key2_oiap, "", ""),
7012e192b24SSimon Glass 	U_BOOT_CMD_MKENT(get_pub_key_oiap, 0, 1,
7022e192b24SSimon Glass 			 do_tpm_get_pub_key_oiap, "", ""),
7032e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
7042e192b24SSimon Glass };
7052e192b24SSimon Glass 
7062e192b24SSimon Glass static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
7072e192b24SSimon Glass {
7082e192b24SSimon Glass 	cmd_tbl_t *tpm_cmd;
7092e192b24SSimon Glass 
7102e192b24SSimon Glass 	if (argc < 2)
7112e192b24SSimon Glass 		return CMD_RET_USAGE;
7122e192b24SSimon Glass 	tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
7132e192b24SSimon Glass 	if (!tpm_cmd)
7142e192b24SSimon Glass 		return CMD_RET_USAGE;
7152e192b24SSimon Glass 
7162e192b24SSimon Glass 	return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
7172e192b24SSimon Glass }
7182e192b24SSimon Glass 
7192e192b24SSimon Glass U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
7202e192b24SSimon Glass "Issue a TPM command",
7212e192b24SSimon Glass "cmd args...\n"
7222e192b24SSimon Glass "    - Issue TPM command <cmd> with arguments <args...>.\n"
7232e192b24SSimon Glass "Admin Startup and State Commands:\n"
7242e192b24SSimon Glass "  info - Show information about the TPM\n"
7252e192b24SSimon Glass "  init\n"
7262e192b24SSimon Glass "    - Put TPM into a state where it waits for 'startup' command.\n"
7272e192b24SSimon Glass "  startup mode\n"
7282e192b24SSimon Glass "    - Issue TPM_Starup command.  <mode> is one of TPM_ST_CLEAR,\n"
7292e192b24SSimon Glass "      TPM_ST_STATE, and TPM_ST_DEACTIVATED.\n"
7302e192b24SSimon Glass "Admin Testing Commands:\n"
7312e192b24SSimon Glass "  self_test_full\n"
7322e192b24SSimon Glass "    - Test all of the TPM capabilities.\n"
7332e192b24SSimon Glass "  continue_self_test\n"
7342e192b24SSimon Glass "    - Inform TPM that it should complete the self-test.\n"
7352e192b24SSimon Glass "Admin Opt-in Commands:\n"
7362e192b24SSimon Glass "  physical_enable\n"
7372e192b24SSimon Glass "    - Set the PERMANENT disable flag to FALSE using physical presence as\n"
7382e192b24SSimon Glass "      authorization.\n"
7392e192b24SSimon Glass "  physical_disable\n"
7402e192b24SSimon Glass "    - Set the PERMANENT disable flag to TRUE using physical presence as\n"
7412e192b24SSimon Glass "      authorization.\n"
7422e192b24SSimon Glass "  physical_set_deactivated 0|1\n"
7432e192b24SSimon Glass "    - Set deactivated flag.\n"
7442e192b24SSimon Glass "Admin Ownership Commands:\n"
7452e192b24SSimon Glass "  force_clear\n"
7462e192b24SSimon Glass "    - Issue TPM_ForceClear command.\n"
7472e192b24SSimon Glass "  tsc_physical_presence flags\n"
7482e192b24SSimon Glass "    - Set TPM device's Physical Presence flags to <flags>.\n"
7492e192b24SSimon Glass "The Capability Commands:\n"
7502e192b24SSimon Glass "  get_capability cap_area sub_cap addr count\n"
7512e192b24SSimon Glass "    - Read <count> bytes of TPM capability indexed by <cap_area> and\n"
7522e192b24SSimon Glass "      <sub_cap> to memory address <addr>.\n"
7532e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
7542e192b24SSimon Glass "Storage functions\n"
7552e192b24SSimon Glass "  loadkey2_oiap parent_handle key_addr key_len usage_auth\n"
7562e192b24SSimon Glass "    - loads a key data from memory address <key_addr>, <key_len> bytes\n"
7572e192b24SSimon Glass "      into TPM using the parent key <parent_handle> with authorization\n"
7582e192b24SSimon Glass "      <usage_auth> (20 bytes hex string).\n"
7592e192b24SSimon Glass "  get_pub_key_oiap key_handle usage_auth\n"
7602e192b24SSimon Glass "    - get the public key portion of a loaded key <key_handle> using\n"
7612e192b24SSimon Glass "      authorization <usage auth> (20 bytes hex string)\n"
7622e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
7632e192b24SSimon Glass "Endorsement Key Handling Commands:\n"
7642e192b24SSimon Glass "  read_pubek addr count\n"
7652e192b24SSimon Glass "    - Read <count> bytes of the public endorsement key to memory\n"
7662e192b24SSimon Glass "      address <addr>\n"
7672e192b24SSimon Glass "Integrity Collection and Reporting Commands:\n"
7682e192b24SSimon Glass "  extend index digest_hex_string\n"
7692e192b24SSimon Glass "    - Add a new measurement to a PCR.  Update PCR <index> with the 20-bytes\n"
7702e192b24SSimon Glass "      <digest_hex_string>\n"
7712e192b24SSimon Glass "  pcr_read index addr count\n"
7722e192b24SSimon Glass "    - Read <count> bytes from PCR <index> to memory address <addr>.\n"
7732e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
7742e192b24SSimon Glass "Authorization Sessions\n"
7752e192b24SSimon Glass "  oiap\n"
7762e192b24SSimon Glass "    - setup an OIAP session\n"
7772e192b24SSimon Glass "  end_oiap\n"
7782e192b24SSimon Glass "    - terminates an active OIAP session\n"
7792e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
7802e192b24SSimon Glass "Non-volatile Storage Commands:\n"
7812e192b24SSimon Glass "  nv_define_space index permission size\n"
7822e192b24SSimon Glass "    - Establish a space at index <index> with <permission> of <size> bytes.\n"
7832e192b24SSimon Glass "  nv_read_value index addr count\n"
7842e192b24SSimon Glass "    - Read <count> bytes from space <index> to memory address <addr>.\n"
7852e192b24SSimon Glass "  nv_write_value index addr count\n"
7862e192b24SSimon Glass "    - Write <count> bytes from memory address <addr> to space <index>.\n"
7872e192b24SSimon Glass "Miscellaneous helper functions:\n"
7882e192b24SSimon Glass "  raw_transfer byte_string\n"
7892e192b24SSimon Glass "    - Send a byte string <byte_string> to TPM and print the response.\n"
7902e192b24SSimon Glass " Non-volatile storage helper functions:\n"
7912e192b24SSimon Glass "    These helper functions treat a non-volatile space as a non-padded\n"
7922e192b24SSimon Glass "    sequence of integer values.  These integer values are defined by a type\n"
7932e192b24SSimon Glass "    string, which is a text string of 'bwd' characters: 'b' means a 8-bit\n"
7942e192b24SSimon Glass "    value, 'w' 16-bit value, 'd' 32-bit value.  All helper functions take\n"
7952e192b24SSimon Glass "    a type string as their first argument.\n"
7962e192b24SSimon Glass "  nv_define type_string index perm\n"
7972e192b24SSimon Glass "    - Define a space <index> with permission <perm>.\n"
7982e192b24SSimon Glass "  nv_read types_string index vars...\n"
7992e192b24SSimon Glass "    - Read from space <index> to environment variables <vars...>.\n"
8002e192b24SSimon Glass "  nv_write types_string index values...\n"
8012e192b24SSimon Glass "    - Write to space <index> from values <values...>.\n"
8022e192b24SSimon Glass );
803