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

Interaction-less update #3363

Merged
merged 10 commits into from
Oct 30, 2023
Merged

Interaction-less update #3363

merged 10 commits into from
Oct 30, 2023

Conversation

cepetr
Copy link
Contributor

@cepetr cepetr commented Oct 20, 2023

This pull request primarily involves a significant update, commonly referred to as an "interaction-less update,".

resolves #2919
resolves #2794

The interaction-less update can be initiated via the command line using trezorctl fw update. However, several conditions must be met for this to work:

  1. The uploaded firmware must come from the same vendor, and its version must be higher.
  2. The current firmware version on the device must be equal to or higher than 2.6.3.
  3. The device must not be in bootloader mode.

If any of these conditions are not met, the standard firmware upload via the bootloader is selected. Additionally, users can manually enable or disable the interaction-less update by specifying the --ilu or --no-ilu options.

The interaction-less update process begins on the trezorctl side by sending a RebootToBootloader message. This message has been extended to include two optional parameters: bootCommand and firmwareHeader. In this context, bootCommand is set to INSTALL UPGRADE, and firmwareHeader contain the new firmware headers (the first ~5.5KB of the binary).

When the firmware receives the RebootToBootloader message with the INSTALL UPGRADE command, it parses and checks the provided firmware header. It compares the vendor and version fields with the current firmware. If the vendor is the same, and the version is higher, it displays a confirmation dialog. Once the user confirms the firmware upgrade, the firmware proceeds to jump to the bootloader.

A new interface between the firmware and the bootloader has been implemented. The firmware can now jump to the bootloader and provide a command (enum) and arguments (up to 256 bytes). In this case, the firmware jumps to the bootloader with the INSTALL_UPGRADE command, and the arguments are set to the hash of the vendor and image header received in the RebootToUploader message.

When the bootloader is initiated and detects the INSTALL_UPGRADE command, it skips the initial screens and immediately starts waiting for host commands.

Following this, trezorctl continues with the standard firmware update process, which includes uploading the new firmware. The bootloader checks whether the uploaded firmware header has the same hash as the firmware confirmed by the user. It also performs the same checks as the firmware (comparing vendor and version). If the firmware is the same and newer, it proceeds with flashing the firmware without further confirmation.

@cepetr cepetr added core Trezor Core firmware. Runs on Trezor Model T and T2B1. trezorlib Python library and the command line trezorctl tool. feature Product related issue visible for end user T2B1 Trezor Safe 3 (F4) python Pull requests that update Python code T2T1 Trezor Model T labels Oct 20, 2023
@cepetr cepetr requested a review from TychoVrahe October 20, 2023 13:08
@cepetr cepetr self-assigned this Oct 20, 2023
Copy link
Contributor

@TychoVrahe TychoVrahe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work. Leaving few comments in addition to mentioned todos and things flagged by CI.

core/embed/bootloader/messages.c Outdated Show resolved Hide resolved
core/embed/bootloader/messages.c Outdated Show resolved Hide resolved
core/embed/bootloader/messages.c Outdated Show resolved Hide resolved
core/embed/trezorhal/stm32f4/supervise.c Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
core/embed/bootloader/memory.ld Outdated Show resolved Hide resolved
common/protob/messages-management.proto Outdated Show resolved Hide resolved
core/embed/trezorhal/common.h Outdated Show resolved Hide resolved
core/embed/bootloader/main.c Show resolved Hide resolved
python/src/trezorlib/device.py Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
python/src/trezorlib/cli/firmware.py Outdated Show resolved Hide resolved
@matejcik matejcik requested review from TychoVrahe and hiviah October 24, 2023 14:43
@matejcik
Copy link
Contributor

@TychoVrahe please take a look at the latest changes
@hiviah please review the bootloader part too

@matejcik
Copy link
Contributor

@mmilata please take over the outstanding UI issues, namely:

  • the "connect to host" screen needs white-on-black variant (similar to the bootloader loader)
  • the "firmware details" screen, incl. fingerprint, should be shared between firmware and bootloader, and used in the firmware part of this PR

Copy link
Contributor

@TychoVrahe TychoVrahe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI issues are still pending:

  • boot args not defined in unix/emulator
  • also the new flash_area_erase_partial funciton is not defined for unix, mentioned below too
  • legacy does not compile due to the changes in reboot to bootloader message (nanopb is used there unlike in core firmware)

core/embed/trezorhal/stm32f4/flash.c Show resolved Hide resolved
core/embed/boardloader/memory.ld Outdated Show resolved Hide resolved
core/embed/trezorhal/stm32f4/flash.c Show resolved Hide resolved
core/embed/firmware/memory_T.ld Show resolved Hide resolved
core/embed/lib/image.c Outdated Show resolved Hide resolved
core/embed/extmod/modtrezorutils/modtrezorutils.c Outdated Show resolved Hide resolved
core/embed/extmod/modtrezorutils/modtrezorutils.c Outdated Show resolved Hide resolved
core/embed/bootloader/messages.c Show resolved Hide resolved
core/src/apps/management/reboot_to_bootloader.py Outdated Show resolved Hide resolved
core/SConscript.prodtest Show resolved Hide resolved
Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some more notes

(@mmilata maybe resolve the Python side while you're on the UI?)

@matejcik
Copy link
Contributor

sorry, can you clarify which screen is that?

sorry, what I meant is "waiting for host"

core/embed/lib/image.c Outdated Show resolved Hide resolved
@mmilata
Copy link
Member

mmilata commented Oct 25, 2023

The UI + python changes are in #3371, feel free to merge or cherry-pick.

Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, now just waiting for @hiviah's review

@matejcik
Copy link
Contributor

minor nit: we should also check auto_update on line 489 to skip the 100ms "wait for touch" period.

Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

important feature that we forgot: ILU must only support full-trust images (so (vhdr.vtrust & VTRUST_ALL) == VTRUST_ALL)
it should not be possible to use ILU to update from unsigned to unsigned.

@matejcik
Copy link
Contributor

... firmware (python) doesn't need to check that (for this PR). It doesn't seem practical to export the vtrust flags to python just for this purpose, so maybe just "if vendor name is UNSAFE DO NOT USE" then reject or something dumb like that. going forward this might be a compile time flag, something coming from modtrezorutils or somesuch.

@cepetr
Copy link
Contributor Author

cepetr commented Oct 27, 2023

@matejcik I've added checking of the vtrust field of the vendor header, see 3ebf3d2 and a3119cb. The checking of the vendor string has not been implemented yet.

@matejcik matejcik force-pushed the cepetr/interless-update branch from cc291e5 to b147929 Compare October 27, 2023 14:16
@matejcik matejcik force-pushed the cepetr/interless-update branch from b147929 to c5817be Compare October 27, 2023 14:57
@matejcik matejcik merged commit c5817be into main Oct 30, 2023
5 of 8 checks passed
@matejcik matejcik deleted the cepetr/interless-update branch October 30, 2023 10:49
@bosomt
Copy link

bosomt commented Nov 7, 2023

QA OK

Info:

  • Suite version: desktop 23.11.1 (9a466944f069ad7aba27ac5aeef84dce12aa7e64)
  • Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) TrezorSuite/23.11.1 Chrome/116.0.5845.228 Electron/26.4.2 Safari/537.36
  • OS: MacIntel
  • Screen: 2560x1440
  • Transport: BridgeTransport 2.0.33

@matejcik matejcik mentioned this pull request Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Trezor Core firmware. Runs on Trezor Model T and T2B1. feature Product related issue visible for end user python Pull requests that update Python code T2B1 Trezor Safe 3 (F4) T2T1 Trezor Model T trezorlib Python library and the command line trezorctl tool.
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Interrupting firmware update at the wrong time erases seed (Almost) interaction-less firmware update
7 participants