Phase 1 of package refactor. Moves all source modules into pm3py/core/ with file renames (hf_14a→hf_iso14a, hf_15→hf_iso15, hf_mf→hf_mfc) and client attribute normalization (hf.a14→hf.iso14a, hf.mf→hf.mfc). pm3py/__init__.py re-exports from core for backward compat. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
262 lines
6.4 KiB
Python
262 lines
6.4 KiB
Python
"""Proxmark3 NG wire protocol constants and CRC."""
|
|
import struct
|
|
from enum import IntEnum
|
|
|
|
# --- Magic values ---
|
|
CMD_PREAMBLE_MAGIC = 0x61334d50 # "PM3a"
|
|
RESP_PREAMBLE_MAGIC = 0x62334d50 # "PM3b"
|
|
CMD_POSTAMBLE_NOCRC = 0x3361 # "a3"
|
|
RESP_POSTAMBLE_NOCRC = 0x3362 # "b3"
|
|
|
|
PM3_CMD_DATA_SIZE = 512
|
|
|
|
# --- Frame formats (little-endian) ---
|
|
CMD_PREAMBLE_FMT = "<IHH" # magic(4) + length_ng(2) + cmd(2) = 8 bytes
|
|
CMD_PREAMBLE_SIZE = 8
|
|
CMD_POSTAMBLE_FMT = "<H" # crc(2) = 2 bytes
|
|
CMD_POSTAMBLE_SIZE = 2
|
|
|
|
RESP_PREAMBLE_FMT = "<IHbbH" # magic(4) + length_ng(2) + status(1) + reason(1) + cmd(2) = 10 bytes
|
|
RESP_PREAMBLE_SIZE = 10
|
|
RESP_POSTAMBLE_FMT = "<H"
|
|
RESP_POSTAMBLE_SIZE = 2
|
|
|
|
# --- MIX frame: 3x uint64 args at start of payload ---
|
|
MIX_ARGS_FMT = "<QQQ"
|
|
MIX_ARGS_SIZE = 24
|
|
|
|
# --- CRC-16/A (ISO 14443-3) ---
|
|
_CRC_TABLE: list[int] = []
|
|
|
|
def _reflect8(b: int) -> int:
|
|
r = 0
|
|
for i in range(8):
|
|
if b & (1 << i):
|
|
r |= 1 << (7 - i)
|
|
return r
|
|
|
|
def _reflect16(v: int) -> int:
|
|
r = 0
|
|
for i in range(16):
|
|
if v & (1 << i):
|
|
r |= 1 << (15 - i)
|
|
return r
|
|
|
|
def _init_crc_table() -> None:
|
|
global _CRC_TABLE
|
|
if _CRC_TABLE:
|
|
return
|
|
poly = 0x1021
|
|
_CRC_TABLE = [0] * 256
|
|
for i in range(256):
|
|
c = _reflect8(i) << 8
|
|
crc = 0
|
|
for _ in range(8):
|
|
if (crc ^ c) & 0x8000:
|
|
crc = ((crc << 1) ^ poly) & 0xFFFF
|
|
else:
|
|
crc = (crc << 1) & 0xFFFF
|
|
c = (c << 1) & 0xFFFF
|
|
_CRC_TABLE[i] = _reflect16(crc)
|
|
|
|
def crc16_a(data: bytes) -> int:
|
|
"""CRC-16/A: poly=0x1021, init=0xC6C6, refin=true, refout=true, xorout=0x0000."""
|
|
_init_crc_table()
|
|
crc = _reflect16(0xC6C6)
|
|
for b in data:
|
|
crc = ((crc >> 8) ^ _CRC_TABLE[(crc & 0xFF) ^ b]) & 0xFFFF
|
|
return crc
|
|
|
|
|
|
# --- Error codes ---
|
|
class PM3Status(IntEnum):
|
|
SUCCESS = 0
|
|
EUNDEF = -1
|
|
EINVARG = -2
|
|
EDEVNOTSUPP = -3
|
|
ETIMEOUT = -4
|
|
EOPABORTED = -5
|
|
ENOTIMPL = -6
|
|
ERFTRANS = -7
|
|
EIO = -8
|
|
EOVFLOW = -9
|
|
ESOFT = -10
|
|
EFLASH = -11
|
|
EMALLOC = -12
|
|
EFILE = -13
|
|
ENOTTY = -14
|
|
EINIT = -15
|
|
EWRONGANSWER = -16
|
|
EOUTOFBOUND = -17
|
|
ECARDEXCHANGE = -18
|
|
EAPDU_ENCODEFAIL = -19
|
|
EAPDU_FAIL = -20
|
|
EFAILED = -21
|
|
EPARTIAL = -22
|
|
ETEAROFF = -23
|
|
ECRC = -24
|
|
ESTATIC_NONCE = -25
|
|
ENOPACS = -26
|
|
ELENGTH = -27
|
|
ENOKEY = -28
|
|
ECRYPTO = -29
|
|
ENOFILE = -30
|
|
ENODATA = -98
|
|
EFATAL = -99
|
|
|
|
|
|
# --- Command IDs ---
|
|
class Cmd(IntEnum):
|
|
# Bootloader
|
|
DEVICE_INFO = 0x0000
|
|
FINISH_WRITE = 0x0003
|
|
HARDWARE_RESET = 0x0004
|
|
START_FLASH = 0x0005
|
|
CHIP_INFO = 0x0006
|
|
BL_VERSION = 0x0007
|
|
|
|
# Debug
|
|
DEBUG_PRINT_STRING = 0x0100
|
|
DEBUG_PRINT_INTEGERS = 0x0101
|
|
DEBUG_PRINT_BYTES = 0x0102
|
|
|
|
# System
|
|
NACK = 0x00FE
|
|
ACK = 0x00FF
|
|
BUFF_CLEAR = 0x0105
|
|
READ_MEM = 0x0106
|
|
VERSION = 0x0107
|
|
STATUS = 0x0108
|
|
PING = 0x0109
|
|
READ_MEM_DOWNLOAD = 0x010A
|
|
READ_MEM_DOWNLOADED = 0x010B
|
|
DOWNLOAD_EML_BIGBUF = 0x0110
|
|
DOWNLOADED_EML_BIGBUF = 0x0111
|
|
CAPABILITIES = 0x0112
|
|
QUIT_SESSION = 0x0113
|
|
SET_DBGMODE = 0x0114
|
|
STANDALONE = 0x0115
|
|
WTX = 0x0116
|
|
TIA = 0x0117
|
|
BREAK_LOOP = 0x0118
|
|
SET_TEAROFF = 0x0119
|
|
LED_CONTROL = 0x011A
|
|
GET_DBGMODE = 0x0120
|
|
|
|
# FPGA
|
|
FPGA_MAJOR_MODE_OFF = 0x0500
|
|
|
|
# LF
|
|
LF_TI_READ = 0x0202
|
|
LF_TI_WRITE = 0x0203
|
|
LF_ACQ_RAW_ADC = 0x0205
|
|
LF_MOD_THEN_ACQ_RAW_ADC = 0x0206
|
|
DOWNLOAD_BIGBUF = 0x0207
|
|
DOWNLOADED_BIGBUF = 0x0208
|
|
LF_UPLOAD_SIM_SAMPLES = 0x0209
|
|
LF_SIMULATE = 0x020A
|
|
LF_HID_WATCH = 0x020B
|
|
LF_HID_SIMULATE = 0x020C
|
|
LF_SET_DIVISOR = 0x020D
|
|
LF_SIMULATE_BIDIR = 0x020E
|
|
SET_ADC_MUX = 0x020F
|
|
LF_HID_CLONE = 0x0210
|
|
LF_EM410X_CLONE = 0x0211
|
|
LF_T55XX_READBL = 0x0214
|
|
LF_T55XX_WRITEBL = 0x0215
|
|
LF_T55XX_RESET_READ = 0x0216
|
|
LF_PCF7931_READ = 0x0217
|
|
LF_EM4X_READWORD = 0x0218
|
|
LF_EM4X_WRITEWORD = 0x0219
|
|
LF_IO_WATCH = 0x021A
|
|
LF_EM4X_PROTECTWORD = 0x021B
|
|
LF_EM410X_WATCH = 0x021C
|
|
LF_SAMPLING_SET_CONFIG = 0x021D
|
|
LF_FSK_SIMULATE = 0x021E
|
|
LF_ASK_SIMULATE = 0x021F
|
|
LF_PSK_SIMULATE = 0x0220
|
|
LF_AWID_WATCH = 0x0221
|
|
LF_VIKING_CLONE = 0x0222
|
|
LF_PCF7931_WRITE = 0x0223
|
|
LF_T55XX_WAKEUP = 0x0224
|
|
LF_COTAG_READ = 0x0225
|
|
LF_T55XX_SET_CONFIG = 0x0226
|
|
LF_SAMPLING_PRINT_CONFIG = 0x0227
|
|
LF_SAMPLING_GET_CONFIG = 0x0228
|
|
LF_EM4X_LOGIN = 0x0229
|
|
LF_EM4X_BF = 0x022A
|
|
LF_T55XX_CHK_PWDS = 0x0230
|
|
LF_T55XX_DANGERRAW = 0x0231
|
|
LF_NRZ_SIMULATE = 0x0232
|
|
LF_SNIFF_RAW_ADC = 0x0360
|
|
LF_HITAG_SNIFF = 0x0370
|
|
|
|
# HF General
|
|
HF_ACQ_RAW_ADC = 0x0301
|
|
HF_ISO15693_ACQ_RAW_ADC = 0x0300
|
|
HF_ISO15693_READER = 0x0310
|
|
HF_ISO15693_SIMULATE = 0x0311
|
|
HF_ISO15693_SNIFF = 0x0312
|
|
HF_ISO15693_COMMAND = 0x0313
|
|
HF_ISO15693_FINDAFI = 0x0315
|
|
HF_ISO15693_CSETUID = 0x0316
|
|
|
|
HF_ISO14443A_SNIFF = 0x0383
|
|
HF_ISO14443A_SIMULATE = 0x0384
|
|
HF_ISO14443A_READER = 0x0385
|
|
HF_ISO14443A_GET_CONFIG = 0x03B1
|
|
HF_ISO14443A_SET_CONFIG = 0x03B2
|
|
|
|
HF_ISO14443B_COMMAND = 0x0305
|
|
HF_ISO14443B_SIMULATE = 0x0381
|
|
HF_ISO14443B_SNIFF = 0x0382
|
|
|
|
# Tuning
|
|
MEASURE_ANTENNA_TUNING = 0x0400
|
|
MEASURE_ANTENNA_TUNING_HF = 0x0401
|
|
MEASURE_ANTENNA_TUNING_LF = 0x0402
|
|
LISTEN_READER_FIELD = 0x0420
|
|
HF_DROPFIELD = 0x0430
|
|
HF_DECAY = 0x0440
|
|
|
|
# MIFARE Classic
|
|
HF_MIFARE_EML_MEMCLR = 0x0601
|
|
HF_MIFARE_EML_MEMSET = 0x0602
|
|
HF_MIFARE_EML_MEMGET = 0x0603
|
|
HF_MIFARE_SIMULATE = 0x0610
|
|
HF_MIFARE_READER = 0x0611
|
|
HF_MIFARE_NESTED = 0x0612
|
|
HF_MIFARE_ACQ_ENCRYPTED_NONCES = 0x0613
|
|
HF_MIFARE_ACQ_NONCES = 0x0614
|
|
HF_MIFARE_STATIC_NESTED = 0x0615
|
|
HF_MIFARE_READBL = 0x0620
|
|
HF_MIFARE_READSC = 0x0621
|
|
HF_MIFARE_WRITEBL = 0x0622
|
|
HF_MIFARE_CHKKEYS = 0x0623
|
|
HF_MIFARE_SETMOD = 0x0624
|
|
HF_MIFARE_CHKKEYS_FAST = 0x0625
|
|
HF_MIFARE_CHKKEYS_FILE = 0x0626
|
|
HF_MIFARE_VALUE = 0x0627
|
|
HF_MIFARE_READBL_EX = 0x0628
|
|
HF_MIFARE_WRITEBL_EX = 0x0629
|
|
HF_MIFARE_SNIFF = 0x0630
|
|
HF_MIFARE_MFKEY = 0x0631
|
|
HF_MIFARE_PERSONALIZE_UID = 0x0632
|
|
HF_MIFARE_CSETBL = 0x0605
|
|
HF_MIFARE_CGETBL = 0x0606
|
|
HF_MIFARE_CIDENT = 0x0607
|
|
|
|
# MIFARE Ultralight
|
|
HF_MIFAREU_READBL = 0x0720
|
|
HF_MIFAREU_READCARD = 0x0721
|
|
HF_MIFAREU_WRITEBL = 0x0722
|
|
HF_MIFARE_NACK_DETECT = 0x0730
|
|
|
|
# HF Sniff/Plot
|
|
HF_SNIFF = 0x0800
|
|
HF_PLOT = 0x0801
|
|
FPGAMEM_DOWNLOAD = 0x0802
|
|
FPGAMEM_DOWNLOADED = 0x0803
|
|
|
|
UNKNOWN = 0xFFFF
|