write_pvalue stores its argument as a NUL-terminated string, which cannot carry binary data such as the 32-byte SHA-256 root key digest consumed by CONFIG_AVB_ROOT_KEY_TEE (persistent value avb.root_pub_digest). Add hex-string variants to provision and dump raw persistent values from the U-Boot shell.
Signed-off-by: Igor Opaniuk <[email protected]> --- cmd/avb.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/cmd/avb.c b/cmd/avb.c index 8fbd48ee5a2..6f8df7ecb6d 100644 --- a/cmd/avb.c +++ b/cmd/avb.c @@ -6,6 +6,7 @@ #include <avb_verify.h> #include <command.h> #include <env.h> +#include <hexdump.h> #include <image.h> #include <malloc.h> #include <mmc.h> @@ -427,6 +428,100 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } +int do_avb_read_pvalue_hex(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *name; + size_t bytes; + size_t bytes_read; + size_t i; + u8 *buffer; + char *endp; + int ret; + + if (!avb_ops) { + printf("AVB is not initialized, please run 'avb init <id>'\n"); + return CMD_RET_FAILURE; + } + + if (argc != 3) + return CMD_RET_USAGE; + + name = argv[1]; + bytes = dectoul(argv[2], &endp); + if (*endp && *endp != '\n') + return CMD_RET_USAGE; + + buffer = malloc(bytes); + if (!buffer) + return CMD_RET_FAILURE; + + ret = avb_ops->read_persistent_value(avb_ops, name, bytes, + buffer, &bytes_read); + if (ret == AVB_IO_RESULT_OK) { + printf("Read %zu bytes, value = ", bytes_read); + for (i = 0; i < bytes_read; i++) + printf("%02x", buffer[i]); + printf("\n"); + free(buffer); + return CMD_RET_SUCCESS; + } + + printf("Failed to read persistent value, err = %d\n", ret); + + free(buffer); + + return CMD_RET_FAILURE; +} + +int do_avb_write_pvalue_hex(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *name; + const char *hex; + size_t len, bytes; + u8 *buffer; + int ret; + + if (!avb_ops) { + printf("AVB is not initialized, please run 'avb init <id>'\n"); + return CMD_RET_FAILURE; + } + + if (argc != 3) + return CMD_RET_USAGE; + + name = argv[1]; + hex = argv[2]; + len = strlen(hex); + if (!len || len % 2) { + printf("Value must be an even number of hex digits\n"); + return CMD_RET_USAGE; + } + bytes = len / 2; + + buffer = malloc(bytes); + if (!buffer) + return CMD_RET_FAILURE; + + if (hex2bin(buffer, hex, bytes)) { + printf("Value is not a valid hex string\n"); + free(buffer); + return CMD_RET_USAGE; + } + + ret = avb_ops->write_persistent_value(avb_ops, name, bytes, buffer); + free(buffer); + if (ret == AVB_IO_RESULT_OK) { + printf("Wrote %zu bytes\n", bytes); + return CMD_RET_SUCCESS; + } + + printf("Failed to write persistent value `%s`, err = %d\n", name, ret); + + return CMD_RET_FAILURE; +} + static struct cmd_tbl cmd_avb[] = { U_BOOT_CMD_MKENT(init, 2, 0, do_avb_init, "", ""), U_BOOT_CMD_MKENT(read_rb, 2, 0, do_avb_read_rb, "", ""), @@ -440,6 +535,8 @@ static struct cmd_tbl cmd_avb[] = { #ifdef CONFIG_OPTEE_TA_AVB U_BOOT_CMD_MKENT(read_pvalue, 3, 0, do_avb_read_pvalue, "", ""), U_BOOT_CMD_MKENT(write_pvalue, 3, 0, do_avb_write_pvalue, "", ""), + U_BOOT_CMD_MKENT(read_pvalue_hex, 3, 0, do_avb_read_pvalue_hex, "", ""), + U_BOOT_CMD_MKENT(write_pvalue_hex, 3, 0, do_avb_write_pvalue_hex, "", ""), #endif }; @@ -478,6 +575,10 @@ U_BOOT_CMD( #ifdef CONFIG_OPTEE_TA_AVB "avb read_pvalue <name> <bytes> - read a persistent value <name>\n" "avb write_pvalue <name> <value> - write a persistent value <name>\n" + "avb read_pvalue_hex <name> <bytes> - read a persistent value <name>\n" + " and print it as hex\n" + "avb write_pvalue_hex <name> <hex> - write the bytes given as a hex\n" + " string to persistent value <name>\n" #endif "avb verify [slot_suffix] - run verification process using hash data\n" " from vbmeta structure\n" -- 2.53.0
