xref: /rk3399_rockchip-uboot/cmd/tpm.c (revision 018f530323b2cc41be05be5b12375d3648f06554)
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  */
print_byte_string(uint8_t * data,size_t count)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  */
parse_byte_string(char * bytes,uint8_t * data,size_t * count_ptr)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  */
report_return_code(int return_code)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  */
type_string_get_num_values(const char * type_str)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  */
type_string_get_space_size(const char * type_str)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  */
type_string_alloc(const char * type_str,uint32_t * count)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  */
type_string_pack(const char * type_str,char * const values[],uint8_t * data)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  */
type_string_write_vars(const char * type_str,uint8_t * data,char * const vars[])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 		}
234*018f5303SSimon Glass 		if (env_set_ulong(*vars, value))
2352e192b24SSimon Glass 			return -1;
2362e192b24SSimon Glass 	}
2372e192b24SSimon Glass 
2382e192b24SSimon Glass 	return 0;
2392e192b24SSimon Glass }
2402e192b24SSimon Glass 
do_tpm_startup(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_nv_define_space(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_nv_read_value(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_nv_write_value(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_extend(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_pcr_read(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_tsc_physical_presence(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_read_pubek(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_physical_set_deactivated(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_get_capability(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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)
TPM_COMMAND_NO_ARG(tpm_self_test_full)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 
4503f603cbbSSimon Glass 	rc = uclass_first_device_err(UCLASS_TPM, devp);
4513f603cbbSSimon 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 
do_tpm_info(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_raw_transfer(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_nv_define(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_nv_read(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_nv_write(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
do_tpm_oiap(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])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 
5950f4b2ba1Smario.six@gdsys.cc #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
do_tpm_load_key_by_sha1(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])5960f4b2ba1Smario.six@gdsys.cc static int do_tpm_load_key_by_sha1(cmd_tbl_t *cmdtp, int flag, int argc, char *
5970f4b2ba1Smario.six@gdsys.cc 				   const argv[])
5980f4b2ba1Smario.six@gdsys.cc {
5990f4b2ba1Smario.six@gdsys.cc 	uint32_t parent_handle = 0;
6000f4b2ba1Smario.six@gdsys.cc 	uint32_t key_len, key_handle, err;
6010f4b2ba1Smario.six@gdsys.cc 	uint8_t usage_auth[DIGEST_LENGTH];
6020f4b2ba1Smario.six@gdsys.cc 	uint8_t parent_hash[DIGEST_LENGTH];
6030f4b2ba1Smario.six@gdsys.cc 	void *key;
6040f4b2ba1Smario.six@gdsys.cc 
6050f4b2ba1Smario.six@gdsys.cc 	if (argc < 5)
6060f4b2ba1Smario.six@gdsys.cc 		return CMD_RET_USAGE;
6070f4b2ba1Smario.six@gdsys.cc 
6080f4b2ba1Smario.six@gdsys.cc 	parse_byte_string(argv[1], parent_hash, NULL);
6090f4b2ba1Smario.six@gdsys.cc 	key = (void *)simple_strtoul(argv[2], NULL, 0);
6100f4b2ba1Smario.six@gdsys.cc 	key_len = simple_strtoul(argv[3], NULL, 0);
6110f4b2ba1Smario.six@gdsys.cc 	if (strlen(argv[4]) != 2 * DIGEST_LENGTH)
6120f4b2ba1Smario.six@gdsys.cc 		return CMD_RET_FAILURE;
6130f4b2ba1Smario.six@gdsys.cc 	parse_byte_string(argv[4], usage_auth, NULL);
6140f4b2ba1Smario.six@gdsys.cc 
6150f4b2ba1Smario.six@gdsys.cc 	err = tpm_find_key_sha1(usage_auth, parent_hash, &parent_handle);
6160f4b2ba1Smario.six@gdsys.cc 	if (err) {
6170f4b2ba1Smario.six@gdsys.cc 		printf("Could not find matching parent key (err = %d)\n", err);
6180f4b2ba1Smario.six@gdsys.cc 		return CMD_RET_FAILURE;
6190f4b2ba1Smario.six@gdsys.cc 	}
6200f4b2ba1Smario.six@gdsys.cc 
6210f4b2ba1Smario.six@gdsys.cc 	printf("Found parent key %08x\n", parent_handle);
6220f4b2ba1Smario.six@gdsys.cc 
6230f4b2ba1Smario.six@gdsys.cc 	err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
6240f4b2ba1Smario.six@gdsys.cc 				 &key_handle);
6250f4b2ba1Smario.six@gdsys.cc 	if (!err) {
6260f4b2ba1Smario.six@gdsys.cc 		printf("Key handle is 0x%x\n", key_handle);
627*018f5303SSimon Glass 		env_set_hex("key_handle", key_handle);
6280f4b2ba1Smario.six@gdsys.cc 	}
6290f4b2ba1Smario.six@gdsys.cc 
6300f4b2ba1Smario.six@gdsys.cc 	return report_return_code(err);
6310f4b2ba1Smario.six@gdsys.cc }
6320f4b2ba1Smario.six@gdsys.cc #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
6330f4b2ba1Smario.six@gdsys.cc 
do_tpm_load_key2_oiap(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])6342e192b24SSimon Glass static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
6352e192b24SSimon Glass 		int argc, char * const argv[])
6362e192b24SSimon Glass {
6372e192b24SSimon Glass 	uint32_t parent_handle, key_len, key_handle, err;
6382e192b24SSimon Glass 	uint8_t usage_auth[DIGEST_LENGTH];
6392e192b24SSimon Glass 	void *key;
6402e192b24SSimon Glass 
6412e192b24SSimon Glass 	if (argc < 5)
6422e192b24SSimon Glass 		return CMD_RET_USAGE;
6432e192b24SSimon Glass 
6442e192b24SSimon Glass 	parent_handle = simple_strtoul(argv[1], NULL, 0);
6452e192b24SSimon Glass 	key = (void *)simple_strtoul(argv[2], NULL, 0);
6462e192b24SSimon Glass 	key_len = simple_strtoul(argv[3], NULL, 0);
6472e192b24SSimon Glass 	if (strlen(argv[4]) != 2 * DIGEST_LENGTH)
6482e192b24SSimon Glass 		return CMD_RET_FAILURE;
6492e192b24SSimon Glass 	parse_byte_string(argv[4], usage_auth, NULL);
6502e192b24SSimon Glass 
6512e192b24SSimon Glass 	err = tpm_load_key2_oiap(parent_handle, key, key_len, usage_auth,
6522e192b24SSimon Glass 			&key_handle);
6532e192b24SSimon Glass 	if (!err)
6542e192b24SSimon Glass 		printf("Key handle is 0x%x\n", key_handle);
6552e192b24SSimon Glass 
6562e192b24SSimon Glass 	return report_return_code(err);
6572e192b24SSimon Glass }
6582e192b24SSimon Glass 
do_tpm_get_pub_key_oiap(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])6592e192b24SSimon Glass static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
6602e192b24SSimon Glass 		int argc, char * const argv[])
6612e192b24SSimon Glass {
6622e192b24SSimon Glass 	uint32_t key_handle, err;
6632e192b24SSimon Glass 	uint8_t usage_auth[DIGEST_LENGTH];
6642e192b24SSimon Glass 	uint8_t pub_key_buffer[TPM_PUBKEY_MAX_LENGTH];
6652e192b24SSimon Glass 	size_t pub_key_len = sizeof(pub_key_buffer);
6662e192b24SSimon Glass 
6672e192b24SSimon Glass 	if (argc < 3)
6682e192b24SSimon Glass 		return CMD_RET_USAGE;
6692e192b24SSimon Glass 
6702e192b24SSimon Glass 	key_handle = simple_strtoul(argv[1], NULL, 0);
6712e192b24SSimon Glass 	if (strlen(argv[2]) != 2 * DIGEST_LENGTH)
6722e192b24SSimon Glass 		return CMD_RET_FAILURE;
6732e192b24SSimon Glass 	parse_byte_string(argv[2], usage_auth, NULL);
6742e192b24SSimon Glass 
6752e192b24SSimon Glass 	err = tpm_get_pub_key_oiap(key_handle, usage_auth,
6762e192b24SSimon Glass 			pub_key_buffer, &pub_key_len);
6772e192b24SSimon Glass 	if (!err) {
6782e192b24SSimon Glass 		printf("dump of received pub key structure:\n");
6792e192b24SSimon Glass 		print_byte_string(pub_key_buffer, pub_key_len);
6802e192b24SSimon Glass 	}
6812e192b24SSimon Glass 	return report_return_code(err);
6822e192b24SSimon Glass }
6832e192b24SSimon Glass 
TPM_COMMAND_NO_ARG(tpm_end_oiap)6842e192b24SSimon Glass TPM_COMMAND_NO_ARG(tpm_end_oiap)
6852e192b24SSimon Glass 
6862e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
6872e192b24SSimon Glass 
6887690be35SMario Six #ifdef CONFIG_TPM_FLUSH_RESOURCES
6897690be35SMario Six static int do_tpm_flush(cmd_tbl_t *cmdtp, int flag, int argc,
6907690be35SMario Six 			char * const argv[])
6917690be35SMario Six {
6927690be35SMario Six 	int type = 0;
6937690be35SMario Six 
6941c08b210Smario.six@gdsys.cc 	if (argc != 3)
6957690be35SMario Six 		return CMD_RET_USAGE;
6967690be35SMario Six 
6971c08b210Smario.six@gdsys.cc 	if (!strcasecmp(argv[1], "key"))
6987690be35SMario Six 		type = TPM_RT_KEY;
6991c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "auth"))
7007690be35SMario Six 		type = TPM_RT_AUTH;
7011c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "hash"))
7027690be35SMario Six 		type = TPM_RT_HASH;
7031c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "trans"))
7047690be35SMario Six 		type = TPM_RT_TRANS;
7051c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "context"))
7067690be35SMario Six 		type = TPM_RT_CONTEXT;
7071c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "counter"))
7087690be35SMario Six 		type = TPM_RT_COUNTER;
7091c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "delegate"))
7107690be35SMario Six 		type = TPM_RT_DELEGATE;
7111c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "daa_tpm"))
7127690be35SMario Six 		type = TPM_RT_DAA_TPM;
7131c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "daa_v0"))
7147690be35SMario Six 		type = TPM_RT_DAA_V0;
7151c08b210Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "daa_v1"))
7167690be35SMario Six 		type = TPM_RT_DAA_V1;
7177690be35SMario Six 
7181c08b210Smario.six@gdsys.cc 	if (!type) {
7191c08b210Smario.six@gdsys.cc 		printf("Resource type %s unknown.\n", argv[1]);
7201c08b210Smario.six@gdsys.cc 		return -1;
7211c08b210Smario.six@gdsys.cc 	}
7221c08b210Smario.six@gdsys.cc 
7231c08b210Smario.six@gdsys.cc 	if (!strcasecmp(argv[2], "all")) {
7247690be35SMario Six 		uint16_t res_count;
7257690be35SMario Six 		uint8_t buf[288];
7267690be35SMario Six 		uint8_t *ptr;
7277690be35SMario Six 		int err;
7287690be35SMario Six 		uint i;
7297690be35SMario Six 
7307690be35SMario Six 		/* fetch list of already loaded resources in the TPM */
7317690be35SMario Six 		err = tpm_get_capability(TPM_CAP_HANDLE, type, buf,
7327690be35SMario Six 					 sizeof(buf));
7331c08b210Smario.six@gdsys.cc 		if (err) {
7341c08b210Smario.six@gdsys.cc 			printf("tpm_get_capability returned error %d.\n", err);
7357690be35SMario Six 			return -1;
7361c08b210Smario.six@gdsys.cc 		}
7377690be35SMario Six 		res_count = get_unaligned_be16(buf);
7387690be35SMario Six 		ptr = buf + 2;
7397690be35SMario Six 		for (i = 0; i < res_count; ++i, ptr += 4)
7407690be35SMario Six 			tpm_flush_specific(get_unaligned_be32(ptr), type);
7417690be35SMario Six 	} else {
7427690be35SMario Six 		uint32_t handle = simple_strtoul(argv[2], NULL, 0);
7437690be35SMario Six 
7441c08b210Smario.six@gdsys.cc 		if (!handle) {
7451c08b210Smario.six@gdsys.cc 			printf("Illegal resource handle %s\n", argv[2]);
7467690be35SMario Six 			return -1;
7471c08b210Smario.six@gdsys.cc 		}
7487690be35SMario Six 		tpm_flush_specific(cpu_to_be32(handle), type);
7497690be35SMario Six 	}
7507690be35SMario Six 
7517690be35SMario Six 	return 0;
7527690be35SMario Six }
7537690be35SMario Six #endif /* CONFIG_TPM_FLUSH_RESOURCES */
7547690be35SMario Six 
7553d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_LIST_RESOURCES
do_tpm_list(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])7563d1df0e3Smario.six@gdsys.cc static int do_tpm_list(cmd_tbl_t *cmdtp, int flag, int argc,
7573d1df0e3Smario.six@gdsys.cc 		       char * const argv[])
7583d1df0e3Smario.six@gdsys.cc {
7593d1df0e3Smario.six@gdsys.cc 	int type = 0;
7603d1df0e3Smario.six@gdsys.cc 	uint16_t res_count;
7613d1df0e3Smario.six@gdsys.cc 	uint8_t buf[288];
7623d1df0e3Smario.six@gdsys.cc 	uint8_t *ptr;
7633d1df0e3Smario.six@gdsys.cc 	int err;
7643d1df0e3Smario.six@gdsys.cc 	uint i;
7653d1df0e3Smario.six@gdsys.cc 
7663d1df0e3Smario.six@gdsys.cc 	if (argc != 2)
7673d1df0e3Smario.six@gdsys.cc 		return CMD_RET_USAGE;
7683d1df0e3Smario.six@gdsys.cc 
7693d1df0e3Smario.six@gdsys.cc 	if (!strcasecmp(argv[1], "key"))
7703d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_KEY;
7713d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "auth"))
7723d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_AUTH;
7733d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "hash"))
7743d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_HASH;
7753d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "trans"))
7763d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_TRANS;
7773d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "context"))
7783d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_CONTEXT;
7793d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "counter"))
7803d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_COUNTER;
7813d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "delegate"))
7823d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_DELEGATE;
7833d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "daa_tpm"))
7843d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_DAA_TPM;
7853d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "daa_v0"))
7863d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_DAA_V0;
7873d1df0e3Smario.six@gdsys.cc 	else if (!strcasecmp(argv[1], "daa_v1"))
7883d1df0e3Smario.six@gdsys.cc 		type = TPM_RT_DAA_V1;
7893d1df0e3Smario.six@gdsys.cc 
7903d1df0e3Smario.six@gdsys.cc 	if (!type) {
7913d1df0e3Smario.six@gdsys.cc 		printf("Resource type %s unknown.\n", argv[1]);
7923d1df0e3Smario.six@gdsys.cc 		return -1;
7933d1df0e3Smario.six@gdsys.cc 	}
7943d1df0e3Smario.six@gdsys.cc 
7953d1df0e3Smario.six@gdsys.cc 	/* fetch list of already loaded resources in the TPM */
7963d1df0e3Smario.six@gdsys.cc 	err = tpm_get_capability(TPM_CAP_HANDLE, type, buf,
7973d1df0e3Smario.six@gdsys.cc 				 sizeof(buf));
7983d1df0e3Smario.six@gdsys.cc 	if (err) {
7993d1df0e3Smario.six@gdsys.cc 		printf("tpm_get_capability returned error %d.\n", err);
8003d1df0e3Smario.six@gdsys.cc 		return -1;
8013d1df0e3Smario.six@gdsys.cc 	}
8023d1df0e3Smario.six@gdsys.cc 	res_count = get_unaligned_be16(buf);
8033d1df0e3Smario.six@gdsys.cc 	ptr = buf + 2;
8043d1df0e3Smario.six@gdsys.cc 
8053d1df0e3Smario.six@gdsys.cc 	printf("Resources of type %s (%02x):\n", argv[1], type);
8063d1df0e3Smario.six@gdsys.cc 	if (!res_count) {
8073d1df0e3Smario.six@gdsys.cc 		puts("None\n");
8083d1df0e3Smario.six@gdsys.cc 	} else {
8093d1df0e3Smario.six@gdsys.cc 		for (i = 0; i < res_count; ++i, ptr += 4)
8103d1df0e3Smario.six@gdsys.cc 			printf("Index %d: %08x\n", i, get_unaligned_be32(ptr));
8113d1df0e3Smario.six@gdsys.cc 	}
8123d1df0e3Smario.six@gdsys.cc 
8133d1df0e3Smario.six@gdsys.cc 	return 0;
8143d1df0e3Smario.six@gdsys.cc }
8153d1df0e3Smario.six@gdsys.cc #endif /* CONFIG_TPM_LIST_RESOURCES */
8163d1df0e3Smario.six@gdsys.cc 
8172e192b24SSimon Glass #define MAKE_TPM_CMD_ENTRY(cmd) \
8182e192b24SSimon Glass 	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
8192e192b24SSimon Glass 
8202e192b24SSimon Glass static cmd_tbl_t tpm_commands[] = {
8212e192b24SSimon Glass 	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
8222e192b24SSimon Glass 	U_BOOT_CMD_MKENT(init, 0, 1,
8232e192b24SSimon Glass 			do_tpm_init, "", ""),
8242e192b24SSimon Glass 	U_BOOT_CMD_MKENT(startup, 0, 1,
8252e192b24SSimon Glass 			do_tpm_startup, "", ""),
8262e192b24SSimon Glass 	U_BOOT_CMD_MKENT(self_test_full, 0, 1,
8272e192b24SSimon Glass 			do_tpm_self_test_full, "", ""),
8282e192b24SSimon Glass 	U_BOOT_CMD_MKENT(continue_self_test, 0, 1,
8292e192b24SSimon Glass 			do_tpm_continue_self_test, "", ""),
8302e192b24SSimon Glass 	U_BOOT_CMD_MKENT(force_clear, 0, 1,
8312e192b24SSimon Glass 			do_tpm_force_clear, "", ""),
8322e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_enable, 0, 1,
8332e192b24SSimon Glass 			do_tpm_physical_enable, "", ""),
8342e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_disable, 0, 1,
8352e192b24SSimon Glass 			do_tpm_physical_disable, "", ""),
8362e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_define_space, 0, 1,
8372e192b24SSimon Glass 			do_tpm_nv_define_space, "", ""),
8382e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_read_value, 0, 1,
8392e192b24SSimon Glass 			do_tpm_nv_read_value, "", ""),
8402e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_write_value, 0, 1,
8412e192b24SSimon Glass 			do_tpm_nv_write_value, "", ""),
8422e192b24SSimon Glass 	U_BOOT_CMD_MKENT(extend, 0, 1,
8432e192b24SSimon Glass 			do_tpm_extend, "", ""),
8442e192b24SSimon Glass 	U_BOOT_CMD_MKENT(pcr_read, 0, 1,
8452e192b24SSimon Glass 			do_tpm_pcr_read, "", ""),
8462e192b24SSimon Glass 	U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
8472e192b24SSimon Glass 			do_tpm_tsc_physical_presence, "", ""),
8482e192b24SSimon Glass 	U_BOOT_CMD_MKENT(read_pubek, 0, 1,
8492e192b24SSimon Glass 			do_tpm_read_pubek, "", ""),
8502e192b24SSimon Glass 	U_BOOT_CMD_MKENT(physical_set_deactivated, 0, 1,
8512e192b24SSimon Glass 			do_tpm_physical_set_deactivated, "", ""),
8522e192b24SSimon Glass 	U_BOOT_CMD_MKENT(get_capability, 0, 1,
8532e192b24SSimon Glass 			do_tpm_get_capability, "", ""),
8542e192b24SSimon Glass 	U_BOOT_CMD_MKENT(raw_transfer, 0, 1,
8552e192b24SSimon Glass 			do_tpm_raw_transfer, "", ""),
8562e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_define, 0, 1,
8572e192b24SSimon Glass 			do_tpm_nv_define, "", ""),
8582e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_read, 0, 1,
8592e192b24SSimon Glass 			do_tpm_nv_read, "", ""),
8602e192b24SSimon Glass 	U_BOOT_CMD_MKENT(nv_write, 0, 1,
8612e192b24SSimon Glass 			do_tpm_nv_write, "", ""),
8622e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
8632e192b24SSimon Glass 	U_BOOT_CMD_MKENT(oiap, 0, 1,
8642e192b24SSimon Glass 			 do_tpm_oiap, "", ""),
8652e192b24SSimon Glass 	U_BOOT_CMD_MKENT(end_oiap, 0, 1,
8662e192b24SSimon Glass 			 do_tpm_end_oiap, "", ""),
8672e192b24SSimon Glass 	U_BOOT_CMD_MKENT(load_key2_oiap, 0, 1,
8682e192b24SSimon Glass 			 do_tpm_load_key2_oiap, "", ""),
8690f4b2ba1Smario.six@gdsys.cc #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
8700f4b2ba1Smario.six@gdsys.cc 	U_BOOT_CMD_MKENT(load_key_by_sha1, 0, 1,
8710f4b2ba1Smario.six@gdsys.cc 			 do_tpm_load_key_by_sha1, "", ""),
8720f4b2ba1Smario.six@gdsys.cc #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
8732e192b24SSimon Glass 	U_BOOT_CMD_MKENT(get_pub_key_oiap, 0, 1,
8742e192b24SSimon Glass 			 do_tpm_get_pub_key_oiap, "", ""),
8752e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
8767690be35SMario Six #ifdef CONFIG_TPM_FLUSH_RESOURCES
8777690be35SMario Six 	U_BOOT_CMD_MKENT(flush, 0, 1,
8787690be35SMario Six 			 do_tpm_flush, "", ""),
8797690be35SMario Six #endif /* CONFIG_TPM_FLUSH_RESOURCES */
8803d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_LIST_RESOURCES
8813d1df0e3Smario.six@gdsys.cc 	U_BOOT_CMD_MKENT(list, 0, 1,
8823d1df0e3Smario.six@gdsys.cc 			 do_tpm_list, "", ""),
8833d1df0e3Smario.six@gdsys.cc #endif /* CONFIG_TPM_LIST_RESOURCES */
8842e192b24SSimon Glass };
8852e192b24SSimon Glass 
do_tpm(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])8862e192b24SSimon Glass static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
8872e192b24SSimon Glass {
8882e192b24SSimon Glass 	cmd_tbl_t *tpm_cmd;
8892e192b24SSimon Glass 
8902e192b24SSimon Glass 	if (argc < 2)
8912e192b24SSimon Glass 		return CMD_RET_USAGE;
8922e192b24SSimon Glass 	tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
8932e192b24SSimon Glass 	if (!tpm_cmd)
8942e192b24SSimon Glass 		return CMD_RET_USAGE;
8952e192b24SSimon Glass 
8962e192b24SSimon Glass 	return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
8972e192b24SSimon Glass }
8982e192b24SSimon Glass 
8992e192b24SSimon Glass U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
9002e192b24SSimon Glass "Issue a TPM command",
9012e192b24SSimon Glass "cmd args...\n"
9022e192b24SSimon Glass "    - Issue TPM command <cmd> with arguments <args...>.\n"
9032e192b24SSimon Glass "Admin Startup and State Commands:\n"
9042e192b24SSimon Glass "  info - Show information about the TPM\n"
9052e192b24SSimon Glass "  init\n"
9062e192b24SSimon Glass "    - Put TPM into a state where it waits for 'startup' command.\n"
9072e192b24SSimon Glass "  startup mode\n"
9082e192b24SSimon Glass "    - Issue TPM_Starup command.  <mode> is one of TPM_ST_CLEAR,\n"
9092e192b24SSimon Glass "      TPM_ST_STATE, and TPM_ST_DEACTIVATED.\n"
9102e192b24SSimon Glass "Admin Testing Commands:\n"
9112e192b24SSimon Glass "  self_test_full\n"
9122e192b24SSimon Glass "    - Test all of the TPM capabilities.\n"
9132e192b24SSimon Glass "  continue_self_test\n"
9142e192b24SSimon Glass "    - Inform TPM that it should complete the self-test.\n"
9152e192b24SSimon Glass "Admin Opt-in Commands:\n"
9162e192b24SSimon Glass "  physical_enable\n"
9172e192b24SSimon Glass "    - Set the PERMANENT disable flag to FALSE using physical presence as\n"
9182e192b24SSimon Glass "      authorization.\n"
9192e192b24SSimon Glass "  physical_disable\n"
9202e192b24SSimon Glass "    - Set the PERMANENT disable flag to TRUE using physical presence as\n"
9212e192b24SSimon Glass "      authorization.\n"
9222e192b24SSimon Glass "  physical_set_deactivated 0|1\n"
9232e192b24SSimon Glass "    - Set deactivated flag.\n"
9242e192b24SSimon Glass "Admin Ownership Commands:\n"
9252e192b24SSimon Glass "  force_clear\n"
9262e192b24SSimon Glass "    - Issue TPM_ForceClear command.\n"
9272e192b24SSimon Glass "  tsc_physical_presence flags\n"
9282e192b24SSimon Glass "    - Set TPM device's Physical Presence flags to <flags>.\n"
9292e192b24SSimon Glass "The Capability Commands:\n"
9302e192b24SSimon Glass "  get_capability cap_area sub_cap addr count\n"
9312e192b24SSimon Glass "    - Read <count> bytes of TPM capability indexed by <cap_area> and\n"
9322e192b24SSimon Glass "      <sub_cap> to memory address <addr>.\n"
9333d1df0e3Smario.six@gdsys.cc #if defined(CONFIG_TPM_FLUSH_RESOURCES) || defined(CONFIG_TPM_LIST_RESOURCES)
9347690be35SMario Six "Resource management functions\n"
9353d1df0e3Smario.six@gdsys.cc #endif
9363d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_FLUSH_RESOURCES
9377690be35SMario Six "  flush resource_type id\n"
9387690be35SMario Six "    - flushes a resource of type <resource_type> (may be one of key, auth,\n"
9397690be35SMario Six "      hash, trans, context, counter, delegate, daa_tpm, daa_v0, daa_v1),\n"
9407690be35SMario Six "      and id <id> from the TPM. Use an <id> of \"all\" to flush all\n"
9417690be35SMario Six "      resources of that type.\n"
9427690be35SMario Six #endif /* CONFIG_TPM_FLUSH_RESOURCES */
9433d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_LIST_RESOURCES
9443d1df0e3Smario.six@gdsys.cc "  list resource_type\n"
9453d1df0e3Smario.six@gdsys.cc "    - lists resources of type <resource_type> (may be one of key, auth,\n"
9463d1df0e3Smario.six@gdsys.cc "      hash, trans, context, counter, delegate, daa_tpm, daa_v0, daa_v1),\n"
9473d1df0e3Smario.six@gdsys.cc "      contained in the TPM.\n"
9483d1df0e3Smario.six@gdsys.cc #endif /* CONFIG_TPM_LIST_RESOURCES */
9492e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
9502e192b24SSimon Glass "Storage functions\n"
9512e192b24SSimon Glass "  loadkey2_oiap parent_handle key_addr key_len usage_auth\n"
9522e192b24SSimon Glass "    - loads a key data from memory address <key_addr>, <key_len> bytes\n"
9532e192b24SSimon Glass "      into TPM using the parent key <parent_handle> with authorization\n"
9542e192b24SSimon Glass "      <usage_auth> (20 bytes hex string).\n"
9550f4b2ba1Smario.six@gdsys.cc #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
9560f4b2ba1Smario.six@gdsys.cc "  load_key_by_sha1 parent_hash key_addr key_len usage_auth\n"
9570f4b2ba1Smario.six@gdsys.cc "    - loads a key data from memory address <key_addr>, <key_len> bytes\n"
9580f4b2ba1Smario.six@gdsys.cc "      into TPM using the parent hash <parent_hash> (20 bytes hex string)\n"
9590f4b2ba1Smario.six@gdsys.cc "      with authorization <usage_auth> (20 bytes hex string).\n"
9600f4b2ba1Smario.six@gdsys.cc #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
9612e192b24SSimon Glass "  get_pub_key_oiap key_handle usage_auth\n"
9622e192b24SSimon Glass "    - get the public key portion of a loaded key <key_handle> using\n"
9632e192b24SSimon Glass "      authorization <usage auth> (20 bytes hex string)\n"
9642e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
9652e192b24SSimon Glass "Endorsement Key Handling Commands:\n"
9662e192b24SSimon Glass "  read_pubek addr count\n"
9672e192b24SSimon Glass "    - Read <count> bytes of the public endorsement key to memory\n"
9682e192b24SSimon Glass "      address <addr>\n"
9692e192b24SSimon Glass "Integrity Collection and Reporting Commands:\n"
9702e192b24SSimon Glass "  extend index digest_hex_string\n"
9712e192b24SSimon Glass "    - Add a new measurement to a PCR.  Update PCR <index> with the 20-bytes\n"
9722e192b24SSimon Glass "      <digest_hex_string>\n"
9732e192b24SSimon Glass "  pcr_read index addr count\n"
9742e192b24SSimon Glass "    - Read <count> bytes from PCR <index> to memory address <addr>.\n"
9752e192b24SSimon Glass #ifdef CONFIG_TPM_AUTH_SESSIONS
9762e192b24SSimon Glass "Authorization Sessions\n"
9772e192b24SSimon Glass "  oiap\n"
9782e192b24SSimon Glass "    - setup an OIAP session\n"
9792e192b24SSimon Glass "  end_oiap\n"
9802e192b24SSimon Glass "    - terminates an active OIAP session\n"
9812e192b24SSimon Glass #endif /* CONFIG_TPM_AUTH_SESSIONS */
9822e192b24SSimon Glass "Non-volatile Storage Commands:\n"
9832e192b24SSimon Glass "  nv_define_space index permission size\n"
9842e192b24SSimon Glass "    - Establish a space at index <index> with <permission> of <size> bytes.\n"
9852e192b24SSimon Glass "  nv_read_value index addr count\n"
9862e192b24SSimon Glass "    - Read <count> bytes from space <index> to memory address <addr>.\n"
9872e192b24SSimon Glass "  nv_write_value index addr count\n"
9882e192b24SSimon Glass "    - Write <count> bytes from memory address <addr> to space <index>.\n"
9892e192b24SSimon Glass "Miscellaneous helper functions:\n"
9902e192b24SSimon Glass "  raw_transfer byte_string\n"
9912e192b24SSimon Glass "    - Send a byte string <byte_string> to TPM and print the response.\n"
9922e192b24SSimon Glass " Non-volatile storage helper functions:\n"
9932e192b24SSimon Glass "    These helper functions treat a non-volatile space as a non-padded\n"
9942e192b24SSimon Glass "    sequence of integer values.  These integer values are defined by a type\n"
9952e192b24SSimon Glass "    string, which is a text string of 'bwd' characters: 'b' means a 8-bit\n"
9962e192b24SSimon Glass "    value, 'w' 16-bit value, 'd' 32-bit value.  All helper functions take\n"
9972e192b24SSimon Glass "    a type string as their first argument.\n"
9982e192b24SSimon Glass "  nv_define type_string index perm\n"
9992e192b24SSimon Glass "    - Define a space <index> with permission <perm>.\n"
10002e192b24SSimon Glass "  nv_read types_string index vars...\n"
10012e192b24SSimon Glass "    - Read from space <index> to environment variables <vars...>.\n"
10022e192b24SSimon Glass "  nv_write types_string index values...\n"
10032e192b24SSimon Glass "    - Write to space <index> from values <values...>.\n"
10042e192b24SSimon Glass );
1005