Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,6 @@ config UTILS_AVB_VERIFY_STACKSIZE
int "Stack size of AVB verification tools"
default 6144

config UTILS_AVB_VERIFY_ENABLE_DEVICE_LOCK
bool "Enable Device Lock"
default y
depends on KVDB

config UTILS_AVB_VERIFY_ENABLE_PERSISTENT_VALUE
bool "Enable Persistent Value"
default y
depends on KVDB

config UTILS_AVB_VERIFY_ENABLE_ROLLBACK_PROTECTION
bool "Enable Rollback Protection"
default y
depends on KVDB

endif

config UTILS_ZIP_VERIFY
Expand Down
60 changes: 16 additions & 44 deletions verify/avb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,61 +17,32 @@
#include "avb_verify.h"
#include <unistd.h>

#define usage(p) usage_line_num(p, __LINE__)
#define PRINT_VERIFY(o, u, as, ar, p, c) \
avb_printf(" %-6s | %-6s | %-8s | %-8s | %-6s | %s\n", o, u, as, ar, p, c)

void usage_line_num(const char* progname, const int line_num)
void usage(const char* progname)
{
avb_printf("Usage: %s [-b] [-c] [-i] <partition> <key> [suffix]\n", progname);
avb_printf(" %s [-I] <partition>\n", progname);
avb_printf("Usage: %s [-b] [-i] <partition> <key> [suffix]\n", progname);
avb_printf(" %s [-U] <image> <partition> <key>\n", progname);

avb_printf("\nVerify\n");
PRINT_VERIFY("Option", "Update", "Allow", "Allow", "IDX", "Description");
PRINT_VERIFY("", "IDX", "Same IDX", "Rollback", "in KV", "");
PRINT_VERIFY("----", "----", "----", "----", "----", "----");
PRINT_VERIFY("-b", "Y", "Y", "N", "Y", "Boot verification that enabled by default");
PRINT_VERIFY("-i", "Y", "Y", "Y", "Y", "Ignore rollback index error during boot verification");
PRINT_VERIFY("-c", "N", "N", "N", "Y", "Comparing rollback index to prevent duplicate installation");
PRINT_VERIFY("-U", "N", "Y", "N", "N", "Upgrade verify by comparing the rollback index in partition and image");

avb_printf("\nInfo print\n");
avb_printf(" %-4s Show image info\n", "-I");
avb_printf(" %-4s Show help\n", "-h");
avb_printf(" %s [-I] <partition>\n", progname);

avb_printf("\nExamples\n");
avb_printf(" - Boot Verify\n");
avb_printf(" %s <partition> <key> [suffix]\n", progname);
avb_printf(" - Comparing rollback index\n");
avb_printf(" %s -c <image> <key> [suffix]\n", progname);
avb_printf(" - Upgrade Verify\n");
avb_printf(" %s -U <image> <partition> <key> [suffix]\n", progname);
avb_printf(" - Image Info\n");
avb_printf(" %s -I <image>\n", progname);

avb_printf("\nLine num: %d\n", line_num);
}

int main(int argc, char* argv[])
{
AvbSlotVerifyFlags flags = 0;
const char* image = NULL;
struct avb_params_t params = { 0 };
int ret;

while ((ret = getopt(argc, argv, "bchiI:U:")) != -1) {
while ((ret = getopt(argc, argv, "bhiI:U:")) != -1) {
switch (ret) {
case 'b':
break;
case 'c':
flags |= AVB_SLOT_VERIFY_FLAGS_NOT_ALLOW_SAME_ROLLBACK_INDEX | AVB_SLOT_VERIFY_FLAGS_NOT_UPDATE_ROLLBACK_INDEX;
break;
case 'i':
flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_ROLLBACK_INDEX_ERROR;
break;
case 'h':
usage(argv[0]);
return 0;
params.flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_ROLLBACK_INDEX_ERROR;
break;
case 'I':
struct avb_hash_desc_t hash_desc;
Expand All @@ -82,9 +53,11 @@ int main(int argc, char* argv[])
return 1;
break;
case 'U':
flags |= UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV;
image = optarg;
g_rollback_index = 0;
params.image = optarg;
break;
case 'h':
usage(argv[0]);
return 0;
break;
default:
usage(argv[0]);
Expand All @@ -98,14 +71,13 @@ int main(int argc, char* argv[])
return 100;
}

ret = avb_verify(argv[optind], argv[optind + 1], argv[optind + 2], flags);
params.partition = argv[optind];
params.key = argv[optind + 1];
params.suffix = argv[optind + 2];

ret = avb_verify(&params);
if (ret != 0)
avb_printf("%s error %d\n", argv[0], ret);
else if (image) {
ret = avb_verify(image, argv[optind + 1], argv[optind + 2], flags);
if (ret != 0)
avb_printf("%s verify %s error %d\n", argv[0], image, ret);
}

return ret;
}
156 changes: 28 additions & 128 deletions verify/avb_verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

#include <errno.h>
#include <fcntl.h>
#ifdef CONFIG_KVDB
#include <kvdb.h>
#endif
#include <libavb.h>
#include <stdio.h>
#include <stdlib.h>
Expand All @@ -29,12 +26,6 @@

#include "avb_verify.h"

#define AVB_PERSISTENT_VALUE "persist.%s"
#define AVB_DEVICE_UNLOCKED "persist.avb.unlocked"
#define AVB_ROLLBACK_LOCATION "persist.avb.rollback.%zu"

uint64_t g_rollback_index;

static AvbIOResult read_from_partition(AvbOps* ops,
const char* partition,
int64_t offset,
Expand Down Expand Up @@ -128,7 +119,7 @@ static AvbIOResult write_to_partition(AvbOps* ops,
return AVB_IO_RESULT_OK;
}

AvbIOResult validate_vbmeta_public_key(AvbOps* ops,
static AvbIOResult validate_vbmeta_public_key(AvbOps* ops,
const uint8_t* public_key_data,
size_t public_key_length,
const uint8_t* public_key_metadata,
Expand All @@ -145,58 +136,11 @@ static AvbIOResult read_rollback_index(AvbOps* ops,
size_t rollback_index_location,
uint64_t* out_rollback_index)
{
#ifdef CONFIG_UTILS_AVB_VERIFY_ENABLE_ROLLBACK_PROTECTION
char key[PROP_NAME_MAX];

snprintf(key, sizeof(key), AVB_ROLLBACK_LOCATION, rollback_index_location);
*out_rollback_index = property_get_int64(key, 0);
#else
*out_rollback_index = 0;
#endif
return AVB_IO_RESULT_OK;
}

static AvbIOResult read_rollback_index_tmp(AvbOps* ops,
size_t rollback_index_location,
uint64_t* out_rollback_index)
{
*out_rollback_index = g_rollback_index;
return AVB_IO_RESULT_OK;
}

AvbIOResult write_rollback_index(AvbOps* ops,
size_t rollback_index_location,
uint64_t rollback_index)
{
#ifdef CONFIG_UTILS_AVB_VERIFY_ENABLE_ROLLBACK_PROTECTION
char key[PROP_NAME_MAX];

snprintf(key, sizeof(key), AVB_ROLLBACK_LOCATION, rollback_index_location);
if (property_set_int64(key, rollback_index) < 0)
return AVB_IO_RESULT_ERROR_IO;
#endif
return AVB_IO_RESULT_OK;
}

AvbIOResult write_rollback_index_tmp(AvbOps* ops,
size_t rollback_index_location,
uint64_t rollback_index)
{
g_rollback_index = rollback_index;
return AVB_IO_RESULT_OK;
}

static AvbIOResult read_is_device_unlocked(AvbOps* ops, bool* out_is_unlocked)
{
#ifdef CONFIG_UTILS_AVB_VERIFY_ENABLE_DEVICE_LOCK
*out_is_unlocked = property_get_bool(AVB_DEVICE_UNLOCKED, false);
#else
*out_is_unlocked = false;
#endif
return AVB_IO_RESULT_OK;
}

static AvbIOResult read_is_device_unlocked_false(AvbOps* ops, bool* out_is_unlocked)
{
*out_is_unlocked = false;
return AVB_IO_RESULT_OK;
Expand Down Expand Up @@ -225,46 +169,6 @@ static AvbIOResult get_size_of_partition(AvbOps* ops,
return AVB_IO_RESULT_OK;
}

static AvbIOResult read_persistent_value(AvbOps* ops,
const char* name,
size_t buffer_size,
uint8_t* out_buffer,
size_t* out_num_bytes_read)
{
#ifdef CONFIG_UTILS_AVB_VERIFY_ENABLE_PERSISTENT_VALUE
ssize_t ret;
char key[PROP_NAME_MAX];

snprintf(key, sizeof(key), AVB_PERSISTENT_VALUE, name);
ret = property_get_buffer(key, out_buffer, buffer_size);
if (ret == -E2BIG) {
*out_num_bytes_read = PROP_VALUE_MAX;
return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
} else if (ret < 0)
return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;

*out_num_bytes_read = ret;
#else
*out_num_bytes_read = 0;
#endif
return AVB_IO_RESULT_OK;
}

static AvbIOResult write_persistent_value(AvbOps* ops,
const char* name,
size_t value_size,
const uint8_t* value)
{
#ifdef CONFIG_UTILS_AVB_VERIFY_ENABLE_PERSISTENT_VALUE
char key[PROP_NAME_MAX];

snprintf(key, sizeof(key), AVB_PERSISTENT_VALUE, name);
if (property_set_buffer(key, value, value_size) < 0)
return AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE;
#endif
return AVB_IO_RESULT_OK;
}

static AvbIOResult validate_public_key_for_partition(AvbOps* ops,
const char* partition,
const uint8_t* public_key_data,
Expand Down Expand Up @@ -292,59 +196,55 @@ static AvbIOResult validate_public_key_for_partition(AvbOps* ops,
return result;
}

int avb_verify(const char* partition, const char* key, const char* suffix, AvbSlotVerifyFlags flags)
int avb_verify(struct avb_params_t* params)
{
struct AvbOps ops = {
(char*)key,
(char*)params->key,
NULL,
NULL,
read_from_partition,
get_preloaded_partition,
write_to_partition,
validate_vbmeta_public_key,
(flags & UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV) ? read_rollback_index_tmp : read_rollback_index,
(flags & UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV) ? write_rollback_index_tmp : write_rollback_index,
(flags & UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV) ? read_is_device_unlocked_false : read_is_device_unlocked,
read_rollback_index,
NULL,
read_is_device_unlocked,
get_unique_guid_for_partition,
get_size_of_partition,
(flags & UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV) ? NULL : read_persistent_value,
(flags & UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV) ? NULL : write_persistent_value,
NULL,
NULL,
validate_public_key_for_partition
};
const char* partitions[] = {
partition,
NULL
const char* partitions[][2] = {
{ params->partition, NULL },
{ params->image, NULL },
};
AvbSlotVerifyData* slot_data = NULL;
AvbSlotVerifyData* slot_data[2] = { 0 };
int ret;
int n;

ret = avb_slot_verify(&ops,
partitions, suffix ? suffix : "",
(flags & ~UTILS_AVB_VERIFY_LOCAL_FLAG_MASK) | AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data);
for (n = 0; n < 2; n++) {
ret = avb_slot_verify(&ops,
partitions[n], params->suffix ? params->suffix : "",
AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slot_data[n]);

if (ret != AVB_SLOT_VERIFY_RESULT_OK || !slot_data)
return ret;
if (ret != AVB_SLOT_VERIFY_RESULT_OK || !slot_data[n] || (!n && !params->image))
goto out;
}

for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
uint64_t rollback_index = slot_data->rollback_indexes[n];
if (rollback_index) {
uint64_t current_rollback_index;
ret = ops.read_rollback_index(&ops, n, &current_rollback_index);
if (ret != AVB_IO_RESULT_OK)
goto out;
if (current_rollback_index != rollback_index && (flags & AVB_SLOT_VERIFY_FLAGS_NOT_UPDATE_ROLLBACK_INDEX) == 0) {
ret = ops.write_rollback_index(&ops, n, rollback_index);
if (ret != AVB_IO_RESULT_OK)
goto out;
}
if (slot_data[1]->rollback_indexes[n] < slot_data[0]->rollback_indexes[n]) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX;
goto out;
}
}

out:
avb_slot_verify_data_free(slot_data);
for (n = 0; n < 2; n++)
if (slot_data[n])
avb_slot_verify_data_free(slot_data[n]);
return ret;
}

Expand All @@ -358,7 +258,7 @@ int avb_hash_desc(const char* full_partition_name, struct avb_hash_desc_t* desc)
get_preloaded_partition,
NULL,
validate_vbmeta_public_key,
read_rollback_index,
NULL,
NULL,
read_is_device_unlocked,
get_unique_guid_for_partition,
Expand Down
13 changes: 8 additions & 5 deletions verify/avb_verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
extern "C" {
#endif

#define UTILS_AVB_VERIFY_LOCAL_FLAG_MASK 0xf000
#define UTILS_AVB_VERIFY_LOCAL_FLAG_NOKV 0x8000

struct avb_hash_desc_t {
uint64_t image_size;
uint8_t hash_algorithm[32]; /* Ref: struct AvbHashDescriptor */
Expand All @@ -35,9 +32,15 @@ struct avb_hash_desc_t {
uint64_t rollback_index;
};

extern uint64_t g_rollback_index;
struct avb_params_t {
const char* partition;
const char* image;
const char* key;
const char* suffix;
AvbSlotVerifyFlags flags;
};

int avb_verify(const char* partition, const char* key, const char* suffix, AvbSlotVerifyFlags flags);
int avb_verify(struct avb_params_t* params);
int avb_hash_desc(const char* full_partition_name, struct avb_hash_desc_t* desc);
void avb_hash_desc_dump(const struct avb_hash_desc_t* desc);

Expand Down
Loading