mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-11-27 02:46:24 -05:00
tkey-libs: Import tag fw-5 of tkey-libs
Use tag fw-5 from https://github.com/tillitis/tkey-libs/
This commit is contained in:
parent
17e5e77187
commit
34e9f0a314
9 changed files with 310 additions and 8 deletions
|
|
@ -31,9 +31,9 @@ LDFLAGS=-T app.lds -L libcommon/ -lcommon -L libcrt0/ -lcrt0
|
||||||
|
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: libcrt0.a libcommon.a libmonocypher.a libblake2s.a
|
all: libcrt0.a libcommon.a libsyscall.a libmonocypher.a libblake2s.a
|
||||||
|
|
||||||
IMAGE=ghcr.io/tillitis/tkey-builder:4
|
IMAGE=ghcr.io/tillitis/tkey-builder:5rc1
|
||||||
|
|
||||||
podman:
|
podman:
|
||||||
podman run --rm --mount type=bind,source=$(CURDIR),target=/src \
|
podman run --rm --mount type=bind,source=$(CURDIR),target=/src \
|
||||||
|
|
@ -47,6 +47,14 @@ check:
|
||||||
libcrt0.a: libcrt0/crt0.o
|
libcrt0.a: libcrt0/crt0.o
|
||||||
$(AR) -qc $@ libcrt0/crt0.o
|
$(AR) -qc $@ libcrt0/crt0.o
|
||||||
|
|
||||||
|
# System calls
|
||||||
|
SYSCALLOBJS=libsyscall/syscall.o libsyscall/sys_wrapper.o
|
||||||
|
|
||||||
|
libsyscall.a: $(SYSCALLOBJS)
|
||||||
|
$(AR) -qc $@ $(SYSCALLOBJS)
|
||||||
|
|
||||||
|
$(SYSCALLOBJS): include/tkey/syscall.h
|
||||||
|
|
||||||
# Common C functions
|
# Common C functions
|
||||||
LIBOBJS=libcommon/assert.o libcommon/led.o libcommon/lib.o \
|
LIBOBJS=libcommon/assert.o libcommon/led.o libcommon/lib.o \
|
||||||
libcommon/proto.o libcommon/touch.o libcommon/io.o
|
libcommon/proto.o libcommon/touch.o libcommon/io.o
|
||||||
|
|
@ -69,13 +77,14 @@ libblake2s.a: $(B2OBJS)
|
||||||
$(AR) -qc $@ $(B2OBJS)
|
$(AR) -qc $@ $(B2OBJS)
|
||||||
$B2OBJS: blake2s/blake2s.h
|
$B2OBJS: blake2s/blake2s.h
|
||||||
|
|
||||||
LIBS=libcrt0.a libcommon.a
|
LIBS=libcrt0.a libcommon.a libsyscall.a
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -f $(LIBS) $(LIBOBJS) libcrt0/crt0.o
|
rm -f $(LIBS) $(LIBOBJS) libcrt0/crt0.o
|
||||||
rm -f libmonocypher.a $(MONOOBJS)
|
rm -f libmonocypher.a $(MONOOBJS)
|
||||||
rm -f libblake2s.a $(B2OBJS)
|
rm -f libblake2s.a $(B2OBJS)
|
||||||
|
rm -f libsyscall.a $(SYSCALLOBJS)
|
||||||
|
|
||||||
# Create compile_commands.json for clangd and LSP
|
# Create compile_commands.json for clangd and LSP
|
||||||
.PHONY: clangd
|
.PHONY: clangd
|
||||||
|
|
@ -85,7 +94,7 @@ compile_commands.json:
|
||||||
bear -- make all
|
bear -- make all
|
||||||
|
|
||||||
# Uses ../.clang-format
|
# Uses ../.clang-format
|
||||||
FMTFILES=include/tkey/*.h libcommon/*.c
|
FMTFILES=include/tkey/*.h libsyscall/*.c libcommon/*.c
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
clang-format --dry-run --ferror-limit=0 $(FMTFILES)
|
clang-format --dry-run --ferror-limit=0 $(FMTFILES)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
# Device libraries for the Tillitis TKey
|
# Device libraries for the Tillitis TKey
|
||||||
|
|
||||||
- C runtime: libcrt0.
|
- C runtime: libcrt0.
|
||||||
|
- System call support: libsyscall.
|
||||||
- Common C functions including protocol calls: libcommon.
|
- Common C functions including protocol calls: libcommon.
|
||||||
- Cryptographic functions: libmonocypher. Based on
|
- Cryptographic functions: libmonocypher. Based on
|
||||||
[Monocypher](https://github.com/LoupVaillant/Monocypher) version
|
[Monocypher](https://github.com/LoupVaillant/Monocypher) version
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
- NOTE WELL! Rewritten I/O functions with new signatures and
|
- NOTE WELL! Rewritten I/O functions with new signatures and
|
||||||
semantics!
|
semantics!
|
||||||
- `blake2s()` with new signature.
|
- `blake2s()` with new signature.
|
||||||
|
- System call support.
|
||||||
|
|
||||||
### BLAKE2s hash function
|
### BLAKE2s hash function
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ path = [
|
||||||
"Makefile",
|
"Makefile",
|
||||||
"README-DIST.txt",
|
"README-DIST.txt",
|
||||||
"README.md",
|
"README.md",
|
||||||
"RELEASE.md"
|
"RELEASE.md",
|
||||||
]
|
]
|
||||||
SPDX-FileCopyrightText = "2022 Tillitis AB <tillitis.se>"
|
SPDX-FileCopyrightText = "2022 Tillitis AB <tillitis.se>"
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
SPDX-License-Identifier = "BSD-2-Clause"
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,6 @@ void puthex(enum ioend dest, const uint8_t ch);
|
||||||
void putinthex(enum ioend dest, const uint32_t n);
|
void putinthex(enum ioend dest, const uint32_t n);
|
||||||
void puts(enum ioend dest, const char *s);
|
void puts(enum ioend dest, const char *s);
|
||||||
void hexdump(enum ioend dest, void *buf, int len);
|
void hexdump(enum ioend dest, void *buf, int len);
|
||||||
void config_endpoints(enum ioend endpoints);
|
void config_endpoints(uint8_t endpoints);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
63
hw/application_fpga/tkey-libs/include/tkey/syscall.h
Normal file
63
hw/application_fpga/tkey-libs/include/tkey/syscall.h
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Tillitis AB <tillitis.se>
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef TKEY_SYSCALL_H
|
||||||
|
#define TKEY_SYSCALL_H
|
||||||
|
|
||||||
|
#define RESET_DIGEST_SIZE 32
|
||||||
|
#define RESET_DATA_SIZE 220
|
||||||
|
|
||||||
|
// Needs to be held synchronized with syscall_num.h in firmware.
|
||||||
|
enum reset_start {
|
||||||
|
START_DEFAULT = 0, // Probably cold boot
|
||||||
|
START_FLASH0 = 1,
|
||||||
|
START_FLASH1 = 2,
|
||||||
|
START_FLASH0_VER = 3,
|
||||||
|
START_FLASH1_VER = 4,
|
||||||
|
START_CLIENT = 5,
|
||||||
|
START_CLIENT_VER = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reset {
|
||||||
|
enum reset_start type;
|
||||||
|
uint8_t app_digest[RESET_DIGEST_SIZE];
|
||||||
|
uint8_t next_app_data[RESET_DATA_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Needs to be held synchronized with syscall_num.h in firmware.
|
||||||
|
enum syscall_num {
|
||||||
|
TK1_SYSCALL_RESET = 1,
|
||||||
|
TK1_SYSCALL_ALLOC_AREA = 2,
|
||||||
|
TK1_SYSCALL_DEALLOC_AREA = 3,
|
||||||
|
TK1_SYSCALL_WRITE_DATA = 4,
|
||||||
|
TK1_SYSCALL_READ_DATA = 5,
|
||||||
|
TK1_SYSCALL_ERASE_DATA = 6,
|
||||||
|
TK1_SYSCALL_GET_VIDPID = 7,
|
||||||
|
TK1_SYSCALL_PRELOAD_STORE = 8,
|
||||||
|
TK1_SYSCALL_PRELOAD_STORE_FIN = 9,
|
||||||
|
TK1_SYSCALL_PRELOAD_DELETE = 10,
|
||||||
|
TK1_SYSCALL_PRELOAD_GET_DIGSIG = 11,
|
||||||
|
TK1_SYSCALL_REG_MGMT = 12,
|
||||||
|
TK1_SYSCALL_STATUS = 13,
|
||||||
|
TK1_SYSCALL_GET_APP_DATA = 14,
|
||||||
|
};
|
||||||
|
|
||||||
|
int syscall(uint32_t number, uint32_t arg1, uint32_t arg2, uint32_t arg3);
|
||||||
|
int sys_reset(struct reset *rst, size_t len);
|
||||||
|
int sys_reset_data(uint8_t next_app_data[RESET_DATA_SIZE]);
|
||||||
|
int sys_alloc(void);
|
||||||
|
int sys_dealloc(void);
|
||||||
|
int sys_write(uint32_t offset, void *buf, size_t len);
|
||||||
|
int sys_read(uint32_t offset, void *buf, size_t len);
|
||||||
|
int sys_erase(uint32_t offset, size_t len);
|
||||||
|
int sys_get_vidpid(void);
|
||||||
|
int sys_preload_delete(void);
|
||||||
|
int sys_preload_store(uint32_t offset, void *app, size_t len);
|
||||||
|
int sys_preload_store_fin(size_t len, uint8_t digest[32],
|
||||||
|
uint8_t signature[64]);
|
||||||
|
int sys_get_digsig(uint8_t digest[32], uint8_t signature[64]);
|
||||||
|
int sys_status(void);
|
||||||
|
#endif
|
||||||
|
|
@ -367,11 +367,11 @@ void hexdump(enum ioend dest, void *buf, int len)
|
||||||
// - IO_CDC
|
// - IO_CDC
|
||||||
// - IO_CH552
|
// - IO_CH552
|
||||||
//
|
//
|
||||||
// Use like this:
|
// Use like this in the bitmask:
|
||||||
//
|
//
|
||||||
// config_endpoints(IO_FIDO|IO_DEBUG)
|
// config_endpoints(IO_FIDO|IO_DEBUG)
|
||||||
//
|
//
|
||||||
void config_endpoints(enum ioend endpoints)
|
void config_endpoints(uint8_t endpoints)
|
||||||
{
|
{
|
||||||
uint8_t cmdbuf[2] = {0};
|
uint8_t cmdbuf[2] = {0};
|
||||||
|
|
||||||
|
|
|
||||||
145
hw/application_fpga/tkey-libs/libsyscall/sys_wrapper.c
Normal file
145
hw/application_fpga/tkey-libs/libsyscall/sys_wrapper.c
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Tillitis AB <tillitis.se>
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
#include <tkey/syscall.h>
|
||||||
|
|
||||||
|
// Reset the TKey. Leave the reset type (enum reset_start) in rst as
|
||||||
|
// well as an optional app_digest, forcing firmware to only allow that
|
||||||
|
// specific app digest, as well as some data to leave to the next app
|
||||||
|
// in chain in next_app_data. Send the length of the next_app_data in len.
|
||||||
|
//
|
||||||
|
// The TKey is reset and firmware starts again.
|
||||||
|
//
|
||||||
|
// Returns non-zero on error.
|
||||||
|
int sys_reset(struct reset *rst, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_RESET, (uint32_t)rst, len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fills in data left from previous app in the chain into
|
||||||
|
// `next_app_data`. Buffer needs to be large enough to receive
|
||||||
|
// RESET_DATA_SIZE bytes.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_reset_data(uint8_t next_app_data[RESET_DATA_SIZE])
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_GET_APP_DATA, (uint32_t)next_app_data, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a flash area for the current app. Must be done before sys_write()
|
||||||
|
// or sys_read(). If the current app already has an area allocated no new
|
||||||
|
// area will be allocated.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_alloc(void)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_ALLOC_AREA, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free an already allocated flash area for the current app.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_dealloc(void)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_DEALLOC_AREA, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write data in `buf` to the app's flash area at byte `offset` within
|
||||||
|
// the area.
|
||||||
|
//
|
||||||
|
// Up to storage area size bytes can be written at once and `offset` must be a
|
||||||
|
// multiple of 256 bytes.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_write(uint32_t offset, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_WRITE_DATA, offset, (uint32_t)buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read `len` bytes into `buf` at byte `offset` from the app's flash
|
||||||
|
// area.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_read(uint32_t offset, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_READ_DATA, offset, (uint32_t)buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase `len` bytes from `offset` within the area.
|
||||||
|
//
|
||||||
|
// Both `len` and `offset` must be a multiple of 4096 bytes.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_erase(uint32_t offset, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_ERASE_DATA, offset, len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the TKey Vendor and Product ID.
|
||||||
|
int sys_get_vidpid(void)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_GET_VIDPID, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the app in flash slot 1. Only available for the verified
|
||||||
|
// management app.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_preload_delete(void)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_PRELOAD_DELETE, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store an app, or possibly just a block of an app, from the `app`
|
||||||
|
// buffer in flash slot 1 at byte `offset`.
|
||||||
|
//
|
||||||
|
// If you can't fit your entire app in the buffer, call
|
||||||
|
// `sys_preload_store` many times as you receive the binary from the
|
||||||
|
// client. Returns 0 on success.
|
||||||
|
//
|
||||||
|
// Up to preloaded app area size bytes can be written at once and `offset` must
|
||||||
|
// be a multiple of 256 bytes.
|
||||||
|
//
|
||||||
|
// Only available for the verified management app.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_preload_store(uint32_t offset, void *app, size_t len)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_PRELOAD_STORE, offset, (uint32_t)app, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize storing of an app where the complete binary size is `len`
|
||||||
|
// in flash slot 1. Returns 0 on success. Only available for the
|
||||||
|
// verified management app.
|
||||||
|
//
|
||||||
|
// Compute a BLAKE2s hash digest over the entire binary. Pass the
|
||||||
|
// result in `app_digest`.
|
||||||
|
//
|
||||||
|
// Sign `app_digest` with your Ed25519 private key and pass the
|
||||||
|
// resulting signature in `app_signature`.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_preload_store_fin(size_t len, uint8_t digest[32], uint8_t signature[64])
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_PRELOAD_STORE_FIN, len, (uint32_t)digest,
|
||||||
|
(uint32_t)signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copies the digest and signature of app in flash slot 1 to
|
||||||
|
// `app_digest` and `app_signature`. Returns 0 on success. Only
|
||||||
|
// available for the verified management app.
|
||||||
|
//
|
||||||
|
// Returns 0 on success.
|
||||||
|
int sys_get_digsig(uint8_t digest[32], uint8_t signature[64])
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_PRELOAD_GET_DIGSIG, (uint32_t)digest,
|
||||||
|
(uint32_t)signature, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns filesystem status. Non-zero when problems have been
|
||||||
|
// detected, so far only that the first copy of the partition table
|
||||||
|
// didn't pass checks.
|
||||||
|
int sys_status(void)
|
||||||
|
{
|
||||||
|
return syscall(TK1_SYSCALL_STATUS, 0, 0, 0);
|
||||||
|
}
|
||||||
83
hw/application_fpga/tkey-libs/libsyscall/syscall.S
Normal file
83
hw/application_fpga/tkey-libs/libsyscall/syscall.S
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Tillitis AB <tillitis.se>
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
.section ".text"
|
||||||
|
.globl syscall
|
||||||
|
|
||||||
|
|
||||||
|
syscall:
|
||||||
|
// Save registers to stack
|
||||||
|
addi sp, sp, -32*4
|
||||||
|
sw x0, 0*4(sp)
|
||||||
|
sw x1, 1*4(sp)
|
||||||
|
// x2 (sp) is assumed to be preserved by the interrupt handler.
|
||||||
|
sw x3, 3*4(sp)
|
||||||
|
sw x4, 4*4(sp)
|
||||||
|
sw x5, 5*4(sp)
|
||||||
|
sw x6, 6*4(sp)
|
||||||
|
sw x7, 7*4(sp)
|
||||||
|
sw x8, 8*4(sp)
|
||||||
|
sw x9, 9*4(sp)
|
||||||
|
// x10 (a0) will contain syscall return value. And should not be saved.
|
||||||
|
sw x11, 11*4(sp)
|
||||||
|
sw x12, 12*4(sp)
|
||||||
|
sw x13, 13*4(sp)
|
||||||
|
sw x14, 14*4(sp)
|
||||||
|
sw x15, 15*4(sp)
|
||||||
|
sw x16, 16*4(sp)
|
||||||
|
sw x17, 17*4(sp)
|
||||||
|
sw x18, 18*4(sp)
|
||||||
|
sw x19, 19*4(sp)
|
||||||
|
sw x20, 20*4(sp)
|
||||||
|
sw x21, 21*4(sp)
|
||||||
|
sw x22, 22*4(sp)
|
||||||
|
sw x23, 23*4(sp)
|
||||||
|
sw x24, 24*4(sp)
|
||||||
|
sw x25, 25*4(sp)
|
||||||
|
sw x26, 26*4(sp)
|
||||||
|
sw x27, 27*4(sp)
|
||||||
|
sw x28, 28*4(sp)
|
||||||
|
sw x29, 29*4(sp)
|
||||||
|
sw x30, 30*4(sp)
|
||||||
|
sw x31, 31*4(sp)
|
||||||
|
|
||||||
|
// Trigger syscall interrupt
|
||||||
|
li t1, 0xe1000000 // Syscall interrupt trigger address
|
||||||
|
sw zero, 0(t1) // Trigger interrupt
|
||||||
|
|
||||||
|
// Restore registers from stack
|
||||||
|
lw x0, 0*4(sp)
|
||||||
|
lw x1, 1*4(sp)
|
||||||
|
// x2 (sp) is assumed to be preserved by the interrupt handler.
|
||||||
|
lw x3, 3*4(sp)
|
||||||
|
lw x4, 4*4(sp)
|
||||||
|
lw x5, 5*4(sp)
|
||||||
|
lw x6, 6*4(sp)
|
||||||
|
lw x7, 7*4(sp)
|
||||||
|
lw x8, 8*4(sp)
|
||||||
|
lw x9, 9*4(sp)
|
||||||
|
// x10 (a0) contains syscall return value. And should not be destroyed.
|
||||||
|
lw x11, 11*4(sp)
|
||||||
|
lw x12, 12*4(sp)
|
||||||
|
lw x13, 13*4(sp)
|
||||||
|
lw x14, 14*4(sp)
|
||||||
|
lw x15, 15*4(sp)
|
||||||
|
lw x16, 16*4(sp)
|
||||||
|
lw x17, 17*4(sp)
|
||||||
|
lw x18, 18*4(sp)
|
||||||
|
lw x19, 19*4(sp)
|
||||||
|
lw x20, 20*4(sp)
|
||||||
|
lw x21, 21*4(sp)
|
||||||
|
lw x22, 22*4(sp)
|
||||||
|
lw x23, 23*4(sp)
|
||||||
|
lw x24, 24*4(sp)
|
||||||
|
lw x25, 25*4(sp)
|
||||||
|
lw x26, 26*4(sp)
|
||||||
|
lw x27, 27*4(sp)
|
||||||
|
lw x28, 28*4(sp)
|
||||||
|
lw x29, 29*4(sp)
|
||||||
|
lw x30, 30*4(sp)
|
||||||
|
lw x31, 31*4(sp)
|
||||||
|
addi sp, sp, 32*4
|
||||||
|
|
||||||
|
ret
|
||||||
Loading…
Add table
Add a link
Reference in a new issue