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 93a49f50c2
commit 9018ae5b33
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, static int load_flash_app(struct partition_table *part_table,
uint8_t digest[32], uint8_t slot) uint8_t digest[32], uint8_t slot)
{ {
if (slot >= N_PRELOADED_APP) {
return -1;
}
if (preload_load(part_table, slot) == -1) { if (preload_load(part_table, slot) == -1) {
return -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) { if (*app_size > TK1_APP_MAX_SIZE) {
return -1; 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) 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"); debug_puts("Create auth\n");
auth_app_create(&part_table->pre_app_data.auth); auth_app_create(&part_table->pre_app_data[ctx->flash_slot].auth);
part_table->pre_app_data.status = PRE_LOADED_STATUS_AUTH; part_table->pre_app_data[ctx->flash_slot].status = PRE_LOADED_STATUS_AUTH;
part_table_write(part_table); 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"); debug_puts("!Authenticated\n");
return FW_STATE_FAIL; return FW_STATE_FAIL;
@ -556,7 +564,8 @@ int main(void)
// TODO Lie and tell filesystem we have a 128 kiB device app // TODO Lie and tell filesystem we have a 128 kiB device app
// on flash. // 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 // TODO Just start something from flash without looking in
// FW_RAM. // FW_RAM.
@ -599,7 +608,7 @@ int main(void)
case FW_STATE_LOAD_FLASH: case FW_STATE_LOAD_FLASH:
// TODO Just lie and say that an app is present but not yet // TODO Just lie and say that an app is present but not yet
// authenticated. // 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) { if (load_flash_app(&part_table, ctx.digest, ctx.flash_slot) < 0) {
debug_puts("Couldn't load app from flash\n"); 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 0x10000UL // 64KiB, 60 KiB reserved, 2 flash pages (2 x 4KiB) for the
// partition table // partition table
#define N_PRELOADED_APP 2
#define ADDR_PRE_LOADED_APP (ADDR_PARTITION_TABLE + SIZE_PARTITION_TABLE) #define ADDR_PRE_LOADED_APP (ADDR_PARTITION_TABLE + SIZE_PARTITION_TABLE)
#define SIZE_PRE_LOADED_APP 0x20000UL // 128KiB #define SIZE_PRE_LOADED_APP 0x20000UL // 128KiB
@ -43,7 +44,7 @@
// Pre-loaded app present but not yet authenticated // Pre-loaded app present but not yet authenticated
#define PRE_LOADED_STATUS_PRESENT 0x02 #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 SIZE_STORAGE_AREA 0x20000UL // 128KiB
#define N_STORAGE_AREA 4 #define N_STORAGE_AREA 4
@ -58,11 +59,21 @@
/* - 16 byte random nonce. */ /* - 16 byte random nonce. */
/* - 16 byte authentication digest. */ /* - 16 byte authentication digest. */
/**/ /**/
/*- Pre-loaded device app */ /*- Pre-loaded device app 1 */
/* - 1 byte status. */ /* - 1 byte status. */
/* - 4 bytes length. */ /* - 4 bytes length. */
/* - 16 bytes random nonce. */ /* - 16 bytes random nonce. */
/* - 16 bytes authentication digest. */ /* - 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 */ /*- Device app storage area */
/* - 1 byte status. */ /* - 1 byte status. */
@ -85,6 +96,8 @@ struct pre_loaded_app_metadata {
uint8_t status; uint8_t status;
uint32_t size; uint32_t size;
struct auth_metadata auth; struct auth_metadata auth;
uint8_t digest[32];
uint8_t signature[64];
} __attribute__((packed)); } __attribute__((packed));
struct app_storage_area { struct app_storage_area {
@ -101,7 +114,7 @@ struct table_header {
struct partition_table { struct partition_table {
struct table_header header; struct table_header header;
struct management_app_metadata mgmt_app_data; 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]; struct app_storage_area app_storage[N_STORAGE_AREA];
} __attribute__((packed)); } __attribute__((packed));

View file

@ -17,9 +17,12 @@
bool preload_check_valid_app(struct partition_table *part_table, bool preload_check_valid_app(struct partition_table *part_table,
uint8_t slot) uint8_t slot)
{ {
if (slot >= N_PRELOADED_APP) {
return false;
}
if (part_table->pre_app_data.status == 0x00 && if (part_table->pre_app_data[slot].status == 0x00 &&
part_table->pre_app_data.size == 0) { part_table->pre_app_data[slot].size == 0) {
/*No valid app*/ /*No valid app*/
return false; 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 */ /* Loads a preloaded app from flash to app RAM */
int preload_load(struct partition_table *part_table, uint8_t from_slot) int preload_load(struct partition_table *part_table, uint8_t from_slot)
{ {
if (from_slot >= N_PRELOADED_APP) {
return -4;
}
/*Check for a valid app in flash */ /*Check for a valid app in flash */
if (!preload_check_valid_app(part_table, from_slot)) { if (!preload_check_valid_app(part_table, from_slot)) {
return -1; return -1;
@ -39,7 +46,7 @@ int preload_load(struct partition_table *part_table, uint8_t from_slot)
/* Read from flash, straight into RAM */ /* Read from flash, straight into RAM */
int ret = flash_read_data(ADDR_PRE_LOADED_APP + int ret = flash_read_data(ADDR_PRE_LOADED_APP +
from_slot * SIZE_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; return ret;
} }
@ -75,8 +82,14 @@ int preload_store(struct partition_table *part_table, uint32_t offset,
return flash_write_data(address, data, size); 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 */ /* Check if we are allowed to store */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
return -3; return -3;
@ -91,9 +104,15 @@ int preload_store_finalize(struct partition_table *part_table, size_t app_size,
return -2; return -2;
} }
part_table->pre_app_data.size = app_size; part_table->pre_app_data[to_slot].size = app_size;
part_table->pre_app_data.status = part_table->pre_app_data[to_slot].status =
PRE_LOADED_STATUS_PRESENT; /* Stored but not yet authenticated */ 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_puts("preload_*_final: size: ");
debug_putinthex(app_size); debug_putinthex(app_size);
debug_lf(); 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) 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 */ /* Check if we are allowed to deleted */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
return -3; return -3;
@ -118,14 +141,14 @@ int preload_delete(struct partition_table *part_table, uint8_t slot)
return 0; return 0;
// TODO: Nothing here, return zero like all is good? // TODO: Nothing here, return zero like all is good?
} }
part_table->pre_app_data.size = 0; part_table->pre_app_data[slot].size = 0;
part_table->pre_app_data.status = 0; part_table->pre_app_data[slot].status = 0;
memset(part_table->pre_app_data.auth.nonce, 0x00, memset(part_table->pre_app_data[slot].auth.nonce, 0x00,
sizeof(part_table->pre_app_data.auth.nonce)); sizeof(part_table->pre_app_data[slot].auth.nonce));
memset(part_table->pre_app_data.auth.authentication_digest, 0x00, memset(part_table->pre_app_data[slot].auth.authentication_digest, 0x00,
sizeof(part_table->pre_app_data.auth.authentication_digest)); sizeof(part_table->pre_app_data[slot].auth.authentication_digest));
part_table_write(part_table); 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_load(struct partition_table *part_table, uint8_t from_slot);
int preload_store(struct partition_table *part_table, uint32_t offset, int preload_store(struct partition_table *part_table, uint32_t offset,
uint8_t *data, size_t size, uint8_t to_slot); 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); int preload_delete(struct partition_table *part_table, uint8_t slot);
#endif #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: case TK1_SYSCALL_PRELOAD_STORE_FIN:
// arg1 app_size // arg1 app_size
// arg2 app_digest
// arg3 app_signature
// always using slot 1 // 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: case TK1_SYSCALL_REG_MGMT:
return mgmt_app_register(&part_table); return mgmt_app_register(&part_table);