Skip to content

Commit 6268e38

Browse files
committed
test(storage): preserve CRC framing in migration fixtures
1 parent 081fad0 commit 6268e38

1 file changed

Lines changed: 35 additions & 5 deletions

File tree

tests/test_storage_version_gate.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,20 @@ def patch(self, off, rel, data):
577577
with open(self.img, "r+b") as f:
578578
f.seek(off + rel)
579579
f.write(data)
580+
# These edits construct alternate-version fixtures, not corrupt
581+
# records. Preserve the optional durable-commit envelope so boot
582+
# reaches the version reader rather than rejecting a stale CRC.
583+
f.seek(off)
584+
record = f.read(2580)
585+
if record[2572:2576] == b"crc1":
586+
crc = 0xffffffff
587+
for (word,) in struct.iter_unpack("<I", record[:2572]):
588+
crc ^= word
589+
for _ in range(32):
590+
crc = ((crc << 1) ^ (0x04c11db7 if crc & 0x80000000
591+
else 0)) & 0xffffffff
592+
f.seek(off + 2576)
593+
f.write(struct.pack("<I", crc))
580594
f.flush()
581595
os.fsync(f.fileno())
582596

@@ -1110,8 +1124,18 @@ def test_v16_blob_upgrades_without_wiping(self):
11101124
derive if the wrapped storage key unwrapped, the 512-byte V16
11111125
ciphertext decrypted, and the seed came back byte-identical.
11121126
"""
1127+
self._check_v16_upgrade()
1128+
1129+
def test_unframed_v16_blob_upgrades_without_wiping(self):
1130+
"""Legacy V16 without the optional CRC envelope preserves its wallet."""
1131+
self._check_v16_upgrade(unframed=True)
1132+
1133+
def _check_v16_upgrade(self, unframed=False):
11131134
addr, off = self._create_wallet()
11141135
self._make_v16_blob(off)
1136+
if unframed:
1137+
self.emu.patch(off, 41, b"\x00" * 3)
1138+
self.emu.patch(off, 2572, b"\xff" * 8)
11151139
self.assertEqual(16, self.emu.read_u32(off, OFF_VERSION))
11161140

11171141
before = self.emu.image()
@@ -1145,7 +1169,7 @@ def test_v16_blob_upgrades_without_wiping(self):
11451169
c.close()
11461170

11471171
def test_unrecognised_version_wipes_on_boot(self):
1148-
"""A downgrade wipes, deliberately -- do not "fix" this.
1172+
"""Unknown full-product versions wipe; Bitcoin-only bands stay intact.
11491173
11501174
A device that has run newer firmware carries a newer stamp. Older
11511175
firmware cannot read it, so version_from_int() returns
@@ -1161,6 +1185,7 @@ def test_unrecognised_version_wipes_on_boot(self):
11611185
addr, off = self._create_wallet()
11621186
unknown = self.emu.read_u32(off, OFF_VERSION) + 1
11631187
self.emu.write_u32(off, OFF_VERSION, unknown)
1188+
before = self.emu.image()
11641189

11651190
self.emu.boot()
11661191
c = self.emu.client(self.method)
@@ -1174,6 +1199,12 @@ def test_unrecognised_version_wipes_on_boot(self):
11741199
"an older signed image would keep the seed." % unknown)
11751200
self.assertFalse(c.features.pin_protection)
11761201
self.assertNotEqual(LABEL, c.features.label)
1202+
# Unknown versions in the Bitcoin-only band are refused without
1203+
# erasing the wallet; full firmware uses its existing wipe policy.
1204+
if self.bitcoin_only:
1205+
self.assertEqual(before, self.emu.image())
1206+
else:
1207+
self.assertNotEqual(before, self.emu.image())
11771208
finally:
11781209
c.close()
11791210

@@ -1215,10 +1246,10 @@ def test_bitcoin_only_band_refuses_without_wiping(self):
12151246
self.emu.read_u32(off, OFF_VERSION), STORAGE_VERSION_BTC_ONLY_BASE,
12161247
"this emulator already stamps its wallets into the bitcoin-only "
12171248
"band, so it is not the multi-chain firmware this test is about")
1218-
before = self.emu.sector(off)
12191249
self.emu.write_u32(
12201250
off, OFF_VERSION,
12211251
STORAGE_VERSION_BTC_ONLY_BASE + self.emu.read_u32(off, OFF_VERSION))
1252+
before = self.emu.image()
12221253

12231254
self.emu.boot()
12241255
c = self.emu.client(self.method)
@@ -1233,10 +1264,9 @@ def test_bitcoin_only_band_refuses_without_wiping(self):
12331264
c.close()
12341265
self.emu.halt()
12351266

1236-
after = self.emu.sector(off)
1267+
after = self.emu.image()
12371268
self.assertEqual(
1238-
before[:OFF_VERSION] + before[OFF_VERSION + 4:],
1239-
after[:OFF_VERSION] + after[OFF_VERSION + 4:],
1269+
before, after,
12401270
"the locked boot MODIFIED the bitcoin-only record. The wallet is "
12411271
"supposed to stay recoverable by reflashing bitcoin-only firmware")
12421272

0 commit comments

Comments
 (0)