mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-08-06 21:54:29 -04:00
Update tk1/README and fpga README regarding system mode
Updates Readme with: - Dynamic execution mode control in hardware - ROM execution - Syscall API - Sensitive assets only read-/writable before first switch to app mode - SPI master only accessible in firmware mode
This commit is contained in:
parent
04eefe01fa
commit
c7e44d3575
2 changed files with 122 additions and 35 deletions
|
@ -108,6 +108,7 @@ Contains:
|
||||||
- General purpose input/output (GPIO) pin control.
|
- General purpose input/output (GPIO) pin control.
|
||||||
- Application introspection: start address and size of binary.
|
- Application introspection: start address and size of binary.
|
||||||
- BLAKE2s function access.
|
- BLAKE2s function access.
|
||||||
|
- Syscall function access.
|
||||||
- Compound Device Identity (CDI).
|
- Compound Device Identity (CDI).
|
||||||
- Unique Device Identity (UDI).
|
- Unique Device Identity (UDI).
|
||||||
- RAM memory protection.
|
- RAM memory protection.
|
||||||
|
@ -115,6 +116,14 @@ Contains:
|
||||||
- SPI main.
|
- SPI main.
|
||||||
- System reset.
|
- System reset.
|
||||||
|
|
||||||
|
### Execution mode control
|
||||||
|
|
||||||
|
The execution mode consists of two modes, firmware mode and
|
||||||
|
application mode. These modes have certain privileges, and in general
|
||||||
|
protects sensitive assets against access when in application mode. The
|
||||||
|
execution mode is dynamically controlled in the hardware, depending on
|
||||||
|
current location of execution.
|
||||||
|
|
||||||
### Illegal instruction monitor
|
### Illegal instruction monitor
|
||||||
|
|
||||||
Execution of illegal instructions will cause the CPU to enter its trap
|
Execution of illegal instructions will cause the CPU to enter its trap
|
||||||
|
|
|
@ -25,13 +25,69 @@ applications.
|
||||||
|
|
||||||
### Control of execution mode
|
### Control of execution mode
|
||||||
|
|
||||||
|
The execution mode consists of two modes, firmware mode and
|
||||||
|
application mode. These modes have certain privileges. The execution
|
||||||
|
mode is dynamically controlled in the hardware, depending on current
|
||||||
|
location of execution. After a reset the device starts in firmware
|
||||||
|
mode, as soon as the executions moves outside of ROM the mode is
|
||||||
|
changed to application mode.
|
||||||
|
|
||||||
|
There also exists an API to access two different function pointers to
|
||||||
|
functions located in ROM, i.e., in firmware. These are the syscall
|
||||||
|
function and the Blake2s function. Since these operates in ROM, they
|
||||||
|
need a higher privilege compared to application mode. The only way
|
||||||
|
back into a raised privilege, is through the blake2s or syscall API.
|
||||||
|
|
||||||
|
The syscall function operates in firmware mode, except for not being
|
||||||
|
able to write to the sensitive assets, see the list of sensitive
|
||||||
|
assets further down.
|
||||||
|
|
||||||
|
The blake2s function operates in application mode, but ROM is
|
||||||
|
executable during the function call.
|
||||||
|
|
||||||
|
For a complete overview, see the modes and privileges depicted in the
|
||||||
|
table below:
|
||||||
|
|
||||||
|
| *name* | *ROM* | *FW RAM* | *SPI* | *Sensitive assets* |
|
||||||
|
|-----------------|--------|-----------|--------|--------------------|
|
||||||
|
| Firmware mode | r/x | r/w | r/w | r/w* |
|
||||||
|
| app mode | r | i | i | r |
|
||||||
|
| syscall | r/x | r/w | r/w | r |
|
||||||
|
| blake2s | r/x | i | i | r |
|
||||||
|
|
||||||
|
Legend:
|
||||||
|
r = readable
|
||||||
|
w = writeable
|
||||||
|
x = executable
|
||||||
|
i = invisible
|
||||||
|
* = only writeable during first time in firmware mode
|
||||||
|
|
||||||
|
|
||||||
|
These sensitive assets are only readable and/or writeable in firmware
|
||||||
|
mode, before the first switch to app mode:
|
||||||
|
- ADDR_APP_START
|
||||||
|
- ADDR_APP_SIZE
|
||||||
|
- ADDR_BLAKE2S
|
||||||
|
- ADDR_SYSCALL
|
||||||
|
- ADDR_CDI_FIRST
|
||||||
|
- ADDR_CDI_LAST
|
||||||
|
- ADDR_RAM_ADDR_RAND
|
||||||
|
- ADDR_RAM_DATA_RAND
|
||||||
|
- ADDR_UDI_FIRST
|
||||||
|
- ADDR_UDI_LAST
|
||||||
|
|
||||||
|
Note that these assets have different properties, some are read-only
|
||||||
|
and some are write-only. The list above only shows if they are
|
||||||
|
restricted in app mode. See each individual API further down to find
|
||||||
|
out more about their properties.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
ADDR_SYSTEM_MODE_CTRL: 0x08
|
ADDR_SYSTEM_MODE_CTRL: 0x08
|
||||||
```
|
```
|
||||||
|
|
||||||
This register controls if the device is executing in FW mode or in App
|
This register is read-only and shows if the device is executing in FW
|
||||||
mode. The register can be written once between power cycles, and only
|
mode or in App mode. If set the device is in app mode.
|
||||||
by FW. If set the device is in app mode.
|
|
||||||
|
|
||||||
|
|
||||||
### Control of RGB LED
|
### Control of RGB LED
|
||||||
|
@ -72,10 +128,10 @@ ADDR_APP_START: 0x0c
|
||||||
ADDR_APP_SIZE: 0x0d
|
ADDR_APP_SIZE: 0x0d
|
||||||
```
|
```
|
||||||
|
|
||||||
These registers provide read only information to the loaded app to
|
These registers provide read-only information to the loaded app to
|
||||||
itself - where it was loaded and its size. The values are written by
|
itself - where it was loaded and its size. The values are written by
|
||||||
FW as part of the loading of the app. The registers can't be written
|
FW as part of the loading of the app. The registers can't be written
|
||||||
when the `ADDR_SYSTEM_MODE_CTRL` has been set.
|
after the `ADDR_SYSTEM_MODE_CTRL` has been set for the first time.
|
||||||
|
|
||||||
|
|
||||||
### Access to Blake2s
|
### Access to Blake2s
|
||||||
|
@ -86,8 +142,31 @@ ADDR_BLAKE2S: 0x10
|
||||||
|
|
||||||
This register provides the 32-bit function pointer address to the
|
This register provides the 32-bit function pointer address to the
|
||||||
Blake2s hash function in the FW. It is written by FW during boot. The
|
Blake2s hash function in the FW. It is written by FW during boot. The
|
||||||
register can't be written to when the `ADDR_SYSTEM_MODE_CTRL` has been
|
register can't be written after the `ADDR_SYSTEM_MODE_CTRL` has been
|
||||||
set.
|
set for the first time.
|
||||||
|
|
||||||
|
This register will default to an illegal address, so if it is left
|
||||||
|
unset by firmware and an application tries to call it the CPU will
|
||||||
|
halt.
|
||||||
|
|
||||||
|
### Syscall access
|
||||||
|
|
||||||
|
```
|
||||||
|
ADDR_SYSCALL: 0x12
|
||||||
|
```
|
||||||
|
|
||||||
|
This register provides the 32-bit function pointer address to the
|
||||||
|
syscall function in the FW. The syscall function provides access to
|
||||||
|
high privilege tasks in a secure manner, such as access to the SPI
|
||||||
|
flash.
|
||||||
|
|
||||||
|
The register is written by FW during boot. The register can't be
|
||||||
|
written after the `ADDR_SYSTEM_MODE_CTRL` has been set for the first
|
||||||
|
time.
|
||||||
|
|
||||||
|
This register will default to an illegal address, so if it is left
|
||||||
|
unset by firmware and an application tries to call it the CPU will
|
||||||
|
halt.
|
||||||
|
|
||||||
|
|
||||||
### Access to CDI
|
### Access to CDI
|
||||||
|
@ -99,10 +178,10 @@ ADDR_CDI_LAST: 0x27
|
||||||
|
|
||||||
These registers provide access to the 256-bit compound device secret
|
These registers provide access to the 256-bit compound device secret
|
||||||
calculated by the FW as part of loading an application. The registers
|
calculated by the FW as part of loading an application. The registers
|
||||||
are written by the FW. The register can't be written to when the
|
are written by the FW. The register can't be written to after the
|
||||||
`ADDR_SYSTEM_MODE_CTRL` has been set. The CDI is readable by apps,
|
`ADDR_SYSTEM_MODE_CTRL` has been set for the first time. The CDI is
|
||||||
which can then use it as a base secret for any other secrets required
|
readable by apps, which can then use it as a base secret to generate
|
||||||
to carry out their intended use case.
|
any other secrets required to carry out their intended use case.
|
||||||
|
|
||||||
|
|
||||||
### Access to UDI
|
### Access to UDI
|
||||||
|
@ -113,7 +192,8 @@ ADDR_UDI_LAST: 0x31
|
||||||
```
|
```
|
||||||
|
|
||||||
These read-only registers provide access to the 64-bit Unique Device
|
These read-only registers provide access to the 64-bit Unique Device
|
||||||
Identity (UDI).
|
Identity (UDI). The register can only be read in firmware mode before
|
||||||
|
the first switch to app mode.
|
||||||
|
|
||||||
The two UDI words are stored using 32 named SB\_LUT4 FPGA multiplexer
|
The two UDI words are stored using 32 named SB\_LUT4 FPGA multiplexer
|
||||||
(MUX) instances, identified in the source code as "udi\_rom\_idx". One
|
(MUX) instances, identified in the source code as "udi\_rom\_idx". One
|
||||||
|
@ -164,38 +244,34 @@ ADDR_CPU_MON_LAST: 0x62
|
||||||
Monitors events and state changes in the SoC and handles security
|
Monitors events and state changes in the SoC and handles security
|
||||||
violations. Currently checks for:
|
violations. Currently checks for:
|
||||||
|
|
||||||
1. Trying to execute instructions in FW\_RAM. *Always enabled.*
|
1. Trying to execute instructions in FW\_RAM. *Always enabled*
|
||||||
2. Trying to access RAM outside of the physical memory. *Always enabled*
|
2. Trying to access RAM outside of the physical memory. *Always enabled*
|
||||||
3. Trying to execute instructions from a memory area in RAM defined by
|
3. Trying to execute instructions in ROM, while ROM being marked as
|
||||||
|
non-executable. Except for the first instruction set in
|
||||||
|
`ADDR_SYSCALL` and `ADDR_BLAKE2S`. *Always enabled*
|
||||||
|
4. Trying to execute instructions from a memory area in RAM defined by
|
||||||
the application.
|
the application.
|
||||||
|
|
||||||
Number 1 and 2 are always enabled. Number 3 is set and enabled by the
|
Number 1, 2 and 3 are always enabled. Number 4 is set and enabled by
|
||||||
device application. Once enabled, by writing to `ADDR_CPU_MON_CTRL`,
|
the device application.
|
||||||
the memory defined by `ADDR_CPU_MON_FIRST` and `ADDR_CPU_MON_LAST`
|
|
||||||
will be protected against execution. Typically the application
|
|
||||||
developer will set this protection to cover the application stack
|
|
||||||
and/or heap.
|
|
||||||
|
|
||||||
An application can write to these registers to define the area and
|
An application must write to the `ADDR_CPU_MON_FIRST` and
|
||||||
then enable the monitor. Once enabled the monitor can't be disabled,
|
`ADDR_CPU_MON_LAST` first, before enabling the monitor by writing to
|
||||||
and the `ADDR_CPU_MON_FIRST` and `ADDR_CPU_MON_LAST` registers can't be
|
`ADDR_CPU_MON_CTRL`. This effectively marks the region defined as
|
||||||
changed. This means that an application that wants to use the monitor
|
data-only, and will protect against execution. Typically a application
|
||||||
must define the area first before enabling the monitor.
|
developer will set this protection to cover the application stack
|
||||||
|
and/or heap. Once enabled the monitor can't be disabled, and the
|
||||||
|
registers can't be written.
|
||||||
|
|
||||||
Once enabled, if the CPU tries to read an instruction from the defined
|
Once enabled, if the CPU tries to read an instruction from the defined
|
||||||
area, the core will force the CPU to instead read an all zero, which
|
area, the core will force the CPU to instead read an all zero
|
||||||
is an illegal instruction. This illegal instruction will trigger the
|
instruction, which is an illegal instruction. This will trigger the
|
||||||
CPU to enter its TRAP state, from which it can't return unless the
|
CPU to enter its TRAP state, from which it can't return unless the
|
||||||
TKey is power cycled.
|
TKey is power cycled.
|
||||||
|
|
||||||
The firmware will not write to these registers as part of loading an
|
Another feature is that when the CPU traps the core will detect it and
|
||||||
app. The app developer must define the area and enable the monitor to
|
start flashing the status LED with a red light, indicating that the
|
||||||
get the protection.
|
CPU is in a trapped state and no further execution is possible.
|
||||||
|
|
||||||
One feature not obvious from the API is that when the CPU traps the
|
|
||||||
core will detect that and start flashing the status LED with a red
|
|
||||||
light indicating that the CPU is in a trapped state and no further
|
|
||||||
execution is possible.
|
|
||||||
|
|
||||||
## SPI-master
|
## SPI-master
|
||||||
|
|
||||||
|
@ -203,6 +279,8 @@ The TK1 includes a minimal SPI-master that provides access to the
|
||||||
Winbond Flash memory mounted on the board. The SPI-master is byte
|
Winbond Flash memory mounted on the board. The SPI-master is byte
|
||||||
oriented and very minimalistic.
|
oriented and very minimalistic.
|
||||||
|
|
||||||
|
The SPI master can only be used in firmware mode.
|
||||||
|
|
||||||
In order to transfer more than a single byte, SW must read status and
|
In order to transfer more than a single byte, SW must read status and
|
||||||
write commands needed to send a sequence of bytes. In order to read
|
write commands needed to send a sequence of bytes. In order to read
|
||||||
out a sequence of bytes from the memory, SW must send as many dummy
|
out a sequence of bytes from the memory, SW must send as many dummy
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue