Experiment with new state machine

This commit is contained in:
Michael Cardell Widerkrantz 2025-03-17 10:31:08 +01:00 committed by Mikael Ågren
parent 6ef1b1c659
commit ab12c201c4
No known key found for this signature in database
GPG key ID: E02DA3D397792C46
2 changed files with 87 additions and 33 deletions

View file

@ -37,6 +37,7 @@ static volatile uint32_t *timer_status = (volatile uint32_t *)TK1_MMIO_TIMER
static volatile uint32_t *timer_ctrl = (volatile uint32_t *)TK1_MMIO_TIMER_CTRL; static volatile uint32_t *timer_ctrl = (volatile uint32_t *)TK1_MMIO_TIMER_CTRL;
static volatile uint32_t *ram_addr_rand = (volatile uint32_t *)TK1_MMIO_TK1_RAM_ADDR_RAND; static volatile uint32_t *ram_addr_rand = (volatile uint32_t *)TK1_MMIO_TK1_RAM_ADDR_RAND;
static volatile uint32_t *ram_data_rand = (volatile uint32_t *)TK1_MMIO_TK1_RAM_DATA_RAND; static volatile uint32_t *ram_data_rand = (volatile uint32_t *)TK1_MMIO_TK1_RAM_DATA_RAND;
static volatile uint8_t *startfrom = (volatile uint8_t *)0xd0000000bb9; /// FW_RAM after stack
// clang-format on // clang-format on
struct partition_table part_table; struct partition_table part_table;
@ -48,7 +49,18 @@ struct context {
uint8_t *loadaddr; // Where we are currently loading a TKey program uint8_t *loadaddr; // Where we are currently loading a TKey program
bool use_uss; // Use USS? bool use_uss; // Use USS?
uint8_t uss[32]; // User Supplied Secret, if any uint8_t uss[32]; // User Supplied Secret, if any
bool from_flash; // App is loaded from flash uint8_t flash_slot; // App is loaded from flash slot number
bool verify; // Verify?
uint8_t ver_digest[32]; // Verify loaded app against this digest
};
enum reset_start {
START_FLASH1 = 1,
START_FLASH2 = 2,
START_FLASH1_VER = 3,
START_FLASH2_VER = 4,
START_CLIENT = 5,
START_CLIENT_VER = 6,
}; };
static void print_hw_version(void); static void print_hw_version(void);
@ -63,13 +75,13 @@ static enum state initial_commands(const struct frame_header *hdr,
static enum state loading_commands(const struct frame_header *hdr, static enum state loading_commands(const struct frame_header *hdr,
const uint8_t *cmd, enum state state, const uint8_t *cmd, enum state state,
struct context *ctx); struct context *ctx);
static void run(const struct context *ctx);
#if !defined(SIMULATION) #if !defined(SIMULATION)
static uint32_t xorwow(uint32_t state, uint32_t acc); static uint32_t xorwow(uint32_t state, uint32_t acc);
#endif #endif
static void scramble_ram(void); static void scramble_ram(void);
static int compute_app_digest(uint8_t *digest); static int compute_app_digest(uint8_t *digest);
static int load_flash_app(struct partition_table *part_table, uint8_t digest[32]); static int load_flash_app(struct partition_table *part_table, uint8_t digest[32]);
static enum state start_where(struct context *ctx);
static void print_hw_version(void) static void print_hw_version(void)
{ {
@ -309,7 +321,7 @@ static enum state loading_commands(const struct frame_header *hdr,
memcpy_s(&rsp[1], CMDSIZE - 1, &ctx->digest, 32); memcpy_s(&rsp[1], CMDSIZE - 1, &ctx->digest, 32);
fwreply(*hdr, FW_RSP_LOAD_APP_DATA_READY, rsp); fwreply(*hdr, FW_RSP_LOAD_APP_DATA_READY, rsp);
state = FW_STATE_RUN; state = FW_STATE_CDI;
break; break;
} }
@ -331,6 +343,9 @@ static enum state loading_commands(const struct frame_header *hdr,
static void jump_to_app(void) static void jump_to_app(void)
{ {
/* Start of app is always at the beginning of RAM */
*app_addr = TK1_RAM_BASE;
debug_puts("Flipping to app mode!\n"); debug_puts("Flipping to app mode!\n");
debug_puts("Jumping to "); debug_puts("Jumping to ");
debug_putinthex(*app_addr); debug_putinthex(*app_addr);
@ -387,14 +402,8 @@ static int load_flash_app(struct partition_table *part_table, uint8_t digest[32]
return 0; return 0;
} }
static void run_flash(const struct context *ctx, struct partition_table *part_table) static enum state auth_flash_app(const struct context *ctx, struct partition_table *part_table)
{ {
/* At this point we expect an app to be loaded into RAM */
*app_addr = TK1_RAM_BASE;
// CDI = hash(uds, hash(app), uss)
compute_cdi(ctx->digest, ctx->use_uss, ctx->uss);
if (part_table->pre_app_data.status == PRE_LOADED_STATUS_PRESENT) { if (part_table->pre_app_data.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.auth);
@ -404,21 +413,11 @@ static void run_flash(const struct context *ctx, struct partition_table *part_ta
if (!auth_app_authenticate(&part_table->pre_app_data.auth)) { if (!auth_app_authenticate(&part_table->pre_app_data.auth)) {
debug_puts("!Authenticated\n"); debug_puts("!Authenticated\n");
assert(1 == 2);
return FW_STATE_FAIL;
} }
jump_to_app(); return FW_STATE_START;
}
static void run(const struct context *ctx)
{
/* At this point we expect an app to be loaded into RAM */
*app_addr = TK1_RAM_BASE;
// CDI = hash(uds, hash(app), uss)
compute_cdi(ctx->digest, ctx->use_uss, ctx->uss);
jump_to_app();
} }
#if !defined(SIMULATION) #if !defined(SIMULATION)
@ -464,6 +463,49 @@ static int compute_app_digest(uint8_t *digest)
*app_size, &b2s_ctx); *app_size, &b2s_ctx);
} }
static enum state start_where(struct context *ctx)
{
// Where do we start? Read resetinfo 'startfrom'
switch (*startfrom) {
case START_FLASH1:
ctx->flash_slot = 1;
return FW_STATE_LOAD_FLASH;
case START_FLASH2:
ctx->flash_slot = 2;
return FW_STATE_LOAD_FLASH;
case START_FLASH1_VER:
ctx->flash_slot = 1;
ctx->verify = true;
// ctx.ver_digest = ...
return FW_STATE_LOAD_FLASH;
case START_FLASH2_VER:
ctx->flash_slot = 2;
ctx->verify = true;
// ctx.ver_digest = ...
return FW_STATE_LOAD_FLASH;
case START_CLIENT:
return FW_STATE_WAITCOMMAND;
case START_CLIENT_VER:
ctx->verify = true;
return FW_STATE_WAITCOMMAND;
default:
debug_puts("Unknown startfrom\n");
return FW_STATE_FAIL;
}
}
int main(void) int main(void)
{ {
struct context ctx = {0}; struct context ctx = {0};
@ -519,12 +561,13 @@ int main(void)
// TODO Just start something from flash without looking in // TODO Just start something from flash without looking in
// FW_RAM. // FW_RAM.
state = FW_STATE_RUN_FLASH; state = FW_STATE_LOAD_FLASH;
for (;;) { for (;;) {
switch (state) { switch (state) {
case FW_STATE_INITIAL: case FW_STATE_INITIAL:
// Where do we start? Read resetinfo 'startfrom' state = start_where(&ctx);
break;
case FW_STATE_WAITCOMMAND: case FW_STATE_WAITCOMMAND:
if (readcommand(&hdr, cmd, state) == -1) { if (readcommand(&hdr, cmd, state) == -1) {
@ -547,11 +590,14 @@ int main(void)
state = loading_commands(&hdr, cmd, state, &ctx); state = loading_commands(&hdr, cmd, state, &ctx);
break; break;
case FW_STATE_RUN: case FW_STATE_CDI:
run(&ctx); // CDI = hash(uds, hash(app), uss)
break; // This is never reached! compute_cdi(ctx.digest, ctx.use_uss, ctx.uss);
case FW_STATE_RUN_FLASH: state = FW_STATE_START;
break;
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.status = PRE_LOADED_STATUS_PRESENT;
@ -562,8 +608,15 @@ int main(void)
break; break;
} }
run_flash(&ctx, &part_table); // CDI = hash(uds, hash(app), uss)
break; // This is never reached! compute_cdi(ctx.digest, ctx.use_uss, ctx.uss);
state = auth_flash_app(&ctx, &part_table);
break;
case FW_STATE_START:
jump_to_app();
break; // Not reached
case FW_STATE_FAIL: case FW_STATE_FAIL:
// fallthrough // fallthrough

View file

@ -10,8 +10,9 @@ enum state {
FW_STATE_INITIAL, FW_STATE_INITIAL,
FW_STATE_WAITCOMMAND, FW_STATE_WAITCOMMAND,
FW_STATE_LOADING, FW_STATE_LOADING,
FW_STATE_RUN, FW_STATE_CDI,
FW_STATE_RUN_FLASH, FW_STATE_LOAD_FLASH,
FW_STATE_START,
FW_STATE_FAIL, FW_STATE_FAIL,
FW_STATE_MAX, FW_STATE_MAX,
}; };