Store app digest and signature for each app slot

This commit is contained in:
Mikael Ågren 2025-03-18 16:25:49 +01:00
parent dd147657a4
commit 6dcb5018d1
No known key found for this signature in database
GPG Key ID: E02DA3D397792C46
5 changed files with 73 additions and 24 deletions

View File

@ -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");

View File

@ -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));

View File

@ -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);

View File

@ -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

View File

@ -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);