You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #587 adds CRC-framed, generation-selected storage journal records, but python-keepkey/tests/test_storage_version_gate.py still mutates flash using the pre-journal model:
active_sector() chooses the first sector beginning with stor, rather than the newest CRC-verified generation selected by firmware find_active_storage();
it edits the version/payload without updating the CRC or converting the record to a genuine unframed legacy record;
it treats 2,572 bytes as the whole record even though framing extends the record to 2,580 bytes, and its “whole sector” comparison covers neither the trailer nor the rest of the 16 KiB sector.
As a result, the synthetic V16 and bitcoin-only records are correctly rejected as corrupt by the new firmware. In a focused pinned-container run:
test_v16_blob_upgrades_without_wiping fails because the invalid framed record is wiped;
test_bitcoin_only_band_refuses_without_wiping fails because boot does not treat the CRC-invalid record as a locked wallet.
Why CI initially hid it
The report screenshot phase runs pytest with || true. It retained three setup/home PNGs for each test, then the screenshot audit failed on their declared count before Phase 2 could re-run and gate the behavioral failures. Thus the visible CI diagnosis mentioned only missing screenshots even though the security assertions themselves were red.
Required remediation
Mirror find_active_storage() selection, including trailer validity, STM32 CRC-32/MPEG-2, and 24-bit generation wrap ordering.
Model all 2,580 framed bytes and compare the complete 16 KiB sector where the report claims byte-for-byte preservation.
When synthesizing shipped V16, clear generation padding and erase the framing trailer so it is a valid legacy record.
When restamping a current framed record into/out of the bitcoin-only band, recompute its CRC before boot.
This is a test/evidence defect, not evidence that valid field records are wiped: the firmware is failing closed on deliberately corrupted CRC-framed fixtures.
Summary
PR #587 adds CRC-framed, generation-selected storage journal records, but
python-keepkey/tests/test_storage_version_gate.pystill mutates flash using the pre-journal model:active_sector()chooses the first sector beginning withstor, rather than the newest CRC-verified generation selected by firmwarefind_active_storage();As a result, the synthetic V16 and bitcoin-only records are correctly rejected as corrupt by the new firmware. In a focused pinned-container run:
test_v16_blob_upgrades_without_wipingfails because the invalid framed record is wiped;test_bitcoin_only_band_refuses_without_wipingfails because boot does not treat the CRC-invalid record as a locked wallet.Why CI initially hid it
The report screenshot phase runs pytest with
|| true. It retained three setup/home PNGs for each test, then the screenshot audit failed on their declared count before Phase 2 could re-run and gate the behavioral failures. Thus the visible CI diagnosis mentioned only missing screenshots even though the security assertions themselves were red.Required remediation
find_active_storage()selection, including trailer validity, STM32 CRC-32/MPEG-2, and 24-bit generation wrap ordering.This is a test/evidence defect, not evidence that valid field records are wiped: the firmware is failing closed on deliberately corrupted CRC-framed fixtures.