Skip to content

Fix touch responsiveness and USB HID issues#777

Merged
kaczmarczyck merged 1 commit into
google:developfrom
pwnall:fix-artemis-touch-usb
May 28, 2026
Merged

Fix touch responsiveness and USB HID issues#777
kaczmarczyck merged 1 commit into
google:developfrom
pwnall:fix-artemis-touch-usb

Conversation

@pwnall

@pwnall pwnall commented May 27, 2026

Copy link
Copy Markdown
Member

This PR addresses two responsiveness issues that may cause the device to hang or drop connections:

  1. Touch State Leak: Implemented Drop for Touch to correctly clear the STATE when a user presence request is interrupted (e.g., by a USB packet or timeout). Added safe extraction in State::touch to handle queued hardware button interrupts (bounces) without hitting unreachable!() and panicking.
  2. USB HID Communication Fixes:
    • Updated MessageAssembler::parse_packet to allow any valid initialization packet (not just CTAPHID_INIT) to abort a hung transaction, in accordance with the CTAP 2.1 specification.
    • Fixed a bug where a new initialization packet arriving immediately after a transaction timeout was incorrectly dropped while returning the MsgTimeout error.

These fixes prevent the firmware from entering unrecoverable states where the LED fails to blink or the device stops responding to the host.

@pwnall pwnall force-pushed the fix-artemis-touch-usb branch from acf9e87 to a05c40b Compare May 27, 2026 21:38
@coveralls

coveralls commented May 27, 2026

Copy link
Copy Markdown

Coverage Status

Coverage is 97.274%pwnall:fix-artemis-touch-usb into google:develop. No base build found for google:develop.

@pwnall pwnall force-pushed the fix-artemis-touch-usb branch 2 times, most recently from 3065d91 to f64ddf4 Compare May 27, 2026 22:31
@pwnall pwnall changed the title Fix Artemis touch responsiveness and USB HID issues Fix touch responsiveness and USB HID issues May 27, 2026

@ia0 ia0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR! I'll only comment on the Touch issue and let @kaczmarczyck address the second point.

Comment thread src/touch.rs Outdated
Comment thread src/touch.rs Outdated
if let Some(state) = this.take() {
state.button.stop();
state.touched.store(true, Relaxed);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should not reach unreachable!(). I wonder if you had to add this because you unconditionally reset the STATE in Drop for Touch. In theory, state.button.stop() will start dropping future events and clear any existing pending events. If that's not the case it's a bug in Wasefire.

That said, the applet could be resilient against Wasefire bugs. I don't think it's a good idea because (at least for development) we want to fail as soon as something impossible happens. We could have a resilient cargo feature to avoid crashes as much as possible, which would be used for production keys (there could be security concerns though, it's a trade-off with availability). @kaczmarczyck what do you think?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thank you very much for explaining!

I removed this diff. I don't want to make development more difficult 😄

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should double check how we deal with parallel connections, and that we don't miss anything else. We didn't test enough since the Wasefire refactoring.

Touches should never be used twice. CTAP2 library code should already ensure this, but the combination with CTAP1 can work in one direction: First requesting on CTAP1, then going into the CTAP2 UP loop. We should drop CTAP1 then. But doesn't need to be done here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

And to answer the question, once it is impossible, we can fail when the impossible happens.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thank you very much for your thoughts!

I'll try to address this in a separate PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think there's anything to do here in the short term:

  1. We need to check whether OpenSK can create 2 Touch objects. If no, simplify the code, but I can do it.
  2. We need to run enough tests to make sure the unreachable is correct.

@pwnall pwnall force-pushed the fix-artemis-touch-usb branch from f64ddf4 to ff90a86 Compare May 28, 2026 08:02
ia0
ia0 previously approved these changes May 28, 2026

@ia0 ia0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM for src/touch.rs. Is there a reason the PR is still a draft?

@ia0 ia0 requested a review from kaczmarczyck May 28, 2026 08:11
@pwnall pwnall marked this pull request as ready for review May 28, 2026 08:11
@ia0 ia0 mentioned this pull request May 28, 2026
kaczmarczyck
kaczmarczyck previously approved these changes May 28, 2026

@kaczmarczyck kaczmarczyck left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving for HID library code

Comment thread libraries/opensk/src/ctap/hid/receive.rs
This commit addresses responsiveness issues and CTAP protocol deviations
in the USB HID transport and user presence handling:

1. User Presence State Leak: When a user presence request is interrupted
   (e.g., by a timeout or an incoming USB packet), the touch state was
   incorrectly left running in the background. This prevented subsequent
   LED blinking and caused a panic if hardware interrupts (bounces) were
   queued. The `Touch` struct now correctly implements `Drop` to clear
   the state, and event handling safely ignores stale interrupts.

2. Transaction Timeout Race Condition: Following a transaction timeout
   (CTAP 2.1 Section 11.2.5.2), the firmware incorrectly dropped the
   next incoming packet while returning a `MsgTimeout` error. If the
   host initiated a new transaction with a `CTAPHID_INIT` packet
   immediately after a timeout, the new initialization packet was
   discarded, leaving the host waiting indefinitely. The timeout logic
   now preserves new initialization packets and only returns a timeout
   error if the host sends a continuation packet for the aborted message.
@pwnall pwnall dismissed stale reviews from kaczmarczyck and ia0 via 5f347c4 May 28, 2026 16:10
@pwnall pwnall force-pushed the fix-artemis-touch-usb branch from ff90a86 to 5f347c4 Compare May 28, 2026 16:10
@pwnall pwnall requested review from ia0 and kaczmarczyck May 28, 2026 16:21
@pwnall

pwnall commented May 28, 2026

Copy link
Copy Markdown
Member Author

@ia0 @kaczmarczyck PTAL?

Apologies if I was supposed to leave the PR as-is rather than add the tests.

@ia0

ia0 commented May 28, 2026

Copy link
Copy Markdown
Member

Apologies if I was supposed to leave the PR as-is rather than add the tests.

No I think that's fine. I'll let @kaczmarczyck merge.

@kaczmarczyck kaczmarczyck merged commit bc1d619 into google:develop May 28, 2026
19 of 20 checks passed
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.

4 participants