Conversation
…ict-up opt-in A WebAuthn login with an allowCredentials (non-resident) credential cost two touches: the platform runs a silent pre-flight getAssertion with the `up` option false to discover which listed credential the key holds, then the real assertion. RS-Key ignored the `up` option entirely and polled the button on every assertion, so the pre-flight took a touch too. Honor up:false: the options map now parses `up`, and get_assertion skips the presence poll and clears the UP flag when up is false — the spec/YubiKey behavior, which makes such a login a single touch. getNextAssertion reuses the originating request's decision (stored in the assertion state) so a silent resident discovery stays silent across the whole walk. Resident-credential / passkey logins were and remain a single touch. The new `strict-up` cargo feature (off by default) restores the touch-on-every-assertion behavior for anyone who prefers an explicit gesture per assertion. `fido-conformance` enables it implicitly so the conformance image keeps the exact behavior the 235/0 pass was validated with. Tests: up:false returns an assertion under a declining presence (no touch) with UP=0, while up:true is denied (mutation-proof); a strict-up-gated test proves up:false still polls the button there. docs/build.md documents the feature. bcdDevice 0x077F -> 0x0780. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ure (was up-button) Requiring a BOOTSEL touch is the secure, correct behavior, so it should be the unconditional default — not a feature that happens to be on by default and that `--no-default-features` silently removes. Invert it: drop the `up-button` feature and add an explicit `no-touch` opt-in for the automated test image. - firmware: the presence.rs / led.rs cfg gates flip from `feature = "up-button"` (and its negation) to `feature = "no-touch"`; firmware/Cargo.toml drops `default = ["up-button"]` + `up-button` and adds `no-touch`. - build plumbing: the no-touch image is now `--features no-touch` everywhere it was `--no-default-features` — the CI `flavors` matrix, check.sh, the nix firmware-no-touch* flavors, and the docs (build / quickstart / testing / interop / architecture / led, README, releases). The default firmware binary is the same touch build as before, so no bcdDevice change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…o-touch refactor) + readme version Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TheMaxMur
added a commit
that referenced
this pull request
Aug 13, 2026
`crates/rsk-display` was extracted from `firmware/` so that something other than
a flashed board with a panel soldered on could run the screen flow. It then sat
there with zero tests, which is the half of the extraction that was never done —
and it is the crate holding the anti-phishing guarantee.
It can run on the host because the panel and the touch controller are already
type parameters and the rest of the board is behind `Hooks`: the doubles here are
a panel that records what was drawn, a pad that reads back a scripted sequence of
samples, and a board whose backlight, wake button and presence flags are fields.
`embassy-time`'s `std` feature supplies the clock, so the deadlines and debounces
under test are the real ones rather than stubs.
115 cases. The ones worth naming are the ones this flow has already got wrong:
- a finger already down when a screen appears is not a tap on it. The panel
reports level, not edges, and a wake press held past the release wait landed
on Onboard's full-width "Continue without PIN" button — consuming a fresh
device's one-time PIN offer (audit run-33).
- a status-glyph change repaints without disarming the panel. The host drives
`led_status` around every dispatch, so counting it as a new surface let a
plain CTAP loop swallow every tap (audit run-34 #14).
- a host ceremony loop cannot hold the auto-lock off. It counts from the last
LOCAL interaction, which is what `power.rs` promises a host cannot postpone
(audit run-34 #15); and "Display sleep: Off" switches off blanking only, not
a security control.
- approve is a HOLD: a brush does not approve, and two three-quarter holds are
not one whole one — lifting the finger resets the fill. A finger left over
from a previous ceremony cannot approve the next one, and an expired
registration card does not read a leftover press as a fresh Save.
- a queued host command cannot shut the PIN pad on its first poll, and never
mid-entry: without the floor, a host repeating any ungated command holds the
owner's unlock pad shut for as long as it likes.
- the device PIN and the FIDO clientPIN have separate retry counters, a spent
budget is not revived by the right PIN, and a panel-set clientPIN ends the
session token the old PIN authorized (CTAP 2.1 §6.5.5.6).
- a `Deny` tap reaches the applet as `Declined`, not as a timeout — the BOOTSEL
button has no such gesture, and over CCID, which carries no CTAPHID_CANCEL,
a cancel correctly degrades to the timeout.
The `no_std` attribute is cfg'd off for test builds, as in `rsk-fs` and `rsk-ui`.
`docs/architecture.md` was missing the crate from its map entirely, right above
the line claiming everything but `firmware` runs the full suite on the host —
true only as of this commit.
Test-only: no `bcdDevice` bump. The gate now lints and runs the crate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.2.8 — single-touch WebAuthn login + touch-default build
Changed
420cfb2). RS-Key nowhonors the platform's silent pre-flight probe (
getAssertionwithup:false):it returns the credential-discovery assertion with no touch and the UP flag
clear, as the spec and YubiKey do. Previously the
upoption was ignored andevery assertion polled the button, so an
allowCredentials(non-resident)login cost two touches. New
strict-upcargo feature (off) restores thetouch-on-every-assertion behavior;
fido-conformanceenables it implicitly.(
3079649). Droppedup-button(which was on by default); the no-touch testimage is now the explicit opt-in
--features no-touch(was--no-default-features) across CI / check.sh / nix / docs. The defaultfirmware binary is unchanged.
bcdDevice 0x077F → 0x0780.
Verification
strict-up); a mutation-checked testproves
up:falseis silent (UP=0) whileup:trueis denied.(PIV/OpenPGP/vendor) all green.
🤖 Generated with Claude Code