From 6dcb5018d10cfeb99d24a379415d987e1b34fdd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=85gren?= Date: Tue, 18 Mar 2025 16:25:49 +0100 Subject: [PATCH] Store app digest and signature for each app slot --- hw/application_fpga/fw/tk1/main.c | 23 +++++++--- hw/application_fpga/fw/tk1/partition_table.h | 19 ++++++-- hw/application_fpga/fw/tk1/preload_app.c | 47 +++++++++++++++----- hw/application_fpga/fw/tk1/preload_app.h | 4 +- hw/application_fpga/fw/tk1/syscall_handler.c | 4 +- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/hw/application_fpga/fw/tk1/main.c b/hw/application_fpga/fw/tk1/main.c index b9bd764..8d94452 100644 --- a/hw/application_fpga/fw/tk1/main.c +++ b/hw/application_fpga/fw/tk1/main.c @@ -379,11 +379,15 @@ static void jump_to_app(void) static int load_flash_app(struct partition_table *part_table, uint8_t digest[32], uint8_t slot) { + if (slot >= N_PRELOADED_APP) { + return -1; + } + if (preload_load(part_table, slot) == -1) { return -1; } - *app_size = part_table->pre_app_data.size; + *app_size = part_table->pre_app_data[slot].size; if (*app_size > TK1_APP_MAX_SIZE) { return -1; } @@ -397,14 +401,18 @@ static int load_flash_app(struct partition_table *part_table, static enum state auth_flash_app(const struct context *ctx, struct partition_table *part_table) { - if (part_table->pre_app_data.status == PRE_LOADED_STATUS_PRESENT) { + if (ctx->flash_slot >= N_PRELOADED_APP) { + return FW_STATE_FAIL; + } + + if (part_table->pre_app_data[ctx->flash_slot].status == PRE_LOADED_STATUS_PRESENT) { debug_puts("Create auth\n"); - auth_app_create(&part_table->pre_app_data.auth); - part_table->pre_app_data.status = PRE_LOADED_STATUS_AUTH; + auth_app_create(&part_table->pre_app_data[ctx->flash_slot].auth); + part_table->pre_app_data[ctx->flash_slot].status = PRE_LOADED_STATUS_AUTH; part_table_write(part_table); } - if (!auth_app_authenticate(&part_table->pre_app_data.auth)) { + if (!auth_app_authenticate(&part_table->pre_app_data[ctx->flash_slot].auth)) { debug_puts("!Authenticated\n"); return FW_STATE_FAIL; @@ -556,7 +564,8 @@ int main(void) // TODO Lie and tell filesystem we have a 128 kiB device app // on flash. - part_table.pre_app_data.size = 0x20000; + part_table.pre_app_data[0].size = 0x20000; + part_table.pre_app_data[1].size = 0x20000; // TODO Just start something from flash without looking in // FW_RAM. @@ -599,7 +608,7 @@ int main(void) case FW_STATE_LOAD_FLASH: // TODO Just lie and say that an app is present but not yet // authenticated. - part_table.pre_app_data.status = PRE_LOADED_STATUS_PRESENT; + part_table.pre_app_data[ctx.flash_slot].status = PRE_LOADED_STATUS_PRESENT; if (load_flash_app(&part_table, ctx.digest, ctx.flash_slot) < 0) { debug_puts("Couldn't load app from flash\n"); diff --git a/hw/application_fpga/fw/tk1/partition_table.h b/hw/application_fpga/fw/tk1/partition_table.h index f59baee..aff72a2 100644 --- a/hw/application_fpga/fw/tk1/partition_table.h +++ b/hw/application_fpga/fw/tk1/partition_table.h @@ -35,6 +35,7 @@ 0x10000UL // 64KiB, 60 KiB reserved, 2 flash pages (2 x 4KiB) for the // partition table +#define N_PRELOADED_APP 2 #define ADDR_PRE_LOADED_APP (ADDR_PARTITION_TABLE + SIZE_PARTITION_TABLE) #define SIZE_PRE_LOADED_APP 0x20000UL // 128KiB @@ -43,7 +44,7 @@ // Pre-loaded app present but not yet authenticated #define PRE_LOADED_STATUS_PRESENT 0x02 -#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP + (2 * SIZE_PRE_LOADED_APP)) +#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP + (N_PRELOADED_APP * SIZE_PRE_LOADED_APP)) #define SIZE_STORAGE_AREA 0x20000UL // 128KiB #define N_STORAGE_AREA 4 @@ -58,11 +59,21 @@ /* - 16 byte random nonce. */ /* - 16 byte authentication digest. */ /**/ -/*- Pre-loaded device app */ +/*- Pre-loaded device app 1 */ /* - 1 byte status. */ /* - 4 bytes length. */ /* - 16 bytes random nonce. */ /* - 16 bytes authentication digest. */ +/* - 32 bytes digest. */ +/* - 64 bytes signature. */ +/**/ +/*- Pre-loaded device app 2 */ +/* - 1 byte status. */ +/* - 4 bytes length. */ +/* - 16 bytes random nonce. */ +/* - 16 bytes authentication digest. */ +/* - 32 bytes digest. */ +/* - 64 bytes signature. */ /**/ /*- Device app storage area */ /* - 1 byte status. */ @@ -85,6 +96,8 @@ struct pre_loaded_app_metadata { uint8_t status; uint32_t size; struct auth_metadata auth; + uint8_t digest[32]; + uint8_t signature[64]; } __attribute__((packed)); struct app_storage_area { @@ -101,7 +114,7 @@ struct table_header { struct partition_table { struct table_header header; struct management_app_metadata mgmt_app_data; - struct pre_loaded_app_metadata pre_app_data; + struct pre_loaded_app_metadata pre_app_data[N_PRELOADED_APP]; struct app_storage_area app_storage[N_STORAGE_AREA]; } __attribute__((packed)); diff --git a/hw/application_fpga/fw/tk1/preload_app.c b/hw/application_fpga/fw/tk1/preload_app.c index 0560bf9..04596f2 100644 --- a/hw/application_fpga/fw/tk1/preload_app.c +++ b/hw/application_fpga/fw/tk1/preload_app.c @@ -17,9 +17,12 @@ bool preload_check_valid_app(struct partition_table *part_table, uint8_t slot) { + if (slot >= N_PRELOADED_APP) { + return false; + } - if (part_table->pre_app_data.status == 0x00 && - part_table->pre_app_data.size == 0) { + if (part_table->pre_app_data[slot].status == 0x00 && + part_table->pre_app_data[slot].size == 0) { /*No valid app*/ return false; } @@ -30,6 +33,10 @@ bool preload_check_valid_app(struct partition_table *part_table, /* Loads a preloaded app from flash to app RAM */ int preload_load(struct partition_table *part_table, uint8_t from_slot) { + if (from_slot >= N_PRELOADED_APP) { + return -1; + } + /*Check for a valid app in flash */ if (!preload_check_valid_app(part_table, from_slot)) { return -1; @@ -39,7 +46,7 @@ int preload_load(struct partition_table *part_table, uint8_t from_slot) /* Read from flash, straight into RAM */ int ret = flash_read_data(ADDR_PRE_LOADED_APP + from_slot * SIZE_PRE_LOADED_APP, - loadaddr, part_table->pre_app_data.size); + loadaddr, part_table->pre_app_data[from_slot].size); return ret; } @@ -75,8 +82,14 @@ int preload_store(struct partition_table *part_table, uint32_t offset, return flash_write_data(address, data, size); } -int preload_store_finalize(struct partition_table *part_table, size_t app_size, uint8_t to_slot) +int preload_store_finalize(struct partition_table *part_table, size_t app_size, + uint8_t app_digest[32], uint8_t app_signature[64], + uint8_t to_slot) { + if (to_slot >= N_PRELOADED_APP) { + return -4; + } + /* Check if we are allowed to store */ if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { return -3; @@ -91,9 +104,15 @@ int preload_store_finalize(struct partition_table *part_table, size_t app_size, return -2; } - part_table->pre_app_data.size = app_size; - part_table->pre_app_data.status = + part_table->pre_app_data[to_slot].size = app_size; + part_table->pre_app_data[to_slot].status = PRE_LOADED_STATUS_PRESENT; /* Stored but not yet authenticated */ + memcpy_s(part_table->pre_app_data[to_slot].digest, + sizeof(part_table->pre_app_data[to_slot].digest), + app_digest, 32); + memcpy_s(part_table->pre_app_data[to_slot].signature, + sizeof(part_table->pre_app_data[to_slot].signature), + app_signature, 64); debug_puts("preload_*_final: size: "); debug_putinthex(app_size); debug_lf(); @@ -108,6 +127,10 @@ int preload_store_finalize(struct partition_table *part_table, size_t app_size, int preload_delete(struct partition_table *part_table, uint8_t slot) { + if (slot >= N_PRELOADED_APP) { + return -4; + } + /* Check if we are allowed to deleted */ if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { return -3; @@ -118,14 +141,14 @@ int preload_delete(struct partition_table *part_table, uint8_t slot) return 0; // TODO: Nothing here, return zero like all is good? } - part_table->pre_app_data.size = 0; - part_table->pre_app_data.status = 0; + part_table->pre_app_data[slot].size = 0; + part_table->pre_app_data[slot].status = 0; - memset(part_table->pre_app_data.auth.nonce, 0x00, - sizeof(part_table->pre_app_data.auth.nonce)); + memset(part_table->pre_app_data[slot].auth.nonce, 0x00, + sizeof(part_table->pre_app_data[slot].auth.nonce)); - memset(part_table->pre_app_data.auth.authentication_digest, 0x00, - sizeof(part_table->pre_app_data.auth.authentication_digest)); + memset(part_table->pre_app_data[slot].auth.authentication_digest, 0x00, + sizeof(part_table->pre_app_data[slot].auth.authentication_digest)); part_table_write(part_table); diff --git a/hw/application_fpga/fw/tk1/preload_app.h b/hw/application_fpga/fw/tk1/preload_app.h index 3401c8a..27ecf11 100644 --- a/hw/application_fpga/fw/tk1/preload_app.h +++ b/hw/application_fpga/fw/tk1/preload_app.h @@ -14,7 +14,9 @@ bool preload_check_valid_app(struct partition_table *part_table, int preload_load(struct partition_table *part_table, uint8_t from_slot); int preload_store(struct partition_table *part_table, uint32_t offset, uint8_t *data, size_t size, uint8_t to_slot); -int preload_store_finalize(struct partition_table *part_table, size_t app_size, uint8_t to_slot); +int preload_store_finalize(struct partition_table *part_table, size_t app_size, + uint8_t app_digest[32], uint8_t app_signature[64], + uint8_t to_slot); int preload_delete(struct partition_table *part_table, uint8_t slot); #endif diff --git a/hw/application_fpga/fw/tk1/syscall_handler.c b/hw/application_fpga/fw/tk1/syscall_handler.c index 86b1392..bbc1e33 100644 --- a/hw/application_fpga/fw/tk1/syscall_handler.c +++ b/hw/application_fpga/fw/tk1/syscall_handler.c @@ -86,8 +86,10 @@ int32_t syscall_handler(uint32_t number, uint32_t arg1, uint32_t arg2, case TK1_SYSCALL_PRELOAD_STORE_FIN: // arg1 app_size + // arg2 app_digest + // arg3 app_signature // always using slot 1 - return preload_store_finalize(&part_table, arg1, 1); + return preload_store_finalize(&part_table, arg1, (uint8_t *)arg2, (uint8_t *)arg3, 1); case TK1_SYSCALL_REG_MGMT: return mgmt_app_register(&part_table);