summaryrefslogtreecommitdiff
path: root/cmd/avb.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/avb.c')
-rw-r--r--cmd/avb.c173
1 files changed, 91 insertions, 82 deletions
diff --git a/cmd/avb.c b/cmd/avb.c
index 783f51b8169..8fbd48ee5a2 100644
--- a/cmd/avb.c
+++ b/cmd/avb.c
@@ -1,8 +1,6 @@
-
+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2018, Linaro Limited
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <avb_verify.h>
@@ -13,6 +11,7 @@
#include <mmc.h>
#define AVB_BOOTARGS "avb_bootargs"
+
static struct AvbOps *avb_ops;
int do_avb_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
@@ -30,8 +29,10 @@ int do_avb_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
avb_ops = avb_ops_alloc(mmc_dev);
if (avb_ops)
return CMD_RET_SUCCESS;
+ else
+ printf("Can't allocate AvbOps");
- printf("Failed to initialize avb2\n");
+ printf("Failed to initialize AVB\n");
return CMD_RET_FAILURE;
}
@@ -43,10 +44,11 @@ int do_avb_read_part(struct cmd_tbl *cmdtp, int flag, int argc,
s64 offset;
size_t bytes, bytes_read = 0;
void *buffer;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, please run 'avb init'\n");
- return CMD_RET_USAGE;
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
+ return CMD_RET_FAILURE;
}
if (argc != 5)
@@ -57,14 +59,15 @@ int do_avb_read_part(struct cmd_tbl *cmdtp, int flag, int argc,
bytes = hextoul(argv[3], NULL);
buffer = (void *)hextoul(argv[4], NULL);
- if (avb_ops->read_from_partition(avb_ops, part, offset, bytes,
- buffer, &bytes_read) ==
- AVB_IO_RESULT_OK) {
+ ret = avb_ops->read_from_partition(avb_ops, part, offset,
+ bytes, buffer, &bytes_read);
+ if (ret == AVB_IO_RESULT_OK) {
printf("Read %zu bytes\n", bytes_read);
return CMD_RET_SUCCESS;
}
- printf("Failed to read from partition\n");
+ printf("Failed to read from partition '%s', err = %d\n",
+ part, ret);
return CMD_RET_FAILURE;
}
@@ -76,10 +79,11 @@ int do_avb_read_part_hex(struct cmd_tbl *cmdtp, int flag, int argc,
s64 offset;
size_t bytes, bytes_read = 0;
char *buffer;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, please run 'avb init'\n");
- return CMD_RET_USAGE;
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
+ return CMD_RET_FAILURE;
}
if (argc != 4)
@@ -96,8 +100,9 @@ int do_avb_read_part_hex(struct cmd_tbl *cmdtp, int flag, int argc,
}
memset(buffer, 0, bytes);
- if (avb_ops->read_from_partition(avb_ops, part, offset, bytes, buffer,
- &bytes_read) == AVB_IO_RESULT_OK) {
+ ret = avb_ops->read_from_partition(avb_ops, part, offset,
+ bytes, buffer, &bytes_read);
+ if (ret == AVB_IO_RESULT_OK) {
printf("Requested %zu, read %zu bytes\n", bytes, bytes_read);
printf("Data: ");
for (int i = 0; i < bytes_read; i++)
@@ -109,7 +114,8 @@ int do_avb_read_part_hex(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_SUCCESS;
}
- printf("Failed to read from partition\n");
+ printf("Failed to read from partition '%s', err = %d\n",
+ part, ret);
free(buffer);
return CMD_RET_FAILURE;
@@ -122,9 +128,10 @@ int do_avb_write_part(struct cmd_tbl *cmdtp, int flag, int argc,
s64 offset;
size_t bytes;
void *buffer;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -136,13 +143,15 @@ int do_avb_write_part(struct cmd_tbl *cmdtp, int flag, int argc,
bytes = hextoul(argv[3], NULL);
buffer = (void *)hextoul(argv[4], NULL);
- if (avb_ops->write_to_partition(avb_ops, part, offset, bytes, buffer) ==
- AVB_IO_RESULT_OK) {
+ ret = avb_ops->write_to_partition(avb_ops, part, offset,
+ bytes, buffer);
+ if (ret == AVB_IO_RESULT_OK) {
printf("Wrote %zu bytes\n", bytes);
return CMD_RET_SUCCESS;
}
- printf("Failed to write in partition\n");
+ printf("Failed to write in partition '%s', err = %d\n",
+ part, ret);
return CMD_RET_FAILURE;
}
@@ -152,9 +161,10 @@ int do_avb_read_rb(struct cmd_tbl *cmdtp, int flag, int argc,
{
size_t index;
u64 rb_idx;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -163,13 +173,14 @@ int do_avb_read_rb(struct cmd_tbl *cmdtp, int flag, int argc,
index = (size_t)hextoul(argv[1], NULL);
- if (avb_ops->read_rollback_index(avb_ops, index, &rb_idx) ==
- AVB_IO_RESULT_OK) {
+ ret = avb_ops->read_rollback_index(avb_ops, index, &rb_idx);
+ if (ret == AVB_IO_RESULT_OK) {
printf("Rollback index: %llx\n", rb_idx);
return CMD_RET_SUCCESS;
}
- printf("Failed to read rollback index\n");
+ printf("Failed to read rollback index id = %zu, err = %d\n",
+ index, ret);
return CMD_RET_FAILURE;
}
@@ -179,9 +190,10 @@ int do_avb_write_rb(struct cmd_tbl *cmdtp, int flag, int argc,
{
size_t index;
u64 rb_idx;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -191,11 +203,12 @@ int do_avb_write_rb(struct cmd_tbl *cmdtp, int flag, int argc,
index = (size_t)hextoul(argv[1], NULL);
rb_idx = hextoul(argv[2], NULL);
- if (avb_ops->write_rollback_index(avb_ops, index, rb_idx) ==
- AVB_IO_RESULT_OK)
+ ret = avb_ops->write_rollback_index(avb_ops, index, rb_idx);
+ if (ret == AVB_IO_RESULT_OK)
return CMD_RET_SUCCESS;
- printf("Failed to write rollback index\n");
+ printf("Failed to write rollback index id = %zu, err = %d\n",
+ index, ret);
return CMD_RET_FAILURE;
}
@@ -205,9 +218,10 @@ int do_avb_get_uuid(struct cmd_tbl *cmdtp, int flag,
{
const char *part;
char buffer[UUID_STR_LEN + 1];
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -216,14 +230,16 @@ int do_avb_get_uuid(struct cmd_tbl *cmdtp, int flag,
part = argv[1];
- if (avb_ops->get_unique_guid_for_partition(avb_ops, part, buffer,
- UUID_STR_LEN + 1) ==
- AVB_IO_RESULT_OK) {
+ ret = avb_ops->get_unique_guid_for_partition(avb_ops, part,
+ buffer,
+ UUID_STR_LEN + 1);
+ if (ret == AVB_IO_RESULT_OK) {
printf("'%s' UUID: %s\n", part, buffer);
return CMD_RET_SUCCESS;
}
- printf("Failed to read UUID\n");
+ printf("Failed to read partition '%s' UUID, err = %d\n",
+ part, ret);
return CMD_RET_FAILURE;
}
@@ -234,15 +250,17 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag,
const char * const requested_partitions[] = {"boot", NULL};
AvbSlotVerifyResult slot_result;
AvbSlotVerifyData *out_data;
+ enum avb_boot_state boot_state;
char *cmdline;
char *extra_args;
char *slot_suffix = "";
+ int ret;
bool unlocked = false;
int res = CMD_RET_FAILURE;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -255,9 +273,10 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag,
printf("## Android Verified Boot 2.0 version %s\n",
avb_version_string());
- if (avb_ops->read_is_device_unlocked(avb_ops, &unlocked) !=
- AVB_IO_RESULT_OK) {
- printf("Can't determine device lock state.\n");
+ ret = avb_ops->read_is_device_unlocked(avb_ops, &unlocked);
+ if (ret != AVB_IO_RESULT_OK) {
+ printf("Can't determine device lock state, err = %d\n",
+ ret);
return CMD_RET_FAILURE;
}
@@ -269,18 +288,23 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag,
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&out_data);
- 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
- */
+ /*
+ * LOCKED devices with custom root of trust setup is not supported (YELLOW)
+ */
+ if (slot_result == AVB_SLOT_VERIFY_RESULT_OK) {
printf("Verification passed successfully\n");
- /* export additional bootargs to AVB_BOOTARGS env var */
+ /*
+ * ORANGE state indicates that device may be freely modified.
+ * Device integrity is left to the user to verify out-of-band.
+ */
+ if (unlocked)
+ boot_state = AVB_ORANGE;
+ else
+ boot_state = AVB_GREEN;
- extra_args = avb_set_state(avb_ops, AVB_GREEN);
+ /* export boot state to AVB_BOOTARGS env var */
+ extra_args = avb_set_state(avb_ops, boot_state);
if (extra_args)
cmdline = append_cmd_line(out_data->cmdline,
extra_args);
@@ -290,30 +314,8 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag,
env_set(AVB_BOOTARGS, cmdline);
res = CMD_RET_SUCCESS;
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
- printf("Verification failed\n");
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
- printf("I/O error occurred during verification\n");
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
- printf("OOM error occurred during verification\n");
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
- printf("Corrupted dm-verity metadata detected\n");
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
- printf("Unsupported version avbtool was used\n");
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
- printf("Checking rollback index failed\n");
- break;
- case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
- printf("Public key was rejected\n");
- break;
- default:
- printf("Unknown error occurred\n");
+ } else {
+ printf("Verification failed, reason: %s\n", str_avb_slot_error(slot_result));
}
if (out_data)
@@ -326,9 +328,10 @@ int do_avb_is_unlocked(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
bool unlock;
+ int ret;
if (!avb_ops) {
- printf("AVB not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -337,13 +340,14 @@ int do_avb_is_unlocked(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_USAGE;
}
- if (avb_ops->read_is_device_unlocked(avb_ops, &unlock) ==
- AVB_IO_RESULT_OK) {
+ ret = avb_ops->read_is_device_unlocked(avb_ops, &unlock);
+ if (ret == AVB_IO_RESULT_OK) {
printf("Unlocked = %d\n", unlock);
return CMD_RET_SUCCESS;
}
- printf("Can't determine device lock state.\n");
+ printf("Can't determine device lock state, err = %d\n",
+ ret);
return CMD_RET_FAILURE;
}
@@ -356,9 +360,10 @@ int do_avb_read_pvalue(struct cmd_tbl *cmdtp, int flag, int argc,
size_t bytes_read;
void *buffer;
char *endp;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -374,15 +379,16 @@ int do_avb_read_pvalue(struct cmd_tbl *cmdtp, int flag, int argc,
if (!buffer)
return CMD_RET_FAILURE;
- if (avb_ops->read_persistent_value(avb_ops, name, bytes, buffer,
- &bytes_read) == AVB_IO_RESULT_OK) {
+ ret = avb_ops->read_persistent_value(avb_ops, name, bytes,
+ buffer, &bytes_read);
+ if (ret == 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");
+ printf("Failed to read persistent value, err = %d\n", ret);
free(buffer);
@@ -394,9 +400,10 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc,
{
const char *name;
const char *value;
+ int ret;
if (!avb_ops) {
- printf("AVB 2.0 is not initialized, run 'avb init' first\n");
+ printf("AVB is not initialized, please run 'avb init <id>'\n");
return CMD_RET_FAILURE;
}
@@ -406,14 +413,16 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc,
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) {
+ ret = avb_ops->write_persistent_value(avb_ops, name,
+ strlen(value) + 1,
+ (const uint8_t *)value);
+ if (ret == AVB_IO_RESULT_OK) {
printf("Wrote %zu bytes\n", strlen(value) + 1);
return CMD_RET_SUCCESS;
}
- printf("Failed to write persistent value\n");
+ printf("Failed to write persistent value `%s` = `%s`, err = %d\n",
+ name, value, ret);
return CMD_RET_FAILURE;
}