Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoC: Automatically control system_mode in hardware using a "blessed" address #299

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

dehanj
Copy link
Member

@dehanj dehanj commented Nov 14, 2024

Description

This is a proof of concept:

  • Syscall API using a C function address to jump to execute a function in ROM
  • Changing system_mode between firmware_mode and app_mode depending on location of execution. A call to syscall_addr_reg will switch back to firmware mode.
  • SPI Master only accessible from firmware mode
  • Restrict ROM from being executable in app_mode, except for the function address in syscall_addr_reg or blak2s_addr_reg.
  • ROM is still readable, and I have verified with tkey-verification that it works.
  • Making sensitive assets only readable/writable before the first system_mode change
  • Readme documentation updated
  • Testbench updated

The utilization in the FPGA does increase, but not significantly. We are at around 95-96% with this solution.
Built locally with yosys-45 and nextpnr-0.7.

ICESTORM_LC:  5111/ 5280    96%

In CI (older toolchain):

ICESTORM_LC:  5105/ 5280    96%

Notes:

  • Removes the option of writing to the system_mode API, still readable however.
  • The hardware construction in this PR can be tested with the firmware in the branch persistant_storage_fw_. Run the hardware and firmware on target using apps with latest commits in tillitis/tkey-testapps:storage.
  • qemu is partly updated, and includes the syscall api, but not any of the hardware locks, use branch tillitis/qemu:test-wo-app-mode and apps from tillitis/tkey-testapps:storage latest commit.
  • Testfw is not updated, and may not function properly at the moment.

Type of change

  • Breaking Change (a change which would cause existing functionality to not work as expected)

Submission checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my changes
  • I have tested and verified my changes on target
  • My changes are well written and CI is passing
  • I have squashed my work to relevant commits and rebased on main for linear history
  • I have added a "Co-authored-by: x" if several people contributed, either pair programming or by squashing commits from different authors.
  • I have updated the documentation where relevant (readme, dev.tillitis.se etc.)
  • QEMU is updated to reflect changes

@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch 4 times, most recently from 4151eed to 8fe67fe Compare November 15, 2024 12:53
@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch from 8fe67fe to dd514d9 Compare November 15, 2024 13:25
@dehanj
Copy link
Member Author

dehanj commented Nov 15, 2024

We can potentially simplify the check due to unsigned arithmetic

%Warning-UNSIGNED: /__w/tillitis-key1/tillitis-key1/hw/application_fpga/core/tk1/rtl/tk1.v:428:27: Comparison is constant due to unsigned arithmetic
                                                                                                 : ... In instance application_fpga.tk1_inst
  428 |             if ((cpu_addr >= FW_ROM_FIRST) && (cpu_addr <= FW_ROM_LAST)) begin
      |                           ^~
                   ... For warning description see https://verilator.org/warn/UNSIGNED?v=5.012
                   ... Use "/* verilator lint_off UNSIGNED */" and lint_on around source to disable this message.
%Error: Exiting due to 1 warning(s)

But we might want to show intent, and if ROM moves it might lower the risk for a bug.

EDIT:
I removed the unnecessary comparison, but added a comment to it.
The comparison costs ~18 LCs, so I don't think it is wort to keep for showing intent.

@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch from dd514d9 to d6ad383 Compare November 18, 2024 09:14
@dehanj dehanj force-pushed the persistant_storage_fw_ branch from a32be6f to b7ba452 Compare November 19, 2024 12:29
@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch 3 times, most recently from b1da566 to d35d2d6 Compare November 21, 2024 08:55
@dehanj dehanj changed the base branch from persistant_storage_fw_ to main November 21, 2024 08:55
@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch 2 times, most recently from 8da93ec to d88af31 Compare November 21, 2024 12:35
@agren agren force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch from d88af31 to 221d673 Compare November 22, 2024 14:27
dehanj and others added 4 commits December 9, 2024 09:33
Add a register to store an address to a syscall function defined in
firmware. Set the reset value to an illegal address, to make sure a call
to an unset address will halt the CPU.

Co-authored-by: Mikael Ågren <[email protected]>
Raise privilege (go to firmware mode) when a function call occurs
to the function set in syscall_addr_reg. Automatically revoke privilege
when executing above ROM (go to app mode).

Remove the option of writing to system_mode through the API.

Co-authored-by: Mikael Ågren <[email protected]>
This is dynamically set by hw in system_mode_ctrl. ROM will reset to
executable, but will be marked as non-executable as soon as we are no
longer executing in ROM, like system_mode.

ROM will be marked as executable again, if function calls are made to
either `syscall_addr_reg` or `blake2s_addr_reg`. Set reset value of
`blake2s_addr_reg` to an illegal address, halting the CPU if it is
called unset.

The blake2s function is 4-byte aligned, to ensure the cpu_addr is is
aligned with the address in the register.

Co-authored-by: Mikael Ågren <[email protected]>
@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch from 221d673 to d3e4455 Compare December 9, 2024 08:41
dehanj and others added 3 commits December 9, 2024 13:26
After the first time system_mode is set to one, the assets will no
longer be read- or writeable, even if system_mode is set to zero at a
later syscall. This is to make sure syscalls does not have the same
privilege as the firmware has at first boot.

We need to monitor when system_mode is set to one, otherwise we might
accedentially lock the assets before actually leaving firmware, for
example if firmware would use a function set in any of the registers
used in system_mode_ctrl.

Co-authored-by: Mikael Ågren <[email protected]>
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
@dehanj dehanj force-pushed the syscall_jmp_to_address_to_enable_fw_mode_persist branch from d3e4455 to c7e44d3 Compare December 9, 2024 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants