Merge branch '2019-10-28-azure-ci-support'
[oweals/u-boot.git] / cmd / avb.c
index dd389cdaf008bed3aa9a6f8445450f1b5eb596b2..5bc158252b30e67b2af3e564fa7fbb7f3177e595 100644 (file)
--- a/cmd/avb.c
+++ b/cmd/avb.c
@@ -7,6 +7,7 @@
 
 #include <avb_verify.h>
 #include <command.h>
+#include <env.h>
 #include <image.h>
 #include <malloc.h>
 #include <mmc.h>
@@ -35,6 +36,8 @@ int do_avb_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (avb_ops)
                return CMD_RET_SUCCESS;
 
+       printf("Failed to initialize avb2\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -65,6 +68,8 @@ int do_avb_read_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                return CMD_RET_SUCCESS;
        }
 
+       printf("Failed to read from partition\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -108,6 +113,8 @@ int do_avb_read_part_hex(cmd_tbl_t *cmdtp, int flag, int argc,
                return CMD_RET_SUCCESS;
        }
 
+       printf("Failed to read from partition\n");
+
        free(buffer);
        return CMD_RET_FAILURE;
 }
@@ -138,6 +145,8 @@ int do_avb_write_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                return CMD_RET_SUCCESS;
        }
 
+       printf("Failed to write in partition\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -158,9 +167,12 @@ int do_avb_read_rb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        if (avb_ops->read_rollback_index(avb_ops, index, &rb_idx) ==
            AVB_IO_RESULT_OK) {
-               printf("Rollback index: %llu\n", rb_idx);
+               printf("Rollback index: %llx\n", rb_idx);
                return CMD_RET_SUCCESS;
        }
+
+       printf("Failed to read rollback index\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -184,6 +196,8 @@ int do_avb_write_rb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
            AVB_IO_RESULT_OK)
                return CMD_RET_SUCCESS;
 
+       printf("Failed to write rollback index\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -210,6 +224,8 @@ int do_avb_get_uuid(cmd_tbl_t *cmdtp, int flag,
                return CMD_RET_SUCCESS;
        }
 
+       printf("Failed to read UUID\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -218,6 +234,8 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag,
 {
        AvbSlotVerifyResult slot_result;
        AvbSlotVerifyData *out_data;
+       char *cmdline;
+       char *extra_args;
 
        bool unlocked = false;
        int res = CMD_RET_FAILURE;
@@ -249,10 +267,23 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag,
 
        switch (slot_result) {
        case AVB_SLOT_VERIFY_RESULT_OK:
+               /* Until we don't have support of changing unlock states, we
+                * assume that we are by default in locked state.
+                * So in this case we can boot only when verification is
+                * successful; we also supply in cmdline GREEN boot state
+                */
                printf("Verification passed successfully\n");
 
                /* export additional bootargs to AVB_BOOTARGS env var */
-               env_set(AVB_BOOTARGS, out_data->cmdline);
+
+               extra_args = avb_set_state(avb_ops, AVB_GREEN);
+               if (extra_args)
+                       cmdline = append_cmd_line(out_data->cmdline,
+                                                 extra_args);
+               else
+                       cmdline = out_data->cmdline;
+
+               env_set(AVB_BOOTARGS, cmdline);
 
                res = CMD_RET_SUCCESS;
                break;
@@ -305,6 +336,78 @@ int do_avb_is_unlocked(cmd_tbl_t *cmdtp, int flag,
                return CMD_RET_SUCCESS;
        }
 
+       printf("Can't determine device lock state.\n");
+
+       return CMD_RET_FAILURE;
+}
+
+int do_avb_read_pvalue(cmd_tbl_t *cmdtp, int flag, int argc,
+                      char * const argv[])
+{
+       const char *name;
+       size_t bytes;
+       size_t bytes_read;
+       void *buffer;
+       char *endp;
+
+       if (!avb_ops) {
+               printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+               return CMD_RET_FAILURE;
+       }
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       name = argv[1];
+       bytes = simple_strtoul(argv[2], &endp, 10);
+       if (*endp && *endp != '\n')
+               return CMD_RET_USAGE;
+
+       buffer = malloc(bytes);
+       if (!buffer)
+               return CMD_RET_FAILURE;
+
+       if (avb_ops->read_persistent_value(avb_ops, name, bytes, buffer,
+                                          &bytes_read) == AVB_IO_RESULT_OK) {
+               printf("Read %zu bytes, value = %s\n", bytes_read,
+                      (char *)buffer);
+               free(buffer);
+               return CMD_RET_SUCCESS;
+       }
+
+       printf("Failed to read persistent value\n");
+
+       free(buffer);
+
+       return CMD_RET_FAILURE;
+}
+
+int do_avb_write_pvalue(cmd_tbl_t *cmdtp, int flag, int argc,
+                       char * const argv[])
+{
+       const char *name;
+       const char *value;
+
+       if (!avb_ops) {
+               printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+               return CMD_RET_FAILURE;
+       }
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       name = argv[1];
+       value = argv[2];
+
+       if (avb_ops->write_persistent_value(avb_ops, name, strlen(value) + 1,
+                                           (const uint8_t *)value) ==
+           AVB_IO_RESULT_OK) {
+               printf("Wrote %zu bytes\n", strlen(value) + 1);
+               return CMD_RET_SUCCESS;
+       }
+
+       printf("Failed to write persistent value\n");
+
        return CMD_RET_FAILURE;
 }
 
@@ -318,6 +421,10 @@ static cmd_tbl_t cmd_avb[] = {
        U_BOOT_CMD_MKENT(read_part_hex, 4, 0, do_avb_read_part_hex, "", ""),
        U_BOOT_CMD_MKENT(write_part, 5, 0, do_avb_write_part, "", ""),
        U_BOOT_CMD_MKENT(verify, 1, 0, do_avb_verify_part, "", ""),
+#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, "", ""),
+#endif
 };
 
 static int do_avb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -352,6 +459,10 @@ U_BOOT_CMD(
        "    partition <partname> and print to stdout\n"
        "avb write_part <partname> <offset> <num> <addr> - write <num> bytes to\n"
        "    <partname> by <offset> using data from <addr>\n"
+#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"
+#endif
        "avb verify - run verification process using hash data\n"
        "    from vbmeta structure\n"
        );