Add files via upload

This commit is contained in:
Niel Nielsen
2026-05-07 20:07:23 +02:00
committed by GitHub
parent f8b0ae6085
commit 36daf7038c
2 changed files with 28 additions and 11 deletions
+9 -2
View File
@@ -7583,10 +7583,15 @@ class HF14AAuthTrace(ReaderRequiredUnit):
"-k", "--key", type=str, required=True, metavar="<hex>",
help="6-byte sector key (12 hex chars)"
)
parser.add_argument(
"-t", "--timeout", type=int, default=5000, metavar="<ms>",
help="Tag-presence polling timeout in ms (1-30000, default 5000)"
)
parser.epilog = """
examples:
hf 14a auth-trace --blk 0 -k FFFFFFFFFFFF
hf 14a auth-trace --blk 4 -b -k A0A1A2A3A4A5
hf 14a auth-trace --blk 0 -k FFFFFFFFFFFF -t 10000 # wait up to 10s for tag
"""
return parser
@@ -7599,13 +7604,15 @@ examples:
key_bytes = bytes.fromhex(key_hex)
key_type = 0x61 if args.b else 0x60
block = args.blk
timeout_ms = max(1, min(30000, int(args.timeout)))
print(f" Running auth trace: block={block} keyType={'B' if args.b else 'A'} key={key_hex.upper()}")
print(" Place CU on a MIFARE Classic card now.")
print(f" Waiting up to {timeout_ms} ms for a MIFARE Classic card... "
f"({CY}place CU on a card now{C0})")
print()
try:
resp = self.cmd.hf14a_auth_trace(block, key_type, key_bytes)
resp = self.cmd.hf14a_auth_trace(block, key_type, key_bytes, timeout_ms=timeout_ms)
except Exception as e:
if 'CMDInvalid' in type(e).__name__ or '2017' in str(e):
print(f"{CR}Command not supported — reflash firmware to enable hf 14a auth-trace{C0}")
+19 -9
View File
@@ -535,28 +535,38 @@ class ChameleonCMD:
timeout_s = (timeout_ms // 1000) + 5
return self.device.send_cmd_sync(Command.HF14A_SNIFF, payload, timeout=timeout_s)
def hf14a_auth_trace(self, block: int, key_type: int, key: bytes):
def hf14a_auth_trace(self, block: int, key_type: int, key: bytes, timeout_ms: int = 5000):
"""
Run a full reader-side ISO14443A + MIFARE Classic Crypto1 auth flow
against a real card and return every wire frame for inspection.
The firmware performs anticoll + SELECT + (optional RATS) + AUTH and
packs all frames — synthesized anticoll plus the live AUTH/NT/NR||AR/AT
— into the same buffer format used by hf14a_sniff:
The firmware polls for a tag in the field for up to `timeout_ms`
milliseconds, then performs anticoll + SELECT + (optional RATS) +
AUTH and packs all frames — synthesized anticoll plus the live
AUTH/NT/NR||AR/AT — into the same buffer format used by hf14a_sniff:
[2 bytes: bit count, big-endian] [N bytes: frame data, ceil(bits/8)] ...
Bit 15 of the bit-count header: 0 = reader→card, 1 = card→reader.
:param block: target block number (0-255)
:param key_type: 0x60 (Key A) or 0x61 (Key B)
:param key: 6-byte sector key
:param block: target block number (0-255)
:param key_type: 0x60 (Key A) or 0x61 (Key B)
:param key: 6-byte sector key
:param timeout_ms: tag-presence polling timeout in ms (1-30000)
:return: Raw response — check .status and .data
"""
if key_type not in (0x60, 0x61):
raise ValueError("key_type must be 0x60 (Key A) or 0x61 (Key B)")
if len(key) != 6:
raise ValueError("key must be exactly 6 bytes")
payload = bytes([key_type, block & 0xFF]) + bytes(key)
return self.device.send_cmd_sync(Command.HF14A_AUTH_TRACE, payload, timeout=3)
timeout_ms = max(1, min(30000, int(timeout_ms)))
payload = (
bytes([key_type, block & 0xFF])
+ bytes(key)
+ bytes([(timeout_ms >> 8) & 0xFF, timeout_ms & 0xFF])
)
# Add a couple of seconds of slack on top of the device-side polling
# window so the USB/BLE round-trip doesn't time out before firmware
# gives up on its own.
return self.device.send_cmd_sync(Command.HF14A_AUTH_TRACE, payload, timeout=(timeout_ms // 1000) + 3)
@expect_response(Status.SUCCESS)
def hf14a_get_config(self):