Commit Graph
14424 Commits
Author SHA1 Message Date
Iceman d66273ea3c Merge branch 'master' into aid
Signed-off-by: Iceman <iceman@iuse.se>
2026-10-23 11:12:00 +07:00
Iceman 8691140de8 Merge pull request #3718 from antoniovazquezblanco/seoskeys
hf seos: Print a better hint on missing keys
2026-10-23 11:09:32 +07:00
Iceman 6adf5a59f2 Merge pull request #3716 from antoniovazquezblanco/seos
HF 14a: Add a SEOS hint
2026-10-23 11:07:26 +07:00
Iceman 9502e1d1b9 Merge pull request #3693 from mfcarroll/fix/psk-fc2-bandpass
lf: fall back to pm3_psk_demod for weak fc/2 PSK when the wave tracke…
2026-10-23 11:06:33 +07:00
Antonio Vázquez Blanco 798f9f3d28 aidlist: Fix uppercase in SEOS, TeslaDAP and LA TAP AIDs 2026-10-21 13:35:29 +02:00
Antonio Vázquez Blanco 75e4e766ec hf seos: Print a better hint on missing keys 2026-10-21 13:29:14 +02:00
Antonio Vázquez Blanco 748394d0ab HF 14a: Add a SEOS hint 2026-10-21 13:11:44 +02:00
Matthew CarrollandClaude Opus 5.5 ac59f2f768 lf: reject fc/2 PSK fallback clocks off nominal
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 17:24:28 -07:00
Matthew CarrollandClaude Opus 5.5 13b841e0b1 lf: cache the fc/2 PSK fallback per graph buffer, name its thresholds
The cache is keyed on a hash of the graph buffer contents: the buffer has
many writers and no change counter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 17:24:28 -07:00
Iceman 693ead0803 Merge pull request #3699 from s00se/replace-deprecated-strtok-with-strtok_r
client: replace deprecated strtok calls with strtok_r
2026-10-18 22:43:20 +07:00
s00se a2501dc6d4 Fixed ndef vcard by replacing deprecated strtok with strtok_r
Use 200112L instead of 200809L
2026-10-18 09:02:13 -06:00
Iceman 42c1c7a76e Merge pull request #3676 from dunderhay/desfire-reader-candidate-probe
Add DESFire reader candidate-key probe
2026-10-18 14:40:53 +07:00
Matthew Carroll 1bc32bff15 Merge remote-tracking branch 'upstream/master' into fix/psk-fc2-bandpass
# Conflicts:
#	CHANGELOG.md
2026-10-17 23:47:19 -07:00
Daniel UnderhayandOpenAI Codex 90525502f1 Add DESFire reader candidate-key probe
Add an opt-in simulator probe that checks a reader's AES authentication continuation against a supplied candidate and stops before the final card response. Expose the result through the firmware protocol and etest bench command, and document the evidence and handshake scope.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-18 16:03:57 +11:00
Iceman e69ac420e1 Merge branch 'master' into codex/gdm-wipe-safety
Signed-off-by: Iceman <iceman@iuse.se>
2026-10-15 11:06:06 +07:00
Iceman 501d8d53f1 Merge pull request #3698 from towelbyte/towelbyte_cotag_sim
Simulate COTAG tag implementation
2026-10-15 11:04:14 +07:00
歐歪 26e762f80d chore: update command description 2026-10-15 01:33:15 +08:00
towelbyte 294fb3c504 Simulate COTAG tag implementation
New CLI command `lf cotag sim` with COTAG tag simulation implementation.

Detects COTAG reader activation sequence and emulates a COTAG tag.

Signed-off-by: andrej@towelbyte.net
2026-10-14 17:14:56 +02:00
phaseloop a8213a6fd5 Fix example usage
Signed-off-by: phaseloop <90922095+phaseloop@users.noreply.github.com>
2026-10-14 13:36:19 +02:00
phaseloop cbad3db692 Niimbot label tag patcher - initial commit
Signed-off-by: phaseloop <90922095+phaseloop@users.noreply.github.com>
2026-10-14 13:14:37 +02:00
歐歪 4405335315 chore: commands file and wording adjustment 2026-10-14 05:07:07 +08:00
歐歪andOpenAI Codex 00fb003f61 Merge upstream/master into codex/gdm-wipe-safety
Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-14 04:19:58 +08:00
Iceman 923c11b7ae Merge branch 'master' into fix/psk-fc2-bandpass
Signed-off-by: Iceman <iceman@iuse.se>
2026-10-13 23:41:09 +07:00
Iceman 8110082977 Merge branch 'master' into fix/t55xx-detect-pwd-guard
Signed-off-by: Iceman <iceman@iuse.se>
2026-10-13 23:36:03 +07:00
Zhaoqi XuandGrok Bot 10fa02ca24 client: free graph and demod buffer save states after restore
save_graphbuffer() and save_buffer8() calloc a copy, and the restore_*()
helpers only copy out of it, so every owner leaked its save state.
check_chiptype() lost 4 * g_GraphTraceLen bytes plus the packed demod
buffer on each online `lf search` (~2 MB after the COTAG probe), and the
Visa2000 demod leaked on every `lf search`, online or offline.

Add free_buffer_savestate() and call it after the last restore in
check_chiptype(), demodTI(), demodVisa2k(), demodzx(),
try_detect_modulation() and t55xx_psk_untrim_head(), including the
early-return and success paths that never restored.

Reported with the check_chiptype() diagnosis and fix by @BeheSQ.

Fixes #3675

Co-Authored-By: Grok Bot <noreply@users.noreply.github.com>
2026-10-11 06:51:44 +08:00
Matthew Carroll 3ba49c6a61 Merge remote-tracking branch 'upstream/master' into fix/t55xx-detect-pwd-guard
# Conflicts:
#	CHANGELOG.md
2026-10-07 09:11:55 -07:00
Matthew CarrollandClaude Opus 5.5 7344c7d5bc lf: fall back to pm3_psk_demod for weak fc/2 PSK when the wave tracker isn't clean
At fc/2 the subcarrier is a one-sample alternation and pskRawDemod_ext finds
wave tops one sample at a time, unfiltered. On a weak tag, sample noise erases
tops; a wave then reads as four samples and counts as a phase shift, and the
bit stream fills with errors although every bit is still in the trace. A T5577
Indala at 22 mm gave the wrong card on 14 of 50 lf search reads.

PSKDemod keeps the tracker's result whenever it is clean, so nothing changes
where master already works. Otherwise, for fc/2, it tries the existing coherent
receiver pm3_psk_demod (now with an optional per-symbol magnitude output) and
keeps that only if it scores well above what level-step leakage can produce,
its bits aren't doubled or constant, and no symbol is weak. The receiver's
output is differential, so one bad decision would flip every later bit: a weak
symbol refuses the trace rather than risk a wrong card (absolute decisions with
weak symbols left to maxErr were tried and gave wrong IDs on dropouts). With no
usable clock from the caller, candidate clocks are tried largest first. Polarity is voted from the
raw level over each phase reversal, the cue pskFindFirstPhaseShift reads at the
first one. Client only; firmware is unchanged.

Base vs this change, same captures:
- T5577 Indala, live lf search: 22 mm 3 right / 14 wrong -> 50 / 0; 24 mm
  0 / 2 -> 50 / 0; 26 mm and 0-20 mm unchanged
- lf t55xx dump, live: 22 and 24 mm blocks 0-2 and page 1 correct 5/5 where
  master reads nothing; unchanged where master reads
- emulated Indala (Chameleon Ultra, clock drifting against the reader):
  lf search right / wrong 56 / 130 -> 91 / 95 of 200; every one of the 95 is
  master's own wrong ID on the same capture
- 27 PSK traces in traces/, weakened with Gaussian noise: correct 341 -> 636 of
  810, wrong IDs 83 -> 21; with recorded Proxmark noise 367 -> 553 of 648,
  33 -> 27. No lost reads and no new wrong IDs in either
- traces/lf_*.pm3 (99): lf search -1 and -1 -c output identical; 1,581
  non-PSK probes: lf search and lf t55xx detect identical
- 200 empty-field captures: no decode, either build

tools/pm3_tests.sh: a weak 24 mm Indala trace must read its ID (fails on
master), and a synthetic NRZ with an fc/2 ripple must not decode as a tag
(the level-step leakage the score check rejects).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 14:45:41 -07:00
歐歪andOpenAI Codex f4c7243387 fix(mifare): reject WUPA mode before GDM wipe
Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-10-06 04:16:28 +08:00
Philippe Teuwen 63063bd030 tune docs for default port 18888 2026-10-02 15:05:19 +02:00
Niel Nielsen 133b981512 Change default TCP server port from 7777 to 18888
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-10-02 14:17:01 +02:00
Matthew CarrollandClaude Opus 5 8917c48cde lf t55xx detect: do not send a password the PWD bit has not confirmed
`lf t55xx detect -p <pwd>` reached for the password whenever detection
failed without one, and sent it across every downlink mode and again
after a wake. On a tag that is not password protected those frames can
be taken for a write: the PWD bit gets set and the tag's data is
destroyed, leaving it locked behind whatever block 7 already held.

`lf t55xx read` and `lf t55xx dump` already guard against this. They
verify the PWD bit in the configuration block before using a password,
and expose -o/--override to bypass the check deliberately. detect had
neither, and T55xxReadBlockEx() treats a live `detect -p` as proof the
bit is set.

detect cannot run the same check -- reading the configuration is what it
is for, and the password is only reached for once that has failed -- so
the risk has to be the user's to accept. Gate it behind -o/--override to
match read and dump, and carry read's warning banner into the help.

No change in behaviour for anyone not passing -p.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-01 16:13:49 -07:00
Niel Nielsen 256f30f0fa Add files via upload
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-10-01 23:04:47 +02:00
Nemanja Nedeljkovic 23d57af8bd lf em 4x05 chk: add EM4305 anti-clone card password to default dictionary
Adds A1856618 to t55xx_default_pwds. This is the verified working login
password (as used with -p); the bit-reversed on-air form 1866A185 does not
authenticate.
2026-09-28 21:26:56 +02:00
iceman1001 2e2598bca9 style 2026-09-27 21:15:18 +02:00
Iceman 2630310336 Merge pull request #3650 from wiillk3/wireless-device-flashing
BWM: add ability to flash over wifi
2026-09-27 19:35:05 +07:00
歐歪andOpenAI Codex 4b99a422c8 fix(mifare): make GDM wipe failure-safe
Stage and verify a valid 4-byte UID before committing the clean configuration, propagate write failures, and preserve recovery when cleanup is incomplete. Correct the sector trailer template.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-09-27 05:16:53 +08:00
歐歪andCodex a991b20a51 hf felica: handle system polling in ARM select
Pass the requested system code to firmware selection so default and system-specific reader modes share one polling path. Keep the RF field active across retries for the system-specific mode.

Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
2026-09-27 01:27:38 +08:00
歐歪andCodex 24e11e3d72 hf felica: support polling a selected system
Add --sys to the FeliCa reader so repeated polling can activate an Express Transit card while keeping the RF field on.

Co-Authored-By: Codex (GPT-6 Sol) <noreply@openai.com>

Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
2026-09-27 01:04:40 +08:00
WillandCursor 8150c2af77 BWM: add ability to flash over wifi
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-26 12:23:47 -04:00
Iceman cbadbf4bfe Merge branch 'master' into pm5-idle-lowpower
Signed-off-by: Iceman <iceman@iuse.se>
2026-09-26 21:51:29 +07:00
Iceman 9ba8b13da6 Merge pull request #3653 from 0x6r1an0y/20260917-15magic-fix
Improve `hf 15 csetuid` command
2026-09-26 21:48:47 +07:00
iceman1001andClaude Opus 4.8 027b225f41 Fix lf t55xx dump password reuse and p1detect for non-Atmel clones
lf t55xx dump: when lf t55xx detect has already recovered and confirmed
the password, T55xxReadBlockEx now trusts that session config instead of
re-probing the config block unauthenticated. A password-gated tag does
not answer that probe, so 'dump -p' failed its safety check on every
block and demanded --override; it now reads directly.

lf t55xx p1detect / lf search: the page-1 trace fingerprint hardcoded
Atmel's manufacturer byte (0x15/0x39) into a 16-bit preamble, so a valid
T5577 clone with another manufacturer (e.g. Tendyron 0x65) was rejected.
The duplicated atmel/silicon checks are collapsed into
t55xx_trace_preamble_match(), which also matches the bare 8-bit ACL 0xE0
- the same anchor lf t55xx trace decodes against.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-25 18:24:44 +02:00
MsprgandClaude Fable 5.1 39bbf20cce pm5: hw bwm ble, the module's BLE settings incl. on/off and pairing
The module ships with BLE open: anyone in range can connect and run
commands, and there was no way to turn the radio off or to require
pairing from the PM5, although the module already implements bonding
with a static passkey (LE Secure Connections + MITM, SPP characteristic
encrypted) behind commands nothing exposed.

New CMD_PM5_BWM_BLE (0x0183): one action byte, then a full status
snapshot back (bwm_ble_status_t: switch, state, bonding, passkey, TX
power, address, name, bonded devices). Client menu `hw bwm ble`:
  status              everything above, with a warning while open
  on | off            persisted radio switch (needs the companion
                      Proxmark5_BWM_esp32 PR; off =
                      nothing can connect, USB/WiFi only)
  pairing on|off [-k] require the 6-digit passkey, set the passkey; a
                      change of on/off restarts the stack (drops a
                      connected client), the factory key 123456 is
                      flagged
  forget -i N | --all remove bonded devices
  txpower -a/-c dBm   advertising / connection power, -24..18 and 20

The firmware replies before restarting the stack so the reply survives
when the command itself arrived over BLE. Fields a module without the
switch cannot answer read 0xFF and print as unknown. A module that does
not answer at all ends the status snapshot after its first query instead
of running into the client's timeout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 10:33:47 +02:00
MsprgandClaude Fable 5.1 0cd1fada0e pm5: auto power-off: idle timeout, unplug switch, stored on the BWM
The USB-unplug power-off left two ways to drain the battery: a PM5
woken by the button and forgotten, and one left idle after the phone
disconnected.

Idle trigger (opt-in, PM5_AUTOOFF_IDLE_MS 0 by default so out of the box
only the unplug trigger exists, as before): on battery the board powers
off after the idle timeout with no interaction and no wireless client.
Interaction is a received command over any transport, any button press,
or a client connecting or leaving; a standalone mode or a long-running
command holds the main loop, so neither can be cut short. The BWM
reports its clients with the LINK_STATE broadcast (8092, companion
Proxmark5_BWM_esp32 PR) which bwm_forward.c tracks; at boot the BLE
half is seeded with a status query since the module only reports
changes. When the timer is due but a client is still tracked, the module
is asked for its BLE state (at most every 10 s), so a lost "client left"
broadcast cannot pin the board on. And right before going off the module
is asked once more: older module firmware never sends the broadcast and
a "connected" one can get lost, and neither may power the board off
under a silent BLE client. No answer means off.

--unplug off: the unplug trigger always won, so "survive the unplug, go
off after N idle seconds" was not reachable. It is its own setting
(default on = unchanged). With it off an unplug only restarts the idle
clock - from the unplug, not from the last command, or a board that sat
idle on USB for an hour would still die with the cable. Unplug detection
is edge-based (VUSB present at the previous poll, absent at this one)
instead of "absent and seen since boot", which would fire on every poll
after a tolerated unplug. VUSB is followed while the feature is switched
off too, so switching it on again on battery is not taken for an unplug.

Stored on the BWM: runtime-only settings reset at every boot, which is
exactly when the idle trigger matters. The PM5 has no settings store, so
the switch, the idle timeout and the unplug switch live in the module's
host value slots (APP_CMD_SET/GET_SYS_HOST_VALUE 1021/1022, companion
PR; slot 0 switch, 1 idle seconds, 2 unplug), loaded at the first
auto-off poll and saved by CMD_PM5_BWM_AUTOOFF with 1 s per write, so a
silent or older module still leaves the reply inside the client's 5 s
wait. Without a module, or with an older one, the defaults apply and the
status says "not stored".

hw bwm autooff [on|off] [--idle <sec>] [--unplug <on|off>]; no argument
shows the state, one fact per line: switch, idle timeout, unplug
power-off, stored on module, USB power, USB seen since boot, unplug
trigger armed, tracked client, the module's BLE state, idle time.
Payload [action][enabled][idle_s u32][unplug, optional] with keep
sentinels; both actions are non-zero so an old firmware, which reads
byte 0 as the enable flag, can only be left enabled. hw status prints
the module's live BLE state and the auto power-off setting; at debug
level also the tracked client, which should agree with the live state.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 10:33:46 +02:00
MsprgandClaude Fable 5.1 5e1b04def1 pm5: hw bwm wifipower, WiFi off or the modem power-save type
New `hw bwm wifipower [off|none|min|max]`. `off` turns the BWM's WiFi
fully off (BLE-only, persisted; the same path as `hw bwm wifi stop`,
and the module's default state). The other three set the ESP's persisted
WiFi modem power-save type (CMD_PM5_BWM_WIFI_PS 0x0182, module commands
2052/2053, esp_wifi_set_ps()) used while WiFi is up: min (the ESP-IDF
default, the modem sleeps between DTIM beacons), max (sleeps for the
whole listen interval, lowest current, slower to react), none (modem
always on, lowest latency). With no argument it reports whether WiFi is
up at all and the stored type. Independent of `hw bwm powersave`.

The link helper's "cmd failed" diagnostic is now printed only at debug
level: a status query while WiFi is off fails by design and was
cluttering every call.

Verified on hardware: default reads min with WiFi off; none, max and
min each set and read back; off tears WiFi down; an unknown value is
rejected; max survives a module reboot. Not measured with WiFi
associated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 10:33:46 +02:00
MsprgandClaude Fable 5.1 552276c75f pm5: hw bwm powersave
New `hw bwm powersave [on|off]` (CMD_PM5_BWM_POWERSAVE 0x0181) shows or
sets the ESP's persisted power-save switch (companion Proxmark5_BWM_esp32
PR: DFS, light sleep and slow advertising after a 30 s fast phase, or
the stock always-on behaviour), so the two can be A/B measured and the
saving turned off when chasing a link problem. `hw status` prints the
state next to the BWM firmware version.

Both module queries in `hw status` are time-bounded (version 2 x 800 ms,
power save 300 ms): a module that is silent, or a firmware without the
command, cannot push the report past the client's timeout.

Verified on hardware: state read/set/persist across an ESP reboot,
`hw status` after 4, 15 and 40 s idle in power-save mode and after 6 s
idle with it off.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 10:33:46 +02:00
4f4acedbdd pm5: reduce idle power (core clock scaling + WFI idle)
Port the "reduce idle power" feature from the Fantasi firmware
(soeinova/Fantasi @ 9671309, plus its later ACC-SOF fix) to the PM5
(AT32F435) target.

Problem
-------
The PM5 firmware ran the ARM core at 288 MHz with a 1.3 V LDO and a
main loop that busy-polled at full speed even when the device was idle.
The 288 MHz PLL and the 1.3 V LDO dominate idle draw, and the busy loop
adds to it. Nothing scaled back when there was no work.

Change
------
New armsrc/pm5_power.c drives a refcounted clock/voltage governor:
- Idle (nothing pending, boost count 0, boot grace elapsed, FPGA off):
  take SCLK off the PLL onto HICK-48, power the PLL down, drop the LDO
  to 1.1 V, park the FPGA 24 MHz clock (PA8 low), and halt the core in
  WFI until the next IRQ or the 1 ms SysTick wake.
- Any timing-critical work holds a 288 MHz boost: AppMain wraps
  PacketReceived (which on the PM5 also covers a standalone mode, since
  it is only entered through a command there); the BWM low-batt poll
  and the RGB indicator wrap their I2C. Boost is refcounted and
  IRQ-guarded.
- USB (OS image) moves to the crystal-less HICK-48 clock, ACC-trimmed
  against the SOF, so powering the PLL down never touches USB. The
  bootrom keeps the HEXT/PLL USB path (AS_BOOTROM), so DFU flashing is
  unchanged.
- bwm_uart_clock_update() re-inits UART4 through the SDK usart_init()
  on each clock switch (the divider set at 288 MHz is 6x off at 48 MHz).
- FpgaIsOff() (fpga_core.c, PM5 only) tracks the last conf word so the
  governor never downclocks while a reader field / emulation is running.
- Wake preamble on the BWM link: the companion module firmware
  (Proxmark5_BWM_esp32) light-sleeps 2 s after the last byte on the link
  and its UART wakes on RX edges but loses the bytes that carried them.
  bwm_uart_write() therefore leads with four 0x55 bytes and a 10 ms
  settle on its first write and after 1 s without a write of its own
  (RX is not tracked: the ring can be drained long after the bytes
  came in). The module only starts light-sleeping once it has seen a
  preamble, so the one sent while it was still booting is repeated
  after the boot-time link negotiation. A module firmware without light
  sleep drops the preamble as noise.

New `hw powersave on|off` toggles the governor at runtime (default on);
`hw status` reports the idle-clock and WFI-asleep fractions.

Behaviour change
----------------
- PM5 idles at 48 MHz with the PLL off and the CPU halted; it boosts to
  288 MHz for commands and BWM housekeeping. Command timing and
  throughput are unchanged (intra-command work is always boosted).
- PM5 USB now runs off HICK-48 (ACC-trimmed) instead of the HEXT PLL.
- New command id CMD_PM5_POWERSAVE (0x0180).

Testing
-------
Built warning-free (gcc) for PLATFORM=PM5 (with and without
PLATFORM_EXTRAS=BWM), PM3RDV4 and PM3GENERIC, armsrc and bootrom. Client
built via the default Makefile. Not built with clang or on
Windows/macOS; nothing outside PM5/AT32 guards changes.

Flashed to a PM5 and exercised against a MIFARE Classic 4K card:
hw version/status/ping (4000 & 512 B), hw tune, hf search, hf 14a
info/reader (x12 across idle gaps), hf mf info/chk/rdbl, lf search/read,
hw powersave off/on, held-field (raw -sk) correctly blocks the downclock,
hw reset + re-enumerate. All pass; USB stays up across downclocks. Idle
reaches ~80-95% at 48 MHz and ~90%+ WFI-halted after a few seconds idle.
Measured at the USB port: idle draw 283 mA -> 207 mA with the stock
BWM firmware.

Co-authored-by: Soei Nova <soeinova@proton.me>
Co-authored-by: noproto <noproto@zeroday.engineering>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 10:33:46 +02:00
Philippe Teuwen 339db44cf1 Mask all bwm commands if device is not compiled for it, avoids copy/paste of bwm commands 2026-09-23 13:47:31 +02:00
Niel Nielsen 51b605c87e Update BWM command condition in cmdhw.c
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-23 13:44:57 +02:00
Niel Nielsen b534f06109 Add IfBwm function declaration in cmdparser.h
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-23 13:44:57 +02:00