mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-08-14 17:35:41 -04:00
Experiment with new state machine
This commit is contained in:
parent
6ef1b1c659
commit
ab12c201c4
2 changed files with 87 additions and 33 deletions
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue