Skip to content

fix(reset): stop displaying internal entropy - #336

Merged
BitHighlander merged 2 commits into
alphafrom
agent/remove-internal-entropy-display
Aug 5, 2026
Merged

fix(reset): stop displaying internal entropy#336
BitHighlander merged 2 commits into
alphafrom
agent/remove-internal-entropy-display

Conversation

@BitHighlander

@BitHighlander BitHighlander commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Security invariant

Production firmware must never render or return the 32-byte internal entropy used as seed pre-image material.

Change

  • removes the Internal Entropy OLED confirmation path from reset
  • removes display_random from the internal reset API
  • keeps the legacy protobuf field decodable but ignores it, preserving host wire compatibility
  • deletes more code than it adds

Before this change, a host could set ResetDevice.display_random, supply the external entropy, and reconstruct SHA256(internal_entropy || external_entropy) after observing the screen once.

Validation

  • clean isolated Docker build
  • direct make xunit execution: firmware 388/388, board 2/2, crypto 4/4, Pallas constant-time 7/7
  • source audit: no production read of display_random and no Internal Entropy screen remains
  • release device build passed (firmware.keepkey.bin: 649,748 bytes)
  • bitcoin-only release build passed (firmware.keepkey.bin: 361,076 bytes)

Compatibility

The protobuf schema is unchanged. Hosts that still send display_random=true receive normal reset behavior without an entropy screen.

Hardware check

On an uninitialized test device, send otherwise-identical reset requests with display_random false and true. Both must follow the same PIN/backup flow, and neither may display entropy bytes.

The wider hardening sequence and acceptance gates are tracked in #334.

@BitHighlander
BitHighlander changed the base branch from develop to alpha August 5, 2026 01:55
Reconciles this branch with alpha now that the dice-entropy work (#341) has
landed there. The two are NOT in tension -- they are complementary, and
merging them clarified why:

  reset_init() keeps dice_entropy and drops display_random. The dice block
  folds rolls into int_entropy; the display block merely SHOWED that value.
  Removing the screen leaves dice untouched functionally.

  The comment above the dice block claimed the displayed entropy was a
  verifiable post-mix commitment. That was wrong and is corrected here: a
  host that supplies ext_entropy and reads the screen once computes
  SHA256(shown || ext) -- the seed pre-image -- and dice change nothing,
  because the displayed value is already post-mix. So the screen actively
  undermined the feature it appeared to support. The roll digest is safe by
  contrast: it hashes the user's own input, not seed material.

  Also carries #341's awaiting_entropy disarm, which closes the
  host-controllable-seed hole on aborted resets.

deps/python-keepkey -> b44f1b3, which retargets the two tests that asserted
the Internal Entropy ButtonRequest. They now send display_random=True and
assert the next message is PinMatrixRequest, testing the compatibility
claim directly.

Verified: ARM device build links (.text 616,620) and 6/6 reset tests pass
against an emulator built from this branch, dice test included.
@BitHighlander
BitHighlander marked this pull request as ready for review August 5, 2026 02:12
@BitHighlander
BitHighlander merged commit f1f99a5 into alpha Aug 5, 2026
15 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.

1 participant