fix(lf): T55xx config via rotation-to-preset match; label the emitted credential
Hardware-validated. Two real bugs in the T55xx config decode, both fixed by requiring a bit-rotation of the recovered repeating word to match a known preset: - Rotation ambiguity: a block read recovers the 32-bit config at an arbitrary bit offset. A real capture came back 0x000A4020 = the EM4100 word 0x00148040 rotated by one; the old "looks sane" scorer accepted the rotation verbatim and mislabeled it FSK1/RF-6. Now every rotation is tried and only a preset match (EM4100/HID/Indala/FDX-B/Viking/default) is accepted -> resolves to 0x00148040 = EM4100. - False positives: garbage config captures (all-0, all-1, a rotation of the tag's own emission) no longer pass -> decode returns None and the reliable emitted-stream decode carries the result. identify_lf label now names the chip + the actual decoded credential: "T5577 (EM4100 00FFFFFFFF)" instead of the config's guess. On real hardware this is now stable 4/4: config 00148040, emitted EM4100 00FFFFFFFF. Tests: rotation recovery (0x000A4020 -> EM4100), no-false-positive on all-1s/random, updated label expectation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -300,6 +300,19 @@ class TestT55xxConfig:
|
||||
assert r["modulation"] == "ASK"
|
||||
assert r["emulating"] == "EM4100 / EM4102"
|
||||
|
||||
def test_config_rotation_recovers_preset(self):
|
||||
# a block read recovers the config at some bit rotation (hardware gave 0x000A4020 =
|
||||
# 0x00148040 >> 1); rotate-matching must still resolve it to the EM4100 preset
|
||||
rotated = ((CONFIG_EM4100 >> 1) | ((CONFIG_EM4100 & 1) << 31)) & 0xFFFFFFFF
|
||||
assert rotated == 0x000A4020
|
||||
r = protocols.decode_t55xx_config(_t55xx_config_env(rotated))
|
||||
assert r and r["config"] == CONFIG_EM4100 and r["emulating"] == "EM4100 / EM4102"
|
||||
|
||||
def test_config_no_false_positive(self):
|
||||
# repeating words that aren't any preset rotation (all-1s, random) -> None, not a bogus config
|
||||
assert protocols.decode_t55xx_config(_t55xx_config_env(0xFFFFFFFF)) is None
|
||||
assert protocols.decode_t55xx_config(_t55xx_config_env(0x12345678)) is None
|
||||
|
||||
def test_preset_labels(self):
|
||||
assert protocols.emulation_name(T5577Config._PRESETS["hid"]) == "HID Prox"
|
||||
assert protocols.emulation_name(T5577Config._PRESETS["indala"]) == "Indala"
|
||||
@@ -332,7 +345,8 @@ class TestIdentifyLF:
|
||||
assert r["chip"] == "T5577"
|
||||
assert r["emulating"] == "EM4100 / EM4102"
|
||||
assert r["emitted"]["id_hex"] == "0102030405"
|
||||
assert r["label"] == "T5577 (EM4100 / EM4102)"
|
||||
# label names the chip + the actual decoded credential (not just the config's guess)
|
||||
assert r["label"] == "T5577 (EM4100 0102030405)"
|
||||
assert any("T55xx block 0" in l for l in lines)
|
||||
|
||||
def test_native_em4100_no_config(self):
|
||||
|
||||
Reference in New Issue
Block a user