diff --git a/hw/application_fpga/fw/tk1/preload_app.c b/hw/application_fpga/fw/tk1/preload_app.c index db5ca20..1d78808 100644 --- a/hw/application_fpga/fw/tk1/preload_app.c +++ b/hw/application_fpga/fw/tk1/preload_app.c @@ -4,11 +4,13 @@ #include "preload_app.h" #include "../tk1_mem.h" #include "flash.h" +#include "htif.h" #include "lib.h" #include "mgmt_app.h" #include "partition_table.h" #include +#include #include /* Returns non-zero if the app is valid */ @@ -19,8 +21,6 @@ bool preload_check_valid_app(partition_table_t *part_table) part_table->pre_app_data.size == 0) { /*No valid app*/ return false; - // TODO: Should we also check nonce, authentication digest for - // non-zero? } return true; @@ -35,9 +35,6 @@ int preload_start(partition_table_t *part_table) } uint8_t *loadaddr = (uint8_t *)TK1_RAM_BASE; - // TODO: Check authentication digest - // TODO: Should this function set *app_size? - /* Read from flash, straight into RAM */ int ret = flash_read_data(ADDR_PRE_LOADED_APP, loadaddr, part_table->pre_app_data.size); @@ -45,22 +42,68 @@ int preload_start(partition_table_t *part_table) return ret; } -int preload_store(partition_table_t *part_table) +/* Expects to receive chunks of data up to 4096 bytes to store into the + * preloaded area. The offset needs to be kept and updated between each call. + * Once done, call preload_store_finalize() with the last parameters. + * */ +int preload_store(partition_table_t *part_table, uint32_t offset, uint8_t *data, + size_t size) { - // TODO: Can reuse the app loading context in main, to keep track of - // where to store. - // Most likely needs to aggregate some data, before it writes to flash. - - /* Check if we are allowed to deleted */ + /* Check if we are allowed to store */ if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { - return -1; + return -3; } - /*Check for a valid app in flash, bale out if it already exists */ + /* Check for a valid app in flash, bale out if it already exists */ if (preload_check_valid_app(part_table)) { return -1; } + if ((offset + size) > SIZE_PRE_LOADED_APP || size > 4096) { + /* Writing outside of area */ + return -2; + } + + uint32_t address = ADDR_PRE_LOADED_APP + offset; + + htif_puts("preload_store: write to addr: "); + htif_putinthex(address); + htif_lf(); + + return flash_write_data(address, data, size); +} + +int preload_store_finalize(partition_table_t *part_table, bool use_uss, + uint8_t *uss, size_t app_size) +{ + /* Check if we are allowed to store */ + if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { + return -3; + } + + /* Check for a valid app in flash, bale out if it already exists */ + if (preload_check_valid_app(part_table)) { + return -1; + } + + // TODO: Maybe add the uss fields + + if (app_size == 0 || app_size > SIZE_PRE_LOADED_APP) { + return -2; + } + + part_table->pre_app_data.size = app_size; + part_table->pre_app_data.status = + 0x02; /* Stored but not yet authenticated */ + htif_puts("preload_*_final: size: "); + htif_putinthex(app_size); + htif_lf(); + + part_table_write(part_table); + + /* Force a restart to authenticate the stored app */ + /* TODO: Should this be done by the management app or by firmware? */ + return 0; } @@ -68,7 +111,7 @@ int preload_delete(partition_table_t *part_table) { /* Check if we are allowed to deleted */ if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) { - return -1; + return -3; } /*Check for a valid app in flash */ @@ -87,6 +130,7 @@ int preload_delete(partition_table_t *part_table) part_table_write(part_table); + /* Assumes the area is 64 KiB block aligned */ flash_block_64_erase(ADDR_PRE_LOADED_APP); // Erase first 64 KB block flash_block_64_erase(ADDR_PRE_LOADED_APP + 0x10000); // Erase second 64 KB block diff --git a/hw/application_fpga/fw/tk1/preload_app.h b/hw/application_fpga/fw/tk1/preload_app.h index ffff4ba..e9375ef 100644 --- a/hw/application_fpga/fw/tk1/preload_app.h +++ b/hw/application_fpga/fw/tk1/preload_app.h @@ -6,11 +6,15 @@ #include "partition_table.h" #include +#include #include bool preload_check_valid_app(partition_table_t *part_table); int preload_start(partition_table_t *part_table); -int preload_store(partition_table_t *part_table); +int preload_store(partition_table_t *part_table, uint32_t offset, uint8_t *data, + size_t size); +int preload_store_finalize(partition_table_t *part_table, bool use_uss, + uint8_t *uss, size_t app_size); int preload_delete(partition_table_t *part_table); #endif diff --git a/hw/application_fpga/fw/tk1/syscall.c b/hw/application_fpga/fw/tk1/syscall.c index 514c3c4..4223cea 100644 --- a/hw/application_fpga/fw/tk1/syscall.c +++ b/hw/application_fpga/fw/tk1/syscall.c @@ -35,7 +35,13 @@ int syscall(syscall_t *ctx) break; case PRELOAD_STORE: - return preload_store(&part_table); + return preload_store(&part_table, ctx->offset, ctx->data, + ctx->size); + break; + + case PRELOAD_STORE_FINALIZE: + return preload_store_finalize(&part_table, ctx->offset, + ctx->data, ctx->size); break; case PRELOAD_DELETE: diff --git a/hw/application_fpga/fw/tk1/syscall.h b/hw/application_fpga/fw/tk1/syscall.h index 1ab7bd6..4eb0812 100644 --- a/hw/application_fpga/fw/tk1/syscall.h +++ b/hw/application_fpga/fw/tk1/syscall.h @@ -25,6 +25,7 @@ enum syscall_cmd { WRITE_DATA, READ_DATA, PRELOAD_STORE, + PRELOAD_STORE_FINALIZE, PRELOAD_DELETE, MGMT_APP_REGISTER, MGMT_APP_UNREGISTER,