- Revise firmware implementation notes
- Document how to do fw syscalls
- Document how to trigger a syscall function in the firmware, how to
pass arguments, what the caller is responsible for and what is
returned.
- Describe hardware syscall implementation
- how the syscall interrupts are triggered,
- the hardware privilege escalation,
- the UDS protection.
Co-authored-by: Daniel Jobson <jobson@tillitis.se>
Co-authored-by: Michael Cardell Widerkrantz <mc@tillitis.se>
Introduce new syscall TK1_SYSCALL_GET_VIDPID to get Vendor ID and
Product ID from the protected Unique Device Identification number.
UDI is protected from device apps to protect the serial number, so
apps won't know the exact TKey they are running on other than the CDI.
It may, however, be important to know what *kind* of TKey they are
running on, so we want to expose the Vendor ID and Product ID.
- fpga: Allow UDI to be read when doing syscalls.
- Add the new syscall to firmware.
- Add test to testapp directly after negative test of reading UDI to
read out VID/PID through a syscall.
Since the introduction of the syscall mechanism we don't allow
execution in ROM anymore so it's impossible to call the firmware's
blake2s() function.
Co-authored-by: Mikael Ågren <mikael@tillitis.se>
In order to be able to leave data for firmware signalling the
intention with a reset or to leave data for the next app in a chain of
apps, we introduce a part of FW_RAM that can be used to store this
data. In order to do this, we:
- Change size of ROM from 6 KB to 8 KB.
- Change size of FW_RAM, from 2 KB to 4 KB.
- Add RESETINFO memory partition inside FW_RAM.
- Add generation of map file.
- Change CFLAGS from using -O2 to using -Os.
- Update address ranges for valid access to ROM and FW_RAM.
- Move stack to be located before data+bss and the RESETINFO data
above them. This also means we introduce hardware stack overflow
protection through the Security Monitor.
- Revise firmware README to the new use of FW_RAM.
Reconfigure the baudrate to keep 500 kbaud.
Correct a forgotten test in testfw that wasn't updated the last time
frequency was raised in commit
75b028505f0d6dc685d37b84d73ddb9db5ee7ea2 in June 17, 2024.
Throwing away mode and length from incoming data. Adding mode and
length to outgoing data.
Splitting responses into frames small enough for the USB<->UART
transceiver to handle.
- Extend hardware checks for invalid memory accesses to include
checking more address space.
- In fw include file: fix two typos for memory ranges that relates to
above that fortunately have no impact on functionality.
This removes the possibility to configure the bit rate, data bits and
stop bits at runtime from the API. This reduces the
usage of LCs with ~4%.
It is still possible to configure the core before building.
Update digest of application_fpga.bin.sha256
- The API changes name from `_SWITCH_APP` to `_SYSTEM_MODE_CTRL`.
- The registers and wires changes name to `system_mode_*`, instead of a
mix of `switch_app_*` and `fw_app_mode`.
- Remove the define `NOCONSOLE`, add define `QEMU_CONSOLE`
- Inverse the use of it, add the define to have QEMU debug output in fw.
- Add a make target `qemu_firmware.elf` which builds the firmware with
QEMU console enabled.
Co-authored-by: Mikael Ågren <mikael@tillitis.se>
Add API address to trigger system reset.
When written to will send system_reset signal
to the reset generator, which then perform a complete
reset cycle of the FPGA system.
Signed-off-by: Joachim Strömbergson <joachim@assured.se>
Update:
- README
- testbench
- Symbolic names and variables in fw
- registers
- port name and wires
- Update fpga and fw digests
Signed-off-by: Joachim Strömbergson <joachim@assured.se>
- Remove all text about other software than firmware.
- Remove the Reset section.
- Include a diagram and detailed explanation about the state machine
in close vicinity.
- Describe the test firmware.
Co-authored-by: Joachim Strömbergson <joachim@assured.se>
The RAM address and data scrambling API was called twice, once before filling
RAM with random values, and once after. Since moving to a significantly
better PRNG (xorwow) this is now deemed unnecessary. See issue #225.
This changes both FPGA and firmware hashes.
Modify the loop to zeroise the FW-RAM instead of the
RAM. RAM is filled with random data at the start of main().
Changes firmware and bitstream digests.
Signed-off-by: Joachim Strömbergson <joachim@assured.se>
- NOTE: This is an optional feature, not built by default. Not included
in the tk1 for sale at Tillitis shop.
- This makes it possible to interface the SPI flash onboard TKey.
- To include the SPI master in the build, use `make application_fpga.bin
YOSYS_FLAG=-DINCLUDE_SPI_MASTER`.
Signed-off-by: Joachim Strömbergson <joachim@assured.se>
xorwow provides significantly better random data, compared to previously
used function. Making it harder to predict what data RAM is filled with.
It adds a startup time of approx 80 ms, but can be compensated with
optimising other parts of the startup routine.
This changes both firmware and fpga hashes.
Signed-off-by: Joachim Strömbergson <joachim@assured.se>
The memset() responsible for the zeroisation of the secure_ctx under
the compute_cdi() function in FW's main.c, was optimised away by the
compiler. Instead of using memset(), secure_wipe() is introduced
which uses a volatile keyword to prevent the compiler to try to
optimise it. Secure_wipe() is now used on all locations handling
removal of sensitive data.
Use _RAM_ADDR_RAND instead of _RAM_ASLR since this is not OS-level
ASLR we're talking about. It's address randomization as seen from
outside of the CPU, not from the process running inside it. Ordinary
ASLR is visible from the CPU.
This file is also included in at least qemu (GPL-2.0-or-later) besides
tillitis-key1 (GPL-2.0-only) and tkey-libs (GPL-2.0-only) so it's
licensed as GPL v2 or later even if the rest of the project is -only.
Instead of putting memory constant into an enum we use defines.
Use the direct memory address instead of ORing constants together to
compute the address.
An enum in ISO C is a signed int. Some of are memory addresses are to
large to fit in a signed int. This is not a problem since we're not
using ISO C (-std=gnu99) but it doesn't look very nice if you turn on
pedantic warnings. Also, if someone would use another compiler which
at least supports the inline assembly we use, but possible not other
GNU extensions, things would probably break.
Instead of putting memory constant into an enum we use defines.
Use the direct memory address instead of ORing constants together to
compute the address.
An enum in ISO C is a signed int. Some of are memory addresses are to
large to fit in a signed int. This is not a problem since we're not
using ISO C (-std=gnu99) but it doesn't look very nice if you turn on
pedantic warnings. Also, if someone would use another compiler which
at least supports the inline assembly we use, but possible not other
GNU extensions, things would probably break.
Since UDS is not byte-readable we copy it by word to local_uds. Now
UDS lives for a short while in local_uds on the stack in FW_RAM and in
the internal buffer of the blake2s context (also in FW_RAM) but is
very soon overwritten.