Commit Graph
14298 Commits
Author SHA1 Message Date
iceman1001andClaude Opus 5 (1M context) ee2d55fafb hf mfdes: put a DESFire card image in emulator memory
Adds the on-device card image a DESFire simulation will read, the client
side that packs a dump into it, and eload / esave / eview.

The layout is in include/desfire_em.h. Tables grow up from the header,
file data grows down from the end, and an allocation only has to leave
the two frontiers apart -- so a three-file card spends a few hundred
bytes rather than a worst case, and the space between them is what the
card has left. The PICC is application 000000 and uses the same struct
as any other application, so key settings and keys are always stated
against an AID. Delete sets a tombstone rather than compacting, which is
not a shortcut: a real card does not reclaim on delete either, measured
as 2080 bytes free with zero applications before an experiment and 2560
after FormatPICC.

Two size limits, and a reader only ever sees the first. cardsize is what
the emulated card claims to hold, so GetFreeMem answers from that and
CreateFile will refuse with OUT_OF_EEPROM when it runs out. Without it a
card impersonating a 2K part would report 7434 bytes free, which no 2K
part does. The image size is what emulator memory physically holds, is
the harder limit, and is never visible.

cardsize is anchored to the free memory the real card reported when the
dump was taken -- observed free plus what we reserve for the same content
-- so the emulation answers what its original answered. That is also a
check on the reservation rule rather than only a convenience: for the
bench card it computed 576 bytes spent, and 1984 + 576 is 2560, exactly
what that card reports when formatted.

Reservation follows what CommitTransaction covers. Backup data, value and
record files each get a shadow region because writes to them are staged
until commit; a standard data file writes through and does not. Sizes
round to a 32 byte granule, which is the granule a real card allocates in.
It deliberately does not reproduce NXP's allocator -- that is
undocumented and does not fit a simple model, a declared 1024 byte record
file costs 1088 on silicon -- so what matters is that the figure is
self-consistent and shrinks as the reader writes.

No new device command. Emulator memory is one shared region, so
CMD_HF_MIFARE_EML_MEMSET and BIG_BUF_EML already reach it, and both
inherit the bounds checking those paths gained earlier.

Verified with the client only, no simulation yet: packing a dump taken
from a DESFire EV2 and walking it back reproduces every field including
file contents byte for byte, the same round trip through the device via
eload and esave is identical, and an image too large is refused by name
rather than truncated -- 'Out of emulator memory laying out AID 112233
file 00: needs 4066 more bytes'.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-14 19:48:45 +02:00
iceman1001 669319b690 update desfire dumpformat to support verison HW,SW,PROD 2026-09-14 19:39:42 +02:00
iceman1001 95f6072e94 minor parse fix for vigik 2026-09-14 19:35:34 +02:00
iceman1001 064f8dd071 added a warning for anti clone counter measures 2026-09-14 18:32:53 +02:00
Niel Nielsen 5f641c6f75 Merge branch 'RfidResearchGroup:master' into master 2026-09-14 16:20:54 +02:00
iceman1001 d2dd2d9f32 text 2026-09-14 14:58:54 +02:00
Niel Nielsen 259f15e7df Merge branch 'RfidResearchGroup:master' into master 2026-09-14 13:11:49 +02:00
iceman1001 8393783548 one more entry in the mad 2026-09-14 12:40:51 +02:00
iceman1001 8f5fd048d3 improve emulator downloads with out of bounds checks 2026-09-14 12:27:06 +02:00
iceman1001 465deeda39 text 2026-09-14 12:24:31 +02:00
iceman1001 aae70014e0 - VIGIK service badge fields now show which ones the RSA signature actually covers 2026-09-14 12:21:47 +02:00
iceman1001 9caa6d6117 minor change we device now reports back EMULATOR memory size to the client. Had to bump capability version number to 11. 2026-09-14 12:16:51 +02:00
iceman1001andClaude Opus 5 (1M context) 6f4643a637 hf mf: add the MAD helpers parseproac needs, and register AID 0x4982
b82f60362 landed parseproac.c without them, so a clean checkout does not
build.

 - mad.c / mad.h: mad_find_aid() and mad_count_aid(); DetectHID() delegates
   to the first, it was already generic
 - mad.json: 0x4982 PROAC, sorted in after NORALSY's 0x4980

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-14 12:13:35 +02:00
iceman1001 b82f603622 urmet parsing 2026-09-14 12:11:42 +02:00
Niel Nielsen 2cbd193d7b Update BLE function comments for clarity and consistency
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-14 11:47:32 +02:00
Niel Nielsen 5922a7112f Update BLE name resolution to use BlueZ mgmt API
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-14 11:47:08 +02:00
iceman1001andClaude Opus 5 (1M context) 82783eae26 hf mf: decode the Hexact payload
Sectors 9 and 11 were printed raw and marked 'not decoded'.

 - remove the XOR keystream and print the ten eight byte records
 - check the eighteen record bytes that are XOR combinations of sector 0,
   sector 15 and the UID, plus three record to record ties
 - 'hf mf view --selftest' now covers the decoder, using a synthetic card
 - sector 15 marker compare ignores case, factory blanks were not matched
 - an all FF or all 00 payload is named, not decrypted
 - sector 15 block 2 is text on a blank, so only read a serial there when
   the first four bytes are not printable

Research. The remaining 58 payload bytes are issuer data and are printed
without interpretation.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-14 09:19:05 +02:00
iceman1001andClaude Opus 5 (1M context) 8fd9bcbebc hf mfdes: dump a whole card to json, and view it back
'hf mfdes dump' walked one application and printed it. It now walks
every application on the PICC, keeps what it reads, and saves a
'hf-mfdes-<UID>-dump.json' card image. '--aid' / '--isoid' / '--dfname'
still narrow it to one application, '--ns' skips the save.

The format is 'mfdes v1', written and read in fileutils.c and documented
in doc/mfdes_dump_format.md. Two decisions worth stating:

 - The PICC level is application 000000, so every key in the file says
   which AID it opens. Key version and key value are separate: a version
   with no key is the normal shape for a key that was found but never
   recovered, and a missing key never means the key is zero.

 - Every file carries a 'Read' flag. A file whose contents could not be
   fetched is recorded as unread with no data at all, rather than as a
   run of zeros. A simulator built on this must not confuse '8 bytes of
   00' with 'we could not read 8 bytes'.

'hf mfdes view -f <fn>' prints such a file with no device attached.

With no '--keys', the dump looks for 'hf-mfdes-<UID>-keys.json' by
itself, so a 'hf mfdes chk -j' run is picked up on the next dump without
naming the file again.

Two fixes fell out of testing against a DESFire EV2:

 - DesfireSetKey() calls DesfireClearContext(), which wipes command set,
   comm mode, KDF and UID, not just the key. Swapping in a per-application
   key that way left the context at 'Communication mode: n/a' and
   DesfireFillFileList() then returned junk file ids. Use
   DesfireSetKeyNoClear().

 - GetVersion and the originality signature are answered unauthenticated.
   Asking for them from inside the authenticated session produced a
   'Wrong communication mode' warning and a run of MAC mismatches.

hex_to_buffer() treats hex_max_len as a byte count while every sprint_hex*
caller passes sizeof(buf) - 1, a character count, so it writes two or
three times the buffer size. Measured, sprint_hex_inrow overflowed at
4098 input bytes. Doubling UTIL_BUFFER_SIZE_SPRINT to 16384 moves that to
8192; the mixed semantics still need auditing across ~30 call sites.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-14 09:11:38 +02:00
Niel Nielsen 1b9eb458ec Merge branch 'RfidResearchGroup:master' into esp32-c2 2026-09-13 18:22:48 +02:00
iceman1001 64b5db4ddd text 2026-09-13 18:22:27 +02:00
Niel Nielsen 284e4b385c Refactor BLE error handling and time functions
Refactor BLE error handling to return standard error codes instead of PM3_* constants. Update time-related functions to use a consistent method for obtaining the current time.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 17:58:45 +02:00
Niel Nielsen 583f05198a Add parsehexact.c to CMakeLists.txt
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 17:57:07 +02:00
Niel Nielsen 0a90b714cc Add files via upload
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 17:31:12 +02:00
Niel Nielsen bf703c24ff Merge branch 'RfidResearchGroup:master' into esp32-c2 2026-09-13 17:03:14 +02:00
Niel Nielsen 50e07859e8 Refactor error handling in select function
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 16:25:09 +02:00
iceman1001andClaude Opus 5 (1M context) e19c6755fe hf mf: stop a refused nested auth from hanging autopwn and eating the keys
MifareNested collected nonces in 'while (target_nt[i] == 0)' with no
attempt counter. When the tag NAKs the nested authentication the loop
re-sent the identical frame forever, so the client's 2s wait expired and
autopwn returned PM3_ETIMEOUT — throwing away every key recovered up to
that point. Reported on a card whose sector 16 refuses the standard MFC
EV1 keys: 32 keys cracked, nothing saved.

A NAK is a refusal, not a glitch, so the device now gives up on it and
reports PM3_EWRONGANSWER. autopwn names the sector it skipped and carries
on, and a timeout falls through to the key table and the dump whenever
anything was recovered.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-13 15:56:41 +02:00
iceman1001 c615ef8930 adapting parser 2026-09-13 15:52:39 +02:00
Niel Nielsen 510767f51e Update return values in ble_posix.h documentation
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 14:54:45 +02:00
Niel Nielsen cdc4d7ad26 Refactor BLE connection error handling and logging
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 14:54:07 +02:00
Niel Nielsen 52fac7ca1b Add parsehexact.c to Makefile build list
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 13:44:42 +02:00
Niel Nielsen ea585bacd6 Fix include directive for dependency files in Makefile
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 13:18:57 +02:00
Niel Nielsen 28daf3e2c4 Enhance BLE capabilities hint and connection logic
Add hints for granting BLE scanning privileges and improve error handling in connection functions.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 13:15:40 +02:00
Niel Nielsen 84dd953cf4 Merge branch 'RfidResearchGroup:master' into esp32-c2 2026-09-13 13:12:32 +02:00
iceman1001andClaude Opus 5 (1M context) 66f9a6b51f hf mfdes: report a select/auth failure once, not twice
DesfireSelectAndAuthenticate*() and its callers both printed the same
error at different severities, so every failure came out as two lines.
The core helper now owns the message and names the AID and the step;
the 23 restatements in cmdhfmfdes.c are gone. Same duplicate pair fixed
in cmdhfgallagher.c.

Also: DesfireAuthErrorToStr() falls back to DesfireGetErrorString() for
the PM3_E* codes the select paths pass through, which used to print an
empty reason, and auth error 7 no longer reuses the text of error 1.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-13 12:58:46 +02:00
iceman1001 7142ddc9bd added hexact parser 2026-09-13 12:55:43 +02:00
Niel Nielsen 7efc83ca1d Implement BD address validation and update BLE logic
Added a function to check if a string is a valid Bluetooth address and updated the BLE connection logic to handle both addresses and names.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 12:44:15 +02:00
Niel Nielsen dcde9dd16e Add ble_resolve_name function for device name resolution
Added a function to resolve advertised device names to their LE addresses.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 12:43:40 +02:00
Niel Nielsen e0fbc4174c Add includes for string and time functions
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 12:43:10 +02:00
iceman1001andClaude Opus 5 (1M context) 72f48c8a02 fileutils: honor a filename extension the user supplied
'-f card.mfd' looked for card.mfd.bin and saved to card.mfd.bin,
because the caller's suffix was appended unless the name already
ended in that exact suffix.

searchFile() now tries the name as typed before falling back to the
suffixed one.  newfilenamemcopyEx() keeps an extension that denotes
the same kind of file it is about to write, and swaps any other for
its own, so 'hf mf dump -f card.mfd' gives card.mfd + card.json
rather than card.mfd + card.mfd.json.  Both classify with
get_filetype() so load and save cannot drift apart.

Also drops the size_t underflow in newfilenamemcopyEx(), where a long
path plus a configured save path made the snprintf bound wrap past
the 1000 byte buffer.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-13 12:19:53 +02:00
iceman1001andClaude Opus 5 (1M context) c77d6455f5 hf mf: identify VIGIK family systems by their static key sets
is_valid_vigik_card() only fired when the MAD advertised aid 0x4910. Plenty of
VIGIK based deployments ship no MAD at all - a Hexact card has HEXACT as key A
on every sector and nothing in sector 0 block 1 - so hf mf view and hf mf dump
--ns said nothing whatsoever about them.

These systems use the same keys on every card they issue, which makes them
identifiable outright. Take the schemas out of armsrc/Standalone/hf_colin.c,
where they sit commented out inside the standalone mode, and match a whole dump
against them:

  Infineon / Hexact / COGELEC / Intratone   key A HEXACT x16, 15 static key B
  Noralsy                                   ALARON / BLARON
  Urmet Captiv                              8829da9daf76 throughout
  VIGIK service badge                       MAD key, then 1KIGIV on sectors 1-4

Every slot a schema pins down has to match, VIGIK_KEY_ANY marks the ones it does
not, so there are 31 exact keys to hit for Hexact and no room for a coincidence.
A HID card carrying a MAD, and a card on default keys, both still match nothing.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-13 09:18:08 +02:00
iceman1001andClaude Opus 5 (1M context) a9105c5089 hf mf: split HID and VIGIK decoding into client/src/parsers/
The shared viewer had the VIGIK sector assembly inlined, and the HID PACS
decode sat in hf mf mad's file branch where hf mf view and hf mf dump --ns
could not reach it. Neither scheme had a home of its own.

Give each one a parser next to parsehrt.c, same shape as that one - an
is_valid_x_card() detector and an x_parser_parse() that prints:

  parsers/parsehid.c    MAD aid 0x484d, PACS sector, Wiegand decode
  parsers/parsevigik.c  MAD aid 0x4910/0x4916, sector assembly

parsevigik.c also takes vigik_get_service(), vigik_verify() and
vigik_annotate() out of mifare/mifarehost.c, 306 lines that were VIGIK only
with a single caller.

mf_view_dump() is now two detector calls, so hf mf view -f and hf mf dump --ns
both decode a HID credential off a live card for the first time, and adding a
scheme is a new file plus two lines. hf mf mad -f keeps its HID decode through
the same parser.

The sector copy in the VIGIK path gains a bounds check; a MAD entry pointing
past the end of a short dump used to read past the buffer.

All three source lists get the new files: client/Makefile,
client/CMakeLists.txt and client/experimental_lib/CMakeLists.txt. The library
one matters because vigik_annotate() moved; without it anything linking
libpm3rrg_rdv4 loses the symbol.

hf mf mad against a card still cannot decode PACS. It authenticates with the
MAD key alone and never reads the application sector, so it has no credential
bytes to work with - unchanged here.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-13 08:37:17 +02:00
iceman1001andClaude Opus 5 (1M context) 36b16b943f hf mf: share the view analysis between a file and a card read
'hf mf view -f' decoded VIGIK PACS and could extract keys with '--sk'. 'hf mf dump
--ns', which reads the same 1K off the card, printed only the blocks and the
verbose key/ACL tables. Same bytes, less analysis, purely because of where they
came from so getting a PACS decode off a live card meant dumping it to a file
and viewing that.

Move everything view does once the blocks are in hand into mf_view_dump() and
call it from both. 'hf mf dump --ns' and 'hf mf view -f' now print byte identical
output for the same card, and dump gains '--sk' to match. The old view leaked its
dump buffer on both VIGIK error returns; the shared version frees it in one place.

Drops a stale commented out convert_mfc_2_arr() call referencing a pdump
variable that no longer exists.

Rounds off #1942. mfc_read_tag() and '--ns' landed long ago, this was the piece
still missing.

hf mf eview, cview and the gen4 view share the same print block but omit
mf_analyse_acl() in verbose, so folding them in changes their output and is
left for a separate decision.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-13 08:22:52 +02:00
iceman1001andClaude Opus 5 (1M context) 971c318d78 smart raw: make --t1 switch the card to T=1 by itself
A card runs the protocol its TD1 names until a PPS changes it. --t1 only
picked the module's T=1 send opcode, so on a card whose ATR offers T=0 first
the APDU went out as T=1 blocks to a card still speaking T=0 and got no
answer at all:

  smart raw --t1 -s -d 00a4040007a000000004101000
  [!] smart card response failed

'smart pps --t1' in the same client session made it work, which is what the
help for 'smart pps' already promised was unnecessary:

  Note 'smart raw --t1' already switches a card to T=1 by itself when
  the ATR offers it; this is for negotiating Fi/Di explicitly.

Do it for real. SmartCardRaw() now runs the PPS when T=1 is asked for and
nothing has selected it yet, taking the ATR it needs first because PPS is
only legal in that window. It fires once per activation: a second --t1 apdu
sees the protocol already in force and sends straight away. A card that does
not offer T=1 is left alone and the apdu still goes out, as before.

Also fix the flag names in the docs and in the error path. 'smart raw's
first example and both 'Choose either' messages said -0 / -1, which have
never existed. tools/pm3_online_tests.sh had copied the example, so its T=0
checks failed with 'invalid option' on every run; its T=1 checks needed no
change beyond dropping the now unnecessary reset.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 23:54:39 +02:00
iceman1001andClaude Opus 5 (1M context) 3853540d31 hf mfdes dump: keep the session across the ISO file id probe
DesfireFillFileList() ends with GetISOFileIDs (0x61). An application created
without ISO file ids answers 0x91F0, and the PICC ends the authentication on a
command error. The client never noticed: dctx->secureChannel still said ev1, so
every later command was framed as MACed against a dead session.

For hf mfdes dump that meant the first file was read as if its response carried
a CMAC. An 8 byte plain free access file came back as exactly 8 bytes of data,
which were consumed as the MAC, so the file content was thrown away and reported
as

  Received MAC is not match with calculated
    received MAC:   A0 A1 A2 A3 A4 A5 A6 A7
  Read operation returned no data from file 0

The next key protected file then failed with 0x91AE, and only that failure
triggered the loop's blind re-authentication, after which the rest of the dump
was correct. Dumping an application that does have ISO file ids was never
affected, because 0x61 succeeds there.

Drop our side of the session when the probe fails so the context tells the
truth, and re-authenticate in CmdHF14ADesDump before the read loop. The two
warnings the probe printed are demoted to DEBUG: an application without ISO
file ids is the normal case, not something to warn about.

Key settings 2 bit 0x20 is not usable to predict this. On a DESFire EV2 both an
application with working ISO file ids and one without report key settings 0F 83,
so the bit reads back as 0 either way.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 23:28:17 +02:00
iceman1001andClaude Opus 5 (1M context) 2449bb2472 hf mfdes: derive the communication mode from the access rights
The PICC applies a file's communication mode only when access is granted by
a key right matching the authenticated key. When the operation is granted by
the free access right (0x0E) instead, it runs in plain, whatever the file
settings say. The client used the file comm mode unconditionally, so any file
created with the default EEEE rights failed with 0x917E on write, and a free
access Full file was printed as its data plus eight unstripped CMAC bytes
instead of being decrypted. Fixes #3393.

Which rights can grant an operation varies, and the rule above is evaluated
over that set. Measured on DESFire EV2, ev1 and ev2 secure channels:

  read / write data    w (or r), rw
  GetValue   0x6C      r, w, rw
  Credit     0x0C      rw only
  Debit      0xDC      r, w, rw
  LimCredit  0x1C      r, w, rw

Credit is the odd one out: a file with r=key0 w=key0 rw=free needs Credit in
plain but Debit in MAC, in the same session. The FreeValue option bit forces
GetValue to plain regardless of the rights.

hf mfdes value never read the file settings at all, which is #2712. e1598cd62
worked around that by dropping CREDIT/DEBIT/LIMITED_CREDIT from
EV1D40TransmitMAC and retrying in plain on a length error. That made MACed
value files impossible to credit by any route, and the retry resent a
byte-identical APDU after the failure had already desynced the CMAC chain,
turning a clear 0x7E into a misleading 0x91AE. Both are reverted and the
command now reads the file settings like read and write do. Fixes #2712.

hf mfdes write resolves the comm mode even when --type is given explicitly,
since that path skipped detection entirely.

The DACLRP branch in the read path is left alone: no LRP capable card was
available to test against.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 23:18:59 +02:00
Matthew CarrollandClaude Opus 5 36f689beaa lf idteck demod: report only what the tag actually holds
Three ways this command reported a credential that was not on the tag.

CmdIdteckDemod always passed its local raw[8] to demodIdteck, never NULL, so
without --raw the command decoded a zeroed stack array rather than the
graphbuffer and reported card id 0 every time. The help's own first example,
plain `lf idteck demod`, has been doing that since --raw was added. It now
passes NULL when no --raw is given, which is the signal path demodIdteck
already has and lf idteck reader already uses.

A raw frame whose first word is not 4944544B printed "No genuine IDTECK found"
and then fell through and announced a tag anyway, with a card id read out of
whatever was passed in. It now stops there. The signal path cannot reach this:
detectIdteck matches the full 32 bit preamble, so lf search and lf idteck
reader are unaffected.

Finally the Idteck card id was packed into a 26 bit wiegand_message_t and run
through HIDUnpack, which prints an HID H10301 line with a facility code and
card number. That is not a decode of anything - the id is 24 bits, byte
reversed off the wire, and Unpack_H10301 returns true for any 26 bit message,
so the parity flag is the only hint and it reads ok for 25% of card ids by
chance. Both committed Idteck traces show it: 4944544B351FBE4B prints
FC: 37 CN: 57103 parity ( ok ), AC40E069 prints FC: 52 CN: 61472 parity
( fail ). Dropped, with the wiegand_formats.h include that came in with it.

Added five offline regression tests. Three fail without this change, one per
defect; lf search over every committed lf trace is byte identical before and
after apart from the two removed H10301 lines.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 12:52:48 -07:00
iceman1001andClaude Opus 5 (1M context) 344c2d6185 trace: stop trace save writing a stale client side buffer
`trace save` saved the client side trace buffer whenever it was non-empty
and only downloaded from device when it was empty. After `trace load` or
`trace list -1` a following sniff -> `trace save` silently wrote the old
trace, byte identical to the previous save, with no way to reset it.
See #3592, and #1252 / #1512 for earlier reports of the same thing.

- `trace save` now downloads from device by default and takes `-1` to save
  the client side buffer, mirroring `trace list`. Offline it falls back to
  the buffer so `trace load` -> `trace save` still works.
- split download_trace() into download_trace_ex(), which hands the caller
  its own buffer. `trace save` uses it and no longer mutates gs_trace, so
  `-1` means the client buffer regardless of what ran before.
- download_trace() freed gs_trace before it knew the download had worked,
  so a timeout threw away a loaded trace. It now swaps on success only.
- added `trace clear` to discard the client side buffer, and a shared
  ClearTraceBuffer() to replace the free/NULL/zero pattern that was
  open coded in ImportTraceBuffer() and CmdTraceLoad().

Help text for both new commands names the device vs client distinction.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 21:39:35 +02:00
iceman1001andClaude Opus 5 (1M context) 255576fa43 make hf 14a antifuzz actually reach a reader
Every answer was modulated after the reader's frame arrived, landing
~1812 carrier periods late against the 1172 the FDT allows, so readers
timed out before any of it mattered. All answers are now precomputed the
way hf 14a sim does it, and a phone answers at 1172 exactly.

Cascade mode sent a cascade tag at every level, which a conforming reader
rejects in the last level its ATQA announced - it dropped the card before
ever sending a SELECT. The cascade tag now appears only below that level;
it is the SAK that lies about the UID being incomplete, and that is what
walks a reader up to cascade level 7.

A bit oriented ANTICOLLISION was answered with the whole UID instead of
the bits the reader still lacked, handing it a frame of the wrong length.
One encoder now builds any tail, with or without collisions in it.

--coll leaves the first UID byte clean and collides every bit after it, so
a reader resolves 24 bits one round trip at a time, is then given a BCC
that checks out, and is cascaded into the same again - 183 answers per
poll against the 3 a real card needs. Colliding byte 0 as well only
produced a UID of all ones, which readers drop before asking for the BCC.

Reader frames that go unanswered are traced instead of silently dropped,
LED B marks an attempt in progress and LED C flips on each step deeper,
and the closing line reports rounds run and how far a reader got.

trace list -t 14a decodes SEL 0x99..0x9F, shows how many UID bits a bit
oriented ANTICOLL claims, and no longer flags those CRC-less frames as
bad CRC.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 21:18:26 +02:00
iceman1001 25b3c88acf fix #3487 2026-09-12 20:56:08 +02:00
iceman1001 11cac99913 fix cident 2026-09-12 20:39:19 +02:00