diff --git a/pm3py/core/hf_iso14a.py b/pm3py/core/hf_iso14a.py index ad129fc..58ec4a4 100644 --- a/pm3py/core/hf_iso14a.py +++ b/pm3py/core/hf_iso14a.py @@ -71,26 +71,58 @@ class HF14ACommands: async def sniff(self, param: int = 0) -> dict: """Sniff ISO14443A traffic.""" - resp = await self._t.send_mix( - Cmd.HF_ISO14443A_SNIFF, arg0=param, timeout=30.0, + resp = await self._t.send_ng( + Cmd.HF_ISO14443A_SNIFF, payload=bytes([param]), timeout=30.0, ) return {"status": resp.status} - async def sim(self, uid: bytes, sak: int = 0x08, atqa: bytes = b"\x04\x00", - flags: int = 0) -> dict: - """Simulate ISO14443A card.""" - if len(uid) == 4: - uid_flag = 0x0010 - elif len(uid) == 7: - uid_flag = 0x0020 - elif len(uid) == 10: - uid_flag = 0x0030 + async def sim(self, tagtype: int = 1, uid: bytes = b"", exit_after: int = 0, + flags: int = 0, rats: bytes = b"", + ulauth_1a1: bytes = b"", ulauth_1a2: bytes = b"", + ulauth_1a2_mirror: bool = False) -> dict: + """Simulate an ISO14443A tag. + + tagtype selects the emulated tag: 1=MIFARE Classic 1k, 2=Ultralight, + 3=DESFire, 4=ISO14443-4, 5=Tnp3xxx, 6=MF Mini, 7=MFU EV1/NTAG215, + 8=MFC 4k, 9=FM11RF005SH, 10=ST25TA, 11=JCOP, 12=Seos, 13=ULC, + 14=ULAES, 15=MF Plus. + + uid: 4, 7, or 10 raw bytes. Empty = take UID from emulator memory. + exit_after: stop after N reader reads (0 = infinite). + ulauth_1a1/ulauth_1a2: ULC (8 byte) / ULAES (16 byte) auth replies. + """ + # Fold the UID length into flags per FLAG_SET_UID_IN_DATA (pm3_cmd.h). + if uid: + if len(uid) == 4: + uid_flag = 0x0010 # FLAG_4B_UID_IN_DATA + elif len(uid) == 7: + uid_flag = 0x0020 # FLAG_7B_UID_IN_DATA + elif len(uid) == 10: + uid_flag = 0x0030 # FLAG_10B_UID_IN_DATA + else: + raise ValueError("UID must be 4, 7, or 10 bytes") else: - raise ValueError("UID must be 4, 7, or 10 bytes") + uid_flag = 0x0000 # FLAG_UID_IN_EMUL - flag_val = flags | uid_flag | 0x0001 # FLAG_INTERACTIVE - payload = atqa + bytes([sak]) + uid - resp = await self._t.send_mix( - Cmd.HF_ISO14443A_SIMULATE, arg0=flag_val, timeout=60.0, payload=payload, + flag_val = (flags & ~0x0030) | uid_flag # FLAG_MASK_UID = 0x0030 + + # struct { u8 tagtype; u16 flags; u8 uid[10]; u8 exitAfter; + # u8 rats[20]; u8 ulauth_1a1_len; u8 ulauth_1a2_len; + # u8 ulauth_1a1[16]; u8 ulauth_1a2[16]; bool mirror; } PACKED + payload = struct.pack( + "