docs: update SLIX2 audit with cross-IC scope corrections

This commit is contained in:
michael
2026-03-18 18:19:59 -07:00
parent e87b9f1933
commit 75cb3d893d
3 changed files with 70 additions and 38 deletions

4
.gitmodules vendored Normal file
View File

@@ -0,0 +1,4 @@
[submodule "firmware"]
path = firmware
url = https://github.com/dangerous-tac0s/proxmark3-pm3py.git
branch = main

View File

@@ -31,54 +31,81 @@ Commands marked MISSING need implementation in the Python transponder model + ta
| Code | Name | Status | Priority | Notes | | Code | Name | Status | Priority | Notes |
|------|------|--------|----------|-------| |------|------|--------|----------|-------|
| 0xA0 | INVENTORY READ | MISSING | Nice to have | Like inventory but returns data blocks | | 0xA0 | INVENTORY READ | OK | - | Like inventory but returns data blocks |
| 0xA1 | FAST INVENTORY READ | MISSING | Nice to have | Same as A0 at double data rate | | 0xA1 | FAST INVENTORY READ | OK | - | Same as A0 at double data rate |
| 0xA2 | SET EAS | MISSING | Nice to have | Enables EAS mode (password protected) | | 0xA2 | SET EAS | OK | - | Enables EAS mode (password protected) |
| 0xA3 | RESET EAS | MISSING | Nice to have | Disables EAS mode | | 0xA3 | RESET EAS | OK | - | Disables EAS mode |
| 0xA4 | LOCK EAS | MISSING | Nice to have | Permanently locks EAS state | | 0xA4 | LOCK EAS | OK | - | Permanently locks EAS state |
| 0xA5 | EAS ALARM | MISSING | Nice to have | Returns 256-bit EAS sequence | | 0xA5 | EAS ALARM | OK | - | Returns 256-bit EAS sequence |
| 0xA6 | PASSWORD PROTECT EAS/AFI | MISSING | Nice to have | Enables password protection for EAS/AFI | | 0xA6 | PASSWORD PROTECT EAS/AFI | OK | - | Enables password protection for EAS/AFI |
| 0xA7 | WRITE EAS ID | MISSING | Nice to have | Writes 16-bit EAS identifier | | 0xA7 | WRITE EAS ID | OK | - | Writes 16-bit EAS identifier |
| 0xAB | GET NXP SYSTEM INFO | MISSING | **Must have** | Returns PP, PP conditions, lock bits, feature flags | | 0xAB | GET NXP SYSTEM INFO | OK | - | Returns PP, PP conditions, lock bits, feature flags |
| 0xB2 | GET RANDOM NUMBER | OK | - | Firmware native handler | | 0xB2 | GET RANDOM NUMBER | OK | - | Firmware native handler + Python model |
| 0xB3 | SET PASSWORD | OK | - | Firmware native + table entries | | 0xB3 | SET PASSWORD | OK | - | XOR password with GET_RANDOM, firmware + table entries |
| 0xB4 | WRITE PASSWORD | MISSING | Should have | Changes password value (requires prior SET PASSWORD) | | 0xB4 | WRITE PASSWORD | OK | - | Changes password value (requires prior SET PASSWORD) |
| 0xB5 | LOCK PASSWORD | MISSING | Should have | Permanently locks a password | | 0xB5 | LOCK PASSWORD | OK | - | Permanently locks a password |
| 0xB6 | PROTECT PAGE | MISSING | **Must have** | Sets protection pointer + access conditions | | 0xB6 | PROTECT PAGE | OK | - | Sets protection pointer + access conditions (requires write auth) |
| 0xB7 | LOCK PAGE PROTECTION | MISSING | Should have | Permanently locks protection config | | 0xB7 | LOCK PAGE PROTECTION | OK | - | Permanently locks protection config |
| 0xB9 | DESTROY | MISSING | Should have | Irreversibly kills tag (XOR password) | | 0xB9 | DESTROY | OK | - | Irreversibly kills tag (XOR password) |
| 0xBA | ENABLE PRIVACY | MISSING | **Must have** | Enters privacy mode (separate from SET PASSWORD) | | 0xBA | ENABLE PRIVACY | OK | - | Enters privacy mode (separate from SET PASSWORD, XOR password) |
| 0xBB | 64-BIT PASSWORD PROTECTION | MISSING | Should have | Requires both R+W passwords | | 0xBB | 64-BIT PASSWORD PROTECTION | OK | - | Requires both R+W passwords |
| 0xBC | STAY QUIET PERSISTENT | MISSING | Nice to have | Persistent quiet survives power cycles | | 0xBC | STAY QUIET PERSISTENT | OK | - | Persistent quiet survives power cycles |
| 0xBD | READ SIGNATURE | MISSING | **Must have** | Returns 32-byte ECC originality signature | | 0xBD | READ SIGNATURE | OK | - | Returns 32-byte ECC originality signature |
### Model Issues ### Model Issues
1. **Password ID 0x10 (EAS/AFI) missing**datasheet lists 5 IDs: 0x01=Read, 0x02=Write, 0x04=Privacy, 0x08=Destroy, 0x10=EAS/AFI. Model only has 4. 1. ~~**Password ID 0x10 (EAS/AFI) missing**~~FIXED: pwd_id 0x10 now in model.
2. **Privacy mode behavior**datasheet says tag responds to GET RANDOM NUMBER AND SET PASSWORD in privacy mode. Model only allows SET PASSWORD. 2. ~~**Privacy mode behavior**~~FIXED: GET_RANDOM now works in privacy mode.
3. **ENABLE PRIVACY (0xBA) is separate** from SET PASSWORD — uses XOR'd password, specifically enters privacy mode. Model conflates with SET PASSWORD pwd_id=privacy. 3. ~~**ENABLE PRIVACY (0xBA) is separate**~~ — FIXED: 0xBA implemented as dedicated command with XOR password.
4. **16-bit counter (block 79)** has special increment-only semantics via WRITE with specific data format. Not modeled. 4. ~~**16-bit counter (block 79)**~~ — FIXED: `BlockAccess.write_mode="counter"` in memory model, LE16 increment with 0xFFFF saturation.
5. **Protection pointer access conditions** — datasheet defines Page L / Page H with separate read/write protection bits (Extended Protection Status byte). Model uses simpler `protection_pointer` integer. 5. **Protection pointer access conditions** — datasheet defines Page L / Page H with separate read/write protection bits (Extended Protection Status byte). Model uses simpler `protection_pointer` integer.
6. ~~**CC byte 3 MBREAD flag missing**~~ — FIXED: NFC Type 5 CC byte 3 was `0x00` (no MBREAD), causing phones to never send READ MULTIPLE BLOCKS. Real SLIX2 tags advertise `0x01` (MBREAD supported). Without this flag, Android NFC reads CC + system info then gives up — it won't fall back to READ SINGLE BLOCK for NDEF data. Fixed in `NfcType5Tag._write_cc()` for all Type 5 tags.
### Implementation Priority ### Implementation Priority
**Next session — must haves:** **Completed (2026-03-17):**
1. GET NXP SYSTEM INFO (0xAB) — static response from tag config 1. ~~GET NXP SYSTEM INFO (0xAB)~~ — model + table compiler
2. READ SIGNATURE (0xBD) — static 32-byte signature 2. ~~READ SIGNATURE (0xBD)~~ — model + table compiler
3. ENABLE PRIVACY (0xBA) — XOR password, enter privacy mode 3. ~~ENABLE PRIVACY (0xBA)~~ — model + table compiler
4. EAS/AFI password (pwd_id 0x10) — add to model 4. ~~EAS/AFI password (pwd_id 0x10)~~ — model + table compiler
5. PROTECT PAGE (0xB6) — set protection pointer via RF 5. ~~PROTECT PAGE (0xB6)~~ — model (write auth required)
Also: Fixed 0xA1/0xA2 names (FAST INVENTORY READ / SET EAS), removed fake config registers,
fixed privacy mode to allow GET_RANDOM, SET_PASSWORD uses XOR with GET_RANDOM.
**After that — should haves:** **Completed (2026-03-18):**
6. WRITE PASSWORD (0xB4) 6. ~~WRITE PASSWORD (0xB4)~~ — model (requires prior SET PASSWORD auth, XOR password)
7. LOCK PASSWORD (0xB5) 7. ~~LOCK PASSWORD (0xB5)~~ — model (permanently locks password, prevents WRITE PASSWORD)
8. DESTROY (0xB9) 8. ~~DESTROY (0xB9)~~ — model (irreversibly kills tag, XOR password, no prior auth)
9. LOCK PAGE PROTECTION (0xB7) 9. ~~LOCK PAGE PROTECTION (0xB7)~~ — model (permanently locks PP config, requires write auth)
10. 64-BIT PASSWORD PROTECTION (0xBB) 10. ~~64-BIT PASSWORD PROTECTION (0xBB)~~ — model (requires both read + write auth)
**Later — nice to haves:** **Completed (2026-03-18):**
11-16. EAS subsystem, INVENTORY READ, STAY QUIET PERSISTENT, counter handling 11. ~~EAS subsystem (0xA2-0xA7)~~ — SET/RESET/LOCK EAS, EAS ALARM, PASSWORD PROTECT EAS/AFI, WRITE EAS ID
12. ~~INVENTORY READ / FAST INVENTORY READ (0xA0/0xA1)~~ — returns UID + block data
13. ~~STAY QUIET PERSISTENT (0xBC)~~ — survives power cycles
**Completed (2026-03-18):**
14. ~~Block 79 counter~~`write_mode="counter"` in BlockAccess, LE16 increment with saturation at 0xFFFF
**All SLIX2 commands implemented.** No remaining gaps.
### Cross-IC Command Scope (2026-03-18)
Full transponder audit against datasheets (SL2S2002, SL2S3003, SL2S6002, NTP5210, NTA5332, AN11809) found command scope issues in the class hierarchy:
1. **SLIX (SL2S2002) had 3 excess commands** — 0xAB (GET NXP SYSTEM INFO), 0xBD (READ SIGNATURE), 0xA7 (WRITE EAS ID) were dispatched at the SLIX/NxpIcodeTag level but are SLIX2+ only per SL2S2002 datasheet and AN11809. Moved dispatch to IcodeSlix2Tag.
2. **NTAG 5 had STAY QUIET PERSISTENT (0xBC) but shouldn't** — inherited from IcodeSlix2Tag. NTP5210 and NTA5332 datasheets omit it; feature flags confirm PERS_QUIET=0b. Blocked at Ntag5PlatformTag.
3. **NTAG 5 was missing WRITE SRAM (0xD3)** — NTA5332 Table 122 lists it. Added to Ntag5LinkTag.
4. **NTAG 5 was missing AREA_1 password IDs (0x40/0x80)** — NTP5210/NTA5332 datasheets list these. Added to Ntag5PlatformTag.
5. **NTAG 5 was missing PICK RANDOM UID (0xC2)** — NTA5332 datasheet 8.2.4.9.15. Added to Ntag5PlatformTag (AES mode).
See `docs/plans/2026-03-18-transponder-audit-fixes.md` for full audit plan.

1
firmware Submodule

Submodule firmware added at 8f8b9c51a1