Commit Graph
23389 Commits
Author SHA1 Message Date
Niel Nielsen 9c12e30b79 Implement IfBwm function for BWM capability check
Added IfBwm function to check BWM capability based on PM3 presence.

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-23 13:44:57 +02:00
Niel Nielsen 9038dacead Implement BWM capability flags in appmain.c
Add conditional compilation for BWM capabilities

Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-23 13:44:57 +02:00
Niel Nielsen 2c8df402f8 Update CAPABILITIES_VERSION to 12
Signed-off-by: Niel Nielsen <nieldk@gmail.com>
2026-09-23 13:44:57 +02:00
iceman1001 495a72e347 text 2026-09-22 15:56:59 +02:00
iceman1001andClaude Opus 5 e824501492 hf mf autopwn: detect static encrypted nonce via the backdoor key
When no sector key was known, autopwn probed for a static encrypted
nonce using the default key FFFFFFFFFFFF. On a FM11RF08S with
non-default keys that auth fails, the probe returns NONCE_FAIL, and
autopwn fell through to darkside/nested instead of the sen recovery.
The later re-detections are gated on known_key, so nothing recovered it.

Probe the known Fudan backdoor keys first, as 'hf mf info' and
'hf mf sen' already do, and run the detection with MF_KEY_BD. The
default key stays as the fallback for cards without a backdoor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 15:41:32 +02:00
iceman1001andClaude Opus 5 7346db71ff hf mfu view: print the stored UL-C / UL-AES key
`hf mfu dump -k` appends the authentication key to the dump file, but
`view` never showed it. The key was there in the hex listing all along,
split across four pages and byte-swapped, which is not something you read
off the screen.

With `-v`, view now prints it. UL-C takes pages 0x2C..0x2F, UL-AES pages
0x30..0x33, and both are unswapped back into the form `-k` expects, so the
printed line can be pasted straight into the next command. The existing
ulc_print_3deskey() does the UL-C side; ulaes_print_key() is its UL-AES
sibling.

Tag type comes from the dump header rather than a card: the three UL-AES
version signatures that ul_select_card() matches on a live tag, and for
UL-C, which answers no GET_VERSION, all-zero version bytes plus a page
count of 0x2F. Key pages that are all zero say so and point at `dump -k`,
since a dump taken without a key legitimately has none.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 15:05:38 +02:00
iceman1001 7ee301a38f added another one 2026-09-22 14:54:44 +02:00
iceman1001 de2aaa48d8 text 2026-09-22 14:48:54 +02:00
iceman1001andClaude Opus 5 e3be641809 hf mf: honour --ns in the FM11RF08S nonce recovery
`hf mf autopwn --ns` asks for no files, but on an FM11RF08S it wrote
them anyway. no_save is read once and only gates the two save blocks
at the end of autopwn; the static encrypted nonce is detected earlier
and returns into HFMFSENRecover from five places, none of which saw
the flag. The recovery path wrote the key file and the dump
unconditionally, and now that the dump carries JSON as well, that was
three files against a flag asking for none.

no_save travels with the call now, and fm11_save_recovery_outputs
returns before it names anything, printing the same "Called with no
save option" line that `hf mf dump` and autopwn already print. The key
table is still shown, so --ns reads the card and leaves nothing on
disk.

`hf mf sen` gains the same `--ns` option, so the flag does not depend
on which command reached the recovery.

--ns does not suppress `--keep-nonces`. That option exists only to
write its evidence file, and a blanket no-save would leave no way to
ask for the evidence without a dump.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 14:24:34 +02:00
iceman1001andClaude Opus 5 42b8fb8367 hf mf: carry --suffix into the FM11RF08S nonce recovery
`hf mf autopwn --suffix <txt>` names its output files
`hf-mf-<uid>-<dump|key>-<suffix>`, but on an FM11RF08S the suffix was
dropped. autopwn detects the static encrypted nonce and returns into
HFMFSENRecover from five separate places, all of them before its own
file naming runs, and the recovery path built `hf-mf-<uid>-key` and
`hf-mf-<uid>-dump` from the card UID alone. Two runs against the same
card overwrote each other, which is the collision the suffix exists to
prevent.

The suffix now travels with the call, so a card autopwn hands over is
named the same way as one autopwn finishes itself.

`hf mf sen` gains the same `--suffix` option, so the naming no longer
depends on which command reached the recovery. It covers the
`--keep-nonces` evidence file too, which collided the same way.

The three names are built by fm11_build_filename() instead of by three
snprintf calls that have to agree on the template.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 14:22:18 +02:00
iceman1001 38e733e37d fix #3655 2026-09-22 13:56:07 +02:00
iceman1001andClaude Opus 5 950ba026bf hf mfdes: check the PICC master key, keep --key, and read 0x1A on its own
`hf mfdes chk` reported "No keys found" on a card whose PICC master key was
still the factory default, and missed a key handed to it on the command line.

The AID list comes from GetApplicationIDs, which never returns 000000, so the
PICC level was never swept - only an explicit `--aid 000000` reached it. That
list is itself gated by PICC key settings bit 1, and a card refusing it aborted
the whole run rather than falling back to the one key number still reachable.
000000 now seeds the sweep, and a refused list leaves the PICC level to check.

A key given with `--key` was written into the key list at parse time and then
overwritten: every round resets the length and refills the same buffer from
index 0. It was counted in "Loaded N keys" and never tried. It is now
re-inserted at the head of its list after each fill, so it is attempt one.

When key settings are unreadable the fallback walked the file access rights to
name the key numbers in use. GetFileIDs, GetISOFileIDs and GetFileSettings are
gated by the same settings bit that just refused GetKeySettings, so that
fallback could never run. GetKeyVersion is not gated at all and names the key numbers
directly, absent ones answering 0x40 NO_SUCH_KEY.

AuthenticateISO (0x1A) was read only when Authenticate (0x0A) had answered
first, but 0x1A covers DES, 2TDEA and 3TDEA where 0x0A covers only the first
two. An application holding 3TDEA keys answers 0x1A alone, so it named no key
type and was skipped outright. chk and detect both read it on its own now.
Because 0x1A cannot separate 2TDEA from 3TDEA, detect also drops a key type on
the first wrong-length challenge instead of waiting for its error counter.

Measured on a DESFire EV2 2K: PICC master key and an application AES key are
both recovered in one run, and the unauthenticated GetKeyVersion sweep keeps
answering across a run of NO_SUCH_KEY errors with no re-select.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 13:55:06 +02:00
iceman1001 ee20f50965 fix duplicates 2026-09-22 12:49:50 +02:00
iceman1001andClaude Opus 5 a3d32ac220 hf mfdes view: name known AIDs
The dump viewer printed bare AID numbers while the live card paths
already resolved them through AIDDFGetCommentStr(). Use the same lookup
here, falling back to the old separator line when the AID is unknown.

    --- AID 578000 --- NORTIC (Card Issuer App) [NPRA]

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 12:46:06 +02:00
iceman1001 5a964c8b5a fix our uniqueness check to als include JSON files 2026-09-22 12:39:26 +02:00
iceman1001 577f6ef45c added entries from Metrodroid project 2026-09-22 12:38:15 +02:00
iceman1001 4d1414a0e9 fix duplicate entries in aid file 2026-09-22 12:36:56 +02:00
Iceman 2539efc901 Merge pull request #3651 from youngh82/pm3-iclass-sio-unknown-tags
hf iclass view: surface unhandled SIO TLV tags in Insights
2026-09-22 16:22:52 +07:00
Iceman f7dd78ebc5 Merge branch 'master' into pm3-iclass-sio-unknown-tags
Signed-off-by: Iceman <iceman@iuse.se>
2026-09-22 16:22:25 +07:00
iceman1001 0aa6c96c22 hook in parser 2026-09-22 11:20:15 +02:00
iceman1001andClaude Opus 5 54e004e252 hf mfdes: add NORTIC travel card parser
NORTIC (Norwegian Ticketing Interoperable Concept) is the Norwegian
national public transport card, on DESFire since 2008 and specified by
Statens vegvesen, now Jernbanedirektoratet, in Handbok V821.

Decodes the card issuer header, file 0C of AID 578000. That file is
free to read, so the parser produces output on any Norwegian card
without key material: country code, format, choice bitmap, card serial
number, validity end date, application owner company, retailer
organisation and card key version.

The transport application, AID 578001, is listed by file with its role
and the key it needs, and any file that was read is dumped as hex. Its
field layouts are in Handbok V821 Del 18, which has no download link,
and every file needs read key 7, which is not public. Nothing there is
guessed at.

NORTIC is EN 1545 and packs fields most significant bit first, which is
the opposite of the RKF Type CL-1 layout in parserkf.c where RKF-0022
7.4.1 numbers bits from the least significant end. Reading a NORTIC
header the RKF way gives country code 144 instead of 578, so the self
test asserts that as a negative control.

Verified field by field against the published card issuer header, every
field matching its documented value, including the validity date 6938
decoding to 2015-12-31. 'hf mfdes view --selftest' runs the checks,
including a round trip through an encoder.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 11:19:24 +02:00
iceman1001andClaude Opus 5 28d49510e2 hf mf: add RKF travel card parser
The RKF travel card (Resekortsföreningen i Norden) is the Nordic public
transport card, specified 2001-2002 on MIFARE Classic and deployed by
Västtrafik, SL Stockholm, Länstrafiken and the Danish Rejsekort.

Decodes the card issuer and support layers (CMI, TCCI, TCAS, TCDI) and
every application object the specification pins down: TCPU purse, TCEL
event log, TCDB, TCCP, TCST, and TCTI/TCCO through an identifier chain
walker covering all 18 data element groups. AID owners are named from
RKF-0019.

Three things the specification does not state, determined from 21 cards:

  - RKF-0022 7.7.1 calls the block checksum 'standard CRC-8' without
    naming the parameters. It is CRC-8/MIFARE-MAD, poly 0x1D init 0xC7,
    which the tree already ships as CRC8Mad().

  - The MAC trio is the final 24 bits of a MACed object. The RKF-0023
    tables list Free (bits) as a trailing summary row, which reads as if
    the authenticator follows a gap after the key identifier; it does
    not. Measured on the fact that MACAlgorithmIdentifier must be 0:
    TCST 42/42 against 15/42, TCCP 20/20 against 13/20.

  - TCPU version 4 drops EndDate and moves Value to bit 16.

Cards reporting a version other than 2 are flagged, and a MAC algorithm
the specification does not define is reported as a layout failure rather
than printed as data.

MAC values are not verified. The master key is in RKF-0018, which was
never published. des_mac() is added to libpcrypto for when that changes,
with the FIPS 113 worked example as its test.

Verified against a Danish Rejsekort whose provenance notes give the
purchase timestamp, card number and balance; the parser reproduces all
three. 48 self test checks on 'hf mf view --selftest', no false
positives across 460 local dumps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 11:14:44 +02:00
iceman1001andClaude Opus 5 82597a32c5 fix: don't treat a RATS NAK as a successful ISO14443-4 activation
iso14443a_select_cardEx() only rejected silence after RATS. A card that
answered with a 4 bit NAK came back as Demod.len == 1, was stored as a
one byte ATS and reported to the client as select status 1, meaning L4
activated. The client then sent GetVersion (90 60 00 00 00) as an I-block
to a card that never left ISO14443-3, and every caller ended with
'timeout while waiting for reply' / 'No tag detected or other tag
communication error (-4)'.

The bogus TL of 0x04 also made iso14a_set_ATS_times() look for a T0 and
read past the single received byte.

Check that the answer to RATS is a well formed ATS, TL plus the bytes TL
counts plus the two CRC bytes, before accepting it. Anything else returns
2, selected but ISO14443-3 only, so the card stays usable over the Classic
path instead of failing detection.

The client side 'try to request ATS even if the tag claims not to support
it' retry had the same hole and stored whatever came back in card.ats, so
guard all four copies of it the same way.

Reported on a clone with ATQA 0004 / SAK 28 that advertises ISO14443-4 it
does not implement. hf mf autopwn on it needed hf 14a config --rats skip
to get past detection; with this it takes the Classic path on its own.

Fixes #3659

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 11:05:07 +02:00
Iceman 983b466ca1 Merge pull request #3656 from 0x6r1an0y/20260922-15693magic-docs
Fill in the ISO15693 magic notes
2026-09-22 07:00:20 +07:00
Iceman be8a0d524e Merge pull request #3657 from 0x6r1an0y/20260922-makefile-fix
fix: preserve UTF-8 in generated command docs
2026-09-22 06:59:35 +07:00
Iceman 12899dc2e8 Merge pull request #3658 from Axi-ohm/fix/bigbuf-align-mask-32bit
BigBuf: widen BIGBUF_ALIGN_MASK to 32-bit for PM5
2026-09-22 06:57:56 +07:00
Axi-ohmandClaude Opus 4.8 3f8edc5563 BigBuf: widen BIGBUF_ALIGN_MASK to 32-bit for PM5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-21 18:34:23 -05:00
歐歪andOpenAI Codex 940f26ce37 build: centralize Python executable definition
Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-09-22 07:24:43 +08:00
歐歪 5360980b48 doc: 15693 wipe command would brick the v3 tag for now 2026-09-22 07:14:31 +08:00
iceman1001andClaude Opus 5 4cca8df3a0 hf mfu: support UL-AES in restore, fix info config output
restore refused UL-AES outright.  The generic page plan assumes the last
four pages are cfg0/cfg1/PWD/PACK, which on UL-AES are the AES keys, so
the data loop walked over the lock page, both config pages and the key
lock bits at 0x2D.  Give UL-AES its own plan: user memory 0x04..0x27,
and lock/cfg0/cfg1 behind -s.  Key pages 0x30..0x37 are left alone, the
dump only ever carries AESKey0 and 0x34..0x37 read back as zeros.

info never printed the UL-AES config.  ulaes_print_configuration() is
called with 0x29 but its first branch tested for 0x2C, so cfg0 and cfg1
fell through to the bare return and only the CMAC page showed up.

info also read page 0x34 as if it were an EV1 config page.  That is the
UIDRetrKey.  Genuine silicon NAKs the read, but a magic or simulated
card would have had its key printed as cfg0/cfg1/PWD/PACK.

Tested on a UL-AES with AUTH0=4, PROT set and secure messaging on.
Restore of an unmodified dump comes back byte identical; a dump carrying
DEADBEEF at 0x27 and CAFEBABE at 0x2B writes 0x27 and leaves 0x2B alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 00:23:02 +02:00
歐歪andOpenAI Codex 6775a78a10 fix: preserve UTF-8 in generated command docs
Transcode the MinGW client's CP850 output before writing command documentation and force Python to read the converted stream as UTF-8. Normalize the remaining escaped Greek mu strings to the project's micro sign convention.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-09-22 05:37:09 +08:00
歐歪 4ea8207400 doc: 15693 magic card 2026-09-22 04:32:14 +08:00
Philippe Teuwen 6150d8fc57 "Starting today in version 2.1.277, if there is no CLAUDE.md in a folder, Claude will check for and use AGENTS.md." 2026-09-19 21:02:32 +02:00
Jooyoung bdaaf9fd85 hf iclass view: surface unhandled SIO TLV tags in Insights
print_iclass_sio_decoded() silently dropped any TLV tag it did not
explicitly handle. Real credentials (e.g. SR) carry context tags such as
[5]/[9] that were therefore invisible in the Insights output, even though
the raw block dump and the --verbose ASN1 view showed them.

Print unhandled tags as 'Unknown tag 0xNN : <hex>' so the human-readable
Insights view is lossless. No semantic guessing is done; --verbose still
provides the full ASN1 TLV.
2026-09-19 02:22:01 -04:00
dxl 2c955d7deb Fixed bug on the PM5 platform where changing PM3_CMD_DATA_SIZE to a larger value broke compatibility for certain commands. 2026-09-18 21:56:29 +02:00
dxl d5ef826587 Before sending data via the SSC, it is best to ensure that the transmitter is ready (TX ready). 2026-09-18 21:56:29 +02:00
dxl 38e06eec5a Fixed a bug on the PM5 platform where an CSPAS error caused a SPI_SSC hang, resulting in random device freezes. 2026-09-18 21:56:29 +02:00
Philippe Teuwen 431f553bfa Fix ProxSpace CI for tagged commits
MSYS2 git fails with
C:\ProxSpace\msys2\usr\bin\git.exe rev-parse refs/tags/v4.23346^{commit}
  Error: fatal: ambiguous argument 'refs/tags/v4.23346^commit': unknown revision or path not in the working tr

GitHub's windows-latest hosted runner images ship with Git, so let's use it
2026-09-18 11:26:49 +02:00
Shawn Hoffman 3c1af8e077 ntag424: implement GetTTStatus and SetConfiguration
fix bug in changekey's keyversion param handling
2026-09-18 00:59:15 +02:00
Philippe Teuwen bed32b1458 standalone modes alphabetical order 2026-09-18 00:52:30 +02:00
Philippe Teuwen 731814f67d changelog 2026-09-18 00:23:52 +02:00
Philippe Teuwen e2acee8a85 Revert "Release v4.23346 - Frosty Lemon"
This reverts commit dc0110c29d.
2026-09-18 00:22:18 +02:00
Philippe Teuwen dc0110c29d Release v4.23346 - Frosty Lemon v4.23346 2026-09-18 00:22:18 +02:00
Philippe Teuwen 67f66ab3d9 prepare release 2026-09-18 00:21:27 +02:00
Philippe Teuwen 7822cbd8b1 silent gcc warnings on ARMHF architecture
The warnings are false-positive: resp.data is a union of uint8_t asBytes[] and uint32_t asDwords[], so the buffer is actually 4-byte aligned — but casting uint8_t* directly to a stricter-aligned struct pointer trips -Wcast-align. Fix by routing through (const void *)
2026-09-17 22:53:58 +02:00
Philippe Teuwen b3beffd59b docker tests 2026-09-17 22:48:34 +02:00
Philippe Teuwen afb55e196a Allow skipping setcap, to ease dockerized release tests 2026-09-17 16:59:19 +02:00
Philippe Teuwen 90c41c6de5 use arraylen 2026-09-17 00:23:18 +02:00
Mistial DeveloperandGPT-Daybreak Blue 8ed285af90 feat(desfire): add DFC credential interoperability
Add bidirectional conversion between DFC v4 credentials and mfdes v1 JSON, with documentation and round-trip coverage. Include H10301 FC69 CN420 factory and field fixtures and an external HID reader test target.

Co-Authored-By: GPT-Daybreak Blue <noreply@openai.com>
2026-09-17 00:08:06 +02:00
Mistial DeveloperandGPT-Daybreak Blue 957896a926 build(desfire): make emulator test hook optional
Exclude the USB test dispatcher and queued-random support from normal firmware builds. Enable them with ENABLE_HFMFDESETEST=1 when running emulator vectors.

Co-Authored-By: GPT-Daybreak Blue <noreply@openai.com>
2026-09-17 00:08:06 +02:00