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 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 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 5950f4b2ba1Smario.six@gdsys.cc #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1 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); 6270f4b2ba1Smario.six@gdsys.cc setenv_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 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 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 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 755*3d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_LIST_RESOURCES 756*3d1df0e3Smario.six@gdsys.cc static int do_tpm_list(cmd_tbl_t *cmdtp, int flag, int argc, 757*3d1df0e3Smario.six@gdsys.cc char * const argv[]) 758*3d1df0e3Smario.six@gdsys.cc { 759*3d1df0e3Smario.six@gdsys.cc int type = 0; 760*3d1df0e3Smario.six@gdsys.cc uint16_t res_count; 761*3d1df0e3Smario.six@gdsys.cc uint8_t buf[288]; 762*3d1df0e3Smario.six@gdsys.cc uint8_t *ptr; 763*3d1df0e3Smario.six@gdsys.cc int err; 764*3d1df0e3Smario.six@gdsys.cc uint i; 765*3d1df0e3Smario.six@gdsys.cc 766*3d1df0e3Smario.six@gdsys.cc if (argc != 2) 767*3d1df0e3Smario.six@gdsys.cc return CMD_RET_USAGE; 768*3d1df0e3Smario.six@gdsys.cc 769*3d1df0e3Smario.six@gdsys.cc if (!strcasecmp(argv[1], "key")) 770*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_KEY; 771*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "auth")) 772*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_AUTH; 773*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "hash")) 774*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_HASH; 775*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "trans")) 776*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_TRANS; 777*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "context")) 778*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_CONTEXT; 779*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "counter")) 780*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_COUNTER; 781*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "delegate")) 782*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_DELEGATE; 783*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "daa_tpm")) 784*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_DAA_TPM; 785*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "daa_v0")) 786*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_DAA_V0; 787*3d1df0e3Smario.six@gdsys.cc else if (!strcasecmp(argv[1], "daa_v1")) 788*3d1df0e3Smario.six@gdsys.cc type = TPM_RT_DAA_V1; 789*3d1df0e3Smario.six@gdsys.cc 790*3d1df0e3Smario.six@gdsys.cc if (!type) { 791*3d1df0e3Smario.six@gdsys.cc printf("Resource type %s unknown.\n", argv[1]); 792*3d1df0e3Smario.six@gdsys.cc return -1; 793*3d1df0e3Smario.six@gdsys.cc } 794*3d1df0e3Smario.six@gdsys.cc 795*3d1df0e3Smario.six@gdsys.cc /* fetch list of already loaded resources in the TPM */ 796*3d1df0e3Smario.six@gdsys.cc err = tpm_get_capability(TPM_CAP_HANDLE, type, buf, 797*3d1df0e3Smario.six@gdsys.cc sizeof(buf)); 798*3d1df0e3Smario.six@gdsys.cc if (err) { 799*3d1df0e3Smario.six@gdsys.cc printf("tpm_get_capability returned error %d.\n", err); 800*3d1df0e3Smario.six@gdsys.cc return -1; 801*3d1df0e3Smario.six@gdsys.cc } 802*3d1df0e3Smario.six@gdsys.cc res_count = get_unaligned_be16(buf); 803*3d1df0e3Smario.six@gdsys.cc ptr = buf + 2; 804*3d1df0e3Smario.six@gdsys.cc 805*3d1df0e3Smario.six@gdsys.cc printf("Resources of type %s (%02x):\n", argv[1], type); 806*3d1df0e3Smario.six@gdsys.cc if (!res_count) { 807*3d1df0e3Smario.six@gdsys.cc puts("None\n"); 808*3d1df0e3Smario.six@gdsys.cc } else { 809*3d1df0e3Smario.six@gdsys.cc for (i = 0; i < res_count; ++i, ptr += 4) 810*3d1df0e3Smario.six@gdsys.cc printf("Index %d: %08x\n", i, get_unaligned_be32(ptr)); 811*3d1df0e3Smario.six@gdsys.cc } 812*3d1df0e3Smario.six@gdsys.cc 813*3d1df0e3Smario.six@gdsys.cc return 0; 814*3d1df0e3Smario.six@gdsys.cc } 815*3d1df0e3Smario.six@gdsys.cc #endif /* CONFIG_TPM_LIST_RESOURCES */ 816*3d1df0e3Smario.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 */ 880*3d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_LIST_RESOURCES 881*3d1df0e3Smario.six@gdsys.cc U_BOOT_CMD_MKENT(list, 0, 1, 882*3d1df0e3Smario.six@gdsys.cc do_tpm_list, "", ""), 883*3d1df0e3Smario.six@gdsys.cc #endif /* CONFIG_TPM_LIST_RESOURCES */ 8842e192b24SSimon Glass }; 8852e192b24SSimon Glass 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" 933*3d1df0e3Smario.six@gdsys.cc #if defined(CONFIG_TPM_FLUSH_RESOURCES) || defined(CONFIG_TPM_LIST_RESOURCES) 9347690be35SMario Six "Resource management functions\n" 935*3d1df0e3Smario.six@gdsys.cc #endif 936*3d1df0e3Smario.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 */ 943*3d1df0e3Smario.six@gdsys.cc #ifdef CONFIG_TPM_LIST_RESOURCES 944*3d1df0e3Smario.six@gdsys.cc " list resource_type\n" 945*3d1df0e3Smario.six@gdsys.cc " - lists resources of type <resource_type> (may be one of key, auth,\n" 946*3d1df0e3Smario.six@gdsys.cc " hash, trans, context, counter, delegate, daa_tpm, daa_v0, daa_v1),\n" 947*3d1df0e3Smario.six@gdsys.cc " contained in the TPM.\n" 948*3d1df0e3Smario.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