mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-04-20 15:25:55 -04:00
fw: Remove TK1_SYSCALL_REG_MGMT
Validate preload API access using the fixed, pre-calculated app digest instead of letting an app register itself as a management app.
This commit is contained in:
parent
5308544064
commit
0ece0c00f1
@ -21,11 +21,6 @@ int install_app(uint8_t secret_key[64])
|
||||
uint8_t app_signature[64];
|
||||
size_t app_size = sizeof(blink);
|
||||
|
||||
if (syscall(TK1_SYSCALL_REG_MGMT, 0, 0, 0) < 0) {
|
||||
puts(IO_CDC, "couldn't register as mgmt\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (syscall(TK1_SYSCALL_PRELOAD_DELETE, 0, 0, 0) < 0) {
|
||||
puts(IO_CDC, "couldn't delete preloaded app\r\n");
|
||||
return -1;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "partition_table.h"
|
||||
#include "preload_app.h"
|
||||
#include "proto.h"
|
||||
#include "mgmt_app.h"
|
||||
#include "state.h"
|
||||
#include "syscall_enable.h"
|
||||
#include "resetinfo.h"
|
||||
@ -42,19 +43,7 @@ static volatile struct reset *resetinfo = (volatile struct reset *)TK1_
|
||||
|
||||
struct partition_table part_table;
|
||||
|
||||
// Locked down what app can start from first flash slot to be exactly
|
||||
// this size, producing this digest.
|
||||
//
|
||||
// To update this, compute the BLAKE2s digest of the app.bin and
|
||||
// insert the size in bytes.
|
||||
#define APP_SIZE_SLOT0 21684
|
||||
// BLAKE2s digest of testloadapp.bin
|
||||
const uint8_t allowed_app_digest[32] = {
|
||||
0x3a, 0x34, 0x6f, 0x1f, 0xb7, 0x7f, 0xa6, 0x71, 0x9b, 0x69, 0x8,
|
||||
0x36, 0xa0, 0x5, 0xe, 0x26, 0x48, 0x8d, 0xab, 0x6a, 0x51, 0xa6,
|
||||
0xe1, 0x18, 0x53, 0xa3, 0x64, 0xc6, 0x5b, 0x42, 0x49, 0xb7,
|
||||
};
|
||||
|
||||
// Context for the loading of a TKey program
|
||||
struct context {
|
||||
uint32_t left; // Bytes left to receive
|
||||
@ -600,9 +589,8 @@ int main(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx.flash_slot == 0) {
|
||||
print_digest(allowed_app_digest);
|
||||
if (!memeq(ctx.digest, allowed_app_digest, 32)) {
|
||||
if (ctx.flash_slot != 1) {
|
||||
if (mgmt_app_init(ctx.digest) != 0) {
|
||||
puts(IO_CDC, "app not allowed!\r\n");
|
||||
assert(1 == 2);
|
||||
}
|
||||
|
@ -3,73 +3,34 @@
|
||||
|
||||
#include <tkey/lib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mgmt_app.h"
|
||||
#include "auth_app.h"
|
||||
#include "partition_table.h"
|
||||
|
||||
/* Returns true if an management app is already registered */
|
||||
static bool mgmt_app_registered(struct management_app_metadata *mgmt_table)
|
||||
{
|
||||
// Locked down what app can start from first flash slot to be exactly
|
||||
// this size, producing this digest.
|
||||
//
|
||||
// To update this, compute the BLAKE2s digest of the app.bin
|
||||
// BLAKE2s digest of testloadapp.bin
|
||||
static const uint8_t allowed_app_digest[32] = {
|
||||
0x88, 0x87, 0xf6, 0x2f, 0x71, 0x1c, 0x3f, 0xdb,
|
||||
0x8c, 0xf7, 0x77, 0x9f, 0xeb, 0x5f, 0xb9, 0xd4,
|
||||
0x2f, 0xfb, 0xdb, 0x1d, 0xf6, 0xdc, 0x62, 0xff,
|
||||
0x91, 0x00, 0x1f, 0x5d, 0x98, 0xb3, 0x50, 0xd4,
|
||||
};
|
||||
static uint8_t current_app_digest[32];
|
||||
|
||||
if (mgmt_table->status == 0x00) {
|
||||
/* No management app registered */
|
||||
return false;
|
||||
// TODO: Should we also check nonce, authentication digest for
|
||||
// non-zero?
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Authenticate an management app */
|
||||
bool mgmt_app_authenticate(struct management_app_metadata *mgmt_table)
|
||||
{
|
||||
if (!mgmt_app_registered(mgmt_table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return auth_app_authenticate(&mgmt_table->auth);
|
||||
}
|
||||
|
||||
/* Register an management app, returns zero on success */
|
||||
int mgmt_app_register(struct partition_table *part_table)
|
||||
{
|
||||
/* Check if the current app is the mgmt app */
|
||||
if (mgmt_app_authenticate(&part_table->mgmt_app_data)) {
|
||||
int mgmt_app_init(uint8_t app_digest[32]) {
|
||||
if (memeq(app_digest, allowed_app_digest, 32)) {
|
||||
memcpy_s(current_app_digest, sizeof(current_app_digest), app_digest, 32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if another management app is registered */
|
||||
if (mgmt_app_registered(&part_table->mgmt_app_data)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auth_app_create(&part_table->mgmt_app_data.auth);
|
||||
part_table->mgmt_app_data.status = 0x01;
|
||||
|
||||
part_table_write(part_table);
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Unregister the currently registered app, returns zero on success */
|
||||
int mgmt_app_unregister(struct partition_table *part_table)
|
||||
/* Authenticate an management app */
|
||||
bool mgmt_app_authenticate(void)
|
||||
{
|
||||
/* Only the management app should be able to unregister itself */
|
||||
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
part_table->mgmt_app_data.status = 0;
|
||||
|
||||
memset(part_table->mgmt_app_data.auth.nonce, 0x00,
|
||||
sizeof(part_table->mgmt_app_data.auth.nonce));
|
||||
|
||||
memset(part_table->mgmt_app_data.auth.authentication_digest, 0x00,
|
||||
sizeof(part_table->mgmt_app_data.auth.authentication_digest));
|
||||
|
||||
part_table_write(part_table);
|
||||
|
||||
return 0;
|
||||
return memeq(current_app_digest, allowed_app_digest, 32) != 0;
|
||||
}
|
||||
|
@ -4,12 +4,10 @@
|
||||
#ifndef MGMT_APP_H
|
||||
#define MGMT_APP_H
|
||||
|
||||
#include "partition_table.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
bool mgmt_app_authenticate(struct management_app_metadata *mgmt_table);
|
||||
int mgmt_app_register(struct partition_table *part_table);
|
||||
int mgmt_app_unregister(struct partition_table *part_table);
|
||||
int mgmt_app_init(uint8_t app_digest[32]);
|
||||
bool mgmt_app_authenticate(void);
|
||||
|
||||
#endif
|
||||
|
@ -39,26 +39,14 @@
|
||||
#define ADDR_PRE_LOADED_APP_0 (ADDR_PARTITION_TABLE + SIZE_PARTITION_TABLE)
|
||||
#define SIZE_PRE_LOADED_APP 0x20000UL // 128KiB
|
||||
|
||||
// Pre-loaded app present and authenticated
|
||||
#define PRE_LOADED_STATUS_AUTH 0x01
|
||||
// Pre-loaded app present but not yet authenticated
|
||||
#define PRE_LOADED_STATUS_PRESENT 0x02
|
||||
|
||||
#define ADDR_STORAGE_AREA (ADDR_PRE_LOADED_APP_0 + (N_PRELOADED_APP * SIZE_PRE_LOADED_APP))
|
||||
#define SIZE_STORAGE_AREA 0x20000UL // 128KiB
|
||||
#define N_STORAGE_AREA 4
|
||||
|
||||
#define EMPTY_AREA
|
||||
|
||||
/* Partition Table */
|
||||
/*- Table header */
|
||||
/* - 1 bytes Version */
|
||||
/**/
|
||||
/*- Management device app */
|
||||
/* - Status. */
|
||||
/* - 16 byte random nonce. */
|
||||
/* - 16 byte authentication digest. */
|
||||
/**/
|
||||
/*- Pre-loaded device app 1 */
|
||||
/* - 4 bytes length. */
|
||||
/* - 32 bytes digest. */
|
||||
@ -81,11 +69,6 @@ struct auth_metadata {
|
||||
uint8_t authentication_digest[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct management_app_metadata {
|
||||
uint8_t status;
|
||||
struct auth_metadata auth;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct pre_loaded_app_metadata {
|
||||
uint32_t size;
|
||||
uint8_t digest[32];
|
||||
@ -105,7 +88,6 @@ struct table_header {
|
||||
|
||||
struct partition_table {
|
||||
struct table_header header;
|
||||
struct management_app_metadata mgmt_app_data;
|
||||
struct pre_loaded_app_metadata pre_app_data[N_PRELOADED_APP];
|
||||
struct app_storage_area app_storage[N_STORAGE_AREA];
|
||||
} __attribute__((packed));
|
||||
|
@ -56,7 +56,7 @@ int preload_store(struct partition_table *part_table, uint32_t offset,
|
||||
uint8_t *data, size_t size, uint8_t to_slot)
|
||||
{
|
||||
/* Check if we are allowed to store */
|
||||
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
|
||||
if (!mgmt_app_authenticate()) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ int preload_store_finalize(struct partition_table *part_table, size_t app_size,
|
||||
}
|
||||
|
||||
/* Check if we are allowed to store */
|
||||
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
|
||||
if (!mgmt_app_authenticate()) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ int preload_delete(struct partition_table *part_table, uint8_t slot)
|
||||
}
|
||||
|
||||
/* Check if we are allowed to deleted */
|
||||
if (!mgmt_app_authenticate(&part_table->mgmt_app_data)) {
|
||||
if (!mgmt_app_authenticate()) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
@ -94,9 +94,6 @@ int32_t syscall_handler(uint32_t number, uint32_t arg1, uint32_t arg2,
|
||||
case TK1_SYSCALL_PRELOAD_GET_DIGSIG:
|
||||
return preload_get_digsig(&part_table, (uint8_t *)arg1, (uint8_t *)arg2, 1);
|
||||
|
||||
case TK1_SYSCALL_REG_MGMT:
|
||||
return mgmt_app_register(&part_table);
|
||||
|
||||
default:
|
||||
assert(1 == 2);
|
||||
}
|
||||
|
@ -13,13 +13,6 @@ type PartTable struct {
|
||||
Header struct {
|
||||
Version uint8
|
||||
}
|
||||
ManagementAppData struct {
|
||||
Status uint8
|
||||
Auth struct {
|
||||
Nonce [16]uint8
|
||||
AuthDigest [16]uint8
|
||||
}
|
||||
}
|
||||
PreLoadedAppData [2]struct {
|
||||
Size uint32
|
||||
Digest [32]uint8
|
||||
@ -39,7 +32,7 @@ type PartTable struct {
|
||||
type Flash struct {
|
||||
Bitstream [0x20000]uint8
|
||||
PartitionTable PartTable
|
||||
PartitionTablePadding [64*1024 - 398]uint8
|
||||
PartitionTablePadding [64*1024 - 365]uint8
|
||||
PreLoadedApp0 [0x20000]uint8
|
||||
PreLoadedApp1 [0x20000]uint8
|
||||
AppStorage [4][0x20000]uint8
|
||||
@ -93,10 +86,6 @@ func printPartTableJson(tbl PartTable) {
|
||||
func printPartTableCondensed(tbl PartTable) {
|
||||
fmt.Printf("Header\n")
|
||||
fmt.Printf(" Version : %d\n", tbl.Header.Version)
|
||||
fmt.Printf("Management App\n")
|
||||
fmt.Printf(" Status : %d\n", tbl.ManagementAppData.Status)
|
||||
fmt.Printf(" Auth.Nonce : %x\n", tbl.ManagementAppData.Auth.Nonce)
|
||||
fmt.Printf(" Auth.AuthDigest : %x\n", tbl.ManagementAppData.Auth.AuthDigest)
|
||||
|
||||
for i, appData := range tbl.PreLoadedAppData {
|
||||
fmt.Printf("Preloaded App %d\n", i)
|
||||
|
Loading…
x
Reference in New Issue
Block a user