From 97582da97798c73565817deb3b4e407ea8f63eef Mon Sep 17 00:00:00 2001 From: Michael Cardell Widerkrantz Date: Wed, 19 Mar 2025 17:32:38 +0100 Subject: [PATCH] Add start of test app for installing and verifying flash app Currently needs LIBDIR set to tkey-libs with blake2s(). --- hw/application_fpga/fw/testloadapp/Makefile | 75 +++++++++++ hw/application_fpga/fw/testloadapp/blink.h | 24 ++++ hw/application_fpga/fw/testloadapp/main.c | 132 ++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 hw/application_fpga/fw/testloadapp/Makefile create mode 100644 hw/application_fpga/fw/testloadapp/blink.h create mode 100644 hw/application_fpga/fw/testloadapp/main.c diff --git a/hw/application_fpga/fw/testloadapp/Makefile b/hw/application_fpga/fw/testloadapp/Makefile new file mode 100644 index 0000000..3e13dc7 --- /dev/null +++ b/hw/application_fpga/fw/testloadapp/Makefile @@ -0,0 +1,75 @@ +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 + +.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 = \ + $(P)/main.c + +TESTLOADAPP_OBJS = \ + $(P)/main.o \ + ../testapp/syscall.o \ + ../tk1/blake2s/blake2s.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) diff --git a/hw/application_fpga/fw/testloadapp/blink.h b/hw/application_fpga/fw/testloadapp/blink.h new file mode 100644 index 0000000..28f3529 --- /dev/null +++ b/hw/application_fpga/fw/testloadapp/blink.h @@ -0,0 +1,24 @@ +#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 diff --git a/hw/application_fpga/fw/testloadapp/main.c b/hw/application_fpga/fw/testloadapp/main.c new file mode 100644 index 0000000..555d922 --- /dev/null +++ b/hw/application_fpga/fw/testloadapp/main.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include "../testapp/syscall.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); + + if (syscall(TK1_SYSCALL_REG_MGMT, 0, 0, 0) < 0) { + puts(IO_CDC, "couldn't register as mgmt\r\n"); + return -1; + } + + int err = syscall(TK1_SYSCALL_PRELOAD_STORE, 0, (uint32_t)blink, + sizeof(blink)); + + if (err < 0) { + puts(IO_CDC, "couldn't store app, error: "); + putinthex(IO_CDC, err); + puts(IO_CDC, "\r\n"); + + return -1; + } + + 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)); + + if (syscall(TK1_SYSCALL_PRELOAD_STORE_FIN, app_size, + (uint32_t)app_digest, (uint32_t)app_signature) < 0) { + puts(IO_CDC, "couldn't finalize storing app\n"); + return -1; + } + + return 0; +} + +int verify(uint8_t pubkey[32]) +{ + uint8_t app_digest[32]; + uint8_t app_signature[64]; + + // pubkey we already have + // read signature + // read digest + + if (!crypto_ed25519_check(app_signature, pubkey, app_digest, + sizeof(app_digest))) { + // failed!!! + } + + // syscall reset flash2_ver with app_digest + + return 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\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; + + default: + break; + } + } +}