tillitis-key/hw/application_fpga/fw/tk1/preload_app.c

134 lines
3.3 KiB
C
Raw Normal View History

2024-09-03 09:27:38 -04:00
// Copyright (C) 2024 - Tillitis AB
// SPDX-License-Identifier: GPL-2.0-only
#include "preload_app.h"
#include "../tk1_mem.h"
#include "flash.h"
#include "lib.h"
#include "mgmt_app.h"
2024-09-03 09:27:38 -04:00
#include "partition_table.h"
2024-09-19 02:52:42 -04:00
#include "htif.h"
2024-09-03 09:27:38 -04:00
#include <stdbool.h>
2024-09-19 02:52:42 -04:00
#include <stddef.h>
2024-09-03 09:27:38 -04:00
#include <stdint.h>
/* Returns non-zero if the app is valid */
bool preload_check_valid_app(partition_table_t *part_table)
{
if (part_table->pre_app_data.status == 0x00 &&
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;
}
/* Loads a preloaded app from flash to app RAM */
int preload_start(partition_table_t *part_table)
{
/*Check for a valid app in flash */
if (!preload_check_valid_app(part_table)) {
return -1;
}
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);
return ret;
}
2024-09-19 02:52:42 -04:00
/* 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)
2024-09-03 09:27:38 -04:00
{
2024-09-19 02:52:42 -04:00
/* Check if we are allowed to store */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
return -1;
}
2024-09-03 09:27:38 -04:00
2024-09-19 02:52:42 -04:00
/* 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,
uint32_t *uss, size_t app_size)
{
/* Check if we are allowed to store */
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
return -1;
}
2024-09-19 02:52:42 -04:00
/* Check for a valid app in flash, bale out if it already exists */
2024-09-03 09:27:38 -04:00
if (preload_check_valid_app(part_table)) {
return -1;
}
2024-09-19 02:52:42 -04:00
part_table->pre_app_data.size = app_size;
part_table->pre_app_data.status = 0x02; /* Stored but not yet authenticated */
part_table_write(part_table);
/* Force a restart to authenticate the stored app */
2024-09-03 09:27:38 -04:00
return 0;
}
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;
}
2024-09-03 09:27:38 -04:00
/*Check for a valid app in flash */
if (!preload_check_valid_app(part_table)) {
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;
memset(part_table->pre_app_data.auth.nonce, 0x00,
sizeof(part_table->pre_app_data.auth.nonce));
memset(part_table->pre_app_data.auth.authentication_digest, 0x00,
sizeof(part_table->pre_app_data.auth.authentication_digest));
part_table_write(part_table);
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
return 0;
}