USBIP protocol errors

I meant without any virtualization, but I guess if all models always works all the time on bare metal regardless of firmware or client version, then that makes the matrix pretty simple!

I’m happy to help with my model T, but I only have the one device and I’m not very keen on going into the danger zone and doing firmware downgrades. Happy to vary versions of the client and Qubes and then do firmware upgrades whenever it makes sense.

I thoroughly tested all Trezor models (One, T, Safe 3 and Safe 5) with Qubes OS, and here are the results:

Following the usual Qubes workflow (attaching the Trezor device from sys-usb to a VM running the wallet):

Trezor One works with:

  • Electrum
  • Trezor Suite
  • Web extensions like Metamask/Rabby on Chrome (and other Chromium-based browsers)

Trezor Model T, Safe 3 and Safe 5:

  • :white_check_mark: Work with Electrum
  • :x: Do not work with Trezor Suite or Chrome-based wallet extensions

To use Model T or Safe 3/5 on Qubes, I have to run the devices directly on sys-usb, as specified in these custom instructions.

This compatibility issue appears to be related to the different USB protocols:

  • Trezor One (and most hardware wallets) uses the HID protocol for USB communication, which works well with Qubes VM passthrough
  • Model T, Safe 3 and Safe 5 use WebUSB, which seems incompatible with Qubes’ USB passthrough mechanism

Electrum can communicate with all Trezor models (including T and Safe) because it’s not browser-based and communicates via HID rather than WebUSB.

I haven’t identified the exact cause of Qubes passthrough issues with WebUSB, but it appears related to how Qubes USB passthrough handles the resetting of WebUSB devices.

2 Likes

Hi @d-arcy, thanks for joining us on this issue. We all agree that Trezor One works correctly under all cases, probably for it to only use HID protocol as you say, which doesn’t have any issues.

For Model T, Safe 3/5 we managed to get it to work with a workaround (attaching/detaching), however I couldn’t get that workaround to work at all on a fresh install (4.2.2 / 4.2.3 / 4.2.4 / 4.3 weekly). It was a different machine so there could be an underlying issue in the mobo/bios that I won’t be debugging, however I’ll be testing on my daily driver with another ssd doing some fresh installs to see if I can replicate the workaround.

I understand. For T and Safe models, when not used with Electrum or Sparrow, I only succeeded following these instructions.

I’m very happy to help to debug this issue. I have all Trezor models in case you need to test.

I’ve been doing some tests on multiple computers and apparently there’s some hardware/bios quirk going on as well.

Test setup:

  • Qubes 4.2.4
  • Fedora 41 xfce stock template
  • Trezor Suite 25.2.2
  • Trezor Safe 3 with firmware 2.8.9 (versions <2.8.7 should work as well, 2.8.7 is completely broken)

Procedure:

  • Install Qubes with default options and encryption
  • Set up only fedora-41-xfce template
  • Create trezor qube
  • Run dnf install -y fuse fuse-libs
  • Download trezor suite and verify signature
  • Run trezor suite
  • Connect Trezor Safe 3 and unlock (pin)
  • Attach TS3 from sys-usb vm to trezor vm
  • From trezor suite, click “I’ve used this device before” and run genuine check
  • If TS3 doesn’t show anything, then connection is broken completely. If it ask for permission to run device check, it means connection works and you can use trezor suite with workaround

Out of 4 systems I’ve tried, only 1 system managed to work out of the box (I replicated the procedure in all setups), being the relevant hardware a cpu amd 5950X and mobo asus rog strix x570-e gaming. The other systems were a mix of amd and intel.

@hax0rbana_adam can you describe what cpu/mobo were you using that had “intermittent success” with Trezor using USB passthrough? We may be able to trim a bios option that could make it work on other setups.

I just re-tested on Qubes 4.2.4, Model T (v2.8.8 firmware), Trezor Suite 25.2.2 using the test procedure in @equbes latest post.

Trezor Suite started and saw the device. It asked me if I had ever used this device before and all that. Once I get to the Dashboard, it says my device is connected and has the name of the device in the upper left corner.

However, when I hover over the picture of the Trezor it says “Unavailable while loading” and the portfolio and assets data never loads.

Detaching the device from the qube and reconnecting it causes it to work fine. What’s interesting is that that I do have the qvm-service --enable sys-usb usb-reset-on-attach workaround that marmarek mentioned set up on this computer and that does not seem to be sufficient.

Can you share what cpu and mobo are you using? Also I’ve tested the usb-reset-on-attach as well but it doesn’t do nothing. The way I use to confirm connection work properly is either “show address in trezor” or “sign message”, trezor is detected as connected under all cases, but these operations only work on the machines that can get trezor to work with the reconnect workaround.

and an AMD Ryzen 9 3900X 12-Core Processor

Interesting, so we have a match on am4 platform working out of the box, the other systems i’ve tried that didn’t work were am5 and intel. @d-arcy are you on the later right? I’ll try to trim bios differences to see if there’s an option enabled by default in one of the working systems.

I’m indeed on an intel system. Never tried the qvm-service --enable sys-usb usb-reset-on-attach workaround tho.

Been doing more tests using usbip (Which is what Qubes OS uses under the hood) software directly:

  • Server and Client under the same machine:

    • am4 Qubes OS (on which passthrough works), running usbip-host on sys-usb and usbip-client on trezor appvm, communication works the same.

    • am5 Qubes OS (on which passthrough did not work), running usbip as above resulting in no communication.

  • Server and client under different machines (am4 & am5)

    • am4 host (Qubes) & am5 client (Arch): communication works correctly
    • am5 host (Arch) & am4 client (Qubes): communication doesn’t work
    • am5 host (Arch) & am5 client (Arch): communication doesn’t work
    • am4 host (Proxmox VM with usb passthrough) & am5 client (Arch): communication works correctly

Note: Trezor Suite 25.3.2 is borked, keep using 25.2.2 for now

From what I get, the issue is related with usbip host code running on non am4 systems. Only difference I noticed from am4 Qubes & Proxmox is that proxmox usb passthrough didn’t need any reconnect workaround, it kept working as if connected directly.

Interesting read here: https://forum.trezor.io/t/trezor-communication-inquiries/13200/13

Apparently HID protocol was removed at firmware 1.7.0 (https://forum.trezor.io/t/trezor-communication-inquiries/13200/14) which makes me wonder how electrum is communicating with Trezor T / S3 / S5.

More findings, while for these tests cases:

am5 host (Arch) & am4 client (Qubes): communication doesn’t work
am5 host (Arch) & am5 client (Arch): communication doesn’t work

Trezor Suite didn’t work, I just tested with trezorctl and it does work correctly (No reconnect needed as well). Debug logs indicate that webusb is indeed being used (and not HID), so this looks like an issue with trezord/trezor-bridge.

[2025-03-21 16:13:48,766] trezorlib.transport.hid INFO: HID transport is disabled: No module named 'hid'
[2025-03-21 16:13:48,789] trezorlib.transport INFO: Enumerating WebUsbTransport: found 1 devices
[2025-03-21 16:13:48,791] trezorlib.transport INFO: Enumerating BridgeTransport: found 0 devices
[2025-03-21 16:13:48,791] trezorlib.transport INFO: Enumerating UdpTransport: found 0 devices
[2025-03-21 16:13:48,792] trezorlib.client INFO: creating client instance for device: webusb:001:1

@d-arcy can you check if it does work on your setup as well? Passthrough trezor from sys-usb to appvm then run trezorctl commands (ie: trezorctl device authenticate).

EDIT:

Good news! After checking trezord options I see there’s one:

-r Reset USB device on session acquiring. Enabled by default (to prevent wrong device states); set to false if you plan to connect to debug link outside of bridge. (default true)

Then after running trezord -r=false both Trezor Suite and Chrome wallets (which uses Trezor Connect) works as expected without any need for reconnect under all setups.

You can get the binary from the appimage using ./Trezor-AppImage --appimage-extract then navigating to ./squashfs-root/resources/bin/bridge/trezord

For AppVMs that intend to connect to trezor, we can create a systemd service that runs trezord (you can grab it from here)

/etc/systemd/system/trezord.service

[Unit]
Description=Trezor Bridge
After=network.target

[Service]
Type=simple
ExecStart=/opt/trezor/bin/trezord -r=false
User=user
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

then on /rw/config/rc.local:

modprobe vhci-hcd # Only if AppVM is running as PVH
systemctl enable --now trezord
1 Like

It works for all Trezor models! This is a much better solution that what is proposed in this guide.

Congrats, @equbes. Do you think that running trezord with the -r=false option might pose any security risks?

Hi @d-arcy, I’ve searched but so far don’t see any security implication, that flag was added since sometimes trezor would end up in a wrong device state that required a physical reconnect, by always resetting it they can skip that step. However so far running with -r=false I’ve neved experienced a wrong device state (although I’m not leaving Trezor connected by long periods of time)

2 Likes

Short update on my end: while running trezord -r=false once the Trezor is attached to the Qube works flawlessy, creating a systemd service that runs trezord at Qube startup does not. This is because trezord expects the Trezor to be already available via USB when it starts. If it’s not attached yet, it fails.

That’s why I added

modprobe vhci-hcd # Only if AppVM is running as PVH

To the rc.local script, the error is not because trezor is not connected (else it would fail running on bare metal as well, because one does not normally have the trezor connected 24/7), it’s because PVH doesn’t run any USB modules which are required by trezord to work.

It might be possible to have the service start up when the device gets plugged in (well, really when it gets attached) and thus the USB controller materializes.

Honestly the trezord binary doesn’t take much resources so I don’t see any downsides on having it run on vm start, the issue with devices can be solved by just loading vhci-hcd module before starting the service.