mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-05 04:36:13 +02:00
Merge tag 'u-boot-dfu-20240215' of https://source.denx.de/u-boot/custodians/u-boot-dfu
u-boot-dfu-20240215 - Fix avb_verify command with SD cards - Add u-boot-dfu maintainer tree for AB/AVB - Avb: report verified boot state based on lock state - Misc avb refactors improve code quality
This commit is contained in:
commit
9e00b6993f
@ -62,6 +62,7 @@ M: Igor Opaniuk <igor.opaniuk@gmail.com>
|
||||
M: Mattijs Korpershoek <mkorpershoek@baylibre.com>
|
||||
R: Sam Protsenko <semen.protsenko@linaro.org>
|
||||
S: Maintained
|
||||
T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git
|
||||
F: boot/android_ab.c
|
||||
F: cmd/ab_select.c
|
||||
F: doc/android/ab.rst
|
||||
@ -72,6 +73,7 @@ ANDROID AVB
|
||||
M: Igor Opaniuk <igor.opaniuk@gmail.com>
|
||||
M: Mattijs Korpershoek <mkorpershoek@baylibre.com>
|
||||
S: Maintained
|
||||
T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git
|
||||
F: cmd/avb.c
|
||||
F: common/avb_verify.c
|
||||
F: doc/android/avb2.rst
|
||||
|
||||
173
cmd/avb.c
173
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;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2018, Linaro Limited
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <avb_verify.h>
|
||||
@ -120,6 +119,55 @@ static const unsigned char avb_root_pub[1032] = {
|
||||
0xd8, 0x7e,
|
||||
};
|
||||
|
||||
const char *str_avb_io_error(AvbIOResult res)
|
||||
{
|
||||
switch (res) {
|
||||
case AVB_IO_RESULT_OK:
|
||||
return "Requested operation was successful";
|
||||
case AVB_IO_RESULT_ERROR_IO:
|
||||
return "Underlying hardware encountered an I/O error";
|
||||
case AVB_IO_RESULT_ERROR_OOM:
|
||||
return "Unable to allocate memory";
|
||||
case AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION:
|
||||
return "Requested partition does not exist";
|
||||
case AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION:
|
||||
return "Bytes requested is outside the range of partition";
|
||||
case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
|
||||
return "Named persistent value does not exist";
|
||||
case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
|
||||
return "Named persistent value size is not supported";
|
||||
case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
|
||||
return "Buffer is too small for the requested operation";
|
||||
default:
|
||||
return "Unknown AVB error";
|
||||
}
|
||||
}
|
||||
|
||||
const char *str_avb_slot_error(AvbSlotVerifyResult res)
|
||||
{
|
||||
switch (res) {
|
||||
case AVB_SLOT_VERIFY_RESULT_OK:
|
||||
return "Verification passed successfully";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
|
||||
return "Allocation of memory failed";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
|
||||
return "I/O error occurred while trying to load data";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
|
||||
return "Digest didn't match or signature checks failed";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
|
||||
return "Rollback index is less than its stored value";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
|
||||
return "Public keys are not accepted";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
|
||||
return "Metadata is invalid or inconsistent";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
|
||||
return "Metadata requires a newer version of libavb";
|
||||
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
|
||||
return "Invalid arguments are used";
|
||||
default:
|
||||
return "Unknown AVB slot verification error";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ============================================================================
|
||||
* Boot states support (GREEN, YELLOW, ORANGE, RED) and dm_verity
|
||||
@ -280,9 +328,9 @@ static unsigned long mmc_read_and_flush(struct mmc_part *part,
|
||||
* Reading fails on unaligned buffers, so we have to
|
||||
* use aligned temporary buffer and then copy to destination
|
||||
*/
|
||||
|
||||
if (unaligned) {
|
||||
printf("Handling unaligned read buffer..\n");
|
||||
debug("%s: handling unaligned read buffer, addr = 0x%p\n",
|
||||
__func__, buffer);
|
||||
tmp_buf = get_sector_buf();
|
||||
buf_size = get_sector_buf_size();
|
||||
if (sectors > buf_size / part->info.blksz)
|
||||
@ -321,7 +369,8 @@ static unsigned long mmc_write(struct mmc_part *part, lbaint_t start,
|
||||
if (unaligned) {
|
||||
tmp_buf = get_sector_buf();
|
||||
buf_size = get_sector_buf_size();
|
||||
printf("Handling unaligned wrire buffer..\n");
|
||||
debug("%s: handling unaligned read buffer, addr = 0x%p\n",
|
||||
__func__, buffer);
|
||||
if (sectors > buf_size / part->info.blksz)
|
||||
sectors = buf_size / part->info.blksz;
|
||||
|
||||
@ -349,28 +398,35 @@ static struct mmc_part *get_partition(AvbOps *ops, const char *partition)
|
||||
dev_num = get_boot_device(ops);
|
||||
part->mmc = find_mmc_device(dev_num);
|
||||
if (!part->mmc) {
|
||||
printf("No MMC device at slot %x\n", dev_num);
|
||||
printf("%s: no MMC device at slot %x\n", __func__, dev_num);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (mmc_init(part->mmc)) {
|
||||
printf("MMC initialization failed\n");
|
||||
ret = mmc_init(part->mmc);
|
||||
if (ret) {
|
||||
printf("%s: MMC initialization failed, err = %d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = mmc_switch_part(part->mmc, part_num);
|
||||
if (ret)
|
||||
goto err;
|
||||
if (IS_MMC(part->mmc)) {
|
||||
ret = mmc_switch_part(part->mmc, part_num);
|
||||
if (ret) {
|
||||
printf("%s: MMC part switch failed, err = %d\n",
|
||||
__func__, ret);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
mmc_blk = mmc_get_blk_desc(part->mmc);
|
||||
if (!mmc_blk) {
|
||||
printf("Error - failed to obtain block descriptor\n");
|
||||
printf("%s: failed to obtain block descriptor\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = part_get_info_by_name(mmc_blk, partition, &part->info);
|
||||
if (ret < 0) {
|
||||
printf("Can't find partition '%s'\n", partition);
|
||||
printf("%s: can't find partition '%s'\n", __func__, partition);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -683,7 +739,7 @@ static AvbIOResult read_rollback_index(AvbOps *ops,
|
||||
{
|
||||
#ifndef CONFIG_OPTEE_TA_AVB
|
||||
/* For now we always return 0 as the stored rollback index. */
|
||||
printf("%s not supported yet\n", __func__);
|
||||
debug("%s: rollback protection is not implemented\n", __func__);
|
||||
|
||||
if (out_rollback_index)
|
||||
*out_rollback_index = 0;
|
||||
@ -729,7 +785,7 @@ static AvbIOResult write_rollback_index(AvbOps *ops,
|
||||
{
|
||||
#ifndef CONFIG_OPTEE_TA_AVB
|
||||
/* For now this is a no-op. */
|
||||
printf("%s not supported yet\n", __func__);
|
||||
debug("%s: rollback protection is not implemented\n", __func__);
|
||||
|
||||
return AVB_IO_RESULT_OK;
|
||||
#else
|
||||
@ -765,8 +821,7 @@ static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
|
||||
{
|
||||
#ifndef CONFIG_OPTEE_TA_AVB
|
||||
/* For now we always return that the device is unlocked. */
|
||||
|
||||
printf("%s not supported yet\n", __func__);
|
||||
debug("%s: device locking is not implemented\n", __func__);
|
||||
|
||||
*out_is_unlocked = true;
|
||||
|
||||
|
||||
@ -38,16 +38,22 @@ AVB 2.0 U-Boot shell commands
|
||||
Provides CLI interface to invoke AVB 2.0 verification + misc. commands for
|
||||
different testing purposes::
|
||||
|
||||
avb init <dev> - initialize avb 2.0 for <dev>
|
||||
avb verify - run verification process using hash data from vbmeta structure
|
||||
avb init <dev> - initialize avb 2 for <dev>
|
||||
avb read_rb <num> - read rollback index at location <num>
|
||||
avb write_rb <num> <rb> - write rollback index <rb> to <num>
|
||||
avb is_unlocked - returns unlock status of the device
|
||||
avb get_uuid <partname> - read and print uuid of partition <partname>
|
||||
avb get_uuid <partname> - read and print uuid of partition <part>
|
||||
avb read_part <partname> <offset> <num> <addr> - read <num> bytes from
|
||||
partition <partname> to buffer <addr>
|
||||
partition <partname> to buffer <addr>
|
||||
avb read_part_hex <partname> <offset> <num> - read <num> bytes from
|
||||
partition <partname> and print to stdout
|
||||
avb write_part <partname> <offset> <num> <addr> - write <num> bytes to
|
||||
<partname> by <offset> using data from <addr>
|
||||
<partname> by <offset> using data from <addr>
|
||||
avb read_pvalue <name> <bytes> - read a persistent value <name>
|
||||
avb write_pvalue <name> <value> - write a persistent value <name>
|
||||
avb verify [slot_suffix] - run verification process using hash data
|
||||
from vbmeta structure
|
||||
[slot_suffix] - _a, _b, etc (if vbmeta partition is slotted)
|
||||
|
||||
Partitions tampering (example)
|
||||
------------------------------
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2018, Linaro Limited
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _AVB_VERIFY_H
|
||||
@ -54,7 +52,8 @@ char *avb_set_enforce_verity(const char *cmdline);
|
||||
char *avb_set_ignore_corruption(const char *cmdline);
|
||||
|
||||
char *append_cmd_line(char *cmdline_orig, char *cmdline_new);
|
||||
|
||||
const char *str_avb_io_error(AvbIOResult res);
|
||||
const char *str_avb_slot_error(AvbSlotVerifyResult res);
|
||||
/**
|
||||
* ============================================================================
|
||||
* I/O helper inline functions
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
# Copyright (c) 2018, Linaro Limited
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2018, Linaro Limited
|
||||
#
|
||||
# Android Verified Boot 2.0 Test
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user