mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-04-21 15:46:31 -04:00
testloadapp: Add app for testing preloaded app functionality
This commit is contained in:
parent
403013a0e8
commit
7e859bd06a
73
hw/application_fpga/fw/testloadapp/Makefile
Normal file
73
hw/application_fpga/fw/testloadapp/Makefile
Normal file
@ -0,0 +1,73 @@
|
||||
P := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
LIBDIR ?= ../../tkey-libs
|
||||
OBJCOPY ?= llvm-objcopy
|
||||
CC = clang
|
||||
CFLAGS = \
|
||||
-target riscv32-unknown-none-elf \
|
||||
-march=rv32iczmmul \
|
||||
-mabi=ilp32 \
|
||||
-mcmodel=medany \
|
||||
-static \
|
||||
-std=gnu99 \
|
||||
-Os \
|
||||
-ffast-math \
|
||||
-fno-common \
|
||||
-fno-builtin-printf \
|
||||
-fno-builtin-putchar \
|
||||
-fno-builtin-memcpy \
|
||||
-nostdlib \
|
||||
-mno-relax \
|
||||
-Wall \
|
||||
-Wpedantic \
|
||||
-Wno-language-extension-token \
|
||||
-Werror \
|
||||
-flto \
|
||||
-g \
|
||||
-I $(LIBDIR)/include \
|
||||
-I $(LIBDIR)
|
||||
|
||||
AS = clang
|
||||
|
||||
ASFLAGS = \
|
||||
-target riscv32-unknown-none-elf \
|
||||
-march=rv32iczmmul \
|
||||
-mabi=ilp32 \
|
||||
-mno-relax
|
||||
|
||||
LDFLAGS = \
|
||||
-T $(LIBDIR)/app.lds \
|
||||
-L $(LIBDIR) -lcrt0 -lcommon -lmonocypher -lblake2s
|
||||
|
||||
.PHONY: all
|
||||
all: testloadapp.bin
|
||||
|
||||
# Turn elf into bin for device
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) --input-target=elf32-littleriscv --output-target=binary $^ $@
|
||||
chmod a-x $@
|
||||
|
||||
.PHONY: tkey-libs
|
||||
tkey-libs:
|
||||
make -C $(LIBDIR)
|
||||
|
||||
TESTLOADAPP_FMTFILES = *.[ch]
|
||||
|
||||
TESTLOADAPP_OBJS = \
|
||||
$(P)/main.o \
|
||||
../testapp/syscall.o \
|
||||
|
||||
testloadapp.elf: tkey-libs $(TESTLOADAPP_OBJS)
|
||||
$(CC) $(CFLAGS) $(TESTLOADAPP_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
clang-format --dry-run --ferror-limit=0 $(TESTLOADAPP_FMTFILES)
|
||||
clang-format --verbose -i $(TESTLOADAPP_FMTFILES)
|
||||
|
||||
.PHONY: checkfmt
|
||||
checkfmt:
|
||||
clang-format --dry-run --ferror-limit=0 --Werror $(TESTLOADAPP_FMTFILES)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f testloadapp.bin testloadapp.elf $(TESTLOADAPP_OBJS)
|
28
hw/application_fpga/fw/testloadapp/blink.h
Normal file
28
hw/application_fpga/fw/testloadapp/blink.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef BLINK_APP_H
|
||||
#define BLINK_APP_H
|
||||
|
||||
uint8_t blink[] = {
|
||||
0x81, 0x40, 0x01, 0x41, 0x81, 0x41, 0x01, 0x42, 0x81, 0x42, 0x01, 0x43,
|
||||
0x81, 0x43, 0x01, 0x44, 0x81, 0x44, 0x01, 0x45, 0x81, 0x45, 0x01, 0x46,
|
||||
0x81, 0x46, 0x01, 0x47, 0x81, 0x47, 0x01, 0x48, 0x81, 0x48, 0x01, 0x49,
|
||||
0x81, 0x49, 0x01, 0x4a, 0x81, 0x4a, 0x01, 0x4b, 0x81, 0x4b, 0x01, 0x4c,
|
||||
0x81, 0x4c, 0x01, 0x4d, 0x81, 0x4d, 0x01, 0x4e, 0x81, 0x4e, 0x01, 0x4f,
|
||||
0x81, 0x4f, 0x37, 0x01, 0x02, 0x40, 0x41, 0x11, 0x17, 0x05, 0x00, 0x00,
|
||||
0x13, 0x05, 0x45, 0x0c, 0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0xc5, 0x0b,
|
||||
0x63, 0x57, 0xb5, 0x00, 0x23, 0x20, 0x05, 0x00, 0x11, 0x05, 0xe3, 0x4d,
|
||||
0xb5, 0xfe, 0x97, 0x00, 0x00, 0x00, 0xe7, 0x80, 0xa0, 0x00, 0x00, 0x00,
|
||||
0x41, 0x11, 0x37, 0x05, 0x00, 0xff, 0x11, 0x48, 0xe1, 0x66, 0x13, 0x86,
|
||||
0xf6, 0x69, 0x93, 0x86, 0x06, 0x6a, 0x09, 0x47, 0x85, 0x47, 0x23, 0x22,
|
||||
0x05, 0x03, 0x02, 0xc2, 0x92, 0x45, 0x63, 0x68, 0xb6, 0x00, 0x92, 0x45,
|
||||
0x85, 0x05, 0x2e, 0xc2, 0x92, 0x45, 0xe3, 0xec, 0xd5, 0xfe, 0x58, 0xd1,
|
||||
0x02, 0xc4, 0xa2, 0x45, 0x63, 0x68, 0xb6, 0x00, 0xa2, 0x45, 0x85, 0x05,
|
||||
0x2e, 0xc4, 0xa2, 0x45, 0xe3, 0xec, 0xd5, 0xfe, 0x5c, 0xd1, 0x02, 0xc6,
|
||||
0xb2, 0x45, 0xe3, 0x66, 0xb6, 0xfc, 0xb2, 0x45, 0x85, 0x05, 0x2e, 0xc6,
|
||||
0xb2, 0x45, 0xe3, 0xec, 0xd5, 0xfe, 0x75, 0xbf, 0x19, 0xca, 0x2a, 0x96,
|
||||
0xaa, 0x86, 0x03, 0xc7, 0x05, 0x00, 0x23, 0x80, 0xe6, 0x00, 0x85, 0x06,
|
||||
0x85, 0x05, 0xe3, 0x9a, 0xc6, 0xfe, 0x82, 0x80, 0x11, 0xca, 0x0a, 0x06,
|
||||
0x2a, 0x96, 0xaa, 0x86, 0x98, 0x41, 0x98, 0xc2, 0x91, 0x06, 0x91, 0x05,
|
||||
0xe3, 0x9c, 0xc6, 0xfe, 0x82, 0x80, 0x01, 0xca, 0x2a, 0x96, 0xaa, 0x86,
|
||||
0x23, 0x80, 0xb6, 0x00, 0x85, 0x06, 0xe3, 0x9d, 0xc6, 0xfe, 0x82, 0x80};
|
||||
|
||||
#endif
|
218
hw/application_fpga/fw/testloadapp/main.c
Normal file
218
hw/application_fpga/fw/testloadapp/main.c
Normal file
@ -0,0 +1,218 @@
|
||||
#include <blake2s/blake2s.h>
|
||||
#include <monocypher/monocypher-ed25519.h>
|
||||
#include <stdint.h>
|
||||
#include <tkey/debug.h>
|
||||
#include <tkey/lib.h>
|
||||
#include <tkey/tk1_mem.h>
|
||||
|
||||
#include "../testapp/syscall.h"
|
||||
#include "../tk1/resetinfo.h"
|
||||
#include "../tk1/syscall_num.h"
|
||||
#include "blink.h"
|
||||
#include "tkey/assert.h"
|
||||
|
||||
// clang-format off
|
||||
static volatile uint32_t *cdi = (volatile uint32_t *) TK1_MMIO_TK1_CDI_FIRST;
|
||||
// clang-format on
|
||||
|
||||
int install_app(uint8_t secret_key[64])
|
||||
{
|
||||
uint8_t app_digest[32];
|
||||
uint8_t app_signature[64];
|
||||
size_t app_size = sizeof(blink);
|
||||
int ret = 0;
|
||||
|
||||
ret = syscall(TK1_SYSCALL_PRELOAD_DELETE, 0, 0, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
puts(IO_CDC, "couldn't delete preloaded app. error: 0x");
|
||||
putinthex(IO_CDC, ret);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = syscall(TK1_SYSCALL_PRELOAD_STORE, 0, (uint32_t)blink,
|
||||
sizeof(blink));
|
||||
|
||||
if (ret != 0) {
|
||||
puts(IO_CDC, "couldn't store app, error: 0x");
|
||||
putinthex(IO_CDC, ret);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
puts(IO_CDC, "blink: ");
|
||||
putinthex(IO_CDC, (uint32_t)blink);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "blink[0]: ");
|
||||
putinthex(IO_CDC, blink[0]);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "sizeof(blink): ");
|
||||
putinthex(IO_CDC, sizeof(blink));
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
if (blake2s(app_digest, 32, NULL, 0, blink, sizeof(blink)) != 0) {
|
||||
puts(IO_CDC, "couldn't compute digest\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
crypto_ed25519_sign(app_signature, secret_key, app_digest,
|
||||
sizeof(app_digest));
|
||||
|
||||
puts(IO_CDC, "app_digest:\r\n");
|
||||
hexdump(IO_CDC, app_digest, sizeof(app_digest));
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "app_signature:\r\n");
|
||||
hexdump(IO_CDC, app_signature, sizeof(app_signature));
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "secret_key:\r\n");
|
||||
hexdump(IO_CDC, secret_key, 64);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
ret = syscall(TK1_SYSCALL_PRELOAD_STORE_FIN, app_size,
|
||||
(uint32_t)app_digest, (uint32_t)app_signature);
|
||||
|
||||
if (ret != 0) {
|
||||
puts(IO_CDC, "couldn't finalize storing app, error:");
|
||||
putinthex(IO_CDC, ret);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int verify(uint8_t pubkey[32])
|
||||
{
|
||||
uint8_t app_digest[32];
|
||||
uint8_t app_signature[64];
|
||||
int ret = 0;
|
||||
|
||||
// pubkey we already have
|
||||
// read signature
|
||||
// read digest
|
||||
ret = syscall(TK1_SYSCALL_PRELOAD_GET_DIGSIG, (uint32_t)app_digest,
|
||||
(uint32_t)app_signature, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
puts(IO_CDC, "couldn't get digsig, error:");
|
||||
putinthex(IO_CDC, ret);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
puts(IO_CDC, "app_digest:\r\n");
|
||||
hexdump(IO_CDC, app_digest, sizeof(app_digest));
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "app_signature:\r\n");
|
||||
hexdump(IO_CDC, app_signature, sizeof(app_signature));
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "pubkey:\r\n");
|
||||
hexdump(IO_CDC, pubkey, 32);
|
||||
puts(IO_CDC, "\r\n");
|
||||
|
||||
puts(IO_CDC, "Checking signature...\r\n");
|
||||
|
||||
if (crypto_ed25519_check(app_signature, pubkey, app_digest,
|
||||
sizeof(app_digest)) != 0) {
|
||||
puts(IO_CDC, "signature check failed\r\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
puts(IO_CDC, "Resetting into pre loaded app (slot 2)...\r\n");
|
||||
|
||||
// syscall reset flash1_ver with app_digest
|
||||
struct reset rst;
|
||||
rst.type = START_FLASH1_VER;
|
||||
memcpy_s(rst.app_digest, sizeof(rst.app_digest), app_digest,
|
||||
sizeof(app_digest));
|
||||
memset(rst.next_app_data, 0, sizeof(rst.next_app_data));
|
||||
|
||||
syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, 0, 0);
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
void reset_from_client(void)
|
||||
{
|
||||
struct reset rst = {0};
|
||||
|
||||
rst.type = START_CLIENT;
|
||||
|
||||
syscall(TK1_SYSCALL_RESET, (uint32_t)&rst, 0, 0);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t secret_key[64];
|
||||
uint8_t pubkey[32];
|
||||
enum ioend endpoint;
|
||||
uint8_t available;
|
||||
uint8_t in = 0;
|
||||
|
||||
// Generate a key pair from CDI
|
||||
crypto_ed25519_key_pair(secret_key, pubkey, (uint8_t *)cdi);
|
||||
|
||||
if (readselect(IO_CDC, &endpoint, &available) < 0) {
|
||||
// readselect failed! I/O broken? Just redblink.
|
||||
assert(1 == 2);
|
||||
}
|
||||
|
||||
if (read(IO_CDC, &in, 1, 1) < 0) {
|
||||
// read failed! I/O broken? Just redblink.
|
||||
assert(1 == 2);
|
||||
}
|
||||
|
||||
puts(IO_CDC, "Hello from testloadapp! 0 = install app in slot 1, 1 = "
|
||||
"verify app, 2 == load app from client\r\n");
|
||||
|
||||
for (;;) {
|
||||
if (readselect(IO_CDC, &endpoint, &available) < 0) {
|
||||
// readselect failed! I/O broken? Just redblink.
|
||||
assert(1 == 2);
|
||||
}
|
||||
|
||||
if (read(IO_CDC, &in, 1, 1) < 0) {
|
||||
// read failed! I/O broken? Just redblink.
|
||||
assert(1 == 2);
|
||||
}
|
||||
|
||||
switch (in) {
|
||||
case '0':
|
||||
if (install_app(secret_key) < 0) {
|
||||
puts(IO_CDC, "Failed to install app\r\n");
|
||||
} else {
|
||||
puts(IO_CDC, "Installed app!\r\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '1':
|
||||
if (verify(pubkey) < 0) {
|
||||
puts(IO_CDC, "Failed to verify app\r\n");
|
||||
} else {
|
||||
puts(IO_CDC, "Verified app!\r\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '2':
|
||||
reset_from_client();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user