Commit Graph
366 Commits
Author SHA1 Message Date
iceman1001andClaude Opus 5 2d70fcb4ff hf mfdes sim: self contained DESFire simulation, and stop bitstream downloads eating emulator memory
The DESFire simulation gets its own ISO 14443-A loop in armsrc/desfiresim.c
rather than hooking into SimulateIso14443aTag(). That function is complicated
enough without a DESFire state machine threaded through it, and the hook had
already got the ATQA wrong once. It still borrows the library helpers from
iso14443a.c -- the precompiled activation answers, the receive call, the send
calls -- so there is no duplicated state machine, and iso14443a.c goes back to
knowing nothing about DESFire. desfiresim.h exports one symbol.

Three fixes were needed to make it actually answer a reader.

1. ISO 7816 wrapping. A reader sends `02 90 60 00 00 00`, not `02 60`. The
   simulation read in[0] as the DESFire command and so saw 0x90, the class
   byte, answering ILLEGAL_COMMAND_CODE to everything -- and in native form
   (status || data) when the reader wanted the wrapped form (data || 91 SW).
   Both framings are handled now, including the Lc/Le distinction: five bytes
   means no data and in[4] is Le, longer means in[4] is Lc with data following.

2. A bitstream download frees and clears BigBuf to get scratch space for the
   decompressor. SimulateIso14443aTagEx() and Mifare1ksim() both guard against
   this by calling FpgaDownloadAndGo_keep_EM() before they allocate anything;
   the new loop did not, so iso14443a_setup() wiped the emulator memory holding
   the card image and the precompiled answers after they had been filled. The
   pointers survive, the bytes do not, and the tag then clocks out zeros.

3. iso14443a_setup() itself used the plain FpgaDownloadAndGo(), which does
   BigBuf_free() and BigBuf_Clear_ext() -- taking the emulator memory with it.
   Every 14a command comes through there, so a card image that `eload` had just
   put in place was destroyed by the next `hf 14a` command whenever the HF
   bitstream was not already resident. Demonstrated before and after:
   `eload` then `hf 14a reader` then `eview` used to report "No DESFire card
   image in emulator memory" and now returns the image intact. This affected
   every emulator memory user, not only DESFire.

Verified against a second Proxmark3 acting as reader, simulating a real
DESFire EV1 8K dump: activation (UID 04268512A25680, ATQA 03 44, SAK 20,
ATS 06 75 77 81 02 80), the three frame GetVersion chain over 0xAF, GetFreeMem,
GetApplicationIDs, SelectApplication, GetKeySettings and GetFileSettings.
`hf mfdes info`, `getaids`, `freemem`, `lsapp` and `lsfiles` all read correctly,
including per application key types (AES, 2TDEA, 3TDEA) and all five EV1 file
types with their real settings -- a value file holding 1000 with limits
[0..10000], a linear record 2/8 of 16 bytes, a cyclic record 1/4 of 24 bytes,
standard files of 256 and 64 bytes, and a backup file of 128 bytes in MAC mode
with keyed rights 1200.

Not implemented yet: GetDFNames (0x6D) and GetISOFileIDs (0x61), so a reader
sees empty ISO IDs and DF names. Everything else answers
ILLEGAL_COMMAND_CODE, which is what a PICC says to a command it does not have.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 14:43:52 +02:00
Niel Nielsen 259f15e7df Merge branch 'RfidResearchGroup:master' into master 2026-09-14 13:11:49 +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
Niel Nielsen 5624a91f98 Decrease PM3_FPC_MAX_DATA from 4096 to 2048
Reduced maximum data size for FPC communication to prevent buffer overrun.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-14 08:38:37 +02:00
Niel Nielsen 96634fb2bf Increase PM3_FPC_MAX_DATA from 2048 to 4096
Fixes the the disconnects when on BLE connection

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 20:18:32 +02:00
Niel Nielsen 094df6102e Update pm3_cmd.h
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-13 11:22:47 +02:00
iceman1001 baea4014c1 fix cident overflows 2026-09-12 20:35:35 +02:00
iceman1001andClaude Opus 5 (1M context) 4d7d49e089 stop an FPGA bitstream download from eating the emulator memory
FpgaDownloadAndGoEx() with keep_em false does BigBuf_free() plus
BigBuf_Clear_ext(): the emulator memory pointer is nulled and all of BigBuf is
zeroed.  iso14443a_setup() calls that variant, and Mifare1ksim(),
SimulateIso14443aTagEx() and SimulateIso14443aTagAID() build their precompiled
anticollision responses in BigBuf first.  CMD_HF_MIFARE_EML_MEMGET had it the
other way round - it downloaded, then read the memory it had just wiped, so
'hf mf eview' and 'hf mf esave' returned their own zeros after any lf hitag,
hf iclass or hf 15 command.  A download already cached early-returns, so which
image the FPGA held decided whether any of this happened.

All five now call FpgaDownloadAndGo_keep_EM() before any BigBuf allocation.
Free-BigBuf floor at download time goes 16384 -> 20480 (ring plus the 4096 byte
emulator block); BigBuf measures 29084..31420 across all standalone configs on
RDV4 and 40120 on a PM3 Easy.

The sim paths also clear the trace before taking their modulation buffer -
BigBuf_malloc() refuses memory a stale trace holds, and MifareSimInit() ignored
the NULL, leaving prepare_tag_modulation() to memcpy 571 bytes over the vector
table at address 0.

'hf mf eload' now zeroes emulator memory device side: CMD_HF_MIFARE_EML_MEMSET
takes a flags byte, set on the first chunk only, so 'hf mf esetblk' and every
other partial write still touch only their own blocks.  That byte is why
CAPABILITIES_VERSION goes 9 -> 10; mismatched client and firmware refuse to
connect rather than write everything one byte offset.

Reported in #2836, whose USB drop is separately addressed by bc289cf43.

Builds clean for PM3RDV4, PM5 and the client; astyle clean.  Not yet verified on
hardware.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 18:49:24 +02:00
iceman1001 f57da9c85d missing files 2026-09-12 15:10:36 +02:00
Niel Nielsen 945619c2d5 Add BLE name command definitions to pm3_cmd.h
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-12 13:27:00 +02:00
iceman1001andClaude Opus 5 (1M context) 6341f40b4c hf mf hardnested: fix the nonce reply length, 9 bytes per pair not 4 per nonce
Thanks @TheArchitect0880 for pointing it out and suggested a first fix.

MifareAcquireEncryptedNonces packs two 4 byte encrypted nonces plus one
byte holding both their encrypted parity nibbles into every entry, but
the reply declared num_nonces * 4 bytes. The client walks that buffer 9
bytes at a time, so on RDV4 it read 612 bytes out of a 544 byte payload
and handed roughly 15 of every 136 nonces to add_nonce() from stale
packet buffer content. Those fake nonces went into the .bin nonce file
too.

Count pairs instead of bytes. num_nonces now reports whole pairs only,
so a button abort or a static nonce bailout part way through a pair
drops the dangling nonce rather than shipping a half built entry whose
parity nibble was never filled in.

MFC_NONCE_PAIR_SIZE and MFC_MAX_NONCE_PAIRS document the layout next to
mf_nonces_resp_t so the 9 vs 4 confusion cannot come back, and the
client now refuses a reply too short for the nonce count it carries.

Both acquisition functions collect straight into the reply buffer rather
than a second PM3_CMD_DATA_SIZE stack array, which halves the stack used
per call. MifareAcquireNonces also returned isOK = 2 on button press,
which is not a PM3_* status; that is PM3_EOPABORTED now.

Co-Authored-By: Claude Opus 5 (1M context)
2026-09-12 10:44:00 +02:00
Iceman 9f641c3ced Merge pull request #3427 from Sanduuz/feature/st25ta_ndef_sim
Added support for emulating ST25TA tag (IKEA Rothult) with custom NDEF response
2026-09-07 15:38:46 +07:00
xilni 342cc37cca docs(bwm): fix stale hw bwm command references 2026-09-07 00:07:07 -04:00
Iceman 2da575ab36 Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
2026-09-06 21:25:31 +07:00
dxl fc355df050 Added IO test capabilities to the factory QC for PM5. 2026-09-05 18:09:46 +02:00
dxl ea5485b4b8 Rename CMD_PM5_QC_TEST to CMD_PM5_QC_TEST_HW
and delete repeated def: CMD_PM5_BWM_SET_CAP
2026-09-05 18:09:46 +02:00
Antiklesys 57a42e3ce9 Stability fix for sc-bigbuf traces 2026-09-05 22:31:52 +08:00
Niel Nielsen eb5b9eb561 Added removed comment again
Added removed comment again

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-05 09:12:39 +02:00
Niel Nielsen 96e13303c8 Update PM3_FPC_MAX_DATA to 2048
Increase maximum data size for FPC from 240 to 2048 bytes.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-05 08:33:03 +02:00
Niel Nielsen cf3730e1b4 Merge branch 'RfidResearchGroup:master' into BWM-work 2026-09-04 14:29:26 +02:00
iceman1001 ace5d63ff9 hitag2: fix simulation against genuine readers, add restore, fix info
Simulation now completes the full exchange with a genuine Paxton reader in
password mode, and crypto mode read/write passes Proxmark-to-Proxmark.

Firmware:
- SOF was one bit period short. The lead-in that compensated for the lost
  head half bit was removed and nothing replaced it, so readers rejected
  every answer with a second START_AUTH. Default is now 6.
- The edge-detect threshold was latched before being measured, so the value
  chosen depended on whether the Proxmark was in a field when sim started.
  It is now measured on field entry and re-armed when the reader leaves.
- The percentile walk latched on run-scoped variables, so one attempt made
  outside a field poisoned every later one.
- Field loss was detected from TIMESTAMP, which is free-running MCU time and
  never stalls. Detect it from receive silence instead.
- Frames of a length the protocol does not have no longer reach the state
  machine; our own modulation tail was resetting the session and breaking
  every write.
- A dropped edge merges two or three reader bit periods into one gap. Those
  bits were discarded; they are now recovered by decomposition, which is what
  made crypto mode work (AUTH decode 15% -> 100%).
- Threshold selection is limited to 20 and 32 and settles in under 25 ms.

Client:
- lf hitag info printed a hardcoded 0x06 and reported 'Password mode' for
  every tag. It now reads page 3, takes -k (4 bytes password, 6 bytes
  crypto), and says so when the config cannot be read.
- lf hitag restore: writes a dump back in dependency order - user pages,
  then key material, then config last - validates the config byte, and
  prints the credential the tag will require afterwards.
- lf hitag crack2 now reports why it failed instead of a bare 'fail'.
- trace list: bit count moved to its own column, relative mode shows a
  Frame Delay Time row rather than renaming Start/End, --frame and -r
  rejected together.
2026-09-04 13:20:29 +02:00
Niel Nielsen 9d12204135 Change BWM_OTA_CHUNK_MAX to 240
Updated maximum firmware bytes per WRITE action from 2048 to 240.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 09:56:04 +02:00
Niel Nielsen fa7aa4e594 Increase PM3_FPC_MAX_DATA from 2048 to 240
240 seems the best choise

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 09:17:49 +02:00
Niel Nielsen ef09ab673b Update BWM_OTA_CHUNK_MAX to allow larger firmware writes
Increased the maximum firmware bytes per WRITE action from 196 to 2048.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 09:15:11 +02:00
Niel Nielsen c1d47f2be9 Reduce BWM_OTA_CHUNK_MAX from 240 to 196
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 09:10:45 +02:00
Niel Nielsen f5029c265f Increase BWM_OTA_CHUNK_MAX from 236 to 240
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 08:31:54 +02:00
Niel Nielsen c4cc31e06b Reduce BWM_OTA_CHUNK_MAX from 248 to 236
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 08:27:17 +02:00
Niel Nielsen 857a85557a Reduce BWM_OTA_CHUNK_MAX from 264 to 248
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 08:22:58 +02:00
Niel Nielsen dec0185b5a Increase BWM_OTA_CHUNK_MAX from 240 to 264
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-04 08:18:39 +02:00
Niel Nielsen 0245e99fde Add new OTA action definitions
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-03 12:58:44 +02:00
Niel Nielsen 1c184f4028 Decrease BWM_OTA_CHUNK_MAX from 256 to 240
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-03 11:49:39 +02:00
Niel Nielsen 9f265e81ea Define BWM_OTA_ACTION_ABORT for OTA commands
Add BWM_OTA_ACTION_ABORT constant for OTA actions.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-03 11:07:18 +02:00
Niel Nielsen e5ed0d52e1 Add BWM OTA chunk size definition
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-03 09:16:21 +02:00
Niel Nielsen a0573bf3cc Update pm3_cmd.h
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-03 07:04:56 +02:00
Niel Nielsen c22d2a7894 make style
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-01 17:57:31 +02:00
Niel Nielsen 769dc479c2 Conditionalize PM3_CMD_DATA_SIZE based on device
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-01 17:57:31 +02:00
Niel Nielsen e25bae7032 Add files via upload
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-01 17:57:31 +02:00
Niel Nielsen dbadc2b8e0 Update MFC_CHKKEYS_FAST_MAX_KEYS definition
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-01 17:57:31 +02:00
Niel Nielsen d8537a1a6c Conditionalize PM3_CMD_DATA_SIZE based on device
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-01 17:57:31 +02:00
iceman1001 9e2092fc66 capabilities: report device frame size so the client can adapt
PM3_CMD_DATA_SIZE went 512 -> 624 without a capabilities bump, so a new
client connects to old firmware and every oversized command dies at the
device's length check with no message.

Append max_cmd_data_size, bump to v9. The client now accepts an older
capabilities struct - it only ever grows by appending, so an older layout
is a prefix - and defaults the frame size for pre-v9 firmware.
SendCommandNG bounds by the device value instead of the compile time one.

Also zero init capabilities_t on the device, it leaked stack bytes.
2026-08-30 20:13:38 +02:00
iceman1001 6d2c35b05b The slight increase of array size makes us use the usb packages the AT91 sends which is 64bytes of size. We maximizing the available bytes basically and it comes with a slight cost of .bss and stack cost. Making bigbuff just abit smaller. We gain: 600 kBs -> 630 kB/s and less number of frames being sent over the wire. \n\nWhen it comes to Pm5 it will need to find its own aligned size to optimize transfers 2026-08-30 19:21:28 +02:00
Niel Nielsen fd81dbd10a Add files via upload
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-08-30 15:24:08 +02:00
iceman1001 ed066d84aa 'hf mfu cchk' - widen 3-pass chkkey nkeys to a full byte
nkeys was a 6 bit field but the client chunked by what fits in a frame -
123 keys in segment mode. nkeys wrapped to 59 while memcpy copied all 123
and the loop advanced by 123, so 64 of every 123 keys were never tested
and never reported. Full key mode was unaffected, it chunks 30.

Give nkeys its own byte. MIFAREU3P_CHKKEY_HEADER goes 18 -> 19, costing
one byte of payload, and segment mode chunks 123 again

Payload layout changed: client and firmware must be updated together.
Thanks Claude!
2026-08-30 13:25:50 +02:00
iceman1001 25d958e5e6 split PM3_CMD_DATA_SIZE_OLD out of PM3_CMD_DATA_SIZE
The OLD frame size was tied to the NG one, but the bootloader only speaks
OLD - growing PM3_CMD_DATA_SIZE would silently change sizeof(PacketCommandOLD)
and break flashing against every deployed bootrom in both directions.

Pin the OLD structs to their own constant and use it on every OLD path:
reply_old and the OLD receive branch on both sides, the bootrom, and the
flasher's write_block/send_finish_write_cmd, which memcpy into a
PacketCommandOLD using the NG size.

No behaviour change - both constants are 512 and armsrc .text is
byte-identical before and after.
2026-08-30 13:03:53 +02:00
Niel Nielsen 7d6ca7ba91 Add BWM_WIFI_ACTION_STATUS definition
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-08-29 19:59:21 +02:00
iceman1001 b0125c036e removed CMD_SMART_SETBAUD since we dont use it any more. Thanks Claude! 2026-08-29 17:46:06 +02:00
iceman1001 a0a3eb4bbf remove CMD_LF_SIMULATE_BIDIR, never implemented 2026-08-29 17:38:41 +02:00
iceman1001 0f11c5c4d1 Phase E - dismantle MIX functionality 2026-08-29 16:50:29 +02:00
iceman1001 7b7ec48bd9 OLD/MIX convert to NG: Phase C10 2026-08-29 15:50:36 +02:00
iceman1001 72ff6a5b80 OLD/MIX convert to NG: Phase C9 2026-08-29 15:18:54 +02:00