Compare commits

...

405 commits

Author SHA1 Message Date
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
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
1f718683b3 Revert "Release v4.20469 - Daddy Iceman"
This reverts commit 9fa173c727.
2025-06-16 16:18:01 +02:00
iceman1001
9fa173c727 Release v4.20469 - Daddy Iceman 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
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
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
249 changed files with 11137 additions and 4215 deletions

View file

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

View file

@ -2,11 +2,62 @@
All notable changes to this project will be documented in this file. 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... 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...
## [Blue Ice][2025-03-25] ## [unreleased][unreleased]
- 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)
## [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) - Added `des_talk.py` script for easier MIFARE DESFire handling (@trigat)
- Fixed `hf 14b info` - wrong endianess when looking for lock bits etc (@gentilkiwi) - 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` - tries to detect static encrypted nonces and also user cancel during chk keys (@iceman1001)
- Added option to `hf mf autopwn` to use SPI flash dictionary (@jmichelp) - Changed `hf mf autopwn` - added option to use SPI flash dictionary (@jmichelp)
- Changed `trace list -t seos` - now annotate ISO7816 (@iceman1001) - Changed `trace list -t seos` - now annotate ISO7816 (@iceman1001)
- Updated aid and mad json files (@iceman1001) - Updated aid and mad json files (@iceman1001)
- Changed `hf 14a apdu` - now can be interrupted and dynamically adds time (@iceman1001) - Changed `hf 14a apdu` - now can be interrupted and dynamically adds time (@iceman1001)
@ -38,9 +89,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Changed `hf mf cload` - now accepts MFC Ev1 sized dumps (@iceman1001) - Changed `hf mf cload` - now accepts MFC Ev1 sized dumps (@iceman1001)
- Changed `hf mfu info` - now properly identify ULEv1 AES 50pF (@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 `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) - 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) - Added `hf seos sam` - Added support for HID SAM SEOS communications (@jkramarz)
- Changed (extended) area accessible by spiffs into last page of FLASH (@piotrva) - 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 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 `lf em 410x sim` to use default gap value of 0 and extended help (@piotrva)
- Changed `hf 14a info` - now identifies MIAFRE Duox (@iceman1001) - Changed `hf 14a info` - now identifies MIAFRE Duox (@iceman1001)
@ -54,13 +105,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Changed extended area for Mifare keys in SPI flash to hold 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 DESFire D40 secure channel crypto (@nvx)
- Fixed `hf mfp info` fix signature check on 4b UID cards (@doegox) - Fixed `hf mfp info` fix signature check on 4b UID cards (@doegox)
- Automatically set maximum read/write block when using predefined types in `hf_mf_ultimatecard` script (@piotrva) - 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, updated spi_flash_decode.py script with more ICs (@ANTodorov) - 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) - Fixed `hf/lf tune` segfault when called from script (@doegox)
- Added option to set and get maximum read/write block number using `hf_mf_ultimatecard` script (@piotrva) - Changed `hf_mf_ultimatecard` - added option to set and get maximum read/write block number (@piotrva)
- Added JEDEC information for SPI flash W25Q64JV (@ANTodorov) - Added JEDEC information for SPI flash W25Q64JV (@ANTodorov)
- Added special iclass legacy config cards in `hf iclass configcard` (@antiklesys) - Changed `hf iclass configcard` - added special iclass legacy config cards (@antiklesys)
- Added simulation function to `hf iclass legrec` (@antiklesys) - Changed `hf iclass legrec` - added simulation function (@antiklesys)
- Added keys from Momentum firmware projects. (@onovy) - Added keys from Momentum firmware projects. (@onovy)
- Added Dutch Statistics Agency default key (@eagle00789) - Added Dutch Statistics Agency default key (@eagle00789)
- Fixed Wiegand decode with hex input dropping the first bit (@emilyastranova) - Fixed Wiegand decode with hex input dropping the first bit (@emilyastranova)

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/% 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" # hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
#all clean install uninstall check: %: 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 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 INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt sim014.bin sim014.sha512.txt
@ -204,7 +207,7 @@ help:
@echo "+ fpga_compress - Make tools/fpga_compress" @echo "+ fpga_compress - Make tools/fpga_compress"
@echo @echo
@echo "+ style - Apply some automated source code formatting rules" @echo "+ style - Apply some automated source code formatting rules"
@echo "+ commands - Regenerate commands documentation files and autocompletion data @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. Set CHECKARGS to pass arguments to the test script"
@echo "+ .../check - Run offline tests against specific target. See above." @echo "+ .../check - Run offline tests against specific target. See above."
@echo "+ miscchecks - Detect various encoding issues in source code" @echo "+ miscchecks - Detect various encoding issues in source code"
@ -264,8 +267,11 @@ ifeq ($(PLATFORM_CHANGED),true)
$(Q)$(MAKE) --no-print-directory -C bootrom clean $(Q)$(MAKE) --no-print-directory -C bootrom clean
$(Q)$(MAKE) --no-print-directory -C armsrc clean $(Q)$(MAKE) --no-print-directory -C armsrc clean
$(Q)$(MAKE) --no-print-directory -C recovery 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 $(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=$(PLATFORM) > .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache $(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache $(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache
@ -366,10 +372,12 @@ release:
@echo "# - Release Tag: $(VERSION)" @echo "# - Release Tag: $(VERSION)"
@echo "# - Release Name: $(RELEASE_NAME)" @echo "# - Release Name: $(RELEASE_NAME)"
# - Removing -Werror... # - 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 "./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" \) -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... # - 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 @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 @echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
# - Committing temporarily... # - Committing temporarily...
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)" @git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"

View file

@ -112,8 +112,8 @@ ifeq ($(DEBUG),1)
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
DEFLDFLAGS = DEFLDFLAGS =
else else
DEFCXXFLAGS = -Wall -O3 -pipe DEFCXXFLAGS = -Wall -Werror -O3 -pipe
DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
DEFLDFLAGS = DEFLDFLAGS =
endif endif

View file

@ -14,6 +14,9 @@ PLATFORM=PM3RDV4
#PLATFORM=PM3ICOPYX #PLATFORM=PM3ICOPYX
#PLATFORM_EXTRAS=FLASH #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: # If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
#PLATFORM_EXTRAS=BTADDON #PLATFORM_EXTRAS=BTADDON
@ -27,6 +30,10 @@ PLATFORM=PM3RDV4
# Only available with PLATFORM=PM3GENERIC # Only available with PLATFORM=PM3GENERIC
#LED_ORDER=PM3EASY #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 # Uncomment the lines below in order to make a 256KB image
# and comment out the lines above # and comment out the lines above

View file

@ -96,12 +96,14 @@ We define generic Proxmark3 platforms as following devices.
- **Note**: currently incompatible with iCopy-X GUI as Proxmark client commands using different syntax - **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**: 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. - **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** **Unknown support status**
- ⚠ VX - ⚠ VX
- **Note**: unknown device hw - **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. 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 +182,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. 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 This repo compiles nicely on
- WSL1 on Windows 10 - WSL1 on Windows 10
- WSL2 on Windows 10/11
- Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases) - Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases)
- Windows/MinGW environment - Windows/MinGW environment
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian - Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian

View file

@ -121,7 +121,7 @@ void BigBuf_Clear_ext(bool verbose) {
memset(BigBuf, 0, s_bigbuf_size); memset(BigBuf, 0, s_bigbuf_size);
clear_trace(); clear_trace();
if (verbose) { if (verbose) {
Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size); if (g_dbglevel >= DBG_ERROR) Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
} }
} }

View file

@ -23,8 +23,8 @@
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) #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_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 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these #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 #define CARD_MEMORY_SIZE 4096
// For now we're storing FM11RF08S nonces in the upper 1k of CARD_MEMORY_SIZE // 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 // but we might have to allocate extra space if one day we've to support sth like a FM11RF32S

View file

@ -186,7 +186,7 @@ showinfo:
# version_pm3.c should be checked on every time fullimage.stage1.elf should be remade # 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 version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
$(info [-] CHECK $@) $(info [-] CHECK $@)
$(Q)$(CP) $< $@ $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(info [-] GEN $@) $(info [-] GEN $@)

View file

@ -119,6 +119,9 @@ define KNOWN_STANDALONE_DEFINITIONS
| HF_REBLAY | 14A Relay over BT | | HF_REBLAY | 14A Relay over BT |
| (RDV4 only) | - Salvador Mendoza | | (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 | | HF_TCPRST | IKEA Rothult read/sim/dump/emul |
| | - Nick Draffen | | | - Nick Draffen |
+----------------------------------------------------------+ +----------------------------------------------------------+
@ -139,11 +142,11 @@ endef
STANDALONE_MODES := LF_SKELETON 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 += 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 += DANKARMULTI
STANDALONE_MODES_REQ_BT := HF_CARDHOPPER HF_REBLAY STANDALONE_MODES_REQ_BT := HF_CARDHOPPER HF_REBLAY
STANDALONE_MODES_REQ_SMARTCARD := 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)),) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)

View file

@ -157,6 +157,10 @@ endif
ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS))) ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS)))
SRC_STANDALONE = hf_young.c SRC_STANDALONE = hf_young.c
endif 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))) ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS)))
SRC_STANDALONE = dankarmulti.c SRC_STANDALONE = dankarmulti.c

View file

@ -157,7 +157,7 @@ void RunMod(void) {
if (button_pressed != BUTTON_NO_CLICK || data_available()) if (button_pressed != BUTTON_NO_CLICK || data_available())
break; break;
else if (state == STATE_SEARCH) { 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); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF(); LED_D_OFF();
SpinDelay(500); SpinDelay(500);
@ -246,7 +246,7 @@ void RunMod(void) {
FLAG_SET_UID_IN_DATA(flags, 7); FLAG_SET_UID_IN_DATA(flags, 7);
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state."); Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0, false, false);
// Go back to search state if user presses pm3-button // Go back to search state if user presses pm3-button
state = STATE_SEARCH; state = STATE_SEARCH;

View file

@ -59,7 +59,7 @@ static const uint8_t magicCARD[4] = "CARD";
static const uint8_t magicEND [4] = "\xff" "END"; static const uint8_t magicEND [4] = "\xff" "END";
static const uint8_t magicRSRT[7] = "RESTART"; static const uint8_t magicRSRT[7] = "RESTART";
static const uint8_t magicERR [4] = "\xff" "ERR"; 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 // Forward declarations
static void become_reader(void); static void become_reader(void);
@ -72,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 reply_with_packet(packet_t *);
static void read_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 *); static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *, uint16_t, uint8_t *, int *);
@ -146,7 +146,7 @@ static void become_reader(void) {
packet_t packet = { 0 }; packet_t packet = { 0 };
packet_t *rx = &packet; packet_t *rx = &packet;
packet_t *tx = &packet; packet_t *tx = &packet;
uint8_t toCard[256] = { 0 }; uint8_t toCard[MAX_FRAME_SIZE] = { 0 };
uint8_t parity[MAX_PARITY_SIZE] = { 0 }; uint8_t parity[MAX_PARITY_SIZE] = { 0 };
while (1) { while (1) {
@ -178,11 +178,15 @@ static void become_reader(void) {
AddCrc14A(toCard, rx->len); AddCrc14A(toCard, rx->len);
ReaderTransmit(toCard, rx->len + 2, NULL); ReaderTransmit(toCard, rx->len + 2, NULL);
tx->len = ReaderReceive(tx->dat, sizeof(tx->dat), parity); // read to toCard instead of tx->dat directly to allow the extra byte for the CRC
if (tx->len == 0) { uint16_t fromCardLen = ReaderReceive(toCard, sizeof(toCard), parity);
if (fromCardLen <= 2) {
tx->len = sizeof(magicERR); tx->len = sizeof(magicERR);
memcpy(tx->dat, magicERR, 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); write_packet(tx);
} }
@ -229,14 +233,15 @@ static void become_card(void) {
tag_response_info_t *canned; tag_response_info_t *canned;
uint32_t cuid; uint32_t cuid;
uint32_t counters[3] = { 0 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages; uint8_t pages;
SimulateIso14443aInit(tagType, flags, data, NULL, 0, &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"); DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
int fromReaderLen; int fromReaderLen;
uint8_t fromReaderDat[256] = { 0 }; uint8_t fromReaderDat[MAX_FRAME_SIZE] = { 0 };
uint8_t parity[MAX_PARITY_SIZE] = { 0 }; uint8_t parity[MAX_PARITY_SIZE] = { 0 };
packet_t packet = { 0 }; packet_t packet = { 0 };
packet_t *tx = &packet; packet_t *tx = &packet;
@ -277,8 +282,14 @@ static void become_card(void) {
memcpy(tx->dat, fromReaderDat, tx->len); memcpy(tx->dat, fromReaderDat, tx->len);
write_packet(tx); 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); read_packet(rx);
if (!no_reply && rx->len > 0) { if (rx->len > 0) {
reply_with_packet(rx); reply_with_packet(rx);
} }
} }
@ -344,7 +355,13 @@ static void cook_ats(packet_t *ats, uint8_t fwi, uint8_t sfgi) {
uint8_t orig_t0 = ats->dat[1]; uint8_t orig_t0 = ats->dat[1];
// Update FSCI in T0 from the received ATS // 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 len = ats->len - 2;
uint8_t *orig_ats_ptr = &ats->dat[2]; uint8_t *orig_ats_ptr = &ats->dat[2];
@ -449,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_responseBuffer [MAX_FRAME_SIZE] = { 0 };
static uint8_t g_modulationBuffer[1024] = { 0 };
static void reply_with_packet(packet_t *packet) { static void reply_with_packet(packet_t *packet) {
tag_response_info_t response = { 0 }; memcpy(g_responseBuffer, packet->dat, packet->len);
response.response = g_responseBuffer; AddCrc14A(g_responseBuffer, packet->len);
response.modulation = g_modulationBuffer; EmSendCmd(g_responseBuffer, packet->len + 2);
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);
} }
@ -496,19 +505,27 @@ static void read_packet(packet_t *packet) {
// clear any remaining buffered data // clear any remaining buffered data
while (cardhopper_data_available()) { while (cardhopper_data_available()) {
cardhopper_read(packet->dat, 255); cardhopper_read(packet->dat, sizeof(packet->dat));
} }
packet->len = 0; packet->len = 0;
return; 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) { static void write_packet(const packet_t *packet) {
cardhopper_write((uint8_t *) packet, packet->len + 1); cardhopper_write((const uint8_t *) packet, packet->len + 1);
} }

View file

@ -498,7 +498,7 @@ failtag:
SpinOff(50); SpinOff(50);
LED_A_ON(); 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(); WDT_HIT();
if (BUTTON_HELD(10) == BUTTON_HOLD) { if (BUTTON_HELD(10) == BUTTON_HOLD) {
WDT_HIT(); WDT_HIT();
@ -785,7 +785,7 @@ static int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
bool isOK = true; 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; isOK = false;
} }
@ -844,8 +844,7 @@ static int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTr
for (uint8_t i = 0; i < keyCount; i++) { for (uint8_t i = 0; i < keyCount; i++) {
/* no need for anticollision. just verify tag is still here */ /* 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) == 0) {
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
break; break;
@ -963,7 +962,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, const
// get UID from chip // get UID from chip
if (workFlags & 0x01) { 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"); DbprintfEx(FLAG_NEWLINE, "Can't select card");
break; break;
}; };

View file

@ -89,22 +89,22 @@ void RunMod(void) {
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state."); 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) { if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) {
DbpString("Mifare Classic 1k"); DbpString("Mifare Classic 1k");
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) { } else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
DbpString("Mifare Classic 4k "); DbpString("Mifare Classic 4k ");
SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) { } else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
DbpString("Mifare Ultralight"); DbpString("Mifare Ultralight");
SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) { } else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) {
DbpString("Mifare DESFire"); DbpString("Mifare DESFire");
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
} else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) { } else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) {
DbpString("Mifare DESFire Ev1/Plus/JCOP"); DbpString("Mifare DESFire Ev1/Plus/JCOP");
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
} else { } else {
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation"); Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0); SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
} }
// Go back to search state if user presses pm3-button // Go back to search state if user presses pm3-button

View file

@ -33,6 +33,7 @@
#include "mifaresim.h" // mifare1ksim #include "mifaresim.h" // mifare1ksim
#include "mifareutil.h" #include "mifareutil.h"
#include "proxmark3_arm.h" #include "proxmark3_arm.h"
#include "spiffs.h"
#include "standalone.h" // standalone definitions #include "standalone.h" // standalone definitions
#include "string.h" #include "string.h"
#include "ticks.h" #include "ticks.h"
@ -534,7 +535,14 @@ void RunMod(void) {
SpinErr(LED_D, 50, 8); SpinErr(LED_D, 50, 8);
partialEmulation = true; partialEmulation = true;
} else { } 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; state = STATE_EMULATE;

View file

@ -21,6 +21,9 @@
#include <inttypes.h> #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 // Set of standard keys to be used
static uint64_t const MATTYRUN_MFC_DEFAULT_KEYS[] = { static uint64_t const MATTYRUN_MFC_DEFAULT_KEYS[] = {
0xFFFFFFFFFFFF, // Default key 0xFFFFFFFFFFFF, // Default key

View file

@ -379,7 +379,7 @@ void RunMod(void) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP) // tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL, NULL, NULL) == false) { if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL, NULL) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_RED_("Error initializing the emulation process!")); DbpString(_RED_("Error initializing the emulation process!"));

View file

@ -268,7 +268,7 @@ void RunMod() {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
// 4 = ISO/IEC 14443-4 - javacard (JCOP) // 4 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL, NULL, NULL) == false) { if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL, NULL) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_RED_("Error initializing the emulation process!")); DbpString(_RED_("Error initializing the emulation process!"));

File diff suppressed because it is too large Load diff

View file

@ -118,8 +118,6 @@ void RunMod(void) {
uint8_t tagType = 10; // 10 = ST25TA IKEA Rothult uint8_t tagType = 10; // 10 = ST25TA IKEA Rothult
tag_response_info_t *responses; tag_response_info_t *responses;
uint32_t cuid = 0; uint32_t cuid = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0; uint8_t pages = 0;
// command buffers // command buffers
@ -193,7 +191,7 @@ void RunMod(void) {
memcpy(data, stuid, sizeof(stuid)); memcpy(data, stuid, sizeof(stuid));
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, counters, tearings, &pages) == false) { if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages, NULL) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the simulation process!"); DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
@ -371,7 +369,7 @@ void RunMod(void) {
memcpy(data, stuid, sizeof(stuid)); memcpy(data, stuid, sizeof(stuid));
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, counters, tearings, &pages) == false) { if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages, NULL) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the simulation process!"); DbpString(_YELLOW_("!!") "Error initializing the simulation process!");

View file

@ -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); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF(); LED_D_OFF();
SpinDelay(500); SpinDelay(500);
@ -253,25 +253,25 @@ void RunMod(void) {
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) { if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 1k"); DbpString("Mifare Classic 1k");
SimulateIso14443aTag(1, flags, data, 0, NULL, 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) { } else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (4b uid)"); DbpString("Mifare Classic 4k (4b uid)");
SimulateIso14443aTag(8, flags, data, 0, NULL, 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) { } else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Classic 4k (7b uid)"); DbpString("Mifare Classic 4k (7b uid)");
SimulateIso14443aTag(8, flags, data, 0, NULL, 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) { } else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
DbpString("Mifare Ultralight"); DbpString("Mifare Ultralight");
SimulateIso14443aTag(2, flags, data, 0, NULL, 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) { } else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
DbpString("Mifare DESFire"); DbpString("Mifare DESFire");
SimulateIso14443aTag(3, flags, data, 0, NULL, 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) { } else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0x03) {
DbpString("Mifare DESFire Ev1/Plus/JCOP"); DbpString("Mifare DESFire Ev1/Plus/JCOP");
SimulateIso14443aTag(3, flags, data, 0, NULL, 0); SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
} else { } else {
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation"); Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
SimulateIso14443aTag(1, flags, data, 0, NULL, 0); SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
} }
} else if (button_pressed == BUTTON_SINGLE_CLICK) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {

View file

@ -99,12 +99,13 @@ int tearoff_hook(void) {
if (g_tearoff_enabled) { if (g_tearoff_enabled) {
if (g_tearoff_delay_us == 0) { if (g_tearoff_delay_us == 0) {
Dbprintf(_RED_("No tear-off delay configured!")); Dbprintf(_RED_("No tear-off delay configured!"));
g_tearoff_enabled = false;
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
} }
SpinDelayUsPrecision(g_tearoff_delay_us); SpinDelayUsPrecision(g_tearoff_delay_us);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
g_tearoff_enabled = false; g_tearoff_enabled = false;
Dbprintf(_YELLOW_("Tear-off triggered!")); if (g_dbglevel >= DBG_ERROR) Dbprintf(_YELLOW_("Tear-off triggered!"));
return PM3_ETEAROFF; return PM3_ETEAROFF;
} else { } else {
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
@ -254,7 +255,7 @@ static uint32_t MeasureAntennaTuningLfData(void) {
void print_stack_usage(void) { void print_stack_usage(void) {
for (uint32_t *p = _stack_start; ; ++p) { for (uint32_t *p = _stack_start; ; ++p) {
if (*p != 0xdeadbeef) { 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; break;
} }
} }
@ -365,7 +366,7 @@ static void print_debug_level(void) {
sprintf(dbglvlstr, "extended"); sprintf(dbglvlstr, "extended");
break; 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. // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
@ -421,11 +422,11 @@ static void SendStatus(uint32_t wait) {
print_debug_level(); print_debug_level();
tosend_t *ts = get_tosend(); tosend_t *ts = get_tosend();
Dbprintf(" ToSendMax............... %d", ts->max); Dbprintf(" ToSendMax........... %d", ts->max);
Dbprintf(" ToSend BUFFERSIZE....... %d", TOSEND_BUFFER_SIZE); Dbprintf(" ToSend BUFFERSIZE... %d", TOSEND_BUFFER_SIZE);
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... 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 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 delta_time = 0;
uint32_t start_time = GetTickCount(); uint32_t start_time = GetTickCount();
#define SLCK_CHECK_MS 50 #define SLCK_CHECK_MS 50
@ -449,10 +450,11 @@ static void SendStatus(uint32_t wait) {
} else { } else {
num = 0; num = 0;
} }
if (num > 0) { if (num > 0) {
Dbprintf(" Mifare.................. "_YELLOW_("%u")" keys (spiffs: "_GREEN_("%s")")", num, MF_KEYS_FILE); Dbprintf(" Mifare... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MF_KEYS_FILE);
} else { } else {
Dbprintf(" Mifare.................. "_RED_("%u")" keys (spiffs: "_RED_("%s")")", num, MF_KEYS_FILE); Dbprintf(" Mifare... "_RED_("%u")" keys - "_RED_("%s"), num, MF_KEYS_FILE);
} }
if (exists_in_spiffs(T55XX_KEYS_FILE)) { if (exists_in_spiffs(T55XX_KEYS_FILE)) {
@ -460,10 +462,11 @@ static void SendStatus(uint32_t wait) {
} else { } else {
num = 0; num = 0;
} }
if (num > 0) { if (num > 0) {
Dbprintf(" T55xx................... "_YELLOW_("%u")" keys (spiffs: "_GREEN_("%s")")", num, T55XX_KEYS_FILE); Dbprintf(" T55xx.... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, T55XX_KEYS_FILE);
} else { } else {
Dbprintf(" T55xx................... "_RED_("%u")" keys (spiffs: "_RED_("%s")")", num, T55XX_KEYS_FILE); Dbprintf(" T55xx.... "_RED_("%u")" keys - "_RED_("%s"), num, T55XX_KEYS_FILE);
} }
if (exists_in_spiffs(ICLASS_KEYS_FILE)) { if (exists_in_spiffs(ICLASS_KEYS_FILE)) {
@ -471,11 +474,38 @@ static void SendStatus(uint32_t wait) {
} else { } else {
num = 0; num = 0;
} }
if (num > 0) { if (num > 0) {
Dbprintf(" iClass.................. "_YELLOW_("%u")" keys (spiffs: "_GREEN_("%s")")", num, ICLASS_KEYS_FILE); Dbprintf(" iClass... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, ICLASS_KEYS_FILE);
} else { } else {
Dbprintf(" iClass.................. "_RED_("%u")" keys (spiffs: "_RED_("%s")")", num, ICLASS_KEYS_FILE); 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 #endif
DbpString(""); DbpString("");
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0); reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
@ -1664,13 +1694,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break; break;
} }
case CMD_HF_ISO14443A_GET_CONFIG: { case CMD_HF_ISO14443A_GET_CONFIG: {
hf14a_config *hf14aconfig = getHf14aConfig(); hf14a_config_t *c = getHf14aConfig();
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)hf14aconfig, sizeof(hf14a_config)); reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(hf14a_config_t));
break; break;
} }
case CMD_HF_ISO14443A_SET_CONFIG: { case CMD_HF_ISO14443A_SET_CONFIG: {
hf14a_config c; hf14a_config_t c;
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config)); memcpy(&c, packet->data.asBytes, sizeof(hf14a_config_t));
setHf14aConfig(&c); setHf14aConfig(&c);
break; break;
} }
@ -1719,10 +1749,13 @@ static void PacketReceived(PacketCommandNG *packet) {
uint8_t uid[10]; uint8_t uid[10];
uint8_t exitAfter; uint8_t exitAfter;
uint8_t rats[20]; uint8_t rats[20];
bool ulc_p1;
bool ulc_p2;
} PACKED; } PACKED;
struct p *payload = (struct p *) packet->data.asBytes; struct p *payload = (struct p *) packet->data.asBytes;
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid,
payload->exitAfter, payload->rats, sizeof(payload->rats)); // ## Simulate iso14443a tag - pass tag type & UID payload->exitAfter, payload->rats, sizeof(payload->rats),
payload->ulc_p1, payload->ulc_p2); // ## Simulate iso14443a tag - pass tag type & UID
break; break;
} }
case CMD_HF_ISO14443A_SIM_AID: { case CMD_HF_ISO14443A_SIM_AID: {
@ -1806,7 +1839,7 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p { struct p {
bool turn_off_field; bool turn_off_field;
uint8_t keyno; uint8_t keyno;
uint8_t key[18]; uint8_t key[16];
} PACKED; } PACKED;
struct p *payload = (struct p *) packet->data.asBytes; struct p *payload = (struct p *) packet->data.asBytes;
MifareUL_AES_Auth(payload->turn_off_field, payload->keyno, payload->key); MifareUL_AES_Auth(payload->turn_off_field, payload->keyno, payload->key);
@ -1969,7 +2002,7 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p *payload = (struct p *) packet->data.asBytes; struct p *payload = (struct p *) packet->data.asBytes;
// //
size_t size = payload->blockno * payload->blockwidth; size_t size = payload->blockcnt * payload->blockwidth;
if (size > PM3_CMD_DATA_SIZE) { if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0); reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return; return;
@ -2226,6 +2259,10 @@ static void PacketReceived(PacketCommandNG *packet) {
iclass_credit_epurse((iclass_credit_epurse_t *)packet->data.asBytes); iclass_credit_epurse((iclass_credit_epurse_t *)packet->data.asBytes);
break; break;
} }
case CMD_HF_ICLASS_TEARBL: {
iClass_TearBlock((iclass_tearblock_req_t *)packet->data.asBytes);
break;
}
#endif #endif
#ifdef WITH_HFSNIFF #ifdef WITH_HFSNIFF
@ -2354,7 +2391,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint16_t available; uint16_t available;
uint16_t pre_available = 0; uint16_t pre_available = 0;
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
uint32_t wait = payload->waittime; uint32_t wait = payload->waittime;
StartTicks(); StartTicks();
@ -2398,7 +2435,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint16_t available; uint16_t available;
uint16_t pre_available = 0; uint16_t pre_available = 0;
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
uint32_t wait = payload->waittime; uint32_t wait = payload->waittime;
StartTicks(); StartTicks();
@ -2694,7 +2731,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint32_t size = packet->oldarg[1]; uint32_t size = packet->oldarg[1];
uint8_t *buff = BigBuf_malloc(size); uint8_t *buff = BigBuf_calloc(size);
if (buff == NULL) { if (buff == NULL) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory"); if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
// Trigger a finish downloading signal with an PM3_EMALLOC // Trigger a finish downloading signal with an PM3_EMALLOC
@ -2899,7 +2936,7 @@ static void PacketReceived(PacketCommandNG *packet) {
case CMD_FLASHMEM_DOWNLOAD: { case CMD_FLASHMEM_DOWNLOAD: {
LED_B_ON(); 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 startidx = packet->oldarg[0];
uint32_t numofbytes = packet->oldarg[1]; uint32_t numofbytes = packet->oldarg[1];
// arg0 = startindex // arg0 = startindex
@ -2931,7 +2968,7 @@ static void PacketReceived(PacketCommandNG *packet) {
case CMD_FLASHMEM_INFO: { case CMD_FLASHMEM_INFO: {
LED_B_ON(); 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_P(spi_flash_pages64k), info->signature, FLASH_MEM_SIGNATURE_LEN); bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k), info->signature, FLASH_MEM_SIGNATURE_LEN);

View file

@ -102,9 +102,7 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
} }
#endif #endif
} }
void print_result(const char *name, const uint8_t *d, size_t void print_result(const char *name, const uint8_t *d, size_t n) {
n) {
const uint8_t *p = d; const uint8_t *p = d;
uint16_t tmp = n & 0xFFF0; uint16_t tmp = n & 0xFFF0;

View file

@ -748,7 +748,7 @@ void em4x50_chk(const char *filename, bool ledcontrol) {
uint16_t pwd_count = 0; uint16_t pwd_count = 0;
uint32_t size = size_in_spiffs(filename); uint32_t size = size_in_spiffs(filename);
pwd_count = size / 4; 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); rdv40_spiffs_read_as_filetype(filename, pwds, size, RDV40_SPIFFS_SAFETY_SAFE);

View file

@ -45,7 +45,7 @@
#define DPRINTF_EXTENDED(x) do { if ((FORCE_ENABLE_LOGGING) || (g_dbglevel >= DBG_EXTENDED)) { Dbprintf x ; } } while (0); #define DPRINTF_EXTENDED(x) do { if ((FORCE_ENABLE_LOGGING) || (g_dbglevel >= DBG_EXTENDED)) { Dbprintf x ; } } while (0);
#define DPRINTF_PROLIX(x) do { if ((FORCE_ENABLE_LOGGING) || (g_dbglevel > DBG_EXTENDED)) { Dbprintf x ; } } while (0); #define DPRINTF_PROLIX(x) do { if ((FORCE_ENABLE_LOGGING) || (g_dbglevel > DBG_EXTENDED)) { Dbprintf x ; } } while (0);
// EM4170 requires a parity bit on commands, other variants do not. // EM4170 requires a parity bit on commands, other variants do not.
static bool g_command_parity = true; static bool g_deprecated_command_parity = false;
static em4x70_tag_t g_tag = { 0 }; static em4x70_tag_t g_tag = { 0 };
@ -905,8 +905,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_id(em4x70_command_bitstream_t
bool result = true; bool result = true;
memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t)); memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t));
out_cmd_bitstream->command = EM4X70_COMMAND_ID; out_cmd_bitstream->command = EM4X70_COMMAND_ID;
//uint8_t cmd = with_command_parity ? 0x3u : 0x1u; uint8_t cmd = 0x3u; // CMD + Parity bit == 0b001'1
uint8_t cmd = 0x3u;
result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false); result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false);
out_cmd_bitstream->to_receive.bitcount = 32; out_cmd_bitstream->to_receive.bitcount = 32;
if (out_cmd_bitstream->to_send.bitcount != expected_bits_to_send) { if (out_cmd_bitstream->to_send.bitcount != expected_bits_to_send) {
@ -920,8 +919,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_um1(em4x70_command_bitstream_
bool result = true; bool result = true;
memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t)); memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t));
out_cmd_bitstream->command = EM4X70_COMMAND_UM1; out_cmd_bitstream->command = EM4X70_COMMAND_UM1;
//uint8_t cmd = with_command_parity ? 0x5u : 0x2u; uint8_t cmd = 0x5u; // CMD + Parity bit == 0b010'1
uint8_t cmd = 0x5u;
result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false); result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false);
out_cmd_bitstream->to_receive.bitcount = 32; out_cmd_bitstream->to_receive.bitcount = 32;
if (out_cmd_bitstream->to_send.bitcount != expected_bits_to_send) { if (out_cmd_bitstream->to_send.bitcount != expected_bits_to_send) {
@ -935,8 +933,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_um2(em4x70_command_bitstream_
bool result = true; bool result = true;
memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t)); memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t));
out_cmd_bitstream->command = EM4X70_COMMAND_UM2; out_cmd_bitstream->command = EM4X70_COMMAND_UM2;
//uint8_t cmd = with_command_parity ? 0xFu : 0x7u; uint8_t cmd = 0xFu; // CMD + Parity bit == 0b111'1
uint8_t cmd = 0xFu;
result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false); result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false);
out_cmd_bitstream->to_receive.bitcount = 64; out_cmd_bitstream->to_receive.bitcount = 64;
if (out_cmd_bitstream->to_send.bitcount != expected_bits_to_send) { if (out_cmd_bitstream->to_send.bitcount != expected_bits_to_send) {
@ -954,8 +951,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_auth(em4x70_command_bitstream
em4x70_bitstream_t *s = &out_cmd_bitstream->to_send; em4x70_bitstream_t *s = &out_cmd_bitstream->to_send;
// uint8_t cmd = with_command_parity ? 0x6u : 0x3u; uint8_t cmd = 0x6u; // CMD + Parity bit == 0b011'0
uint8_t cmd = 0x6u; // HACK - always sent with cmd parity
result = result && add_nibble_to_bitstream(s, cmd, false); result = result && add_nibble_to_bitstream(s, cmd, false);
// Reader: [RM][0][Command][N55..N0][0000000][f(RN)27..f(RN)0] // Reader: [RM][0][Command][N55..N0][0000000][f(RN)27..f(RN)0]
@ -1004,8 +1000,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_pin(em4x70_command_bitstream_
out_cmd_bitstream->command = EM4X70_COMMAND_PIN; out_cmd_bitstream->command = EM4X70_COMMAND_PIN;
//uint8_t cmd = with_command_parity ? 0x9u : 0x4u; uint8_t cmd = 0x9u; // CMD + Parity bit == 0b100'1
uint8_t cmd = 0x9u; // HACK - always sent with cmd parity, with extra zero bit in RM?
result = result && add_nibble_to_bitstream(s, cmd, false); result = result && add_nibble_to_bitstream(s, cmd, false);
// Send tag's ID ... indexes 4 .. 35 // Send tag's ID ... indexes 4 .. 35
@ -1037,8 +1032,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_write(em4x70_command_bitstrea
em4x70_bitstream_t *s = &out_cmd_bitstream->to_send; em4x70_bitstream_t *s = &out_cmd_bitstream->to_send;
//uint8_t cmd = with_command_parity ? 0xAu : 0x5u; uint8_t cmd = 0xAu; // CMD + Parity bit == 0b101'0
uint8_t cmd = 0xAu; // HACK - always sent with cmd parity, with extra zero bit in RM?
result = result && add_nibble_to_bitstream(s, cmd, false); result = result && add_nibble_to_bitstream(s, cmd, false);
if ((address & 0x0Fu) != address) { if ((address & 0x0Fu) != address) {
@ -1097,7 +1091,7 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon
em4x70_command_bitstream_t auth_cmd; em4x70_command_bitstream_t auth_cmd;
const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators; const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators;
generator->auth(&auth_cmd, g_command_parity, rnd, frnd); generator->auth(&auth_cmd, g_deprecated_command_parity, rnd, frnd);
bool result = send_bitstream_and_read(&auth_cmd); bool result = send_bitstream_and_read(&auth_cmd);
if (result) { if (result) {
@ -1185,7 +1179,7 @@ static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t *
static int send_pin(const uint32_t pin) { static int send_pin(const uint32_t pin) {
em4x70_command_bitstream_t send_pin_cmd; em4x70_command_bitstream_t send_pin_cmd;
const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators; const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators;
generator->pin(&send_pin_cmd, g_command_parity, &g_tag.data[4], pin); generator->pin(&send_pin_cmd, g_deprecated_command_parity, &g_tag.data[4], pin);
bool result = send_bitstream_wait_ack_wait_read(&send_pin_cmd); bool result = send_bitstream_wait_ack_wait_read(&send_pin_cmd);
return result ? PM3_SUCCESS : PM3_ESOFT; return result ? PM3_SUCCESS : PM3_ESOFT;
@ -1196,7 +1190,7 @@ static int write(const uint16_t word, const uint8_t address) {
em4x70_command_bitstream_t write_cmd; em4x70_command_bitstream_t write_cmd;
const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators; const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators;
generator->write(&write_cmd, g_command_parity, word, address); generator->write(&write_cmd, g_deprecated_command_parity, word, address);
bool result = send_bitstream_wait_ack_wait_ack(&write_cmd); bool result = send_bitstream_wait_ack_wait_ack(&write_cmd);
if (!result) { if (!result) {
@ -1283,7 +1277,7 @@ static uint8_t encoded_bit_array_to_byte(const uint8_t *bits, int count_of_bits)
static bool em4x70_read_id(void) { static bool em4x70_read_id(void) {
em4x70_command_bitstream_t read_id_cmd; em4x70_command_bitstream_t read_id_cmd;
const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators; const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators;
generator->id(&read_id_cmd, g_command_parity); generator->id(&read_id_cmd, g_deprecated_command_parity);
bool result = send_bitstream_and_read(&read_id_cmd); bool result = send_bitstream_and_read(&read_id_cmd);
if (result) { if (result) {
@ -1300,7 +1294,7 @@ static bool em4x70_read_id(void) {
static bool em4x70_read_um1(void) { static bool em4x70_read_um1(void) {
em4x70_command_bitstream_t read_um1_cmd; em4x70_command_bitstream_t read_um1_cmd;
const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators; const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators;
generator->um1(&read_um1_cmd, g_command_parity); generator->um1(&read_um1_cmd, g_deprecated_command_parity);
bool result = send_bitstream_and_read(&read_um1_cmd); bool result = send_bitstream_and_read(&read_um1_cmd);
if (result) { if (result) {
@ -1319,7 +1313,7 @@ static bool em4x70_read_um1(void) {
static bool em4x70_read_um2(void) { static bool em4x70_read_um2(void) {
em4x70_command_bitstream_t read_um2_cmd; em4x70_command_bitstream_t read_um2_cmd;
const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators; const em4x70_command_generators_t *generator = &legacy_em4x70_command_generators;
generator->um2(&read_um2_cmd, g_command_parity); generator->um2(&read_um2_cmd, g_deprecated_command_parity);
bool result = send_bitstream_and_read(&read_um2_cmd); bool result = send_bitstream_and_read(&read_um2_cmd);
if (result) { if (result) {
@ -1435,7 +1429,7 @@ void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) {
bool success_with_UM2 = false; bool success_with_UM2 = false;
// Support tags with and without command parity bits // Support tags with and without command parity bits
g_command_parity = etd->parity; g_deprecated_command_parity = false;
init_tag(); init_tag();
em4x70_setup_read(); em4x70_setup_read();
@ -1463,10 +1457,10 @@ void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) {
void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) {
int status = PM3_ESOFT; int status = PM3_ESOFT;
g_command_parity = etd->parity; g_deprecated_command_parity = false;
// Disable to prevent sending corrupted data to the tag. // Disable to prevent sending corrupted data to the tag.
if (g_command_parity) { if (g_deprecated_command_parity) {
DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 write` is non-functional and may corrupt data on the tag.")); DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 write` is non-functional and may corrupt data on the tag."));
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); // reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
// return; // return;
@ -1499,7 +1493,7 @@ void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) {
int status = PM3_ESOFT; int status = PM3_ESOFT;
g_command_parity = etd->parity; g_deprecated_command_parity = false;
init_tag(); init_tag();
em4x70_setup_read(); em4x70_setup_read();
@ -1534,10 +1528,10 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) {
uint8_t response[3] = {0}; uint8_t response[3] = {0};
g_command_parity = etd->parity; g_deprecated_command_parity = false;
// Disable to prevent sending corrupted data to the tag. // Disable to prevent sending corrupted data to the tag.
if (g_command_parity) { if (g_deprecated_command_parity) {
DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 auth` is non-functional.")); DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 auth` is non-functional."));
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); // reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
// return; // return;
@ -1562,10 +1556,10 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) {
int status = PM3_ESOFT; int status = PM3_ESOFT;
uint8_t response[2] = {0}; uint8_t response[2] = {0};
g_command_parity = etd->parity; g_deprecated_command_parity = false;
// Disable to prevent sending corrupted data to the tag. // Disable to prevent sending corrupted data to the tag.
if (g_command_parity) { if (g_deprecated_command_parity) {
DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 brute` is non-functional and may corrupt data on the tag.")); DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 brute` is non-functional and may corrupt data on the tag."));
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); // reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
// return; // return;
@ -1590,10 +1584,10 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) {
int status = PM3_ESOFT; int status = PM3_ESOFT;
g_command_parity = etd->parity; g_deprecated_command_parity = false;
// Disable to prevent sending corrupted data to the tag. // Disable to prevent sending corrupted data to the tag.
if (g_command_parity) { if (g_deprecated_command_parity) {
DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 setpin` is non-functional and may corrupt data on the tag.")); DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 setpin` is non-functional and may corrupt data on the tag."));
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); // reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
// return; // return;
@ -1639,10 +1633,10 @@ void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) {
int status = PM3_ESOFT; int status = PM3_ESOFT;
g_command_parity = etd->parity; g_deprecated_command_parity = false;
// Disable to prevent sending corrupted data to the tag. // Disable to prevent sending corrupted data to the tag.
if (g_command_parity) { if (g_deprecated_command_parity) {
DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 setkey` is non-functional and may corrupt data on the tag.")); DPRINTF_ALWAYS(("Use of `--par` option with `lf em 4x70 setkey` is non-functional and may corrupt data on the tag."));
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0); // reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
// return; // return;

View file

@ -857,7 +857,7 @@ void SmartCardRaw(const smart_card_raw_t *p) {
LED_D_ON(); LED_D_ON();
uint16_t len = 0; uint16_t len = 0;
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
// check if alloacted... // check if alloacted...
smartcard_command_t flags = p->flags; smartcard_command_t flags = p->flags;
@ -937,7 +937,7 @@ void SmartCardUpgrade(uint64_t arg0) {
bool isOK = true; bool isOK = true;
uint16_t length = arg0, pos = 0; uint16_t length = arg0, pos = 0;
const uint8_t *fwdata = BigBuf_get_addr(); 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) { while (length) {

View file

@ -36,7 +36,7 @@
// 8051 speaks with smart card. // 8051 speaks with smart card.
// 1000*50*3.07 = 153.5ms // 1000*50*3.07 = 153.5ms
// 1 byte transfer == 1ms with max frame being 256 bytes // 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); void I2C_recovery(void);

View file

@ -40,7 +40,7 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
LED_D_ON(); LED_D_ON();
uint16_t len = 0; uint16_t len = 0;
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
resp[0] = prepend; resp[0] = prepend;
// check if alloacted... // check if alloacted...
smartcard_command_t flags = p->flags; smartcard_command_t flags = p->flags;

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,7 @@
// times in samples @ 212kHz when acting as reader // times in samples @ 212kHz when acting as reader
#define ICLASS_READER_TIMEOUT_ACTALL 330 // 1558us, nominal 330us + 7slots*160us = 1450us #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 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 #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. // The length of a received command will in most cases be no more than 18 bytes.
@ -72,4 +73,5 @@ 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 iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time, bool shallow_mod);
void iClass_Recover(iclass_recover_req_t *msg); void iClass_Recover(iclass_recover_req_t *msg);
void iClass_TearBlock(iclass_tearblock_req_t *msg);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -125,8 +125,8 @@ typedef enum {
#endif #endif
void printHf14aConfig(void); void printHf14aConfig(void);
void setHf14aConfig(const hf14a_config *hc); void setHf14aConfig(const hf14a_config_t *hc);
hf14a_config *getHf14aConfig(void); hf14a_config_t *getHf14aConfig(void);
void iso14a_set_timeout(uint32_t timeout); void iso14a_set_timeout(uint32_t timeout);
uint32_t iso14a_get_timeout(void); uint32_t iso14a_get_timeout(void);
@ -143,7 +143,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
void RAMFUNC SniffIso14443a(uint8_t param); void RAMFUNC SniffIso14443a(uint8_t param);
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads, void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
uint8_t *ats, size_t ats_len); uint8_t *ats, size_t ats_len, bool ulc_part1, bool ulc_part2);
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid, 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 *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
@ -152,21 +152,25 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
uint8_t *ats, size_t ats_len, tag_response_info_t **responses, uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages); uint32_t *cuid, uint8_t *pages,
uint8_t *ulc_key);
bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len); bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len);
void iso14443a_antifuzz(uint32_t flags); void iso14443a_antifuzz(uint32_t flags);
void ReaderIso14443a(PacketCommandNG *c); void ReaderIso14443a(PacketCommandNG *c);
void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing); void ReaderTransmit(const uint8_t *frame, uint16_t len, uint32_t *timing);
void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing); void ReaderTransmitBitsPar(const 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 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); uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_maxlen, uint8_t *par);
void iso14443a_setup(uint8_t fpga_minor_mode); 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 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_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_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr,
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades); 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); void iso14a_set_trigger(bool enable);
int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen); int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen);
@ -181,8 +185,9 @@ 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_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 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, bool EmLogTrace(const uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime,
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); 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 ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
void DetectNACKbug(void); void DetectNACKbug(void);

View file

@ -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 * 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(); const tosend_t *ts = get_tosend();
CodeIso14443bAsReader(cmd, len, framing); CodeIso14443bAsReader(cmd, len, framing);
TransmitFor14443b_AsReader(start_time); TransmitFor14443b_AsReader(start_time);
@ -1800,7 +1800,7 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
/** /**
* SRx Initialise. * 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 // INITIATE command: wake up the tag using the INITIATE
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
uint8_t r_init[3] = { 0x00 }; 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 act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY }; static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY };
static uint8_t read_conf[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x01, 0xfa, 0x22 }; 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 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_aia[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x05, 0xde, 0x64};
uint8_t read_check_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; 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... // 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}; uint8_t cmd[] = {ISO14443B_READ_BLK, blocknr, 0x00, 0x00};
AddCrc14B(cmd, 2); AddCrc14B(cmd, 2);

View file

@ -45,8 +45,11 @@ int iso14443b_select_card(iso14b_card_select_t *card);
void SimulateIso14443bTag(const uint8_t *pupi); void SimulateIso14443bTag(const uint8_t *pupi);
void read_14b_st_block(uint8_t blocknr); 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 SniffIso14443b(void);
void SendRawCommand14443B(iso14b_raw_cmd_t *p); 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 // States for 14B SIM command
#define SIM_POWER_OFF 0 #define SIM_POWER_OFF 0

View file

@ -985,10 +985,11 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
DecodeTagFSK_t dtfm = { 0 }; DecodeTagFSK_t dtfm = { 0 };
DecodeTagFSK_t *dtf = &dtfm; DecodeTagFSK_t *dtf = &dtfm;
if (fsk) if (fsk) {
DecodeTagFSKInit(dtf, response, max_len); DecodeTagFSKInit(dtf, response, max_len);
else } else {
DecodeTagInit(dt, response, max_len); DecodeTagInit(dt, response, max_len);
}
// wait for last transfer to complete // wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
@ -1014,8 +1015,9 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
for (;;) { for (;;) {
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
if (behindBy == 0) if (behindBy == 0) {
continue; continue;
}
samples++; samples++;
if (samples == 1) { if (samples == 1) {
@ -2657,7 +2659,7 @@ void BruteforceIso15693Afi(uint32_t flags) {
Dbprintf("AFI = %i UID = %s", i, iso15693_sprintUID(NULL, recv + 2)); Dbprintf("AFI = %i UID = %s", i, iso15693_sprintUID(NULL, recv + 2));
} }
aborted = (BUTTON_PRESS() && data_available()); aborted = (BUTTON_PRESS() || data_available());
if (aborted) { if (aborted) {
break; break;
} }

View file

@ -236,8 +236,13 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) {
FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER); FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
// When in reader mode, give the field a bit of time to settle. // 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. // Optimal timing window for LF ADC measurements to be performed:
SpinDelay(10); // 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 // 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; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;

View file

@ -83,14 +83,14 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
break; break;
} }
case MF_WAKE_WUPA: { case MF_WAKE_WUPA: {
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &WUPA_POLLING_PARAMETERS) == 0) { if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &WUPA_POLLING_PARAMETERS, false) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
return false; return false;
}; };
break; break;
} }
case MF_WAKE_REQA: { case MF_WAKE_REQA: {
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &REQA_POLLING_PARAMETERS) == 0) { if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &REQA_POLLING_PARAMETERS, false) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
return false; return false;
}; };
@ -274,7 +274,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) {
return; return;
}; };
if (!mifare_ultra_auth(keybytes)) { if (mifare_ultra_auth(keybytes) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed"); if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
OnError(1); OnError(1);
return; return;
@ -304,7 +304,7 @@ void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes) {
return; return;
}; };
if (!mifare_ultra_aes_auth(keyno, keybytes)) { if (mifare_ultra_aes_auth(keyno, keybytes) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed"); if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT); OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
return; return;
@ -344,7 +344,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
uint8_t key[16] = {0x00}; uint8_t key[16] = {0x00};
memcpy(key, datain, sizeof(key)); memcpy(key, datain, sizeof(key));
if (!mifare_ultra_auth(key)) { if (mifare_ultra_auth(key) == 0) {
OnError(1); OnError(1);
return; return;
} }
@ -1947,7 +1947,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
// Now append the SPI flash dictionnary // Now append the SPI flash dictionnary
if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(MF_KEYS_FILE, dictkeys + (keyCount * MF_KEY_LENGTH), (key_mem_available - keyCount) * MF_KEY_LENGTH, RDV40_SPIFFS_SAFETY_SAFE)) { if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(MF_KEYS_FILE, dictkeys + (keyCount * MF_KEY_LENGTH), (key_mem_available - keyCount) * MF_KEY_LENGTH, RDV40_SPIFFS_SAFETY_SAFE)) {
if (g_dbglevel >= DBG_ERROR) { if (g_dbglevel >= DBG_ERROR) {
Dbprintf("loaded " _GREEN_("%u") " keys from spiffs file `" _YELLOW_("%s") "`", key_mem_available, MF_KEYS_FILE); Dbprintf("loaded " _GREEN_("%u") " keys from spiffs file `" _YELLOW_("%s") "`", key_mem_available - keyCount, MF_KEYS_FILE);
} }
} else { } else {
Dbprintf("Spiffs file `" _RED_("%s") "` cannot be read", MF_KEYS_FILE); Dbprintf("Spiffs file `" _RED_("%s") "` cannot be read", MF_KEYS_FILE);
@ -1955,6 +1955,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
} }
// Replace client provided keys // Replace client provided keys
datain = dictkeys; datain = dictkeys;
keyCount = key_mem_available;
} }
#endif #endif
@ -2908,7 +2909,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
} }
// read block // read block
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != MAX_MIFARE_FRAME_SIZE)) { if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != MIFARE_BLOCK_SIZE + CRC16_SIZE)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("read block send command error"); if (g_dbglevel >= DBG_ERROR) Dbprintf("read block send command error");
errormsg = 0; errormsg = 0;
break; break;
@ -3021,9 +3022,10 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// reset card // reset card
mf_reset_card(); mf_reset_card();
// Use special magic detection function that always attempts RATS regardless of SAK
res = iso14443a_select_card(uid, card, &cuid, true, 0, false); res = iso14443a_select_card_for_magic(uid, card, &cuid, true, 0);
if (res) { if (res) {
mf_reset_card();
if (cuid == 0xAA55C396) { if (cuid == 0xAA55C396) {
flag |= MAGIC_FLAG_GEN_UNFUSED; flag |= MAGIC_FLAG_GEN_UNFUSED;
} }
@ -3219,7 +3221,7 @@ void MifareHasStaticNonce(void) {
} }
if (counter) { if (counter) {
Dbprintf("Static nonce......... " _YELLOW_("%08x"), nt); Dbprintf("Static nonce....... " _YELLOW_("%08x"), nt);
data[0] = NONCE_STATIC; data[0] = NONCE_STATIC;
} else { } else {
data[0] = NONCE_NORMAL; data[0] = NONCE_NORMAL;
@ -3514,7 +3516,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
int retval = PM3_SUCCESS; int retval = PM3_SUCCESS;
uint8_t block_cmd[5] = { 0x90, 0xf0, 0xcc, 0xcc, 0x10 }; uint8_t block_cmd[5] = { 0x90, 0xf0, 0xcc, 0xcc, 0x10 };
uint8_t cmdlen = sizeof(block_cmd) + MAX_MIFARE_FRAME_SIZE; uint8_t cmdlen = sizeof(block_cmd) + MIFARE_BLOCK_SIZE + CRC16_SIZE;
uint8_t *cmd = BigBuf_calloc(cmdlen); uint8_t *cmd = BigBuf_calloc(cmdlen);
iso14a_card_select_t *card_info = (iso14a_card_select_t *) BigBuf_calloc(sizeof(iso14a_card_select_t)); iso14a_card_select_t *card_info = (iso14a_card_select_t *) BigBuf_calloc(sizeof(iso14a_card_select_t));
@ -3531,7 +3533,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
bool doReselect = false; bool doReselect = false;
if (block_len < MIFARE_BLOCK_SIZE) { if (block_len < MIFARE_BLOCK_SIZE) {
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, 0, &cmd[sizeof(block_cmd)], MAX_MIFARE_FRAME_SIZE, NULL, NULL) != MAX_MIFARE_FRAME_SIZE)) { if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, 0, &cmd[sizeof(block_cmd)], MIFARE_BLOCK_SIZE + CRC16_SIZE, NULL, NULL) != MIFARE_BLOCK_SIZE + CRC16_SIZE)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Read manufacturer block failed"); if (g_dbglevel >= DBG_ERROR) Dbprintf("Read manufacturer block failed");
retval = PM3_ESOFT; retval = PM3_ESOFT;
goto OUT; goto OUT;
@ -3560,13 +3562,13 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
AddCrc14A(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE); AddCrc14A(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE);
if (doReselect) { if (doReselect) {
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
retval = PM3_ESOFT; retval = PM3_ESOFT;
goto OUT; goto OUT;
} }
} }
retval = DoGen3Cmd(cmd, sizeof(block_cmd) + MAX_MIFARE_FRAME_SIZE); retval = DoGen3Cmd(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE + CRC16_SIZE);
} }
OUT: OUT:

View file

@ -60,7 +60,7 @@ bool InitDesfireCard(void) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(true); 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"); if (g_dbglevel >= DBG_ERROR) DbpString("Can't select card");
OnError(1); OnError(1);
return false; return false;
@ -157,7 +157,7 @@ void MifareDesfireGetInformation(void) {
pcb_blocknum = 0; pcb_blocknum = 0;
// card select - information // 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) { if (g_dbglevel >= DBG_ERROR) {
DbpString("Can't select card"); DbpString("Can't select card");
} }

View file

@ -579,21 +579,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
counter++; 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(); FpgaEnableTracing();
//Now, get data //Now, get data
int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par); int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par);
@ -760,10 +745,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// WORK // WORK
case MFEMUL_WORK: { case MFEMUL_WORK: {
if (g_dbglevel >= DBG_EXTENDED) {
// Dbprintf("[MFEMUL_WORK] Enter in case");
}
if (receivedCmd_len == 0) { if (receivedCmd_len == 0) {
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received"); if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
break; break;
@ -1039,8 +1020,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
} }
} }
AddCrc14A(response, MIFARE_BLOCK_SIZE); AddCrc14A(response, MIFARE_BLOCK_SIZE);
mf_crypto1_encrypt(pcs, response, MAX_MIFARE_FRAME_SIZE, response_par); mf_crypto1_encrypt(pcs, response, MIFARE_BLOCK_SIZE + CRC16_SIZE, response_par);
EmSendCmdPar(response, MAX_MIFARE_FRAME_SIZE, response_par); EmSendCmdPar(response, MIFARE_BLOCK_SIZE + CRC16_SIZE, response_par);
FpgaDisableTracing(); FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED) { if (g_dbglevel >= DBG_EXTENDED) {
@ -1052,7 +1033,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
numReads++; numReads++;
if (exitAfterNReads > 0 && numReads == exitAfterNReads) { if (exitAfterNReads > 0 && numReads == exitAfterNReads) {
Dbprintf("[MFEMUL_WORK] %d reads done, exiting", numReads); Dbprintf("[MFEMUL_WORK] " _YELLOW_("%u") " reads done, exiting", numReads);
finished = true; finished = true;
} }
break; break;
@ -1309,7 +1290,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// WRITE BL2 // WRITE BL2
case MFEMUL_WRITEBL2: { 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); mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, receivedCmd_dec);

View file

@ -100,7 +100,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
uint16_t pos; uint16_t pos;
uint8_t dcmd[4] = {cmd, data, 0x00, 0x00}; uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
uint8_t ecmd[4] = {0x00, 0x00, 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); AddCrc14A(dcmd, 2);
memcpy(ecmd, dcmd, sizeof(dcmd)); memcpy(ecmd, dcmd, sizeof(dcmd));
@ -440,21 +440,17 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
uint8_t key[16] = { 0 }; uint8_t key[16] = { 0 };
memcpy(key, keybytes, sizeof(key)); memcpy(key, keybytes, sizeof(key));
uint16_t len = 0;
// 1 cmd + 16 bytes + 2 crc // 1 cmd + 16 bytes + 2 crc
uint8_t resp[19] = {0x00}; uint8_t resp[19] = {0x00};
uint8_t respPar[5] = {0}; uint8_t respPar[5] = {0};
// setup AES // setup AES
mbedtls_aes_context actx; mbedtls_aes_context actx;
mbedtls_aes_init(&actx); mbedtls_aes_init(&actx);
mbedtls_aes_init(&actx);
mbedtls_aes_setkey_dec(&actx, key, 128); mbedtls_aes_setkey_dec(&actx, key, 128);
// Send REQUEST AUTHENTICATION / receive tag nonce // 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 (len != 19) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len); if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
return 0; return 0;

View file

@ -218,17 +218,19 @@ out:
* *
* @return Status code indicating success or failure of the operation. * @return Status code indicating success or failure of the operation.
*/ */
int sam_get_version(void) { int sam_get_version(bool info) {
int res = PM3_SUCCESS; int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_get_version"); DbpString("start sam_get_version");
}
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME; uint16_t response_len = ISO7816_MAX_FRAME;
uint8_t payload[] = { uint8_t payload[] = {
0xa0, 0x02, // <- SAM command 0xa0, // <- SAM command
0x02, // <- Length
0x82, 0x00 // <- get version 0x82, 0x00 // <- get version
}; };
uint16_t payload_len = sizeof(payload); uint16_t payload_len = sizeof(payload);
@ -252,8 +254,9 @@ int sam_get_version(void) {
// 82 01 // 82 01
// 01 // 01
// 90 00 // 90 00
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_get_version"); DbpString("end sam_get_version");
}
if (response[5] != 0xbd) { if (response[5] != 0xbd) {
Dbprintf("Invalid SAM response"); Dbprintf("Invalid SAM response");
@ -266,18 +269,18 @@ int sam_get_version(void) {
} }
uint8_t *sam_version_an = sam_find_asn1_node(sam_response_an, 0x80); uint8_t *sam_version_an = sam_find_asn1_node(sam_response_an, 0x80);
if (sam_version_an == NULL) { if (sam_version_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString("SAM get version failed"); if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get version failed"));
goto error; goto error;
} }
uint8_t *sam_build_an = sam_find_asn1_node(sam_response_an, 0x81); uint8_t *sam_build_an = sam_find_asn1_node(sam_response_an, 0x81);
if (sam_build_an == NULL) { if (sam_build_an == NULL) {
if (g_dbglevel >= DBG_ERROR) DbpString("SAM get firmware ID failed"); if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get firmware ID failed"));
goto error; goto error;
} }
if (g_dbglevel >= DBG_INFO) { if (g_dbglevel >= DBG_INFO || info) {
DbpString("SAM get version successful"); DbpString(_BLUE_("-- SAM Information --"));
Dbprintf("Firmware version: %X.%X", sam_version_an[2], sam_version_an[3]); Dbprintf(_YELLOW_("Firmware version: ")"%d.%d", sam_version_an[2], sam_version_an[3]);
Dbprintf("Firmware ID: "); Dbprintf(_YELLOW_("Firmware ID: "));
Dbhexdump(sam_build_an[1], sam_build_an + 2, false); Dbhexdump(sam_build_an[1], sam_build_an + 2, false);
} }
goto out; goto out;
@ -289,8 +292,79 @@ error:
out: out:
BigBuf_free(); BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_get_version"); 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; return res;
} }
@ -350,12 +424,10 @@ void sam_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type
} }
void sam_send_ack(void) { void sam_send_ack(void) {
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME; uint16_t response_len = ISO7816_MAX_FRAME;
uint8_t payload[] = { uint8_t payload[] = { 0xa0, 0 };
0xa0, 0
};
uint16_t payload_len = sizeof(payload); uint16_t payload_len = sizeof(payload);
sam_send_payload( sam_send_payload(

View file

@ -39,7 +39,8 @@ int sam_send_payload(
uint16_t *response_len uint16_t *response_len
); );
int sam_get_version(void); 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); 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_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type, const uint8_t *const data, uint8_t len);

View file

@ -46,11 +46,12 @@
*/ */
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) { 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; int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_send_request_iso14a"); DbpString("start sam_send_request_iso14a");
}
uint8_t *buf1 = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *buf1 = BigBuf_calloc(ISO7816_MAX_FRAME);
uint8_t *buf2 = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *buf2 = BigBuf_calloc(ISO7816_MAX_FRAME);
if (buf1 == NULL || buf2 == NULL) { if (buf1 == NULL || buf2 == NULL) {
res = PM3_EMALLOC; res = PM3_EMALLOC;
goto out; goto out;
@ -102,10 +103,13 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
nfc_tx_len = sam_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf); 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; bool is_cmd_check = ((nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_CHECK);
if (is_cmd_check && break_on_nr_mac) { if (is_cmd_check && break_on_nr_mac) {
memcpy(response, nfc_tx_buf, nfc_tx_len); memcpy(response, nfc_tx_buf, nfc_tx_len);
*response_len = nfc_tx_len; *response_len = nfc_tx_len;
if (g_dbglevel >= DBG_INFO) { if (g_dbglevel >= DBG_INFO) {
DbpString("NR-MAC: "); DbpString("NR-MAC: ");
Dbhexdump((*response_len) - 1, response + 1, false); Dbhexdump((*response_len) - 1, response + 1, false);
@ -114,7 +118,8 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
goto out; goto out;
} }
bool is_cmd_update = (nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_UPDATE; 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) { 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 // block update(2) command and fake the response to prevent update of epurse
@ -222,18 +227,27 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
// 07 // 07
// 90 00 // 90 00
if (request_len == 0) { if (request_len == 0) {
if (
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0x8a && sam_rx_buf[5 + 4] == 0x03) 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)) {
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)
) { if (g_dbglevel >= DBG_ERROR) {
if (g_dbglevel >= DBG_ERROR)
Dbprintf("No PACS data in SAM response"); Dbprintf("No PACS data in SAM response");
}
res = PM3_ESOFT; res = PM3_ESOFT;
} }
} }
*response_len = sam_rx_buf[5 + 1] + 2; 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;
}
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); memcpy(response, sam_rx_buf + 5, *response_len);
goto out; goto out;
@ -255,10 +269,10 @@ out:
*/ */
static int sam_set_card_detected_picopass(const picopass_hdr_t *card_select) { static int sam_set_card_detected_picopass(const picopass_hdr_t *card_select) {
int res = PM3_SUCCESS; int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_set_card_detected"); DbpString("start sam_set_card_detected");
}
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME; uint16_t response_len = ISO7816_MAX_FRAME;
// a0 12 // a0 12
@ -314,8 +328,9 @@ error:
out: out:
BigBuf_free(); BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_set_card_detected"); DbpString("end sam_set_card_detected");
}
return res; return res;
} }
@ -336,11 +351,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
const bool breakOnNrMac = !!(flags & BITMASK(2)); const bool breakOnNrMac = !!(flags & BITMASK(2));
const bool preventEpurseUpdate = !!(flags & BITMASK(3)); const bool preventEpurseUpdate = !!(flags & BITMASK(3));
const bool shallow_mod = !!(flags & BITMASK(4)); const bool shallow_mod = !!(flags & BITMASK(4));
const bool info = !!(flags & BITMASK(5));
uint8_t *cmd = c->data.asBytes + 1; uint8_t *cmd = c->data.asBytes + 1;
uint16_t cmd_len = c->length - 1; uint16_t cmd_len = c->length - 1;
int res = PM3_EFAILED; int res = PM3_EFAILED;
uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 };
uint8_t sam_response_len = 0;
clear_trace(); clear_trace();
I2C_Reset_EnterMainProgram(); I2C_Reset_EnterMainProgram();
@ -349,16 +367,21 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
StartTicks(); StartTicks();
// step 1: ping SAM // step 1: ping SAM
sam_get_version(); sam_get_version(info);
if (!skipDetect) { if (info) {
sam_get_serial_number();
goto out;
}
if (skipDetect == false) {
// step 2: get card information // step 2: get card information
picopass_hdr_t card_a_info; picopass_hdr_t card_a_info;
uint32_t eof_time = 0; uint32_t eof_time = 0;
// implicit StartSspClk() happens here // implicit StartSspClk() happens here
Iso15693InitReader(); Iso15693InitReader();
if (!select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod)) { if (select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod) == false) {
goto err; goto err;
} }
@ -369,14 +392,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
} }
// step 3: SamCommand RequestPACS, relay NFC communication // 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_iso15(cmd, cmd_len, sam_response, &sam_response_len, shallow_mod, breakOnNrMac, preventEpurseUpdate); res = sam_send_request_iso15(cmd, cmd_len, sam_response, &sam_response_len, shallow_mod, breakOnNrMac, preventEpurseUpdate);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
goto err; goto err;
} }
if (g_dbglevel >= DBG_INFO)
if (g_dbglevel >= DBG_INFO) {
print_result("Response data", sam_response, sam_response_len); print_result("Response data", sam_response, sam_response_len);
}
goto out; goto out;

View file

@ -51,13 +51,14 @@
*/ */
static int sam_set_card_detected_seos(iso14a_card_select_t *card_select) { static int sam_set_card_detected_seos(iso14a_card_select_t *card_select) {
int res = PM3_SUCCESS; int res = PM3_SUCCESS;
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("start sam_set_card_detected"); DbpString("start sam_set_card_detected");
}
uint8_t *request = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *request = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t request_len = ISO7816_MAX_FRAME; uint16_t request_len = ISO7816_MAX_FRAME;
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME); uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
uint16_t response_len = ISO7816_MAX_FRAME; uint16_t response_len = ISO7816_MAX_FRAME;
const uint8_t payload[] = { const uint8_t payload[] = {
@ -107,8 +108,9 @@ error:
out: out:
BigBuf_free(); BigBuf_free();
if (g_dbglevel >= DBG_DEBUG) if (g_dbglevel >= DBG_DEBUG) {
DbpString("end sam_set_card_detected"); DbpString("end sam_set_card_detected");
}
return res; return res;
} }
@ -280,7 +282,7 @@ int sam_seos_get_pacs(PacketCommandNG *c) {
StartTicks(); StartTicks();
// step 1: ping SAM // step 1: ping SAM
sam_get_version(); sam_get_version(false);
if (skipDetect == false) { if (skipDetect == false) {
// step 2: get card information // step 2: get card information

View file

@ -312,7 +312,7 @@ static int is_valid_filename(const char *filename) {
*/ */
static void copy_in_spiffs(const char *src, const char *dst) { static void copy_in_spiffs(const char *src, const char *dst) {
uint32_t size = size_in_spiffs(src); 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); read_from_spiffs(src, (uint8_t *)mem, size);
write_to_spiffs(dst, (uint8_t *)mem, size); write_to_spiffs(dst, (uint8_t *)mem, size);
} }

View file

@ -218,7 +218,7 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) {
} }
// transfer from device to client // transfer from device to client
int usart_writebuffer_sync(uint8_t *data, size_t len) { int usart_writebuffer_sync(const uint8_t *data, size_t len) {
// Wait for current PDC bank to be free // Wait for current PDC bank to be free
// (and check next bank too, in case there will be a usart_writebuffer_async) // (and check next bank too, in case there will be a usart_writebuffer_async)

View file

@ -25,7 +25,7 @@ extern uint32_t g_usart_baudrate;
extern uint8_t g_usart_parity; extern uint8_t g_usart_parity;
void usart_init(uint32_t baudrate, uint8_t parity); void usart_init(uint32_t baudrate, uint8_t parity);
int usart_writebuffer_sync(uint8_t *data, size_t len); int usart_writebuffer_sync(const uint8_t *data, size_t len);
uint32_t usart_read_ng(uint8_t *data, size_t len); uint32_t usart_read_ng(uint8_t *data, size_t len);
uint16_t usart_rxdata_available(void); uint16_t usart_rxdata_available(void);

View file

@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19
# version_pm3.c should be checked on every compilation # version_pm3.c should be checked on every compilation
version_pm3.c: default_version_pm3.c .FORCE version_pm3.c: default_version_pm3.c .FORCE
$(info [=] CHECK $@) $(info [=] CHECK $@)
$(Q)$(CP) $< $@ $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
all: showinfo $(OBJS) all: showinfo $(OBJS)

View file

@ -434,7 +434,7 @@ set (TARGET_SOURCES
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c
COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c COMMAND sh ${PM3_ROOT}/tools/mkversion.sh ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c
DEPENDS ${PM3_ROOT}/common/default_version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c
) )
@ -692,7 +692,7 @@ add_executable(proxmark3
${ADDITIONAL_SRC} ${ADDITIONAL_SRC}
) )
target_compile_options(proxmark3 PUBLIC -Wall -O3) target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
if (EMBED_READLINE) if (EMBED_READLINE)
if (NOT SKIPREADLINE EQUAL 1) if (NOT SKIPREADLINE EQUAL 1)
add_dependencies(proxmark3 ncurses readline) add_dependencies(proxmark3 ncurses readline)

View file

@ -446,7 +446,7 @@ endif
PM3CFLAGS += -DHAVE_SNPRINTF PM3CFLAGS += -DHAVE_SNPRINTF
CXXFLAGS ?= -Wall CXXFLAGS ?= -Wall -Werror
CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES)
PM3CXXFLAGS = $(CXXFLAGS) PM3CXXFLAGS = $(CXXFLAGS)
@ -889,11 +889,19 @@ endif
ifneq (,$(INSTALLSHARE)) ifneq (,$(INSTALLSHARE))
$(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) $(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
# hack ahead: inject installation path into pm3_resources.py # hack ahead: inject installation path into pm3_resources.py
$(Q)sed -i 's|^TOOLS_PATH \?= \?None|TOOLS_PATH="$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)"|' pyscripts/pm3_resources.py ifeq ($(platform),Darwin)
$(Q)sed -i 's|^DICTS_PATH \?= \?None|DICTS_PATH="$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/dictionaries"|' pyscripts/pm3_resources.py $(Q)sed -E -i '' 's|^TOOLS_PATH \?= \?None|TOOLS_PATH="$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)"|' pyscripts/pm3_resources.py
$(Q)sed -E -i '' 's|^DICTS_PATH \?= \?None|DICTS_PATH="$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/dictionaries"|' pyscripts/pm3_resources.py
$(Q)$(INSTALLSUDO) $(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
$(Q)sed -E -i '' 's|^TOOLS_PATH \?=.*|TOOLS_PATH = None|' pyscripts/pm3_resources.py
$(Q)sed -E -i '' 's|^DICTS_PATH \?=.*|DICTS_PATH = None|' pyscripts/pm3_resources.py
else
$(Q)sed -i 's|^TOOLS_PATH \?= \?None|TOOLS_PATH="$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)"|' pyscripts/pm3_resources.py
$(Q)sed -i 's|^DICTS_PATH \?= \?None|DICTS_PATH="$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/dictionaries"|' pyscripts/pm3_resources.py
$(Q)$(INSTALLSUDO) $(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) $(Q)$(INSTALLSUDO) $(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
$(Q)sed -i 's|^TOOLS_PATH \?=.*|TOOLS_PATH = None|' pyscripts/pm3_resources.py $(Q)sed -i 's|^TOOLS_PATH \?=.*|TOOLS_PATH = None|' pyscripts/pm3_resources.py
$(Q)sed -i 's|^DICTS_PATH \?=.*|DICTS_PATH = None|' pyscripts/pm3_resources.py $(Q)sed -i 's|^DICTS_PATH \?=.*|DICTS_PATH = None|' pyscripts/pm3_resources.py
endif
endif endif
@true @true
@ -987,7 +995,7 @@ src/pm3_pywrap.c: pm3.i
# version_pm3.c should be checked on every compilation # version_pm3.c should be checked on every compilation
src/version_pm3.c: default_version_pm3.c .FORCE src/version_pm3.c: default_version_pm3.c .FORCE
$(info [=] CHECK $@) $(info [=] CHECK $@)
$(Q)$(CP) $< $@ $(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
# easy printing of MAKE VARIABLES # easy printing of MAKE VARIABLES
print-%: ; @echo $* = $($*) print-%: ; @echo $* = $($*)

View file

@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE
m m
pm3rrg_rdv4_mbedtls) pm3rrg_rdv4_mbedtls)
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool

View file

@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE
../../include ../../include
../src) ../src)
target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser)
target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -3621,12 +3621,12 @@ TRex *trex_compile(const TRexChar *pattern, const TRexChar **error, int flags) {
exp->_first = trex_newnode(exp, OP_EXPR); exp->_first = trex_newnode(exp, OP_EXPR);
exp->_error = error; exp->_error = error;
exp->_jmpbuf = malloc(sizeof(jmp_buf)); exp->_jmpbuf = malloc(sizeof(jmp_buf));
if (exp->_jmpbuf == NULL) { if (exp->_jmpbuf == NULL) {
trex_free(exp); trex_free(exp);
return NULL; return NULL;
} }
exp->_flags = flags; exp->_flags = flags;
if (setjmp(*((jmp_buf *)exp->_jmpbuf)) == 0) { if (setjmp(*((jmp_buf *)exp->_jmpbuf)) == 0) {
int res = trex_list(exp); int res = trex_list(exp);

View file

@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE
@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3)
target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE
-mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f)
set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3)
target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE
-mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f)
set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3)
target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE
-mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f)
set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3)
target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE
-mmmx -msse2 -mavx -mavx2 -mno-avx512f) -mmmx -msse2 -mavx -mavx2 -mno-avx512f)
set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3)
target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE
-mmmx -msse2 -mavx -mavx2 -mavx512f) -mmmx -msse2 -mavx -mavx2 -mavx512f)
set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE
@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS)
hardnested/hardnested_bf_core.c hardnested/hardnested_bf_core.c
hardnested/hardnested_bitarray_core.c) hardnested/hardnested_bitarray_core.c)
target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3)
target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE
-mfpu=neon) -mfpu=neon)
set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON)
@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC
hardnested/hardnested_bruteforce.c hardnested/hardnested_bruteforce.c
$<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd> $<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd>
${SIMD_TARGETS}) ${SIMD_TARGETS})
target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(pm3rrg_rdv4_hardnested PRIVATE target_include_directories(pm3rrg_rdv4_hardnested PRIVATE
../../common ../../common

View file

@ -177,14 +177,15 @@ crack_states_thread(void *x) {
char progress_text[80]; char progress_text[80];
char keystr[19]; char keystr[19];
snprintf(keystr, sizeof(keystr), "%012" PRIX64 " ", key); snprintf(keystr, sizeof(keystr), "%012" PRIX64, key);
snprintf(progress_text, sizeof(progress_text), "Brute force phase completed. Key found: " _GREEN_("%s"), keystr); snprintf(progress_text, sizeof(progress_text), "Brute force phase completed. Key found: " _GREEN_("%s"), keystr);
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0); hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
PrintAndLogEx(INFO, "---------+---------+---------------------------------------------------------+-----------------+-------");
break; break;
} else if (keys_found) { } else if (keys_found) {
break; break;
} else { } else {
if (!thread_arg->silent) { if (thread_arg->silent == false) {
char progress_text[80]; char progress_text[80];
snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%% ", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states)); snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%% ", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states));
float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested / 2; float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested / 2;
@ -337,7 +338,7 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
bucket_count = 0; bucket_count = 0;
for (statelist_t *p = candidates; p != NULL; p = p->next) { for (statelist_t *p = candidates; p != NULL; p = p->next) {
if (p->states[ODD_STATE] != NULL && p->states[EVEN_STATE] != NULL) { if (p->states[ODD_STATE] != NULL && p->states[EVEN_STATE] != NULL) {
if (!ensure_buckets_alloc(bucket_count + 1)) { if (ensure_buckets_alloc(bucket_count + 1) == false) {
PrintAndLogEx(ERR, "Can't allocate buckets, abort!"); PrintAndLogEx(ERR, "Can't allocate buckets, abort!");
return false; return false;
} }
@ -375,6 +376,7 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
thread_args[i].best_first_bytes = best_first_bytes; thread_args[i].best_first_bytes = best_first_bytes;
pthread_create(&threads[i], NULL, crack_states_thread, (void *)&thread_args[i]); pthread_create(&threads[i], NULL, crack_states_thread, (void *)&thread_args[i]);
} }
for (uint32_t i = 0; i < num_brute_force_threads; i++) { for (uint32_t i = 0; i < num_brute_force_threads; i++) {
pthread_join(threads[i], 0); pthread_join(threads[i], 0);
} }
@ -385,11 +387,13 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
uint64_t elapsed_time = msclock() - start_time; uint64_t elapsed_time = msclock() - start_time;
if (bf_rate != NULL) if (bf_rate != NULL) {
*bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0); *bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0);
}
if (keys_found > 0) if (keys_found > 0) {
*found_key = found_bs_key; *found_key = found_bs_key;
}
return (keys_found != 0); return (keys_found != 0);
} }

View file

@ -3,7 +3,7 @@ add_library(pm3rrg_rdv4_id48 STATIC
id48/id48_generator.c id48/id48_generator.c
id48/id48_recover.c id48/id48_recover.c
) )
target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO) target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -Werror -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO)
target_include_directories(pm3rrg_rdv4_id48 PRIVATE id48) target_include_directories(pm3rrg_rdv4_id48 PRIVATE id48)
target_include_directories(pm3rrg_rdv4_id48 INTERFACE id48) target_include_directories(pm3rrg_rdv4_id48 INTERFACE id48)
set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC
target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H)
target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson)
target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3)
set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -52,5 +52,5 @@ if (NOT MINGW)
endif (NOT MINGW) endif (NOT MINGW)
target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua)
target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -49,5 +49,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common)
target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls)
target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE
../src ../src
../../include) ../../include)
target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng)
target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC
target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor)
# Strange errors on Mingw when compiling with -O3 # Strange errors on Mingw when compiling with -O3
target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2)
set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -179,7 +179,9 @@
#ifndef unlikely #ifndef unlikely
# define unlikely(x) __builtin_expect(!!(x), 0) # define unlikely(x) __builtin_expect(!!(x), 0)
#endif #endif
#ifndef unreachable
# define unreachable() __builtin_unreachable() # define unreachable() __builtin_unreachable()
#endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# define likely(x) (x) # define likely(x) (x)
# define unlikely(x) (x) # define unlikely(x) (x)

View file

@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c)
target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED)
target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami)
target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON)

View file

@ -1905,15 +1905,14 @@ FF16014FEFC7
# Food GEM # Food GEM
6686FADE5566 6686FADE5566
# #
# Samsung Data Systems (SDS) — Electronic Locks # Samsung Data Systems (SDS)
# Gen 1 S10 KA/KB is FFFFFFFFFFFF, incompatible with Gen 2 locks # 10-11 A/B (Gen 2)
# 9B7C25052FC3
# SDS Gen 2 S10 KB
C22E04247D9A C22E04247D9A
6C4F77534170
704153564F6C
# #
# Data from Discord, French pool # Data from Discord, French pool
# SDS Gen 2 S10 KA
9B7C25052FC3
494446555455 494446555455
# #
# Data from Discord, seems to be related to ASSA # Data from Discord, seems to be related to ASSA
@ -3108,3 +3107,80 @@ AB921CF0752C
265A5F32DE73 265A5F32DE73
567D734C403C 567D734C403C
2426217B3B3B 2426217B3B3B
#
# Card keys from Andalusian public transport system (Consorcio de Transportes)
1848A8D1E4C5
16EE1FE134E4
5246B8F4ACFC
515A8209843C
0EF7636AA829
E59D0F78C413
5AF68604DD6B
B0BCB22DCBA3
51B3EF60BF56
99100225D83B
63C88F562B97
B30B6A5AD434
D33E4A4A0041
9C0A4CC89D61
5204D83D8CD3
A662F9DC0D3D
#
# Card keys from EMT Malaga (Spain) bus system
41534E354936
454D41343253
4541444C4130
46305234324E
505444505232
5239425A3546
454449434631
414F4544384C
344E4F4E4937
45444E413254
3255534D3033
4F554D523935
3141544D3735
494E47463539
32414F4E3341
41534C473637
534E41395430
41364C38364F
525241414D39
41304532334F
4D4545494F35
4E324C453045
394143494E32
5352554E3245
324553553036
444D414E3539
324745413232
4E4E41455236
394C52493639
4D4941413236
414D504F3243
434C414E3639
# Key for Waferlock shadow programming card and shadow user card
333030313536
#
# Poland Warsaw public transport card keys
2481118e5355
b6f0fc87f57f
e4fdac292bed
5888180adbe6
d572c9491137
64ea317b7abd
a39a286285db
898989890823
898989891789
898989893089
b6e56bad206a
8fe6fa230c69
4d1095f1af34
1ad2f99bb9e9
891089898989
896389898989
890163898989
898927638989
898989063889
898989428989
898989048989

View file

@ -4,10 +4,12 @@ ffffffffffffffff
0011223344556677 0011223344556677
1122334455667788 1122334455667788
a0a1a2a3a4a5a6a7 a0a1a2a3a4a5a6a7
d3f7d3f7d3f7d3f7
00000000000000000000000000000000 #NXP Default 3DES/AES 00000000000000000000000000000000 #NXP Default 3DES/AES
000000000000000000000000000000000000000000000000 #NXP Default 3K3DES 000000000000000000000000000000000000000000000000 #NXP Default 3K3DES
00112233445566778899AABBCCDDEEFF0102030405060708 00112233445566778899AABBCCDDEEFF0102030405060708
ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff
d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7
425245414B4D454946594F5543414E21 # default UL-C key 425245414B4D454946594F5543414E21 # default UL-C key
00112233445566778899AABBCCDDEEFF #TI TRF7970A sloa213 00112233445566778899AABBCCDDEEFF #TI TRF7970A sloa213
79702553797025537970255379702553 #TI TRF7970A sloa213 79702553797025537970255379702553 #TI TRF7970A sloa213

View file

@ -434,7 +434,7 @@ set (TARGET_SOURCES
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c
COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c COMMAND sh ${PM3_ROOT}/tools/mkversion.sh ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c
DEPENDS ${PM3_ROOT}/common/default_version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c
) )

View file

@ -216,7 +216,7 @@ local function perform_check(uid, numsectors)
for sector = 0, #keys do for sector = 0, #keys do
-- Check if user aborted -- Check if user aborted
if core.kbd_enter_pressed() then if core.kbd_enter_pressed() then
print('Aborted by user') print('Aborted via keyboard!')
break break
end end

View file

@ -0,0 +1,357 @@
local ansicolors = require('ansicolors')
local cmds = require('commands')
local getopt = require('getopt')
local lib14a = require('read14a')
local utils = require('utils')
-- globals
copyright = ''
author = 'Dmitry Malenok'
version = 'v1.0.0'
desc = [[
The script provides functionality for writing Mifare Ultralight Ultra/UL-5 tags.
]]
example = [[
-- restpre (write) dump to tag
]]..ansicolors.yellow..[[script run hf_mfu_ultra -f hf-mfu-3476FF1514D866-dump.bin -k ffffffff -r]]..ansicolors.reset..[[
-- wipe tag (]]..ansicolors.red..[[Do not use it with UL-5!]]..ansicolors.reset..[[)
]]..ansicolors.yellow..[[script run hf_mfu_ultra -k 1d237f76 -w ]]..ansicolors.reset..[[
]]
usage = [[
script run hf_mfu_ultra -h -f <dump filename> -k <passwd> -w -r
]]
arguments = [[
-h this help
-f filename for the datadump to read (bin)
-k pwd to use with the restore and wipe operations
-r restore a binary dump to tag
-w wipe tag (]]..ansicolors.red..[[Do not use it with UL-5!]]..ansicolors.reset..[[)
]]
local _password = nil
local _defaultPassword = 'FFFFFFFF'
local _dumpstart = 0x38*2 + 1
---
--- Handles errors
local function error(err)
print(ansicolors.red.."ERROR:"..ansicolors.reset, err)
core.clearCommandBuffer()
return nil, err
end
---
-- sets the global password variable
local function setPassword(password)
if password == nil or #password == 0 then
_password = nil;
elseif #password ~= 8 then
return false, 'Password must be 4 hex bytes'
else
_password = password
end
return true, 'Sets'
end
--- Parses response data
local function parseResponse(rawResponse)
local resp = Command.parse(rawResponse)
local len = tonumber(resp.arg1) * 2
return string.sub(tostring(resp.data), 0, len);
end
---
--- Sends raw data to PM3 and returns raw response if any
local function sendRaw(rawdata, options)
local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW
if options.keep_signal then
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
end
if options.connect then
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_CONNECT
end
if options.no_select then
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_SELECT
end
if options.append_crc then
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
end
local arg2 = #rawdata / 2
if options.bits7 then
arg2 = arg2 | tonumber(bit32.lshift(7, 16))
end
local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
arg1 = flags,
arg2 = arg2,
data = rawdata}
return command:sendMIX(options.ignore_response)
end
---
--- Sends raw data to PM3 and returns parsed response
local function sendWithResponse(payload, options)
local opts;
if options then
opts = options
else
opts = {ignore_response = false, keep_signal = true, append_crc = true}
end
local rawResp, err = sendRaw(payload, opts)
if err then return err end
return parseResponse(rawResp)
end
---
-- Authenticates if password is provided
local function authenticate(password)
if password then
local resp, err = sendWithResponse('1B'..password)
if err then return err end
-- looking for 2 bytes (4 symbols) of PACK and 2 bytes (4 symbols) of CRC
if not resp or #resp ~=8 then return false, 'It seems that password is wrong' end
return true
end
return true
end
--
-- selects tag and authenticates if password is provided
local function connect()
core.clearCommandBuffer()
local info, err = lib14a.read(true, true)
if err then
lib14a.disconnect()
return false, err
end
core.clearCommandBuffer()
return authenticate(_password)
end
--
-- reconnects and selects tag again
local function reconnect()
lib14a.disconnect()
utils.Sleep(1)
local info, err = connect()
if not info then return false, "Unable to select tag: "..err end
return true
end
--
-- checks tag version
local function checkTagVersion()
local resp, err = sendWithResponse('60');
if err or resp == nil then return false, err end
if string.find(resp, '0034210101000E03') ~= 1 then return false, 'Wrong tag version: '..string.sub(resp,1,-5) end
return true
end
--
-- sends magic wakeup command
local function magicWakeup()
io.write('Sending magic wakeup command...')
local resp, err = sendRaw('5000', {ignore_response = false, append_crc = true})
if err or resp == nil then return false, "Unable to send first magic wakeup command: "..err end
resp, err = sendRaw('40', {connect = true, no_select = true, ignore_response = false, keep_signal = true, append_crc = false, bits7 = true})
if err or resp == nil then return false, "Unable to send first magic wakeup command: "..err end
resp, err = sendRaw('43', {ignore_response = false, keep_signal = true, append_crc = false})
if err or resp == nil then return false, "Unable to send second magic wakeup command: "..err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
return true
end
--
-- Writes dump to tag
local function writeDump(filename)
print(string.rep('--',20))
local info, err = connect()
if not info then return false, "Unable to select tag: "..err end
info, err = checkTagVersion()
if not info then return info, err end
-- load dump from file
if not filename then return false, 'No dump filename provided' end
io.write('Loading dump from file '..filename..'...')
local dump
dump, err = utils.ReadDumpFile(filename)
if not dump then return false, err end
if #dump ~= _dumpstart - 1 + 0xa4*2 then return false, 'Invalid dump file' end
print(ansicolors.green..'done'..ansicolors.reset..'.')
local resp
for i = 3, 0x23 do
local blockStart = i * 8 + _dumpstart
local block = string.sub(dump, blockStart, blockStart + 7)
local cblock = string.format('%02x',i)
io.write('Writing block 0x'..cblock..'...')
resp, err = sendWithResponse('A2'..cblock..block)
if err ~= nil then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
end
-- set password
io.write('Setting password and pack ')
info, err = reconnect()
if not info then return false, err end
local passwordStart = 0x27*8 + _dumpstart
local password = string.sub(dump, passwordStart, passwordStart + 7)
local packBlock = string.sub(dump, passwordStart+8, passwordStart + 15)
io.write('(password: '..password..') (pack block: '..packBlock..')...')
resp, err = sendWithResponse('A227'..password)
if err ~= nil then return false, err end
resp, err = sendWithResponse('A228'..packBlock)
if err ~= nil then return false, err end
if not setPassword(password) then return false, 'Unable to set password' end
info, err = reconnect()
if not info then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
-- set configs and locks
for i = 0x24, 0x26 do
local blockStart = i * 8 + _dumpstart
local block = string.sub(dump, blockStart, blockStart + 7)
local cblock = string.format('%02x',i)
io.write('Writing block 0x'..cblock..'...')
resp, err = sendWithResponse('A2'..cblock..block)
if err ~= nil then return false, err end
info, err = reconnect()
if not info then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
end
info, err = magicWakeup()
if not info then return false, err end
-- set uid and locks
for i = 0x2, 0x0, -1 do
local blockStart = i * 8 + _dumpstart
local block = string.sub(dump, blockStart, blockStart + 7)
local cblock = string.format('%02x',i)
io.write('Writing block 0x'..cblock..'...')
resp, err = sendWithResponse('A2'..cblock..block, {connect = i == 0x2, ignore_response = false, keep_signal = i ~= 0, append_crc = true})
if err ~= nil then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
end
print(ansicolors.green..'The dump has been written to the tag.'..ansicolors.reset)
return true
end
--
-- Wipes tag
local function wipe()
print(string.rep('--',20))
print('Wiping tag')
local info, err = connect()
if not info then return false, "Unable to select tag: "..err end
info, err = checkTagVersion()
if not info then return info, err end
local resp
-- clear lock bytes on page 0x02
resp, err = sendWithResponse('3000')
if err or resp == nil then return false, err end
local currentLowLockPage = string.sub(resp,17,24)
if(string.sub(currentLowLockPage,5,8) ~= '0000') then
info, err = magicWakeup()
if not info then return false, err end
local newLowLockPage = string.sub(currentLowLockPage,1,4)..'0000'
io.write('Clearing lock bytes on page 0x02...')
resp, err = sendWithResponse('A202'..newLowLockPage, {connect = true, ignore_response = false, keep_signal = true, append_crc = true})
if err ~= nil then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
end
-- clear lock bytes on page 0x24
io.write('Clearing lock bytes on page 0x24...')
info, err = reconnect()
if not info then return false, err end
resp, err = sendWithResponse('A224000000BD')
if err ~= nil then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
-- clear configs
io.write('Clearing cfg0 and cfg1...')
resp, err = sendWithResponse('A225000000FF')
if err ~= nil then return false, err end
resp, err = sendWithResponse('A22600050000')
if err ~= nil then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
-- clear password
io.write('Reseting password (and pack) to default ('.._defaultPassword..') and 0000...')
info, err = reconnect()
if not info then return false, err end
resp, err = sendWithResponse('A227'.._defaultPassword)
if err ~= nil then return false, err end
resp, err = sendWithResponse('A22800000000')
if err ~= nil then return false, err end
if not setPassword(_defaultPassword) then return false, 'Unable to set password' end
info, err = reconnect()
if not info then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
-- clear other blocks
for i = 3, 0x23 do
local cblock = string.format('%02x',i)
io.write('Clearing block 0x'..cblock..'...')
resp, err = sendWithResponse('A2'..cblock..'00000000')
if err ~= nil then return false, err end
print(ansicolors.green..'done'..ansicolors.reset..'.')
end
print(ansicolors.green..'The tag has been wiped.'..ansicolors.reset)
lib14a.disconnect()
return true
end
--
-- Prints help
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example)
end
---
-- The main entry point
local function main(args)
if #args == 0 then return help() end
local dumpFilename = nil
for opt, value in getopt.getopt(args, 'hf:k:rw') do
local res, err
res = true
if opt == "h" then return help() end
if opt == "f" then dumpFilename = value end
if opt == 'k' then res, err = setPassword(value) end
if opt == 'r' then res, err = writeDump(dumpFilename) end
if opt == 'w' then res, err = wipe() end
if not res then return error(err) end
end
end
main(args)

View file

@ -0,0 +1,747 @@
--[[
Simple script to program DIY kyber crystals
works on real kyber crystals and EM4305 2.12x12mm chips
simply run the program and select a profile via a number
issues
if you are getting errors when trying to read or write a chip
run the cmd "lf tune" with no chip on the device, then move the chip over the coils till you see the lowest voltage. try different angles and in the center and or the edge of the antenna ring.
once you find the lowest voltage then try running the script again.
if thats still not working run "lf tune" again and put the chip in the best position like before
the total voltage may be too high to reduce it slowly lower tin foil over the antenna and watch the voltage.
the foil should be a bit bigger than the coil exact size does not matter.
data pulled from here
https://docs.google.com/spreadsheets/d/13P_GE6tNYpGvoVUTEQvA3SQzMqpZ-SoiWaTNoJoTV9Q/edit?usp=sharing
--]]
local cmds = require('commands')
local utils = require('utils')
function send_command(cmd)
core.console(cmd)
return ""
end
function get_profile_data(profile_name)
local profiles = {
["wipe chip"] = {
[0] = "00000000",
[1] = "00000000",
[2] = "00000000",
[3] = "00000000",
[4] = "00000000",
[5] = "00000000",
[6] = "00000000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Qui-Gon Jinn"] = {
[0] = "00040072",
[1] = "6147FBB3",
[2] = "00000000",
[3] = "000064FC",
[4] = "0001805F",
[5] = "000001FF",
[6] = "0C803000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Qui-Gon Jinn 2"] = {
[0] = "00040072",
[1] = "6148C1EF",
[2] = "00000000",
[3] = "000050C2",
[4] = "0001805F",
[5] = "000001FF",
[6] = "0C803000",
[7] = "00000000",
[8] = "10000040",
[9] = "00000000"
},
["Yoda"] = {
[0] = "00040072",
[1] = "660A50D6",
[2] = "00000000",
[3] = "0000379F",
[4] = "0001805F",
[5] = "000001FF",
[6] = "00C03000",
[7] = "00000000",
[8] = "00100040",
[9] = "00000000"
},
["Yoda 2"] = {
[0] = "00040072",
[1] = "667B2FEE",
[2] = "00000000",
[3] = "0000BDB6",
[4] = "0001805F",
[5] = "000001FF",
[6] = "00C03000",
[7] = "00000000",
[8] = "00100040",
[9] = "00000000"
},
["Yoda 8-Ball"] = {
[0] = "00040072",
[1] = "67AD7FC8",
[2] = "00000000",
[3] = "0000E0FE",
[4] = "0001805F",
[5] = "000001FF",
[6] = "5D183000",
[7] = "00000000",
[8] = "00000140",
[9] = "00000000"
},
["Old Obi-Wan"] = {
[0] = "00040072",
[1] = "6147BBB9",
[2] = "00000000",
[3] = "0000BE24",
[4] = "0001805F",
[5] = "000001FF",
[6] = "29803000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Old Luke"] = {
[0] = "00040072",
[1] = "614097AE",
[2] = "00000000",
[3] = "0000C134",
[4] = "0001805F",
[5] = "000001FF",
[6] = "25C03000",
[7] = "00000000",
[8] = "00100060",
[9] = "00000000"
},
["Old Obi-Wan 2"] = {
[0] = "00040072",
[1] = "614009A2",
[2] = "00000000",
[3] = "0000CF62",
[4] = "0001805F",
[5] = "000001FF",
[6] = "29803000",
[7] = "00000000",
[8] = "01000060",
[9] = "00000000"
},
["Old Luke 2"] = {
[0] = "00040072",
[1] = "75952DE5",
[2] = "00000000",
[3] = "00009988",
[4] = "0001805F",
[5] = "000001FF",
[6] = "25C03000",
[7] = "00000000",
[8] = "00010060",
[9] = "00000000"
},
["Old Obi-Wan 3"] = {
[0] = "00040072",
[1] = "65413B42",
[2] = "00000000",
[3] = "00001702",
[4] = "0001805F",
[5] = "000001FF",
[6] = "29803000",
[7] = "00000000",
[8] = "01000060",
[9] = "00000000"
},
["Mace Windu"] = {
[0] = "00040072",
[1] = "6147CCD4",
[2] = "00000000",
[3] = "0000A092",
[4] = "0001805F",
[5] = "000001FF",
[6] = "63C03000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Mace Windu 2"] = {
[0] = "00040072",
[1] = "6609B150",
[2] = "00000000",
[3] = "0000287E",
[4] = "0001805F",
[5] = "000001FF",
[6] = "63C03000",
[7] = "00000000",
[8] = "00010070",
[9] = "00000000"
},
["Mace Windu 3"] = {
[0] = "00040072",
[1] = "613F42AD",
[2] = "00000000",
[3] = "00002147",
[4] = "0001805F",
[5] = "000001FF",
[6] = "6F803000",
[7] = "00000000",
[8] = "01000070",
[9] = "00000000"
},
["Mace Windu 4"] = {
[0] = "00040072",
[1] = "667B5B82",
[2] = "00000000",
[3] = "000050DF",
[4] = "0001805F",
[5] = "000001FF",
[6] = "6F803000",
[7] = "00000000",
[8] = "10000070",
[9] = "00000000"
},
["Mace Windu 5"] = {
[0] = "00040072",
[1] = "614869C4",
[2] = "00000000",
[3] = "0000D691",
[4] = "0001805F",
[5] = "000001FF",
[6] = "6F803000",
[7] = "00000000",
[8] = "01000070",
[9] = "00000000"
},
["Mace Windu 6"] = {
[0] = "00040072",
[1] = "759BEA43",
[2] = "00000000",
[3] = "00006CA0",
[4] = "0001805F",
[5] = "000001FF",
[6] = "63C03000",
[7] = "00000000",
[8] = "00100070",
[9] = "00000000"
},
["Mace Windu 7"] = {
[0] = "00040072",
[1] = "768E0D9D",
[2] = "00000000",
[3] = "0000668C",
[4] = "0001805F",
[5] = "000001FF",
[6] = "6F803000",
[7] = "00000000",
[8] = "01000070",
[9] = "00000000"
},
["Temple Guard"] = {
[0] = "00040072",
[1] = "60954FDA",
[2] = "00000000",
[3] = "0000905A",
[4] = "0001805F",
[5] = "000001FF",
[6] = "7B003000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Maz Kanata"] = {
[0] = "00040072",
[1] = "6679DFF4",
[2] = "00000000",
[3] = "0000D691",
[4] = "0001805F",
[5] = "000001FF",
[6] = "77403000",
[7] = "00000000",
[8] = "00100030",
[9] = "00000000"
},
["Maz Kanata 2"] = {
[0] = "00040072",
[1] = "60953999",
[2] = "00000000",
[3] = "0000F521",
[4] = "0001805F",
[5] = "000001FF",
[6] = "77403000",
[7] = "00000000",
[8] = "00100030",
[9] = "00000000"
},
["Temple Guard 2"] = {
[0] = "00040072",
[1] = "667A67C5",
[2] = "00000000",
[3] = "00002B9C",
[4] = "0001805F",
[5] = "000001FF",
[6] = "7B003000",
[7] = "00000000",
[8] = "10000030",
[9] = "00000000"
},
["Maz Kanata 3"] = {
[0] = "00040072",
[1] = "7A213721",
[2] = "00000000",
[3] = "000083AB",
[4] = "0001805F",
[5] = "000001FF",
[6] = "77403000",
[7] = "00000000",
[8] = "00010030",
[9] = "00000000"
},
["Chirrut Îmwe"] = {
[0] = "00040072",
[1] = "6094F399",
[2] = "00000000",
[3] = "00009519",
[4] = "0001805F",
[5] = "000001FF",
[6] = "14403000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Chirrut Îmwe 2"] = {
[0] = "00040072",
[1] = "667A9AB7",
[2] = "00000000",
[3] = "00003BE4",
[4] = "0001805F",
[5] = "000001FF",
[6] = "14403000",
[7] = "00000000",
[8] = "00010000",
[9] = "00000000"
},
["Ahsoka Tano"] = {
[0] = "00040072",
[1] = "667B1626",
[2] = "00000000",
[3] = "00007907",
[4] = "0001805F",
[5] = "000001FF",
[6] = "18003000",
[7] = "00000000",
[8] = "10000000",
[9] = "00000000"
},
["Chirrut Îmwe 3"] = {
[0] = "00040072",
[1] = "667B7E07",
[2] = "00000000",
[3] = "00002960",
[4] = "0001805F",
[5] = "000001FF",
[6] = "14403000",
[7] = "00000000",
[8] = "00100000",
[9] = "00000000"
},
["Darth Vader"] = {
[0] = "00040072",
[1] = "6148C4F8",
[2] = "00000000",
[3] = "0000FDFF",
[4] = "0001805F",
[5] = "000001FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Darth Sidious"] = {
[0] = "00040072",
[1] = "613F8964",
[2] = "00000000",
[3] = "0000C0C1",
[4] = "0001805F",
[5] = "000001FF",
[6] = "52403000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Darth Maul"] = {
[0] = "00040072",
[1] = "613FD2A9",
[2] = "00000000",
[3] = "0000DAD2",
[4] = "0001805F",
[5] = "000001FF",
[6] = "46C03000",
[7] = "00000000",
[8] = "00000000",
[9] = "00000000"
},
["Count Dooku"] = {
[0] = "00040072",
[1] = "6140880C",
[2] = "00000000",
[3] = "0000952D",
[4] = "0001805F",
[5] = "000001FF",
[6] = "31403000",
[7] = "00000000",
[8] = "00010010",
[9] = "00000000"
},
["Darth Vader 2"] = {
[0] = "00040072",
[1] = "667B33DC",
[2] = "00000000",
[3] = "0000E804",
[4] = "0001805F",
[5] = "000001FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "01000010",
[9] = "00000000"
},
["Darth Maul 2"] = {
[0] = "00040072",
[1] = "667B26E9",
[2] = "00000000",
[3] = "00007689",
[4] = "0001805F",
[5] = "000001FF",
[6] = "46C03000",
[7] = "00000000",
[8] = "00100010",
[9] = "00000000"
},
["Vader 8-Ball"] = {
[0] = "00040072",
[1] = "6A92B478",
[2] = "00000000",
[3] = "00004CD1",
[4] = "0001805F",
[5] = "000001FF",
[6] = "3E183000",
[7] = "00000000",
[8] = "00000110",
[9] = "00000000"
},
["Darth Maul 3"] = {
[0] = "00040072",
[1] = "7597EF7E",
[2] = "00000000",
[3] = "00003BC0",
[4] = "0001805F",
[5] = "000001FF",
[6] = "46C03000",
[7] = "00000000",
[8] = "00100010",
[9] = "00000000"
},
["Darth Sidious 2"] = {
[0] = "00040072",
[1] = "768E4402",
[2] = "00000000",
[3] = "0000A0D2",
[4] = "0001805F",
[5] = "000001FF",
[6] = "52403000",
[7] = "00000000",
[8] = "10000010",
[9] = "00000000"
},
["Snoke"] = {
[0] = "00040072",
[1] = "6540BD8F",
[2] = "00000000",
[3] = "000064B9",
[4] = "0001805F",
[5] = "000001FF",
[6] = "1B183000",
[7] = "00000000",
[8] = "00001010",
[9] = "00000000"
},
["Luke Skywalker"] = {
[0] = "00040072",
[1] = "804B08F0",
[2] = "00000000",
[3] = "00006BF1",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "0C803000",
[7] = "00000000",
[8] = "00000000",
[9] = "050D0000"
},
["Luminara Unduli"] = {
[0] = "00040072",
[1] = "7B83C85A",
[2] = "00000000",
[3] = "000052CE",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "0C803000",
[7] = "00000000",
[8] = "00000000",
[9] = "180D0000"
},
["Plo Koon"] = {
[0] = "00040072",
[1] = "7B8998F3",
[2] = "00000000",
[3] = "00007703",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "29803000",
[7] = "00000000",
[8] = "00000000",
[9] = "040D0000"
},
["Plo Koon 2"] = {
[0] = "00040072",
[1] = "7B8413EA",
[2] = "00000000",
[3] = "0000D8F3",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "29803000",
[7] = "00000000",
[8] = "00000000",
[9] = "040D0000"
},
["Plo Koon 3"] = {
[0] = "00040072",
[1] = "7B84222B",
[2] = "00000000",
[3] = "000023E3",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "29803000",
[7] = "00000000",
[8] = "00000000",
[9] = "040D0000"
},
["Mace Windu S2"] = {
[0] = "00040072",
[1] = "7B8936EA",
[2] = "00000000",
[3] = "0000520D",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "6F803000",
[7] = "00000000",
[8] = "00000000",
[9] = "070D0000"
},
["General Grievous"] = {
[0] = "00040072",
[1] = "7B896284",
[2] = "00000000",
[3] = "00008529",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "6F803000",
[7] = "00000000",
[8] = "00000000",
[9] = "060D0000"
},
["Rey Skywalker"] = {
[0] = "00040072",
[1] = "7B88F3F4",
[2] = "00000000",
[3] = "00001511",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "7B003000",
[7] = "00000000",
[8] = "00000000",
[9] = "170D0000"
},
["Rey Skywalker 2"] = {
[0] = "00040072",
[1] = "7B841039",
[2] = "00000000",
[3] = "0000EA22",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "7B003000",
[7] = "00000000",
[8] = "00000000",
[9] = "170D0000"
},
["Krin Dagbard"] = {
[0] = "00040072",
[1] = "7B894F46",
[2] = "00000000",
[3] = "00007BC2",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "18003000",
[7] = "00000000",
[8] = "00000000",
[9] = "140D0000"
},
["Krin Dagbard 2"] = {
[0] = "00040072",
[1] = "7B841797",
[2] = "00000000",
[3] = "00006A58",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "18003000",
[7] = "00000000",
[8] = "00000000",
[9] = "140D0000"
},
["Grand Inquisitor"] = {
[0] = "00040072",
[1] = "7B841185",
[2] = "00000000",
[3] = "00004656",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "00000000",
[9] = "130D0000"
},
["Maul"] = {
[0] = "00040072",
[1] = "7B895525",
[2] = "00000000",
[3] = "00003104",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "00000000",
[9] = "110D0000"
},
["Grand Inquisitor 2"] = {
[0] = "00040072",
[1] = "804B091A",
[2] = "00000000",
[3] = "00005909",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "00000000",
[9] = "130D0000"
},
["Asajj Ventress"] = {
[0] = "00040072",
[1] = "7A1C1F46",
[2] = "00000000",
[3] = "00008E4D",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "00000000",
[9] = "080D0000"
},
["Darth Sidious s2"] = {
[0] = "00040072",
[1] = "00000000",
[2] = "00000000",
[3] = "00000000",
[4] = "0001805F",
[5] = "18C631FF",
[6] = "5E003000",
[7] = "00000000",
[8] = "00000000",
[9] = "010D0000"
}
}
-- When called without arguments, return the whole table
if not profile_name then
return profiles
end
-- Otherwise return the specific profile or wipe chip
return profiles[profile_name] or profiles["wipe chip"]
end
function get_profile_names()
-- Get the complete profiles table from get_profile_data
local all_profiles = get_profile_data()
local names = {}
for name, _ in pairs(all_profiles) do
table.insert(names, name)
end
table.sort(names)
return names
end
function select_profile()
local profile_names = get_profile_names()
print("\nAvailable profiles:")
for i, name in ipairs(profile_names) do
print(string.format("%d. %s", i, name))
end
while true do
io.write("\nSelect profile (1-" .. #profile_names .. "): ")
local choice = tonumber(io.read())
if choice and choice >= 1 and choice <= #profile_names then
return profile_names[choice]
else
print("Invalid selection. Please try again.")
end
end
end
function main()
print("\n[=== kyber crystal programmer ===]")
-- Get profile from command line argument or prompt user
local profile_name = args and args[1]
if not profile_name then
--print("\nNo profile specified as argument.")
profile_name = select_profile()
end
local data_to_write = get_profile_data(profile_name)
print("\n[+] Using profile: " .. profile_name)
-- Display what will be written
print("\n[+] Data to be written:")
for addr, data in pairs(data_to_write) do
print(string.format("Address %d: %s", addr, data))
end
-- Step 1: Wipe the tag
print("\n[+] Wiping tag...")
send_command("lf em 4x05 wipe --4305")
-- Step 2: Write data
print("\n[+] Writing data...")
for addr, data in pairs(data_to_write) do
send_command("lf em 4x05 write -a " .. addr .. " -d " .. data)
utils.Sleep(0.5)
end
-- Step 3: Read back and display data for verification
print("\n[+] Verifying writes by reading back data...")
for addr, expected_data in pairs(data_to_write) do
local output = send_command("lf em 4x05 read -a " .. addr)
end
print("\n[+] Read complete. Review output above.")
end
main()

View file

@ -1,128 +1,128 @@
local getopt = require('getopt') local getopt = require('getopt')
copyright = '' copyright = ''
author = "TheChamp669" author = "TheChamp669"
version = 'v1.0.0' version = 'v1.0.0'
desc = [[ desc = [[
Perform bulk enrollment of 26 bit AWID style RFID Tags Perform bulk enrollment of 26 bit AWID style RFID Tags
For more info, check the comments in the code For more info, check the comments in the code
]] ]]
example = [[ example = [[
-- --
script run lf_awid_bulkclone.lua -f 1 -b 1000 script run lf_awid_bulkclone.lua -f 1 -b 1000
]] ]]
usage = [[ usage = [[
script run lf_awid_bulkclone.lua -f facility -b base_id_num script run lf_awid_bulkclone.lua -f facility -b base_id_num
]] ]]
arguments = [[ arguments = [[
-h : this help -h : this help
-f : facility id -f : facility id
-b : starting card id -b : starting card id
]] ]]
local DEBUG = true local DEBUG = true
--- ---
-- A debug printout-function -- A debug printout-function
local function dbg(args) local function dbg(args)
if not DEBUG then return end if not DEBUG then return end
if type(args) == 'table' then if type(args) == 'table' then
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
print('###', args) print('###', args)
end end
end end
--- ---
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
local function oops(err) local function oops(err)
print('ERROR:', err) print('ERROR:', err)
core.clearCommandBuffer() core.clearCommandBuffer()
return nil, errr return nil, errr
end end
--- ---
-- Usage help -- Usage help
local function help() local function help()
print(copyright) print(copyright)
print(author) print(author)
print(version) print(version)
print(desc) print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset) print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage) print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset) print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments) print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset) print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example) print(example)
end end
--- ---
-- Exit message -- Exit message
local function exitMsg(msg) local function exitMsg(msg)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print(msg) print(msg)
print() print()
end end
local function showHelp() local function showHelp()
print("Usage: script run <scriptname> [-h]") print("Usage: script run <scriptname> [-h]")
print("Options:") print("Options:")
print("-h \t This help") print("-h \t This help")
end end
local function main(args) local function main(args)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print() print()
if #args == 0 then return help() end if #args == 0 then return help() end
for o, a in getopt.getopt(args, 'f:b:c:h') do for o, a in getopt.getopt(args, 'f:b:c:h') do
if o == 'h' then return help() end if o == 'h' then return help() end
if o == 'f' then if o == 'f' then
if isempty(a) then if isempty(a) then
print('You did not supply a facility code, using 255') print('You did not supply a facility code, using 255')
fc = 255 fc = 255
else else
fc = a fc = a
end end
end end
if o == 'b' then if o == 'b' then
if isempty(a) then if isempty(a) then
print('You did not supply a starting card number, using 59615') print('You did not supply a starting card number, using 59615')
cn = 59615 cn = 59615
else else
cn = a cn = a
end end
end end
end end
-- Example starting values -- Example starting values
local sessionStart = os.date("%Y_%m_%d_%H_%M_%S") -- Capture the session start time local sessionStart = os.date("%Y_%m_%d_%H_%M_%S") -- Capture the session start time
print("Session Start: " .. sessionStart) print("Session Start: " .. sessionStart)
print("Facility Code,Card Number") print("Facility Code,Card Number")
while true do while true do
print(string.format("Preparing to Write: Facility Code %d, Card Number %d", fc, cn)) print(string.format("Preparing to Write: Facility Code %d, Card Number %d", fc, cn))
local command = string.format("lf awid clone --fmt 26 --fc %d --cn %d", fc, cn) local command = string.format("lf awid clone --fmt 26 --fc %d --cn %d", fc, cn)
core.console(command) core.console(command)
print(string.format("%d,%d", fc, cn)) print(string.format("%d,%d", fc, cn))
print("Press Enter to continue with the next card number or type 'q' and press Enter to quit.") print("Press Enter to continue with the next card number or type 'q' and press Enter to quit.")
local user_input = io.read() local user_input = io.read()
if user_input:lower() == 'q' then if user_input:lower() == 'q' then
break break
else else
cn = cn + 1 cn = cn + 1
end end
end end
end end
main(args) main(args)

View file

@ -299,7 +299,7 @@ local function main(args)
if answer == 'n' then if answer == 'n' then
core.console('clear') core.console('clear')
print( string.rep('--',39) ) print( string.rep('--',39) )
print(ac.red..' USER ABORTED'..ac.reset) print(ac.red..' Aborted via keyboard!'..ac.reset)
print( string.rep('--',39) ) print( string.rep('--',39) )
break break
end end

View file

@ -198,7 +198,7 @@ local function main(args)
core.console('lf em 410x reader') core.console('lf em 410x reader')
end end
else else
print(ac.red..'User aborted'..ac.reset) print(ac.red..'aborted via keyboard!'..ac.reset)
low = i low = i
break break
end end

View file

@ -1,131 +1,131 @@
local getopt = require('getopt') local getopt = require('getopt')
local ansicolors = require('ansicolors') local ansicolors = require('ansicolors')
local cmds = require('commands') local cmds = require('commands')
copyright = '' copyright = ''
author = "TheChamop669" author = "TheChamop669"
version = 'v1.0.1' version = 'v1.0.1'
desc = [[ desc = [[
Perform bulk enrollment of 26 bit H10301 style RFID Tags Perform bulk enrollment of 26 bit H10301 style RFID Tags
For more info, check the comments in the code For more info, check the comments in the code
]] ]]
example = [[ example = [[
-- --
script run lf_hid_bulkclone_v2.lua -f 1 -b 1000 script run lf_hid_bulkclone_v2.lua -f 1 -b 1000
]] ]]
usage = [[ usage = [[
script run lf_hid_bulkclone_v2.lua -f facility -b base_id_num script run lf_hid_bulkclone_v2.lua -f facility -b base_id_num
]] ]]
arguments = [[ arguments = [[
-h : this help -h : this help
-f : facility id -f : facility id
-b : starting card id -b : starting card id
]] ]]
local DEBUG = true local DEBUG = true
--- ---
-- A debug printout-function -- A debug printout-function
local function dbg(args) local function dbg(args)
if not DEBUG then return end if not DEBUG then return end
if type(args) == 'table' then if type(args) == 'table' then
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
print('###', args) print('###', args)
end end
end end
--- ---
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
local function oops(err) local function oops(err)
print('ERROR:', err) print('ERROR:', err)
core.clearCommandBuffer() core.clearCommandBuffer()
return nil, errr return nil, errr
end end
--- ---
-- Usage help -- Usage help
local function help() local function help()
print(copyright) print(copyright)
print(author) print(author)
print(version) print(version)
print(desc) print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset) print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage) print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset) print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments) print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset) print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example) print(example)
end end
--- ---
-- Exit message -- Exit message
local function exitMsg(msg) local function exitMsg(msg)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print(msg) print(msg)
print() print()
end end
local function main(args) local function main(args)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print() print()
if #args == 0 then return help() end if #args == 0 then return help() end
for o, a in getopt.getopt(args, 'f:b:h') do for o, a in getopt.getopt(args, 'f:b:h') do
if o == 'h' then return help() end if o == 'h' then return help() end
if o == 'f' then if o == 'f' then
if isempty(a) then if isempty(a) then
print('You did not supply a facility code, using 0') print('You did not supply a facility code, using 0')
fc = 10 fc = 10
else else
fc = a fc = a
end end
end end
if o == 'b' then if o == 'b' then
if isempty(a) then if isempty(a) then
print('You did not supply a starting card number, using 1000') print('You did not supply a starting card number, using 1000')
cn = 1000 cn = 1000
else else
cn = a cn = a
end end
end end
end end
local successful_writes = {} local successful_writes = {}
local timestamp = os.date('%Y-%m-%d %H:%M:%S', os.time()) local timestamp = os.date('%Y-%m-%d %H:%M:%S', os.time())
while true do while true do
print(string.format("Writing Facility Code: %d, Card Number: %d", fc, cn)) print(string.format("Writing Facility Code: %d, Card Number: %d", fc, cn))
local command = string.format("lf hid clone -w H10301 --fc %d --cn %d", fc, cn) local command = string.format("lf hid clone -w H10301 --fc %d --cn %d", fc, cn)
core.console(command) core.console(command)
table.insert(successful_writes, string.format("%d,%d", fc, cn)) table.insert(successful_writes, string.format("%d,%d", fc, cn))
print("Press Enter to write the next card, type 'r' and press Enter to retry, or type 'q' and press Enter to quit.") print("Press Enter to write the next card, type 'r' and press Enter to retry, or type 'q' and press Enter to quit.")
local user_input = io.read() local user_input = io.read()
if user_input:lower() == 'q' then if user_input:lower() == 'q' then
print("Timestamp: ", timestamp) print("Timestamp: ", timestamp)
print("Successful Writes:") print("Successful Writes:")
for _, v in ipairs(successful_writes) do print(v) end for _, v in ipairs(successful_writes) do print(v) end
break break
elseif user_input:lower() ~= 'r' then elseif user_input:lower() ~= 'r' then
cn = cn + 1 cn = cn + 1
end end
end end
end end
main(args) main(args)
--[[ --[[
Notes: Notes:
1. The `lf hid clone` command is used to write HID formatted data to T5577 cards, using the H10301 format. 1. The `lf hid clone` command is used to write HID formatted data to T5577 cards, using the H10301 format.
2. The script prompts the user for the initial facility code and card number at the start of the session. 2. The script prompts the user for the initial facility code and card number at the start of the session.
3. Users can continue to write to the next card, retry the current write, or quit the session by responding to the prompts. 3. Users can continue to write to the next card, retry the current write, or quit the session by responding to the prompts.
4. Upon quitting, the script prints all successful writes along with a timestamp. 4. Upon quitting, the script prints all successful writes along with a timestamp.
5. Password-related features have been removed in this version of the script as they are not supported by the `lf hid clone` command. 5. Password-related features have been removed in this version of the script as they are not supported by the `lf hid clone` command.
]] ]]

View file

@ -1,125 +1,125 @@
local getopt = require('getopt') local getopt = require('getopt')
local cmds = require('commands') local cmds = require('commands')
copyright = '' copyright = ''
author = "TheChamp669" author = "TheChamp669"
version = 'v1.0.0' version = 'v1.0.0'
desc = [[ desc = [[
Perform bulk enrollment of 26 bit IO Prox / Kantech style RFID Tags Perform bulk enrollment of 26 bit IO Prox / Kantech style RFID Tags
The vnc is set to 2. The vnc is set to 2.
For more info, check the comments in the code For more info, check the comments in the code
]] ]]
example = [[ example = [[
-- --
script run lf_ioprox_bulkclone.lua -f 1 -b 1000 script run lf_ioprox_bulkclone.lua -f 1 -b 1000
]] ]]
usage = [[ usage = [[
script run lf_ioprox_bulkclone.lua -f facility -b base_id_num script run lf_ioprox_bulkclone.lua -f facility -b base_id_num
]] ]]
arguments = [[ arguments = [[
-h : this help -h : this help
-f : facility id -f : facility id
-b : starting card id -b : starting card id
]] ]]
local DEBUG = true local DEBUG = true
--- ---
-- A debug printout-function -- A debug printout-function
local function dbg(args) local function dbg(args)
if not DEBUG then return end if not DEBUG then return end
if type(args) == 'table' then if type(args) == 'table' then
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
print('###', args) print('###', args)
end end
end end
--- ---
-- This is only meant to be used when errors occur -- This is only meant to be used when errors occur
local function oops(err) local function oops(err)
print('ERROR:', err) print('ERROR:', err)
core.clearCommandBuffer() core.clearCommandBuffer()
return nil, errr return nil, errr
end end
--- ---
-- Usage help -- Usage help
local function help() local function help()
print(copyright) print(copyright)
print(author) print(author)
print(version) print(version)
print(desc) print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset) print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage) print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset) print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments) print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset) print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example) print(example)
end end
--- ---
-- Exit message -- Exit message
local function exitMsg(msg) local function exitMsg(msg)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print(msg) print(msg)
print() print()
end end
local function main(args) local function main(args)
print( string.rep('--',20) ) print( string.rep('--',20) )
print( string.rep('--',20) ) print( string.rep('--',20) )
print() print()
if #args == 0 then return help() end if #args == 0 then return help() end
for o, a in getopt.getopt(args, 'f:b:h') do for o, a in getopt.getopt(args, 'f:b:h') do
if o == 'h' then return help() end if o == 'h' then return help() end
if o == 'f' then if o == 'f' then
if isempty(a) then if isempty(a) then
print('You did not supply a facility code, using 0') print('You did not supply a facility code, using 0')
fc = 0 fc = 0
else else
fc = a fc = a
end end
end end
if o == 'b' then if o == 'b' then
if isempty(a) then return oops('You must supply the flag -b (starting card number)') end if isempty(a) then return oops('You must supply the flag -b (starting card number)') end
cn = a cn = a
end end
end end
local successful_writes = {} local successful_writes = {}
local timestamp = os.date('%Y-%m-%d %H:%M:%S', os.time()) local timestamp = os.date('%Y-%m-%d %H:%M:%S', os.time())
while true do while true do
print(string.format("Setting fob to Facility Code: %d, Card Number: %d", fc, cn)) print(string.format("Setting fob to Facility Code: %d, Card Number: %d", fc, cn))
-- Writing to block 0 with the specific data for ioProx card format -- Writing to block 0 with the specific data for ioProx card format
core.console("lf t55xx write -b 0 -d 00147040") core.console("lf t55xx write -b 0 -d 00147040")
-- Command to set facility code and card number on the fob -- Command to set facility code and card number on the fob
local command = string.format("lf io clone --vn 2 --fc %d --cn %d", fc, cn) local command = string.format("lf io clone --vn 2 --fc %d --cn %d", fc, cn)
core.console(command) core.console(command)
table.insert(successful_writes, string.format("%d,%d", fc, cn)) table.insert(successful_writes, string.format("%d,%d", fc, cn))
print("Fob created successfully.") print("Fob created successfully.")
print("Press Enter to create the next fob, type 'r' and press Enter to retry, or type 'q' and press Enter to quit.") print("Press Enter to create the next fob, type 'r' and press Enter to retry, or type 'q' and press Enter to quit.")
local user_input = io.read() local user_input = io.read()
if user_input:lower() == 'q' then if user_input:lower() == 'q' then
print("Timestamp: ", timestamp) print("Timestamp: ", timestamp)
print("Successful Writes:") print("Successful Writes:")
for _, v in ipairs(successful_writes) do print(v) end for _, v in ipairs(successful_writes) do print(v) end
break break
elseif user_input:lower() ~= 'r' then elseif user_input:lower() ~= 'r' then
cn = cn + 1 cn = cn + 1
end end
end end
end end
main(args) main(args)

View file

@ -1,488 +1,488 @@
local getopt = require('getopt') local getopt = require('getopt')
local utils = require('utils') local utils = require('utils')
local ac = require('ansicolors') local ac = require('ansicolors')
local os = require('os') local os = require('os')
local dash = string.rep('--', 32) local dash = string.rep('--', 32)
local dir = os.getenv('HOME') .. '/.proxmark3/logs/' local dir = os.getenv('HOME') .. '/.proxmark3/logs/'
local logfile = (io.popen('dir /a-d /o-d /tw /b/s "' .. dir .. '" 2>nul:'):read("*a"):match("%C+")) local logfile = (io.popen('dir /a-d /o-d /tw /b/s "' .. dir .. '" 2>nul:'):read("*a"):match("%C+"))
local log_file_path = dir .. "Paxton_log.txt" local log_file_path = dir .. "Paxton_log.txt"
local nam = "" local nam = ""
local pm3 = require('pm3') local pm3 = require('pm3')
p = pm3.pm3() p = pm3.pm3()
local command = core.console local command = core.console
command('clear') command('clear')
author = ' Author: jareckib - 30.01.2025' author = ' Author: jareckib - 30.01.2025'
tutorial = ' Based on Equipter tutorial - Downgrade Paxton to EM4102' tutorial = ' Based on Equipter tutorial - Downgrade Paxton to EM4102'
version = ' version v1.20' version = ' version v1.20'
desc = [[ desc = [[
The script automates the copying of Paxton fobs read - write. The script automates the copying of Paxton fobs read - write.
It also allows manual input of data for blocks 4-7. It also allows manual input of data for blocks 4-7.
The third option is reading data stored in the log file and create new fob. The third option is reading data stored in the log file and create new fob.
Additionally, the script calculates the ID for downgrading Paxton to EM4102. Additionally, the script calculates the ID for downgrading Paxton to EM4102.
]] ]]
usage = [[ usage = [[
script run paxton_clone script run paxton_clone
]] ]]
arguments = [[ arguments = [[
script run paxton_clone -h : this help script run paxton_clone -h : this help
]] ]]
local debug = true local debug = true
local function dbg(args) local function dbg(args)
if not DEBUG then return end if not DEBUG then return end
if type(args) == 'table' then if type(args) == 'table' then
local i = 1 local i = 1
while args[i] do while args[i] do
dbg(args[i]) dbg(args[i])
i = i+1 i = i+1
end end
else else
print('###', args) print('###', args)
end end
end end
local function help() local function help()
print() print()
print(author) print(author)
print(tutorial) print(tutorial)
print(version) print(version)
print(desc) print(desc)
print(ac.cyan..' Usage'..ac.reset) print(ac.cyan..' Usage'..ac.reset)
print(usage) print(usage)
print(ac.cyan..' Arguments'..ac.reset) print(ac.cyan..' Arguments'..ac.reset)
print(arguments) print(arguments)
end end
local function reset_log_file() local function reset_log_file()
local file = io.open(logfile, "w+") local file = io.open(logfile, "w+")
file:write("") file:write("")
file:close() file:close()
end end
local function read_log_file(logfile) local function read_log_file(logfile)
local file = io.open(logfile, "r") local file = io.open(logfile, "r")
if not file then if not file then
error(" Could not open the file") error(" Could not open the file")
end end
local content = file:read("*all") local content = file:read("*all")
file:close() file:close()
return content return content
end end
local function parse_blocks(result) local function parse_blocks(result)
local blocks = {} local blocks = {}
for line in result:gmatch("[^\r\n]+") do for line in result:gmatch("[^\r\n]+") do
local block_num, block_data = line:match("%[%=%]%s+%d/0x0([4-7])%s+%|%s+([0-9A-F ]+)") local block_num, block_data = line:match("%[%=%]%s+%d/0x0([4-7])%s+%|%s+([0-9A-F ]+)")
if block_num and block_data then if block_num and block_data then
block_num = tonumber(block_num) block_num = tonumber(block_num)
block_data = block_data:gsub("%s+", "") block_data = block_data:gsub("%s+", "")
blocks[block_num] = block_data blocks[block_num] = block_data
end end
end end
return blocks return blocks
end end
local function hex_to_bin(hex_string) local function hex_to_bin(hex_string)
local bin_string = "" local bin_string = ""
local hex_to_bin_map = { local hex_to_bin_map = {
['0'] = "0000", ['1'] = "0001", ['2'] = "0010", ['3'] = "0011", ['0'] = "0000", ['1'] = "0001", ['2'] = "0010", ['3'] = "0011",
['4'] = "0100", ['5'] = "0101", ['6'] = "0110", ['7'] = "0111", ['4'] = "0100", ['5'] = "0101", ['6'] = "0110", ['7'] = "0111",
['8'] = "1000", ['9'] = "1001", ['A'] = "1010", ['B'] = "1011", ['8'] = "1000", ['9'] = "1001", ['A'] = "1010", ['B'] = "1011",
['C'] = "1100", ['D'] = "1101", ['E'] = "1110", ['F'] = "1111" ['C'] = "1100", ['D'] = "1101", ['E'] = "1110", ['F'] = "1111"
} }
for i = 1, #hex_string do for i = 1, #hex_string do
bin_string = bin_string .. hex_to_bin_map[hex_string:sub(i, i)] bin_string = bin_string .. hex_to_bin_map[hex_string:sub(i, i)]
end end
return bin_string return bin_string
end end
local function remove_last_two_bits(binary_str) local function remove_last_two_bits(binary_str)
return binary_str:sub(1, #binary_str - 2) return binary_str:sub(1, #binary_str - 2)
end end
local function split_into_5bit_chunks(binary_str) local function split_into_5bit_chunks(binary_str)
local chunks = {} local chunks = {}
for i = 1, #binary_str, 5 do for i = 1, #binary_str, 5 do
table.insert(chunks, binary_str:sub(i, i + 4)) table.insert(chunks, binary_str:sub(i, i + 4))
end end
return chunks return chunks
end end
local function remove_parity_bit(chunks) local function remove_parity_bit(chunks)
local no_parity_chunks = {} local no_parity_chunks = {}
for _, chunk in ipairs(chunks) do for _, chunk in ipairs(chunks) do
if #chunk == 5 then if #chunk == 5 then
table.insert(no_parity_chunks, chunk:sub(2)) table.insert(no_parity_chunks, chunk:sub(2))
end end
end end
return no_parity_chunks return no_parity_chunks
end end
local function convert_to_hex(chunks) local function convert_to_hex(chunks)
local hex_values = {} local hex_values = {}
for _, chunk in ipairs(chunks) do for _, chunk in ipairs(chunks) do
if #chunk > 0 then if #chunk > 0 then
table.insert(hex_values, string.format("%X", tonumber(chunk, 2))) table.insert(hex_values, string.format("%X", tonumber(chunk, 2)))
end end
end end
return hex_values return hex_values
end end
local function convert_to_decimal(chunks) local function convert_to_decimal(chunks)
local decimal_values = {} local decimal_values = {}
for _, chunk in ipairs(chunks) do for _, chunk in ipairs(chunks) do
table.insert(decimal_values, tonumber(chunk, 2)) table.insert(decimal_values, tonumber(chunk, 2))
end end
return decimal_values return decimal_values
end end
local function find_until_before_f(hex_values) local function find_until_before_f(hex_values)
local result = {} local result = {}
for _, value in ipairs(hex_values) do for _, value in ipairs(hex_values) do
if value == 'F' then if value == 'F' then
break break
end end
table.insert(result, value) table.insert(result, value)
end end
return result return result
end end
local function process_block(block) local function process_block(block)
local binary_str = hex_to_bin(block) local binary_str = hex_to_bin(block)
binary_str = remove_last_two_bits(binary_str) binary_str = remove_last_two_bits(binary_str)
local chunks = split_into_5bit_chunks(binary_str) local chunks = split_into_5bit_chunks(binary_str)
local no_parity_chunks = remove_parity_bit(chunks) local no_parity_chunks = remove_parity_bit(chunks)
return no_parity_chunks return no_parity_chunks
end end
local function calculate_id_net(blocks) local function calculate_id_net(blocks)
local all_hex_values = {} local all_hex_values = {}
for _, block in ipairs(blocks) do for _, block in ipairs(blocks) do
local hex_values = convert_to_hex(process_block(block)) local hex_values = convert_to_hex(process_block(block))
for _, hex in ipairs(hex_values) do for _, hex in ipairs(hex_values) do
table.insert(all_hex_values, hex) table.insert(all_hex_values, hex)
end end
end end
local selected_hex_values = find_until_before_f(all_hex_values) local selected_hex_values = find_until_before_f(all_hex_values)
if #selected_hex_values == 0 then if #selected_hex_values == 0 then
error(ac.red..' Error: '..ac.reset..'No valid data found in blocks 4 and 5') error(ac.red..' Error: '..ac.reset..'No valid data found in blocks 4 and 5')
end end
local combined_hex = table.concat(selected_hex_values) local combined_hex = table.concat(selected_hex_values)
if not combined_hex:match("^%x+$") then if not combined_hex:match("^%x+$") then
error(ac.red..' Error: '..ac.reset..'Invalid data in blocks 4 and 5') error(ac.red..' Error: '..ac.reset..'Invalid data in blocks 4 and 5')
end end
local decimal_id = tonumber(combined_hex) local decimal_id = tonumber(combined_hex)
local stripped_hex_id = string.format("%X", decimal_id) local stripped_hex_id = string.format("%X", decimal_id)
local padded_hex_id = string.format("%010X", decimal_id) local padded_hex_id = string.format("%010X", decimal_id)
return decimal_id, padded_hex_id return decimal_id, padded_hex_id
end end
local function calculate_id_switch(blocks) local function calculate_id_switch(blocks)
local all_decimal_values = {} local all_decimal_values = {}
for _, block in ipairs(blocks) do for _, block in ipairs(blocks) do
local decimal_values = convert_to_decimal(process_block(block)) local decimal_values = convert_to_decimal(process_block(block))
for _, dec in ipairs(decimal_values) do for _, dec in ipairs(decimal_values) do
table.insert(all_decimal_values, dec) table.insert(all_decimal_values, dec)
end end
end end
if #all_decimal_values < 15 then if #all_decimal_values < 15 then
error(ac.red..' Error:'..ac.reset..' Not enough data after processing blocks 4, 5, 6, and 7') error(ac.red..' Error:'..ac.reset..' Not enough data after processing blocks 4, 5, 6, and 7')
end end
local id_positions = {9, 11, 13, 15, 2, 4, 6, 8} local id_positions = {9, 11, 13, 15, 2, 4, 6, 8}
local id_numbers = {} local id_numbers = {}
for _, pos in ipairs(id_positions) do for _, pos in ipairs(id_positions) do
table.insert(id_numbers, all_decimal_values[pos]) table.insert(id_numbers, all_decimal_values[pos])
end end
local decimal_id = tonumber(table.concat(id_numbers)) local decimal_id = tonumber(table.concat(id_numbers))
local padded_hex_id = string.format("%010X", decimal_id) local padded_hex_id = string.format("%010X", decimal_id)
return decimal_id, padded_hex_id return decimal_id, padded_hex_id
end end
local function name_exists_in_log(name) local function name_exists_in_log(name)
local file = io.open(log_file_path, "r") local file = io.open(log_file_path, "r")
if not file then if not file then
return false return false
end end
local pattern = "^Name:%s*" .. name .. "%s*$" local pattern = "^Name:%s*" .. name .. "%s*$"
for line in file:lines() do for line in file:lines() do
if line:match(pattern) then if line:match(pattern) then
file:close() file:close()
return true return true
end end
end end
file:close() file:close()
return false return false
end end
local function log_result(blocks, em410_id, name) local function log_result(blocks, em410_id, name)
local log_file = io.open(log_file_path, "a") local log_file = io.open(log_file_path, "a")
if log_file then if log_file then
log_file:write("Name: " .. name .. "\n") log_file:write("Name: " .. name .. "\n")
log_file:write("Date: ", os.date("%Y-%m-%d %H:%M:%S"), "\n") log_file:write("Date: ", os.date("%Y-%m-%d %H:%M:%S"), "\n")
for i = 4, 7 do for i = 4, 7 do
log_file:write(string.format("Block %d: %s\n", i, blocks[i] or "nil")) log_file:write(string.format("Block %d: %s\n", i, blocks[i] or "nil"))
end end
log_file:write(string.format('EM4102 ID: %s\n', em410_id or "nil")) log_file:write(string.format('EM4102 ID: %s\n', em410_id or "nil"))
log_file:write('--------------------------\n') log_file:write('--------------------------\n')
log_file:close() log_file:close()
print(' Log saved as: pm3/.proxmark3/logs/' ..ac.yellow..' Paxton_log.txt'..ac.reset) print(' Log saved as: pm3/.proxmark3/logs/' ..ac.yellow..' Paxton_log.txt'..ac.reset)
else else
print(" Failed to open log file for writing.") print(" Failed to open log file for writing.")
end end
end end
local function verify_written_data(original_blocks) local function verify_written_data(original_blocks)
p:console('lf hitag read --ht2 -k BDF5E846') p:console('lf hitag read --ht2 -k BDF5E846')
local result = read_log_file(logfile) local result = read_log_file(logfile)
local verified_blocks = parse_blocks(result) local verified_blocks = parse_blocks(result)
local success = true local success = true
for i = 4, 7 do for i = 4, 7 do
if original_blocks[i] ~= verified_blocks[i] then if original_blocks[i] ~= verified_blocks[i] then
print(' Verification failed.. Block '..ac.green.. i ..ac.reset.. ' inconsistent.') print(' Verification failed.. Block '..ac.green.. i ..ac.reset.. ' inconsistent.')
success = false success = false
end end
end end
if success then if success then
print(ac.green..' Verification successful. Data was written correctly.' .. ac.reset) print(ac.green..' Verification successful. Data was written correctly.' .. ac.reset)
else else
print(ac.yellow.. ' Adjust the position of the Paxton fob on the coil.' .. ac.reset) print(ac.yellow.. ' Adjust the position of the Paxton fob on the coil.' .. ac.reset)
end end
end end
local function handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3) local function handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3)
while true do while true do
io.write(" Create Paxton choose " .. ac.cyan .. "1" .. ac.reset .. " or EM4102 choose " .. ac.cyan .. "2 " .. ac.reset) io.write(" Create Paxton choose " .. ac.cyan .. "1" .. ac.reset .. " or EM4102 choose " .. ac.cyan .. "2 " .. ac.reset)
local choice = io.read() local choice = io.read()
if choice == "1" then if choice == "1" then
io.write(" Place the" .. ac.cyan .. " Paxton " .. ac.reset .. "Fob on the coil to write.." .. ac.green .. " ENTER " .. ac.reset .. "to continue..") io.write(" Place the" .. ac.cyan .. " Paxton " .. ac.reset .. "Fob on the coil to write.." .. ac.green .. " ENTER " .. ac.reset .. "to continue..")
io.read() io.read()
print(dash) print(dash)
p:console("lf hitag wrbl --ht2 -p 4 -d " .. blocks[4] .. " -k BDF5E846") p:console("lf hitag wrbl --ht2 -p 4 -d " .. blocks[4] .. " -k BDF5E846")
p:console("lf hitag wrbl --ht2 -p 5 -d " .. blocks[5] .. " -k BDF5E846") p:console("lf hitag wrbl --ht2 -p 5 -d " .. blocks[5] .. " -k BDF5E846")
p:console("lf hitag wrbl --ht2 -p 6 -d " .. blocks[6] .. " -k BDF5E846") p:console("lf hitag wrbl --ht2 -p 6 -d " .. blocks[6] .. " -k BDF5E846")
p:console("lf hitag wrbl --ht2 -p 7 -d " .. blocks[7] .. " -k BDF5E846") p:console("lf hitag wrbl --ht2 -p 7 -d " .. blocks[7] .. " -k BDF5E846")
reset_log_file() reset_log_file()
--timer(5) --timer(5)
verify_written_data(blocks) verify_written_data(blocks)
elseif choice == "2" then elseif choice == "2" then
io.write(" Place the" .. ac.cyan .. " T5577 " .. ac.reset .. "tag on the coil and press" .. ac.green .. " ENTER " .. ac.reset .. "to continue..") io.write(" Place the" .. ac.cyan .. " T5577 " .. ac.reset .. "tag on the coil and press" .. ac.green .. " ENTER " .. ac.reset .. "to continue..")
io.read() io.read()
p:console("lf em 410x clone --id " .. padded_hex_id) p:console("lf em 410x clone --id " .. padded_hex_id)
print(' Cloned EM4102 to T5577 with ID ' ..ac.green.. padded_hex_id ..ac.reset) print(' Cloned EM4102 to T5577 with ID ' ..ac.green.. padded_hex_id ..ac.reset)
else else
print(ac.yellow .. " Invalid choice." .. ac.reset .. " Please enter " .. ac.cyan .. "1" .. ac.reset .. " or " .. ac.cyan .. "2" .. ac.reset) print(ac.yellow .. " Invalid choice." .. ac.reset .. " Please enter " .. ac.cyan .. "1" .. ac.reset .. " or " .. ac.cyan .. "2" .. ac.reset)
goto ask_again goto ask_again
end end
while true do while true do
print(dash) print(dash)
io.write(" Make next RFID Fob"..ac.cyan.." (y/n) "..ac.reset) io.write(" Make next RFID Fob"..ac.cyan.." (y/n) "..ac.reset)
local another = io.read() local another = io.read()
if another:lower() == "n" then if another:lower() == "n" then
if was_option_3 then if was_option_3 then
print(" No writing to Paxton_log.txt - Name: " ..ac.green.. nam .. ac.reset.. " exist") print(" No writing to Paxton_log.txt - Name: " ..ac.green.. nam .. ac.reset.. " exist")
return return
end end
print() print()
print(ac.green .. " Saving Paxton_log file..." .. ac.reset) print(ac.green .. " Saving Paxton_log file..." .. ac.reset)
while true do while true do
io.write(" Enter a name for database (cannot be empty/duplicate): "..ac.yellow) io.write(" Enter a name for database (cannot be empty/duplicate): "..ac.yellow)
name = io.read() name = io.read()
io.write(ac.reset..'') io.write(ac.reset..'')
if name == nil or name:match("^%s*$") then if name == nil or name:match("^%s*$") then
print(ac.red .. ' ERROR:'..ac.reset..' Name cannot be empty.') print(ac.red .. ' ERROR:'..ac.reset..' Name cannot be empty.')
else else
if name_exists_in_log(name) then if name_exists_in_log(name) then
print(ac.yellow .. ' Name exists!!! '..ac.reset.. 'Please choose a different name.') print(ac.yellow .. ' Name exists!!! '..ac.reset.. 'Please choose a different name.')
else else
break break
end end
end end
end end
log_result(blocks, padded_hex_id, name) log_result(blocks, padded_hex_id, name)
print(ac.green .. " Log saved successfully!" .. ac.reset) print(ac.green .. " Log saved successfully!" .. ac.reset)
reset_log_file() reset_log_file()
return return
elseif another:lower() == "y" then elseif another:lower() == "y" then
goto ask_again goto ask_again
else else
print(ac.yellow.." Invalid response."..ac.reset.." Please enter"..ac.cyan.." y"..ac.reset.." or"..ac.cyan.." n"..ac.reset) print(ac.yellow.." Invalid response."..ac.reset.." Please enter"..ac.cyan.." y"..ac.reset.." or"..ac.cyan.." n"..ac.reset)
end end
end end
::ask_again:: ::ask_again::
end end
end end
local function is_valid_hex(input) local function is_valid_hex(input)
return #input == 8 and input:match("^[0-9A-Fa-f]+$") return #input == 8 and input:match("^[0-9A-Fa-f]+$")
end end
local function main(args) local function main(args)
while true do while true do
for o, a in getopt.getopt(args, 'h') do for o, a in getopt.getopt(args, 'h') do
if o == 'h' then return help() end if o == 'h' then return help() end
end end
command('clear') command('clear')
print(dash) print(dash)
print(ac.green .. ' Select option: ' .. ac.reset) print(ac.green .. ' Select option: ' .. ac.reset)
print(ac.cyan .. ' 1' .. ac.reset .. ' - Read Paxton blocks 4-7 to make a copy') print(ac.cyan .. ' 1' .. ac.reset .. ' - Read Paxton blocks 4-7 to make a copy')
print(ac.cyan .. ' 2' .. ac.reset .. ' - Manually input data for Paxton blocks 4-7') print(ac.cyan .. ' 2' .. ac.reset .. ' - Manually input data for Paxton blocks 4-7')
print(ac.cyan .. " 3" .. ac.reset .. " - Search in Paxton_log by name and use the data") print(ac.cyan .. " 3" .. ac.reset .. " - Search in Paxton_log by name and use the data")
print(dash) print(dash)
while true do while true do
io.write(' Your choice '..ac.cyan..'(1/2/3): ' .. ac.reset) io.write(' Your choice '..ac.cyan..'(1/2/3): ' .. ac.reset)
input_option = io.read() input_option = io.read()
if input_option == "1" or input_option == "2" or input_option == "3" then if input_option == "1" or input_option == "2" or input_option == "3" then
break break
else else
print(ac.yellow .. ' Invalid choice.' .. ac.reset .. ' Please enter ' .. ac.cyan .. '1' .. ac.reset .. ' or ' .. ac.cyan .. '2' .. ac.reset..' or'..ac.cyan..' 3'..ac.reset) print(ac.yellow .. ' Invalid choice.' .. ac.reset .. ' Please enter ' .. ac.cyan .. '1' .. ac.reset .. ' or ' .. ac.cyan .. '2' .. ac.reset..' or'..ac.cyan..' 3'..ac.reset)
end end
end end
local was_option_3 = false local was_option_3 = false
if input_option == "1" then if input_option == "1" then
local show_place_message = true local show_place_message = true
while true do while true do
if show_place_message then if show_place_message then
io.write(' Place the' .. ac.cyan .. ' Paxton' .. ac.reset .. ' Fob on the coil to read..' .. ac.green .. 'ENTER' .. ac.reset .. ' to continue..') io.write(' Place the' .. ac.cyan .. ' Paxton' .. ac.reset .. ' Fob on the coil to read..' .. ac.green .. 'ENTER' .. ac.reset .. ' to continue..')
end end
io.read() io.read()
print(dash) print(dash)
p:console('lf hitag read --ht2 -k BDF5E846') p:console('lf hitag read --ht2 -k BDF5E846')
if not logfile then if not logfile then
error(" No files in this directory") error(" No files in this directory")
end end
local result = read_log_file(logfile) local result = read_log_file(logfile)
local blocks = parse_blocks(result) local blocks = parse_blocks(result)
local empty_block = false local empty_block = false
for i = 4, 7 do for i = 4, 7 do
if not blocks[i] then if not blocks[i] then
empty_block = true empty_block = true
break break
end end
end end
if empty_block then if empty_block then
io.write(ac.yellow .. ' Adjust the Fob position on the coil.' .. ac.reset .. ' Press' .. ac.green .. ' ENTER' .. ac.reset .. ' to continue..') io.write(ac.yellow .. ' Adjust the Fob position on the coil.' .. ac.reset .. ' Press' .. ac.green .. ' ENTER' .. ac.reset .. ' to continue..')
show_place_message = false show_place_message = false
else else
print(' Readed blocks:') print(' Readed blocks:')
print() print()
for i = 4, 7 do for i = 4, 7 do
if blocks[i] then if blocks[i] then
print(string.format(" Block %d: %s%s%s", i, ac.yellow, blocks[i], ac.reset)) print(string.format(" Block %d: %s%s%s", i, ac.yellow, blocks[i], ac.reset))
end end
end end
local decimal_id, padded_hex_id local decimal_id, padded_hex_id
if blocks[5] and (blocks[5]:sub(4, 4) == 'F' or blocks[5]:sub(4, 4) == 'f') then if blocks[5] and (blocks[5]:sub(4, 4) == 'F' or blocks[5]:sub(4, 4) == 'f') then
print(dash) print(dash)
print(' Identified Paxton ' .. ac.cyan .. 'Net2' .. ac.reset) print(' Identified Paxton ' .. ac.cyan .. 'Net2' .. ac.reset)
decimal_id, padded_hex_id = calculate_id_net({blocks[4], blocks[5]}) decimal_id, padded_hex_id = calculate_id_net({blocks[4], blocks[5]})
else else
print(dash) print(dash)
print(' Identified Paxton ' .. ac.cyan .. 'Switch2' .. ac.reset) print(' Identified Paxton ' .. ac.cyan .. 'Switch2' .. ac.reset)
decimal_id, padded_hex_id = calculate_id_switch({blocks[4], blocks[5], blocks[6], blocks[7]}) decimal_id, padded_hex_id = calculate_id_switch({blocks[4], blocks[5], blocks[6], blocks[7]})
end end
print(string.format(" ID for EM4102 is: %s", ac.green .. padded_hex_id .. ac.reset)) print(string.format(" ID for EM4102 is: %s", ac.green .. padded_hex_id .. ac.reset))
print(dash) print(dash)
handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3) handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3)
break break
end end
end end
elseif input_option == "2" then elseif input_option == "2" then
local blocks = {} local blocks = {}
for i = 4, 7 do for i = 4, 7 do
while true do while true do
io.write(ac.reset..' Enter data for block ' .. i .. ': ' .. ac.yellow) io.write(ac.reset..' Enter data for block ' .. i .. ': ' .. ac.yellow)
local input = io.read() local input = io.read()
input = input:upper() input = input:upper()
if is_valid_hex(input) then if is_valid_hex(input) then
blocks[i] = input blocks[i] = input
break break
else else
print(ac.yellow .. ' Invalid input.' .. ac.reset .. ' Each block must be 4 bytes (8 hex characters).') print(ac.yellow .. ' Invalid input.' .. ac.reset .. ' Each block must be 4 bytes (8 hex characters).')
end end
end end
end end
local decimal_id, padded_hex_id local decimal_id, padded_hex_id
if blocks[5] and (blocks[5]:sub(4, 4) == 'F' or blocks[5]:sub(4, 4) == 'f') then if blocks[5] and (blocks[5]:sub(4, 4) == 'F' or blocks[5]:sub(4, 4) == 'f') then
print(ac.reset.. dash) print(ac.reset.. dash)
print(' Identified Paxton ' .. ac.cyan .. 'Net2' .. ac.reset) print(' Identified Paxton ' .. ac.cyan .. 'Net2' .. ac.reset)
decimal_id, padded_hex_id = calculate_id_net({blocks[4], blocks[5]}) decimal_id, padded_hex_id = calculate_id_net({blocks[4], blocks[5]})
else else
print(ac.reset.. dash) print(ac.reset.. dash)
print(' Identified Paxton ' .. ac.cyan .. 'Switch2' .. ac.reset) print(' Identified Paxton ' .. ac.cyan .. 'Switch2' .. ac.reset)
decimal_id, padded_hex_id = calculate_id_switch({blocks[4], blocks[5], blocks[6], blocks[7]}) decimal_id, padded_hex_id = calculate_id_switch({blocks[4], blocks[5], blocks[6], blocks[7]})
end end
print(dash) print(dash)
print(string.format(" ID for EM4102 is: %s", ac.green .. padded_hex_id .. ac.reset)) print(string.format(" ID for EM4102 is: %s", ac.green .. padded_hex_id .. ac.reset))
print(dash) print(dash)
if not padded_hex_id then if not padded_hex_id then
print(ac.red..' ERROR: '..ac.reset.. 'Invalid block data provided') print(ac.red..' ERROR: '..ac.reset.. 'Invalid block data provided')
return return
end end
handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3) handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3)
break break
elseif input_option == "3" then elseif input_option == "3" then
was_option_3 = true was_option_3 = true
local retries = 3 local retries = 3
while retries > 0 do while retries > 0 do
io.write(' Enter the name to search ('..retries..' attempts) : '..ac.yellow) io.write(' Enter the name to search ('..retries..' attempts) : '..ac.yellow)
local user_input = io.read() local user_input = io.read()
io.write(ac.reset..'') io.write(ac.reset..'')
if user_input == nil or user_input:match("^%s*$") then if user_input == nil or user_input:match("^%s*$") then
print(ac.yellow..' Error: '..ac.reset.. 'Empty name !!!') print(ac.yellow..' Error: '..ac.reset.. 'Empty name !!!')
end end
local name_clean = "^Name:%s*" .. user_input:gsub("%s", "%%s") .. "%s*$" local name_clean = "^Name:%s*" .. user_input:gsub("%s", "%%s") .. "%s*$"
local file = io.open(log_file_path, "r") local file = io.open(log_file_path, "r")
if not file then if not file then
print(ac.red .. ' Error:'..ac.reset.. 'Could not open log file.') print(ac.red .. ' Error:'..ac.reset.. 'Could not open log file.')
return return
end end
local lines = {} local lines = {}
for line in file:lines() do for line in file:lines() do
table.insert(lines, line) table.insert(lines, line)
end end
file:close() file:close()
local found = false local found = false
for i = 1, #lines do for i = 1, #lines do
if lines[i]:match(name_clean) then if lines[i]:match(name_clean) then
nam = user_input nam = user_input
local blocks = { local blocks = {
[4] = lines[i + 2]:match("Block 4: (.+)"), [4] = lines[i + 2]:match("Block 4: (.+)"),
[5] = lines[i + 3]:match("Block 5: (.+)"), [5] = lines[i + 3]:match("Block 5: (.+)"),
[6] = lines[i + 4]:match("Block 6: (.+)"), [6] = lines[i + 4]:match("Block 6: (.+)"),
[7] = lines[i + 5]:match("Block 7: (.+)") [7] = lines[i + 5]:match("Block 7: (.+)")
} }
local em4102_id = lines[i + 6]:match("EM4102 ID: (.+)") local em4102_id = lines[i + 6]:match("EM4102 ID: (.+)")
print(dash) print(dash)
print(' I found the data under the name: '..ac.yellow ..nam.. ac.reset) print(' I found the data under the name: '..ac.yellow ..nam.. ac.reset)
for j = 4, 7 do for j = 4, 7 do
print(string.format(" Block %d: %s%s%s", j, ac.yellow, blocks[j] or "N/A", ac.reset)) print(string.format(" Block %d: %s%s%s", j, ac.yellow, blocks[j] or "N/A", ac.reset))
end end
print(" EM4102 ID: " .. ac.green .. (em4102_id or "N/A") .. ac.reset) print(" EM4102 ID: " .. ac.green .. (em4102_id or "N/A") .. ac.reset)
print(dash) print(dash)
local decimal_id, padded_hex_id = em4102_id, em4102_id local decimal_id, padded_hex_id = em4102_id, em4102_id
handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3, nam) handle_cloning(decimal_id, padded_hex_id, blocks, was_option_3, nam)
found = true found = true
break break
end end
end end
if not found then if not found then
retries = retries - 1 retries = retries - 1
else else
break break
end end
end end
if retries == 0 then if retries == 0 then
print(ac.yellow .. " Name not found after 3 attempts." .. ac.reset) print(ac.yellow .. " Name not found after 3 attempts." .. ac.reset)
end end
end end
print(dash) print(dash)
print(' Exiting script Lua...') print(' Exiting script Lua...')
return return
end end
end end
main(args) main(args)

View file

@ -28,6 +28,7 @@ Full license text: <https://www.gnu.org/licenses/gpl-3.0.html>
import subprocess import subprocess
import time import time
import sys
import os import os
import re import re
@ -100,24 +101,33 @@ def send_proxmark_command(command):
def authenticate_and_menu(): def authenticate_and_menu():
com_mode = input("Enter communication mode (PLAIN, MAC, ENCRYPT) (Default: PLAIN): ").strip() or "plain"
key_type = input("Enter key type (DES, 2TDEA, 3TDEA, AES): ").strip() key_type = input("Enter key type (DES, 2TDEA, 3TDEA, AES): ").strip()
key = input("Enter 8, 16, 24 or 32-byte hex key (no spaces): ").strip() key = input("Enter 8, 16, or 24-byte hex key (no spaces): ").strip()
# Authenticate # Authenticate
auth_command = f"hf mfdes auth -t {key_type} -k {key}" auth_command = f"hf mfdes auth -t {key_type} -k {key} -m {com_mode}"
auth_response = send_proxmark_command(auth_command) auth_response = send_proxmark_command(auth_command)
print(auth_response) print(auth_response)
# print("DEBUG: Raw Proxmark response:\n", repr(auth_response))
# Check for Proxmark failure messages # Check for Proxmark failure messages
if "error" in auth_response.lower() or "must have" in auth_response.lower(): if "error" in auth_response.lower() or "must have" in auth_response.lower():
print("❌ Authentication failed. Check your connection, key, and key type.") print("❌ Authentication failed. Check your connection, mode, key type, and key.")
return return
while True: while True:
# Get AIDs # Get AIDs
aids_command = f"hf mfdes getaids -n 0 -t {key_type} -k {key}" aids_command = f"hf mfdes getaids -n 0 -t {key_type} -k {key} -m {com_mode}"
aids_response = send_proxmark_command(aids_command) aids_response = send_proxmark_command(aids_command)
# Check for communication mode errors
com_mode_error_match = re.search(r"Wrong communication mode", aids_response)
crc_error_match = re.search(r"CRC32 error", aids_response)
if com_mode_error_match or crc_error_match:
print("❌ Incorrect communication mode.\n")
return
print(aids_response) print(aids_response)
# Regex to match valid 6-character hex AIDs # Regex to match valid 6-character hex AIDs
@ -144,7 +154,8 @@ def authenticate_and_menu():
print("3. Delete an AID") print("3. Delete an AID")
print("4. Format PICC") print("4. Format PICC")
print("5. Show free memory") print("5. Show free memory")
print("6. Exit") print("6. Change keys")
print("7. Exit")
choice = input("Enter your choice: ").strip() choice = input("Enter your choice: ").strip()
@ -157,32 +168,39 @@ def authenticate_and_menu():
selected_aid = aids[selected_index] selected_aid = aids[selected_index]
print(f"\nSelecting AID: {selected_aid}") print(f"\nSelecting AID: {selected_aid}")
select_command = f"hf mfdes selectapp --aid {selected_aid} -t {key_type} -k {key}" select_command = f"hf mfdes selectapp --aid {selected_aid} -t {key_type} -k {key} -m {com_mode}"
select_response = send_proxmark_command(select_command) select_response = send_proxmark_command(select_command)
print(select_response) print(select_response)
# Retrieve AID key 0
aid_key_type = input(f"Enter AID encryption algorithm (DES, 2TDEA, 3TDEA, AES) (Default: {key_type.upper()}): ").strip() or key_type
aid_key = input(f"Enter AID key (Default: {key}): ").strip() or key
# Show file menu # Show file menu
aid_file_menu(selected_aid, key_type, key) aid_file_menu(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "2": elif choice == "2":
create_aid(key_type, key) create_aid(key_type, key, com_mode)
elif choice == "3": elif choice == "3":
delete_aid(key_type, key) delete_aid(key_type, key, com_mode)
elif choice == "4": elif choice == "4":
format_picc(key_type, key) format_picc(key_type, key, com_mode)
elif choice == "5": elif choice == "5":
free_memory(key_type, key) free_memory(key_type, key, com_mode)
elif choice == "6": elif choice == "6":
change_key(key_type, key, com_mode)
elif choice == "7":
print("Exiting...") print("Exiting...")
break break
else: else:
print("Invalid choice, please try again.") print("Invalid choice, please try again.")
def aid_file_menu(selected_aid, key_type, key): def aid_file_menu(selected_aid, key_type, key, com_mode, aid_key_type, aid_key):
while True: while True:
print(f"\n[ AID {selected_aid} is open ]") print(f"\n[ AID {selected_aid} is open ]")
@ -191,50 +209,52 @@ def aid_file_menu(selected_aid, key_type, key):
print("2. Read a File") print("2. Read a File")
print("3. Create a File") print("3. Create a File")
print("4. Write to a File") print("4. Write to a File")
print("5. Delete a File") print("5. Edit File Restrictions")
print("6. Exit") print("6. Delete a File")
print("7. Back")
choice = input("Enter your choice: ").strip() choice = input("Enter your choice: ").strip()
if choice == "1": if choice == "1":
list_files(selected_aid, key_type, key) list_files(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "2": elif choice == "2":
read_file(selected_aid, key_type, key) read_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "3": elif choice == "3":
create_file(selected_aid, key_type, key) create_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "4": elif choice == "4":
write_to_file(selected_aid, key_type, key) write_to_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "5": elif choice == "5":
delete_file(selected_aid, key_type, key) edit_file_restriction(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "6": elif choice == "6":
delete_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
elif choice == "7":
print("Returning to AID selection...") print("Returning to AID selection...")
break break
else: else:
print("Invalid choice, please try again.") print("Invalid choice, please try again.")
def create_aid(key_type, key): def create_aid(key_type, key, com_mode):
aid = input("Enter new AID (6 hex characters, e.g., 112233): ").strip() aid = input("Enter new AID (6 hex characters, e.g., 112233): ").strip()
iso_fid = input("Enter ISO File ID (4 hex characters, e.g., 1234): ").strip() iso_fid = input("Enter ISO File ID (4 hex characters, e.g., 1234): ").strip()
dstalgo = input("Enter encryption algorithm (DES, 2TDEA, 3TDEA, AES): ").strip().upper() dstalgo = input(f"Enter encryption algorithm (DES, 2TDEA, 3TDEA, AES) (Default: {key_type.upper()}): ").strip() or key_type
create_command = f"hf mfdes createapp -n 0 --aid {aid} --fid {iso_fid} --dstalgo {dstalgo} -t {key_type} -k {key} -m {com_mode} -a"
create_command = f"hf mfdes createapp -n 0 --aid {aid} --fid {iso_fid} --dstalgo {dstalgo} -t {key_type} -k {key} -a"
response = send_proxmark_command(create_command) response = send_proxmark_command(create_command)
print(response) print(response)
def delete_aid(key_type, key): def delete_aid(key_type, key, com_mode):
aid = input("Enter AID to delete (6 hex characters): ").strip() aid = input("Enter AID to delete (6 hex characters): ").strip()
delete_command = f"hf mfdes deleteapp --aid {aid} -n 0 -t {key_type} -k {key}" delete_command = f"hf mfdes deleteapp --aid {aid} -n 0 -t {key_type} -k {key} -m {com_mode}"
response = send_proxmark_command(delete_command) response = send_proxmark_command(delete_command)
print(response) print(response)
def format_picc(key_type, key): def format_picc(key_type, key, com_mode):
confirm = input("Are you sure you want to format the PICC? This will erase all data. (y/n): ").strip().lower() confirm = input("Are you sure you want to format the PICC? This will erase all data. (y/n): ").strip().lower()
if confirm == "y": if confirm == "y":
format_command = f"hf mfdes formatpicc -t {key_type} -k {key} -v" format_command = f"hf mfdes formatpicc -t {key_type} -k {key} -m {com_mode} -v"
response = send_proxmark_command(format_command) response = send_proxmark_command(format_command)
print(response) print(response)
elif confirm == "n": elif confirm == "n":
@ -242,9 +262,9 @@ def format_picc(key_type, key):
else: else:
print("Invalid input. Please enter 'y' or 'n'.") print("Invalid input. Please enter 'y' or 'n'.")
def free_memory(key_type, key): def free_memory(key_type, key, com_mode):
memory_command = f"hf mfdes freemem -t {key_type} -k {key}" memory_command = f"hf mfdes freemem -t {key_type} -k {key} -m {com_mode}"
response = send_proxmark_command(memory_command) response = send_proxmark_command(memory_command)
for line in response.splitlines(): for line in response.splitlines():
@ -254,10 +274,54 @@ def free_memory(key_type, key):
print("❌ Unable to retrieve free memory information.") print("❌ Unable to retrieve free memory information.")
def list_files(aid, key_type, key): def change_key(key_type, key, com_mode):
print("\nChange Key - Choose Target:")
print("1. PICC (Card Master Key)")
print("2. Application Key")
target = input("Change key for (1/2)? (Default: 1): ").strip() or "1"
aid = ""
if target == "2":
aid = input("Enter 6-digit AID (e.g., 010203): ").strip()
print("\n!! Verify and securely store the new key !!")
print("Key length guide:")
print(" DES : 8 bytes (16 hex chars)")
print(" 2TDEA : 16 bytes (32 hex chars)")
print(" 3TDEA : 24 bytes (48 hex chars)")
print(" AES : 16 bytes (32 hex chars)")
newalgo = input(f"Enter new key encryption algorithm (DES, 2TDEA, 3TDEA, AES) "
f"(Default: {key_type.upper()}): ").strip() or key_type
newkey = input(f"Enter new 8, 16, or 24-byte hex key (no spaces) (Default: {key}): ").strip() or key
confirm = input("Are you sure you want to change the key? (Key 0) (y or n): ").strip().lower()
if confirm == "y":
changekey_command = f"hf mfdes changekey -n 0 -t {key_type} -k {key} -m {com_mode} " \
f"--newalgo {newalgo} --newkey {newkey} --newver 00 -v"
if aid:
app_key_type = input(f"Enter original application encryption algorithm (DES, 2TDEA, 3TDEA, AES) "
f"(Default: DES): ").strip() or "DES"
app_key = input(f"Enter original application key "
f"(Default: 0000000000000000): ").strip() or "0000000000000000"
changekey_command = f"hf mfdes changekey -n 0 -t {app_key_type} -k {app_key} -m {com_mode} " \
f"--newalgo {newalgo} --newkey {newkey} --newver 00 --aid {aid} -v"
response = send_proxmark_command(changekey_command)
print(response)
print("\nReauthenticate with the master key.")
sys.exit()
elif confirm == "n":
print("Cancelled.")
else:
print("Invalid input. Please enter 'y' or 'n'.")
def list_files(aid, key_type, key, com_mode, aid_key_type, aid_key):
print("\nFetching file list...") print("\nFetching file list...")
command = f"hf mfdes getfileids --aid {aid} -t {key_type} -k {key}" command = f"hf mfdes getfileids --aid {aid} -t {aid_key_type} -k {aid_key} -m {com_mode}"
response = send_proxmark_command(command) response = send_proxmark_command(command)
# Extract file IDs by looking for "File ID:" regex # Extract file IDs by looking for "File ID:" regex
@ -276,7 +340,7 @@ def list_files(aid, key_type, key):
print("No files found in this AID.") print("No files found in this AID.")
return [] return []
def read_file(aid, key_type, key): def read_file(aid, key_type, key, com_mode, aid_key_type, aid_key):
file_id = input("Enter file ID to read: ").strip() file_id = input("Enter file ID to read: ").strip()
@ -288,7 +352,8 @@ def read_file(aid, key_type, key):
length_input = input("Enter length to read (e.g., 16 for 16 bytes, 64 for 64 bytes, default full read): ").strip() or "0" length_input = input("Enter length to read (e.g., 16 for 16 bytes, 64 for 64 bytes, default full read): ").strip() or "0"
length_hex = format(int(length_input), '06X') # Convert to 3-byte hex length_hex = format(int(length_input), '06X') # Convert to 3-byte hex
read_command = f"hf mfdes read --aid {aid} --fid {file_id} -t {key_type} -k {key} --offset {offset_hex} --length {length_hex}" read_command = f"hf mfdes read --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} " \
f"--offset {offset_hex} --length {length_hex} -m {com_mode}"
response = send_proxmark_command(read_command) response = send_proxmark_command(read_command)
# Extract and display file content # Extract and display file content
@ -299,7 +364,7 @@ def read_file(aid, key_type, key):
return response return response
def create_file(aid, key_type, key): def create_file(aid, key_type, key, com_mode, aid_key_type, aid_key):
# Prompt for file ID in hex format # Prompt for file ID in hex format
file_id = input("Enter file ID (2 hex characters, e.g., 01, 02): ").strip() file_id = input("Enter file ID (2 hex characters, e.g., 01, 02): ").strip()
@ -332,16 +397,17 @@ def create_file(aid, key_type, key):
print(f"Invalid file size: {e}") print(f"Invalid file size: {e}")
return return
create_command = f"hf mfdes createfile --aid {aid} --fid {file_id} --isofid {iso_file_id} --size {file_size_hex} -t {key_type} -k {key}" create_command = f"hf mfdes createfile --aid {aid} --fid {file_id} --isofid {iso_file_id} " \
f"--size {file_size_hex} -t {aid_key_type} -k {aid_key} -m {com_mode}"
response = send_proxmark_command(create_command) response = send_proxmark_command(create_command)
print(response) print(response)
def write_to_file(aid, key_type, key): def write_to_file(aid, key_type, key, com_mode, aid_key_type, aid_key):
file_id = input("Enter file ID to write to: ").strip() file_id = input("Enter file ID to write to: ").strip()
# Get file size # Get file size
file_size_command = f"hf mfdes getfilesettings --aid {aid} --fid {file_id} -t {key_type} -k {key}" file_size_command = f"hf mfdes getfilesettings --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m {com_mode}"
response = send_proxmark_command(file_size_command) response = send_proxmark_command(file_size_command)
# Extract the file size from the response # Extract the file size from the response
@ -376,15 +442,49 @@ def write_to_file(aid, key_type, key):
else: else:
print("❌ Invalid choice. Please choose 1 for text or 2 for hex.") print("❌ Invalid choice. Please choose 1 for text or 2 for hex.")
write_command = f"hf mfdes write --aid {aid} --fid {file_id} -t {key_type} -k {key} -d {write_data_hex}" write_command = f"hf mfdes write --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -d {write_data_hex} -m {com_mode}"
response = send_proxmark_command(write_command) response = send_proxmark_command(write_command)
print(response) print(response)
def delete_file(aid, key_type, key): def edit_file_restriction(aid, key_type, key, com_mode, aid_key_type, aid_key):
while True:
print("\nNOTE: This only works if you have changed the default keys.")
print("The Proxmark3 and other tools will automatically attempt to read files using DESFire default keys.")
print("\nWould you like to apply or remove a key from the file?")
print("1. Apply key 0 (Requires authentication for access)")
print("2. Remove key (Make file freely accessible)")
print("3. Back")
choice = input("Enter your choice (1, 2, or 3): ").strip()
if choice == "3":
print("Returning to the previous menu.")
break
file_id = input("Enter file ID to update: ").strip()
if choice == "1":
edit_file_command = f"hf mfdes chfilesettings --rawrights 0000 --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m {com_mode}"
print("Applying key 0 for read, write, and change access. This ensures authentication is required to access the file.")
elif choice == "2":
# Must use encrypt communications mode to remove restrictions
edit_file_command = f"hf mfdes chfilesettings --rawrights EEEE --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m encrypt"
print("Removing key restrictions. File will be freely accessible.")
else:
print("❌ Invalid choice. Please enter 1, 2, or 3.")
continue
response = send_proxmark_command(edit_file_command)
print(response)
break
def delete_file(aid, key_type, key, com_mode, aid_key_type, aid_key):
file_id = input("Enter file ID to delete: ").strip() file_id = input("Enter file ID to delete: ").strip()
delete_command = f"hf mfdes deletefile --aid {aid} --fid {file_id} -t {key_type} -k {key}" delete_command = f"hf mfdes deletefile --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m {com_mode}"
response = send_proxmark_command(delete_command) response = send_proxmark_command(delete_command)
print(response) print(response)

View file

@ -90,13 +90,14 @@ def lprint(s='', end='\n', flush=False, prompt="[" + color("=", fg="yellow") +
- logfile (R) - logfile (R)
""" """
s = f"{prompt}" + f"\n{prompt}".join(s.split('\n')) s = f"{prompt}" + f"\n{prompt}".join(s.split('\n'))
print(s, end=end, flush=flush) safe_s = s.encode('utf-8', errors='ignore').decode('utf-8')
print(safe_s, end=end, flush=flush)
if log is True: if log is True:
global logbuffer global logbuffer
if logfile is not None: if logfile is not None:
with open(logfile, 'a') as f: with open(logfile, 'a', encoding='utf-8') as f:
f.write(s + end) f.write(safe_s + end)
else: else:
# buffering # buffering
logbuffer += s + end logbuffer += s + end

View file

@ -226,6 +226,7 @@ def recovery(init_check=False, final_check=False, keep=False, no_oob=False,
dict_dnwd = None dict_dnwd = None
def_nt = ["" for _ in range(NUM_SECTORS)] def_nt = ["" for _ in range(NUM_SECTORS)]
if supply_chain: if supply_chain:
default_nonces = ''
try: try:
default_nonces = f'{save_path}hf-mf-{uid:04X}-default_nonces.json' default_nonces = f'{save_path}hf-mf-{uid:04X}-default_nonces.json'
with open(default_nonces, 'r') as file: with open(default_nonces, 'r') as file:
@ -584,8 +585,6 @@ def recovery(init_check=False, final_check=False, keep=False, no_oob=False,
if "Found keys have been dumped to" in line: if "Found keys have been dumped to" in line:
keyfile = line[line.index("`"):].strip("`") keyfile = line[line.index("`"):].strip("`")
else: else:
show()
show(color("found keys:", fg="green"), prompt=plus)
show(prompt=plus) show(prompt=plus)
show("-----+-----+--------------+---+--------------+----", prompt=plus) show("-----+-----+--------------+---+--------------+----", prompt=plus)
show(" Sec | Blk | key A |res| key B |res", prompt=plus) show(" Sec | Blk | key A |res| key B |res", prompt=plus)

View file

@ -211,6 +211,37 @@ def Describe_Usage_2_1(Usage, ContractMediumEndDate, Certificate):
print(' left... :', Usage.nom_bits_left()) print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16))) print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_2_2(Usage, ContractMediumEndDate, Certificate):
EventDateStamp = Usage.nom(10)
EventTimeStamp = Usage.nom(11)
unk0 = Usage.nom_bits(8)
EventCode_Nature = Usage.nom(5)
EventCode_Type = Usage.nom(5)
unk1 = Usage.nom_bits(11)
EventGeoRouteId = Usage.nom(14)
EventGeoRoute_Direction = Usage.nom(2)
EventGeoVehicleId = Usage.nom(16)
unk2 = Usage.nom_bits(4)
EventValidityTimeFirstStamp = Usage.nom(11)
unk3 = Usage.nom_bits(3)
EventCountPassengers_mb = Usage.nom(4)
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' unk0... :', unk0)
print(' Code/Nature : 0x{:x} ({})'.format(EventCode_Nature, TYPE_EventCode_Nature.get(EventCode_Nature, '?')))
print(' Code/Type : 0x{:x} ({})'.format(EventCode_Type, TYPE_EventCode_Type.get(EventCode_Type, '?')))
print(' unk1... :', unk1)
print(' GeoRouteId : {}'. format(EventGeoRouteId))
print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?')))
print(' GeoVehicleId : {}'. format(EventGeoVehicleId))
print(' unk2... :', unk2)
print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' unk3... :', unk3)
print(' Passengers(?) : {}'. format(EventCountPassengers_mb))
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_3(Usage, ContractMediumEndDate, Certificate): def Describe_Usage_3(Usage, ContractMediumEndDate, Certificate):
EventDateStamp = Usage.nom(10) EventDateStamp = Usage.nom(10)
EventTimeStamp = Usage.nom(11) EventTimeStamp = Usage.nom(11)
@ -258,6 +289,7 @@ ISO_Countries = {
FRA_OrganizationalAuthority_Contract_Provider = { FRA_OrganizationalAuthority_Contract_Provider = {
0x000: { 0x000: {
1: InterticHelper('Valenciennes', 'Transvilles / Keolis', Describe_Usage_1_1),
5: InterticHelper('Lille', 'Ilévia / Keolis', Describe_Usage_1_1), 5: InterticHelper('Lille', 'Ilévia / Keolis', Describe_Usage_1_1),
7: InterticHelper('Lens-Béthune', 'Tadao / Transdev', Describe_Usage_1_1), 7: InterticHelper('Lens-Béthune', 'Tadao / Transdev', Describe_Usage_1_1),
}, },
@ -273,6 +305,9 @@ FRA_OrganizationalAuthority_Contract_Provider = {
0x021: { 0x021: {
1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1), 1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1),
}, },
0x040: {
28: InterticHelper('Colmar', 'Trace / Keolis', Describe_Usage_1_1),
},
0x057: { 0x057: {
1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), # Strange usage ?, kept on generic 1 1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), # Strange usage ?, kept on generic 1
}, },
@ -289,7 +324,7 @@ FRA_OrganizationalAuthority_Contract_Provider = {
0x502: { 0x502: {
83: InterticHelper('Annecy', 'Sibra', Describe_Usage_2), 83: InterticHelper('Annecy', 'Sibra', Describe_Usage_2),
84: InterticHelper('Bourg-en-Bresse', 'Rubis / Keolis'), 84: InterticHelper('Bourg-en-Bresse', 'Rubis / Keolis'),
10: InterticHelper('Clermont-Ferrand', 'T2C'), 10: InterticHelper('Clermont-Ferrand', 'T2C', Describe_Usage_2_2),
}, },
0x907: { 0x907: {
1: InterticHelper('Dijon', 'Divia / Keolis'), 1: InterticHelper('Dijon', 'Divia / Keolis'),
@ -315,6 +350,9 @@ FRA_OrganizationalAuthority_Contract_Provider = {
4: InterticHelper('Angers', 'Irigo / RATP', Describe_Usage_1_2), 4: InterticHelper('Angers', 'Irigo / RATP', Describe_Usage_1_2),
7: InterticHelper('Saint-Nazaire', 'Stran'), 7: InterticHelper('Saint-Nazaire', 'Stran'),
}, },
0x920: {
9: InterticHelper('Aix-en-Provence', 'Aixenbus / Keolis', Describe_Usage_2_1),
},
} }
MAR_OrganizationalAuthority_Contract_Provider = { MAR_OrganizationalAuthority_Contract_Provider = {

View file

@ -36,7 +36,7 @@ DIR_PATH = os.path.dirname(os.path.abspath(__file__))
if TOOLS_PATH is None: if TOOLS_PATH is None:
if os.path.basename(os.path.dirname(DIR_PATH)) == 'client': if os.path.basename(os.path.dirname(DIR_PATH)) == 'client':
# dev setup # dev setup
DEV_TOOLS_PATH = os.path.normpath(os.path.join(DIR_PATH, "..", "..", "tools", "mfc", "card_only")) DEV_TOOLS_PATH = os.path.normpath(os.path.join(DIR_PATH, "..", "..", "tools"))
if os.path.isdir(DEV_TOOLS_PATH): if os.path.isdir(DEV_TOOLS_PATH):
TOOLS_PATH = DEV_TOOLS_PATH TOOLS_PATH = DEV_TOOLS_PATH
@ -62,11 +62,11 @@ def find_tool(tool_name):
str: The full path to the tool if found, otherwise None. str: The full path to the tool if found, otherwise None.
""" """
if TOOLS_PATH is not None: if TOOLS_PATH is not None:
tool = os.path.join(TOOLS_PATH, tool_name) for root, _, files in os.walk(TOOLS_PATH):
if os.path.isfile(tool): if tool_name in files:
return tool return os.path.join(root, tool_name)
elif os.path.isfile(tool + ".exe"): elif tool_name + ".exe" in files:
return tool + ".exe" return os.path.join(root, tool_name + ".exe")
# if not found, search in the user PATH # if not found, search in the user PATH
for path in os.environ["PATH"].split(os.pathsep): for path in os.environ["PATH"].split(os.pathsep):
env_tool = os.path.join(path, tool_name) env_tool = os.path.join(path, tool_name)

View file

@ -391,12 +391,20 @@
"Description": "Key as a Service // FID 01: Standard Data", "Description": "Key as a Service // FID 01: Standard Data",
"Type": "pacs" "Type": "pacs"
}, },
{
"AID": "F51780",
"Vendor": "ASSA ABLOY",
"Country": "SE",
"Name": "SMARTair",
"Description": "SMARTair Credential",
"Type": "pacs"
},
{ {
"AID": "F51BC0", "AID": "F51BC0",
"Vendor": "STid Group", "Vendor": "STid Group",
"Country": "FR", "Country": "FR",
"Name": "CCT Card / DTA Tag / PCG Fob", "Name": "CCT Card / DTA Tag / PCG Fob",
"Description": "STid Easyline / Architect Access Credetials", "Description": "STid Easyline / Architect Access Credentials",
"Type": "pacs" "Type": "pacs"
}, },
{ {
@ -887,12 +895,20 @@
"Description": "car2go - Member Card // Multi Functional Badge / Private Application #1", "Description": "car2go - Member Card // Multi Functional Badge / Private Application #1",
"Type": "carsharing" "Type": "carsharing"
}, },
{
"AID": "000005",
"Vendor": "Transports Metropolitans de Barcelona (TMB)",
"Country": "ES",
"Name": "T-mobilitat (BCN)",
"Description": "BCN T-mobilitat",
"Type": "transport"
},
{ {
"AID": "000001", "AID": "000001",
"Vendor": "Invalid / Reserved", "Vendor": "Invalid / Reserved",
"Country": "", "Country": "",
"Name": "Invalid / Reserved", "Name": "Invalid / Reserved",
"Description": "Used by ATL Breeze, MAD Tarjeta Transporte Publico, and YVR Compass", "Description": "Used by ATL Breeze, PHL FREEDOM, and YVR Compass",
"Type": "transport" "Type": "transport"
}, },
{ {
@ -915,7 +931,7 @@
"AID": "010000", "AID": "010000",
"Vendor": "Consorcio Regional de Transportes Publicos Regulares de Madrid (CRTM)", "Vendor": "Consorcio Regional de Transportes Publicos Regulares de Madrid (CRTM)",
"Country": "ES", "Country": "ES",
"Name": "Tarjeta Transporte Publico (MAD) (Alternative Endian)", "Name": "Tarjeta Transporte Publico (MAD)",
"Description": "MAD Public Transport Card", "Description": "MAD Public Transport Card",
"Type": "transport" "Type": "transport"
}, },
@ -1183,6 +1199,22 @@
"Description": "DUB Leap Card // Transport for Ireland // FIDs: 01,1F: Backup Data; 02-0A: Standard Data", "Description": "DUB Leap Card // Transport for Ireland // FIDs: 01,1F: Backup Data; 02-0A: Standard Data",
"Type": "transport" "Type": "transport"
}, },
{
"AID": "402301",
"Vendor": "Ministry of Transport, Communications and Works of the Republic of Cyprus",
"Country": "CY",
"Name": "motion BUS CARD (ECN)",
"Description": "ECN motion BUS CARD (App 1)",
"Type": "transport"
},
{
"AID": "415431",
"Vendor": "Athens Urban Transport Organization (OASA)",
"Country": "GR",
"Name": "ATH.ENA CARD (ATH)",
"Description": "ATH ATH.ENA CARD",
"Type": "transport"
},
{ {
"AID": "444D01", "AID": "444D01",
"Vendor": "Delhi Metro Rail Corporation Limited", "Vendor": "Delhi Metro Rail Corporation Limited",
@ -1255,6 +1287,14 @@
"Description": "FIDs: 00-07: Standard Data", "Description": "FIDs: 00-07: Standard Data",
"Type": "transport" "Type": "transport"
}, },
{
"AID": "502301",
"Vendor": "Ministry of Transport, Communications and Works of the Republic of Cyprus",
"Country": "CY",
"Name": "motion BUS CARD (ECN)",
"Description": "ECN motion BUS CARD (App 2)",
"Type": "transport"
},
{ {
"AID": "534531", "AID": "534531",
"Vendor": "Transport for New South Wales (TfNSW)", "Vendor": "Transport for New South Wales (TfNSW)",
@ -1287,6 +1327,14 @@
"Description": "FIDs 01: Product Retailer; 02: Service Provider; 03: Special Event; 04: Stored Value; 05: General Event Log; 06: SV Reload Log; 0A: Environment; 0C: Card Holder", "Description": "FIDs 01: Product Retailer; 02: Service Provider; 03: Special Event; 04: Stored Value; 05: General Event Log; 06: SV Reload Log; 0A: Environment; 0C: Card Holder",
"Type": "transport" "Type": "transport"
}, },
{
"AID": "602301",
"Vendor": "Ministry of Transport, Communications and Works of the Republic of Cyprus",
"Country": "CY",
"Name": "motion BUS CARD (ECN)",
"Description": "ECN motion BUS CARD (App 3)",
"Type": "transport"
},
{ {
"AID": "634000", "AID": "634000",
"Vendor": "Doha Metro and Lusail Tram via Qatar Rail", "Vendor": "Doha Metro and Lusail Tram via Qatar Rail",
@ -1303,6 +1351,14 @@
"Description": "Umo Mobility Card", "Description": "Umo Mobility Card",
"Type": "transport" "Type": "transport"
}, },
{
"AID": "7A007A",
"Vendor": "Regional Transportation Commission of Southern Nevada (RTC) via Masabi Ltd",
"Country": "US",
"Name": "RTC TAP & GO (LAS)",
"Description": "LAS TAP & GO; Masabi Justride Tap and Ride DESFire Smartcard",
"Type": "transport"
},
{ {
"AID": "784000", "AID": "784000",
"Vendor": "Roads & Transport Authority (Government of Dubai)", "Vendor": "Roads & Transport Authority (Government of Dubai)",
@ -1527,6 +1583,14 @@
"Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data", "Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data",
"Type": "transport" "Type": "transport"
}, },
{
"AID": "F21400",
"Vendor": "Spokane Transit Authority (STA) via INIT",
"Country": "US",
"Name": "Connect Card (GEG)",
"Description": "GEG Connect Card",
"Type": "transport"
},
{ {
"AID": "F40110", "AID": "F40110",
"Vendor": "ITSO Ltd", "Vendor": "ITSO Ltd",

View file

@ -0,0 +1,8 @@
$$$$$$\ $$$$$$\ $$$$$$$$\ $$\ $$\ $$$$$$\ $$\ $$\ 
\_$$ _|$$ __$$\ $$ _____|$$$\ $$$ |$$ __$$\ $$$\ $$ |
$$ | $$ / \__|$$ | $$$$\ $$$$ |$$ / $$ |$$$$\ $$ |
$$ | $$ | $$$$$\ $$\$$\$$ $$ |$$$$$$$$ |$$ $$\$$ |
$$ | $$ | $$ __| $$ \$$$ $$ |$$ __$$ |$$ \$$$$ |
$$ | $$ | $$\ $$ | $$ |\$ /$$ |$$ | $$ |$$ |\$$$ |
$$$$$$\ \$$$$$$ |$$$$$$$$\ $$ | \_/ $$ |$$ | $$ |$$ | \$$ |
\______| \______/ \________|\__| \__|\__| \__|\__| \__|

File diff suppressed because it is too large Load diff

View file

@ -192,21 +192,24 @@ static int CmdFlashMemLoad(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "mem load", CLIParserInit(&ctx, "mem load",
"Loads binary file into flash memory on device\n" "Loads binary file into flash memory on device\n"
"Warning: mem area to be written must have been wiped first\n" "Warning! - mem area to be written must have been wiped first\n\n"
"( dictionaries are serviced as files in spiffs so no wipe is needed )", "OBS! - dictionaries are serviced as files in spiffs so no wipe is needed",
"mem load -f myfile -> upload file myfile values at default offset 0\n" "mem load -f myfile -> upload file myfile values at default offset 0\n"
"mem load -f myfile -o 1024 -> upload file myfile values at offset 1024\n" "mem load -f myfile -o 1024 -> upload file myfile values at offset 1024\n"
"mem load -f mfc_default_keys -m -> upload MFC keys\n" "mem load -f mfc_default_keys -m -> upload MIFARE Classic keys\n"
"mem load -f t55xx_default_pwds -t -> upload T55XX passwords\n" "mem load -f t55xx_default_pwds -t -> upload T55XX passwords\n"
"mem load -f iclass_default_keys -i -> upload iCLASS keys\n" "mem load -f iclass_default_keys -i -> upload iCLASS keys\n"
"mem load -f mfulc_default_keys --ulc -> upload MIFARE UL-C keys\n"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_int0("o", "offset", "<dec>", "offset in memory"), arg_int0("o", "offset", "<dec>", "offset in memory"),
arg_lit0("m", "mifare,mfc", "upload 6 bytes keys (mifare key dictionary)"), arg_lit0("m", "mfc", "upload 6 bytes keys (MIFARE Classic dictionary)"),
arg_lit0("i", "iclass", "upload 8 bytes keys (iClass key dictionary)"), arg_lit0("i", "iclass", "upload 8 bytes keys (iClass dictionary)"),
arg_lit0("t", "t55xx", "upload 4 bytes keys (password dictionary)"), arg_lit0("t", "t55xx", "upload 4 bytes keys (T55xx dictionary)"),
arg_lit0(NULL, "ulc", "upload 16 bytes keys (MIFARE UL-C dictionary)"),
arg_lit0(NULL, "aes", "upload 16 bytes keys (MIFARE UL-AES dictionary)"),
arg_str1("f", "file", "<fn>", "file name"), arg_str1("f", "file", "<fn>", "file name"),
arg_param_end arg_param_end
}; };
@ -216,28 +219,35 @@ static int CmdFlashMemLoad(const char *Cmd) {
bool is_mfc = arg_get_lit(ctx, 2); bool is_mfc = arg_get_lit(ctx, 2);
bool is_iclass = arg_get_lit(ctx, 3); bool is_iclass = arg_get_lit(ctx, 3);
bool is_t55xx = arg_get_lit(ctx, 4); bool is_t55xx = arg_get_lit(ctx, 4);
bool is_ulc = arg_get_lit(ctx, 5);
bool is_ulaes = arg_get_lit(ctx, 6);
int fnlen = 0; int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
char spiffsDest[32] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
Dictionary_t d = DICTIONARY_NONE; Dictionary_t d = DICTIONARY_NONE;
if (is_mfc) { if (is_mfc) {
d = DICTIONARY_MIFARE; d = DICTIONARY_MIFARE;
PrintAndLogEx(INFO, "treating file as MIFARE Classic keys"); PrintAndLogEx(INFO, "Treating file as MIFARE Classic keys");
} else if (is_iclass) { } else if (is_iclass) {
d = DICTIONARY_ICLASS; d = DICTIONARY_ICLASS;
PrintAndLogEx(INFO, "treating file as iCLASS keys"); PrintAndLogEx(INFO, "Treating file as iCLASS keys");
} else if (is_t55xx) { } else if (is_t55xx) {
d = DICTIONARY_T55XX; d = DICTIONARY_T55XX;
PrintAndLogEx(INFO, "treating file as T55xx passwords"); PrintAndLogEx(INFO, "Treating file as T55xx passwords");
} else if (is_ulc) {
d = DICTIONARY_MIFARE_ULC;
PrintAndLogEx(INFO, "Treating file as MIFARE Ultralight-C keys");
} else if (is_ulaes) {
d = DICTIONARY_MIFARE_ULAES;
PrintAndLogEx(INFO, "Treating file as MIFARE Ultralight AES keys");
} }
uint8_t spi_flash_pages = 0; uint8_t spi_flash_pages = 0;
int res = rdv4_get_flash_pages64k(&spi_flash_pages); int res = rdv4_get_flash_pages64k(&spi_flash_pages);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to get flash pages count (%x)", res); PrintAndLogEx(ERR, "Failed to get flash pages count (%x)", res);
return res; return res;
} }
@ -246,6 +256,8 @@ static int CmdFlashMemLoad(const char *Cmd) {
uint8_t keylen = 0; uint8_t keylen = 0;
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE_P(spi_flash_pages), sizeof(uint8_t)); uint8_t *data = calloc(FLASH_MEM_MAX_SIZE_P(spi_flash_pages), sizeof(uint8_t));
char spiffsDest[32] = {0};
switch (d) { switch (d) {
case DICTIONARY_MIFARE: { case DICTIONARY_MIFARE: {
keylen = MF_KEY_LENGTH; keylen = MF_KEY_LENGTH;
@ -292,6 +304,36 @@ static int CmdFlashMemLoad(const char *Cmd) {
strcpy(spiffsDest, ICLASS_KEYS_FILE); strcpy(spiffsDest, ICLASS_KEYS_FILE);
break; break;
} }
case DICTIONARY_MIFARE_ULC: {
keylen = MFULC_KEY_LENGTH;
res = loadFileDICTIONARY(filename, data, &datalen, keylen, &keycount);
if (res || !keycount) {
free(data);
return PM3_EFILE;
}
if (datalen > FLASH_MEM_MAX_SIZE_P(spi_flash_pages)) {
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
free(data);
return PM3_EOVFLOW;
}
strcpy(spiffsDest, MFULC_KEYS_FILE);
break;
}
case DICTIONARY_MIFARE_ULAES: {
keylen = MFULAES_KEY_LENGTH;
res = loadFileDICTIONARY(filename, data, &datalen, keylen, &keycount);
if (res || !keycount) {
free(data);
return PM3_EFILE;
}
if (datalen > FLASH_MEM_MAX_SIZE_P(spi_flash_pages)) {
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
free(data);
return PM3_EOVFLOW;
}
strcpy(spiffsDest, MFULAES_KEYS_FILE);
break;
}
case DICTIONARY_NONE: { case DICTIONARY_NONE: {
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen); res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
@ -330,7 +372,12 @@ static int CmdFlashMemLoad(const char *Cmd) {
free(data); free(data);
return res; return res;
} }
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")" passwords to file "_GREEN_("%s"), keycount, spiffsDest);
if (d == DICTIONARY_T55XX) {
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")" passwords to file "_GREEN_("%s"), keycount, spiffsDest);
} else {
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")" keys to file "_GREEN_("%s"), keycount, spiffsDest);
}
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
} else { } else {
@ -729,6 +776,7 @@ static int CmdFlashMemInfo(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "{ SPI File system }"}, {"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "{ SPI File system }"},
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"-----------", CmdHelp, IfPm3Flash, "------------------- " _CYAN_("Operations") " -------------------"},
{"baudrate", CmdFlashmemSpiBaud, IfPm3Flash, "Set Flash memory Spi baudrate"}, {"baudrate", CmdFlashmemSpiBaud, IfPm3Flash, "Set Flash memory Spi baudrate"},
{"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"}, {"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"},
{"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"}, {"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"},

View file

@ -26,7 +26,9 @@ typedef enum {
DICTIONARY_NONE = 0, DICTIONARY_NONE = 0,
DICTIONARY_MIFARE, DICTIONARY_MIFARE,
DICTIONARY_T55XX, DICTIONARY_T55XX,
DICTIONARY_ICLASS DICTIONARY_ICLASS,
DICTIONARY_MIFARE_ULC,
DICTIONARY_MIFARE_ULAES,
} Dictionary_t; } Dictionary_t;
int CmdFlashMem(const char *Cmd); int CmdFlashMem(const char *Cmd);

View file

@ -576,10 +576,11 @@ static int CmdFlashMemSpiFFSView(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"-----------", CmdHelp, IfPm3Flash, "------------------- " _CYAN_("Operations") " -------------------"},
{"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS file system"}, {"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS file system"},
{"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented file system"}, {"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented file system"},
{"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS file system"}, {"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS file system"},
{"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print file system info and usage statistics"}, {"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "File system information and usage statistics"},
{"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS file system if not already mounted"}, {"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS file system if not already mounted"},
{"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS file system"}, {"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS file system"},
{"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS file system"}, {"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS file system"},

View file

@ -231,60 +231,60 @@ int CmdHFSearch(const char *Cmd) {
} }
*/ */
DropField();
PROMPT_CLEARLINE; PROMPT_CLEARLINE;
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, _RED_("No known/supported 13.56 MHz tags found")); PrintAndLogEx(WARNING, _RED_("No known/supported 13.56 MHz tags found"));
res = PM3_ESOFT; return res;
} else { }
// no need to print 14A hints, since it will print itself // no need to print 14A hints, since it will print itself
if (success[THINFILM]) { if (success[THINFILM]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf thinfilm") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf thinfilm") "` commands\n");
} }
if (success[LTO]) { if (success[LTO]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf lto") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf lto") "` commands\n");
} }
if (success[LEGIC]) { if (success[LEGIC]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf legic") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf legic") "` commands\n");
} }
if (success[TOPAZ]) { if (success[TOPAZ]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf topaz") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf topaz") "` commands\n");
} }
if (success[PROTO_TEXKOM]) { if (success[PROTO_TEXKOM]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf texkom") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf texkom") "` commands\n");
} }
if (success[PROTO_XEROX]) { if (success[PROTO_XEROX]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf xerox") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf xerox") "` commands\n");
} }
if (success[ISO_14443B]) { if (success[ISO_14443B]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 14b") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 14b") "` commands\n");
} }
if (success[ISO_15693]) { if (success[ISO_15693]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 15") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 15") "` commands\n");
} }
if (success[ICLASS]) { if (success[ICLASS]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf iclass") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf iclass") "` commands\n");
} }
if (success[FELICA]) { if (success[FELICA]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf felica") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf felica") "` commands\n");
} }
if (success[PROTO_CRYPTORF]) { if (success[PROTO_CRYPTORF]) {
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n"); PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n");
}
} }
DropField();
return res; return res;
} }
@ -477,7 +477,7 @@ int CmdHFSniff(const char *Cmd) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
PrintAndLogEx(INFO, "User aborted"); PrintAndLogEx(WARNING, "\naborted via keyboard!");
break; break;
} }
@ -600,7 +600,7 @@ static command_t CommandTable[] = {
{"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"}, {"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"},
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
{"vas", CmdHFVAS, AlwaysAvailable, "{ Apple Value Added Service }"}, {"vas", CmdHFVAS, AlwaysAvailable, "{ Apple Value Added Service... }"},
#ifdef HAVE_GD #ifdef HAVE_GD
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"}, {"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,7 @@
#define CMDHF14A_H__ #define CMDHF14A_H__
#include "common.h" #include "common.h"
#include "pm3_cmd.h" //hf14a_config #include "pm3_cmd.h" //hf14a_config_t
#include "mifare.h" // structs #include "mifare.h" // structs
// structure and database for uid -> tagtype lookups // structure and database for uid -> tagtype lookups
@ -36,6 +36,16 @@ typedef struct {
const char *hint; const char *hint;
} hintAIDList_t; } hintAIDList_t;
typedef struct {
uint8_t vendor_id;
uint8_t product_type;
uint8_t product_subtype;
uint8_t major_product_version;
uint8_t minor_product_version;
uint8_t storage_size;
uint8_t protocol_type;
} version_hw_t;
typedef enum { typedef enum {
MTNONE = 0, MTNONE = 0,
MTCLASSIC = 1, MTCLASSIC = 1,
@ -49,6 +59,9 @@ typedef enum {
MTFUDAN = 256, MTFUDAN = 256,
MTISO18092 = 512, MTISO18092 = 512,
MT424 = 1024, MT424 = 1024,
MTULTRALIGHT_C = 2048,
MTDUOX = 4096,
MTNTAG = 8192,
} nxp_mifare_type_t; } nxp_mifare_type_t;
int CmdHF14A(const char *Cmd); int CmdHF14A(const char *Cmd);
@ -59,10 +72,13 @@ int CmdHF14ANdefRead(const char *Cmd); // used by cmdnfc.c
int CmdHF14ANdefFormat(const char *Cmd); // used by cmdnfc.c int CmdHF14ANdefFormat(const char *Cmd); // used by cmdnfc.c
int CmdHF14ANdefWrite(const char *Cmd); // used by cmdnfc.c int CmdHF14ANdefWrite(const char *Cmd); // used by cmdnfc.c
int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status);
int hf14a_getconfig(hf14a_config *config); int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status,
int hf14a_setconfig(hf14a_config *config, bool verbose); uint8_t ats_hist_len, uint8_t *ats_hist,
bool version_hw_available, version_hw_t *version_hw);
int hf14a_getconfig(hf14a_config_t *config);
int hf14a_setconfig(hf14a_config_t *config, bool verbose);
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search); int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
int infoHF14A4Applications(bool verbose); int infoHF14A4Applications(bool verbose);
const char *getTagInfo(uint8_t uid); const char *getTagInfo(uint8_t uid);
@ -70,10 +86,11 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card);
int ExchangeAPDU14a(const uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); int ExchangeAPDU14a(const uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode); int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode);
iso14a_polling_parameters_t iso14a_get_polling_parameters(bool use_ecp, bool use_magsafe);
int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card); int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card);
int SelectCard14443A_4_WithParameters(bool disconnect, bool verbose, iso14a_card_select_t *card, iso14a_polling_parameters_t *polling_parameters); int SelectCard14443A_4_WithParameters(bool disconnect, bool verbose, iso14a_card_select_t *card, iso14a_polling_parameters_t *polling_parameters);
bool Get_apdu_in_framing(void); bool Get_apdu_in_framing(void);
void Set_apdu_in_framing(bool v); void Set_apdu_in_framing(bool v);
int hf14a_getversion_data(iso14a_card_select_t *card, uint64_t select_status, version_hw_t *hw);
#endif #endif

View file

@ -1411,7 +1411,7 @@ static bool HF14B_ask_ct_reader(bool verbose) {
return false; return false;
} }
bool HF14B_picopass_reader(bool verbose, bool info) { static bool HF14B_picopass_reader(bool verbose) {
iso14b_raw_cmd_t packet = { iso14b_raw_cmd_t packet = {
.flags = (ISO14B_CONNECT | ISO14B_SELECT_PICOPASS | ISO14B_DISCONNECT), .flags = (ISO14B_CONNECT | ISO14B_SELECT_PICOPASS | ISO14B_DISCONNECT),
@ -1437,10 +1437,8 @@ bool HF14B_picopass_reader(bool verbose, bool info) {
return false; return false;
} }
memcpy(card, resp.data.asBytes, sizeof(picopass_hdr_t)); memcpy(card, resp.data.asBytes, sizeof(picopass_hdr_t));
if (info) { PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "iCLASS / Picopass CSN: " _GREEN_("%s"), sprint_hex(card->csn, sizeof(card->csn)));
PrintAndLogEx(SUCCESS, "iCLASS / Picopass CSN: " _GREEN_("%s"), sprint_hex(card->csn, sizeof(card->csn)));
}
free(card); free(card);
return true; return true;
} }
@ -3029,14 +3027,15 @@ int infoHF14B(bool verbose, bool do_aid_search) {
// try unknown 14b read commands (to be identified later) // try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass. // could be read of calypso, CEPAS, moneo, or pico pass.
if (verbose) PrintAndLogEx(FAILED, "no 14443-B tag found"); if (verbose) {
PrintAndLogEx(FAILED, "no 14443-B tag found");
}
return PM3_EOPABORTED; return PM3_EOPABORTED;
} }
// get and print general info about all known 14b chips // get and print general info about all known 14b chips
int readHF14B(bool loop, bool verbose, bool read_plot) { int readHF14B(bool loop, bool verbose, bool read_plot) {
bool found = false; bool found = false;
bool info = true;
int res = PM3_SUCCESS; int res = PM3_SUCCESS;
do { do {
found = false; found = false;
@ -3052,7 +3051,7 @@ int readHF14B(bool loop, bool verbose, bool read_plot) {
goto plot; goto plot;
// Picopass // Picopass
found |= HF14B_picopass_reader(verbose, info); found |= HF14B_picopass_reader(verbose);
if (found) if (found)
goto plot; goto plot;

View file

@ -31,6 +31,5 @@ int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card);
int infoHF14B(bool verbose, bool do_aid_search); int infoHF14B(bool verbose, bool do_aid_search);
int readHF14B(bool loop, bool verbose, bool read_plot); int readHF14B(bool loop, bool verbose, bool read_plot);
bool HF14B_picopass_reader(bool verbose, bool info);
#endif #endif

View file

@ -50,22 +50,6 @@
#define Logic1 Iso15693Logic1 #define Logic1 Iso15693Logic1
#define FrameEOF Iso15693FrameEOF #define FrameEOF Iso15693FrameEOF
#define CARD_MEMORY_SIZE 4096 #define CARD_MEMORY_SIZE 4096
#define HF15_UID_LENGTH 8
#ifndef Crc15
# define Crc15(data, len) Crc16ex(CRC_15693, (data), (len))
#endif
#ifndef CheckCrc15
# define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len))
#endif
#ifndef AddCrc15
#define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1)
#endif
#ifndef ISO15_RAW_LEN
#define ISO15_RAW_LEN(x) (sizeof(iso15_raw_cmd_t) + (x))
#endif
#ifndef ISO15_ERROR_HANDLING_RESPONSE #ifndef ISO15_ERROR_HANDLING_RESPONSE
#define ISO15_ERROR_HANDLING_RESPONSE { \ #define ISO15_ERROR_HANDLING_RESPONSE { \
@ -98,6 +82,11 @@
} }
#endif #endif
typedef struct {
uint8_t lock;
uint8_t block[8];
} t15memory_t;
// structure and database for uid -> tagtype lookups // structure and database for uid -> tagtype lookups
typedef struct { typedef struct {
uint64_t uid; uint64_t uid;
@ -279,22 +268,22 @@ static int CmdHF15Help(const char *Cmd);
static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
int reason = 0; int reason = 0;
int index = originality_check_verify(uid, 8, signature, 32, PK_MFC); int index = originality_check_verify(uid, 8, signature, 32, PK_15);
if (index >= 0) { if (index >= 0) {
reason = 1; reason = 1;
} else { } else {
// try with sha256 // try with sha256
index = originality_check_verify_ex(uid, 8, signature, 32, PK_MFC, false, true); index = originality_check_verify_ex(uid, 8, signature, 32, PK_15, false, true);
if (index >= 0) { if (index >= 0) {
reason = 2; reason = 2;
} else { } else {
// try with reversed uid / signature // try with reversed uid / signature
index = originality_check_verify_ex(uid, 8, signature, 32, PK_MFC, true, false); index = originality_check_verify_ex(uid, 8, signature, 32, PK_15, true, false);
if (index >= 0) { if (index >= 0) {
reason = 3; reason = 3;
} else { } else {
// try with sha256 and reversed uid / signature // try with sha256 and reversed uid / signature
index = originality_check_verify_ex(uid, 8, signature, 32, PK_MFC, true, true); index = originality_check_verify_ex(uid, 8, signature, 32, PK_15, true, true);
if (index >= 0) { if (index >= 0) {
reason = 3; reason = 3;
} }
@ -474,7 +463,7 @@ static int getUID(bool verbose, bool loop, uint8_t *buf) {
// used with 'hf search' // used with 'hf search'
bool readHF15Uid(bool loop, bool verbose) { bool readHF15Uid(bool loop, bool verbose) {
uint8_t uid[HF15_UID_LENGTH] = {0}; uint8_t uid[ISO15693_UID_LENGTH] = {0};
if (getUID(verbose, loop, uid) != PM3_SUCCESS) { if (getUID(verbose, loop, uid) != PM3_SUCCESS) {
return false; return false;
} }
@ -665,7 +654,7 @@ static int NxpTestEAS(const uint8_t *uid) {
return PM3_EINVARG; return PM3_EINVARG;
} }
uint8_t approxlen = 3 + HF15_UID_LENGTH + 2; uint8_t approxlen = 3 + ISO15693_UID_LENGTH + 2;
iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen); iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen);
if (packet == NULL) { if (packet == NULL) {
PrintAndLogEx(WARNING, "Failed to allocate memory"); PrintAndLogEx(WARNING, "Failed to allocate memory");
@ -677,8 +666,8 @@ static int NxpTestEAS(const uint8_t *uid) {
packet->raw[packet->rawlen++] = ISO15693_EAS_ALARM; packet->raw[packet->rawlen++] = ISO15693_EAS_ALARM;
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); // add UID memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH); // add UID
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
AddCrc15(packet->raw, packet->rawlen); AddCrc15(packet->raw, packet->rawlen);
packet->rawlen += 2; packet->rawlen += 2;
@ -720,7 +709,7 @@ static int NxpCheckSig(uint8_t *uid) {
return PM3_EINVARG; return PM3_EINVARG;
} }
uint8_t approxlen = 3 + HF15_UID_LENGTH + 2; uint8_t approxlen = 3 + ISO15693_UID_LENGTH + 2;
iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen); iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen);
if (packet == NULL) { if (packet == NULL) {
PrintAndLogEx(WARNING, "Failed to allocate memory"); PrintAndLogEx(WARNING, "Failed to allocate memory");
@ -733,8 +722,8 @@ static int NxpCheckSig(uint8_t *uid) {
packet->raw[packet->rawlen++] = ISO15693_READ_SIGNATURE; packet->raw[packet->rawlen++] = ISO15693_READ_SIGNATURE;
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); // add UID memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH); // add UID
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
AddCrc15(packet->raw, packet->rawlen); AddCrc15(packet->raw, packet->rawlen);
packet->rawlen += 2; packet->rawlen += 2;
@ -787,7 +776,7 @@ static int NxpSysInfo(uint8_t *uid) {
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
memcpy(packet->raw + 3, uid, 8); // add UID memcpy(packet->raw + 3, uid, 8); // add UID
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
AddCrc15(packet->raw, packet->rawlen); AddCrc15(packet->raw, packet->rawlen);
packet->rawlen += 2; packet->rawlen += 2;
@ -900,11 +889,11 @@ static int StCheckSig(uint8_t *uid) {
} }
// ISO15693 Protocol params // ISO15693 Protocol params
packet->raw[packet->rawlen++] = arg_get_raw_flag(HF15_UID_LENGTH, false, false, false); packet->raw[packet->rawlen++] = arg_get_raw_flag(ISO15693_UID_LENGTH, false, false, false);
packet->raw[packet->rawlen++] = ISO15693_READBLOCK; packet->raw[packet->rawlen++] = ISO15693_READBLOCK;
// add UID (scan, uid) // add UID (scan, uid)
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
packet->flags = (ISO15_CONNECT | ISO15_READ_RESPONSE | ISO15_NO_DISCONNECT); packet->flags = (ISO15_CONNECT | ISO15_READ_RESPONSE | ISO15_NO_DISCONNECT);
uint16_t blkoff = packet->rawlen; uint16_t blkoff = packet->rawlen;
char signature_hex[65] = {0}; char signature_hex[65] = {0};
@ -943,9 +932,9 @@ static int StCheckSig(uint8_t *uid) {
uint8_t signature[16]; uint8_t signature[16];
size_t signature_len; size_t signature_len;
hexstr_to_byte_array(signature_hex, signature, &signature_len); hexstr_to_byte_array(signature_hex, signature, &signature_len);
uint8_t uid_swap[HF15_UID_LENGTH]; uint8_t uid_swap[ISO15693_UID_LENGTH];
reverse_array_copy(uid, HF15_UID_LENGTH, uid_swap); reverse_array_copy(uid, ISO15693_UID_LENGTH, uid_swap);
int index = originality_check_verify_ex(uid_swap, HF15_UID_LENGTH, signature, signature_len, PK_ST25TV, false, true); int index = originality_check_verify_ex(uid_swap, ISO15693_UID_LENGTH, signature, signature_len, PK_ST25TV, false, true);
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return originality_check_print(signature, signature_len, index); return originality_check_print(signature, signature_len, index);
} }
@ -970,7 +959,7 @@ static int CmdHF15Info(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
bool unaddressed = arg_get_lit(ctx, 2); bool unaddressed = arg_get_lit(ctx, 2);
@ -987,7 +976,7 @@ static int CmdHF15Info(const char *Cmd) {
} }
// default fallback to scan for tag. // default fallback to scan for tag.
if (unaddressed == false && uidlen != HF15_UID_LENGTH) { if (unaddressed == false && uidlen != ISO15693_UID_LENGTH) {
scan = true; scan = true;
} }
@ -1014,10 +1003,10 @@ static int CmdHF15Info(const char *Cmd) {
free(packet); free(packet);
return PM3_EINVARG; return PM3_EINVARG;
} }
uidlen = HF15_UID_LENGTH; uidlen = ISO15693_UID_LENGTH;
} }
if (uidlen == HF15_UID_LENGTH) { if (uidlen == ISO15693_UID_LENGTH) {
// add UID (scan, uid) // add UID (scan, uid)
memcpy(packet->raw + packet->rawlen, uid, uidlen); memcpy(packet->raw + packet->rawlen, uid, uidlen);
packet->rawlen += uidlen; packet->rawlen += uidlen;
@ -1251,8 +1240,11 @@ static int CmdHF15ELoad(const char *Cmd) {
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) || ((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
(tag->pagesCount == 0) || (tag->pagesCount == 0) ||
(tag->bytesPerPage == 0)) { (tag->bytesPerPage == 0)) {
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d", PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
tag->pagesCount, tag->bytesPerPage); tag->pagesCount,
tag->bytesPerPage
);
free(tag); free(tag);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -1486,7 +1478,7 @@ static int CmdHF15Sim(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
struct { struct {
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
uint8_t block_size; uint8_t block_size;
} PACKED payload; } PACKED payload;
memset(&payload, 0, sizeof(payload)); memset(&payload, 0, sizeof(payload));
@ -1497,7 +1489,7 @@ static int CmdHF15Sim(const char *Cmd) {
CLIParserFree(ctx); CLIParserFree(ctx);
// sanity checks // sanity checks
if (uidlen != 0 && uidlen != HF15_UID_LENGTH) { if (uidlen != 0 && uidlen != ISO15693_UID_LENGTH) {
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got ( " _RED_("%i") " )", uidlen); PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got ( " _RED_("%i") " )", uidlen);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -1624,7 +1616,7 @@ static int CmdHF15WriteAfi(const char *Cmd) {
struct { struct {
uint8_t pwd[4]; uint8_t pwd[4];
bool use_pwd; bool use_pwd;
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
bool use_uid; bool use_uid;
uint8_t afi; uint8_t afi;
} PACKED payload; } PACKED payload;
@ -1645,7 +1637,7 @@ static int CmdHF15WriteAfi(const char *Cmd) {
} }
payload.use_uid = false; payload.use_uid = false;
if (uidlen == HF15_UID_LENGTH) { if (uidlen == ISO15693_UID_LENGTH) {
payload.use_uid = true; payload.use_uid = true;
} }
@ -1703,7 +1695,7 @@ static int CmdHF15WriteDsfid(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t uid[HF15_UID_LENGTH] = {0}; uint8_t uid[ISO15693_UID_LENGTH] = {0};
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
@ -1742,10 +1734,10 @@ static int CmdHF15WriteDsfid(const char *Cmd) {
free(packet); free(packet);
return PM3_EINVARG; return PM3_EINVARG;
} }
uidlen = HF15_UID_LENGTH; uidlen = ISO15693_UID_LENGTH;
} }
if (uidlen == HF15_UID_LENGTH) { if (uidlen == ISO15693_UID_LENGTH) {
// add UID (scan, uid) // add UID (scan, uid)
memcpy(packet->raw + packet->rawlen, uid, uidlen); memcpy(packet->raw + packet->rawlen, uid, uidlen);
packet->rawlen += uidlen; packet->rawlen += uidlen;
@ -1807,7 +1799,7 @@ static int CmdHF15Dump(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t uid[HF15_UID_LENGTH] = {0}; uint8_t uid[ISO15693_UID_LENGTH] = {0};
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
@ -1838,7 +1830,7 @@ static int CmdHF15Dump(const char *Cmd) {
} }
// default fallback to scan for tag. // default fallback to scan for tag.
if (uidlen != HF15_UID_LENGTH && !unaddressed) { if (uidlen != ISO15693_UID_LENGTH && !unaddressed) {
scan = true; scan = true;
} }
@ -1874,11 +1866,11 @@ static int CmdHF15Dump(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { } else {
reverse_array(uid, HF15_UID_LENGTH); reverse_array(uid, ISO15693_UID_LENGTH);
} }
// add UID (scan, uid) // add UID (scan, uid)
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
used_uid = true; used_uid = true;
} else { } else {
PrintAndLogEx(INFO, "Using unaddressed mode"); PrintAndLogEx(INFO, "Using unaddressed mode");
@ -1915,35 +1907,49 @@ static int CmdHF15Dump(const char *Cmd) {
uint8_t dCpt = 10; uint8_t dCpt = 10;
int res = iso15_error_handling_card_response(d, resp.length); int res = iso15_error_handling_card_response(d, resp.length);
if (res != PM3_SUCCESS) { if (res == PM3_ECRC) {
free(tag); free(tag);
free(packet); free(packet);
return res; return res;
} }
memcpy(tag->uid, &d[2], 8); if (res == PM3_SUCCESS) {
memcpy(tag->uid, d + 2, 8);
if (d[1] & 0x01) { if (d[1] & 0x01) {
tag->dsfid = d[dCpt++]; tag->dsfid = d[dCpt];
} }
dCpt++;
if (d[1] & 0x02) { if (d[1] & 0x02) {
tag->afi = d[dCpt++]; tag->afi = d[dCpt];
} }
dCpt++;
if (d[1] & 0x04) {
tag->pagesCount = d[dCpt] + 1;
tag->bytesPerPage = d[dCpt + 1] + 1;
} else {
// Set tag memory layout values (if can't be read in SYSINFO)
tag->bytesPerPage = blocksize;
tag->pagesCount = 128;
}
dCpt += 2;
if (d[1] & 0x08) {
tag->ic = d[dCpt];
}
dCpt++;
if (d[1] & 0x04) {
tag->pagesCount = d[dCpt++] + 1;
tag->bytesPerPage = d[dCpt++] + 1;
} else { } else {
tag->uid[0] = 0xE0;
tag->dsfid = 0;
tag->afi = 0;
// Set tag memory layout values (if can't be read in SYSINFO) // Set tag memory layout values (if can't be read in SYSINFO)
tag->bytesPerPage = blocksize; tag->bytesPerPage = blocksize;
tag->pagesCount = 128; tag->pagesCount = 128;
} }
if (d[1] & 0x08) {
tag->ic = d[dCpt++];
}
// add length for blockno (1) // add length for blockno (1)
packet->rawlen++; packet->rawlen++;
packet->raw[0] |= ISO15_REQ_OPTION; // Add option to dump lock status packet->raw[0] |= ISO15_REQ_OPTION; // Add option to dump lock status
@ -2178,10 +2184,10 @@ static int CmdHF15Readmulti(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t uid[HF15_UID_LENGTH] = {0x00}; uint8_t uid[ISO15693_UID_LENGTH] = {0x00};
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
bool unaddressed = arg_get_lit(ctx, 2); bool unaddressed = arg_get_lit(ctx, 2);
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter. bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter.
@ -2239,11 +2245,11 @@ static int CmdHF15Readmulti(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { } else {
reverse_array(uid, HF15_UID_LENGTH); reverse_array(uid, ISO15693_UID_LENGTH);
} }
// add UID (scan, uid) // add UID (scan, uid)
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
} else { } else {
PrintAndLogEx(INFO, "Using unaddressed mode"); PrintAndLogEx(INFO, "Using unaddressed mode");
@ -2255,7 +2261,9 @@ static int CmdHF15Readmulti(const char *Cmd) {
// 0 means 1 page, // 0 means 1 page,
// 1 means 2 pages, ... // 1 means 2 pages, ...
if (blockcnt > 0) blockcnt--; if (blockcnt > 0) {
blockcnt--;
}
packet->raw[packet->rawlen++] = blockno; packet->raw[packet->rawlen++] = blockno;
packet->raw[packet->rawlen++] = blockcnt; packet->raw[packet->rawlen++] = blockcnt;
@ -2285,7 +2293,7 @@ static int CmdHF15Readmulti(const char *Cmd) {
ISO15_ERROR_HANDLING_CARD_RESPONSE(d, resp.length) ISO15_ERROR_HANDLING_CARD_RESPONSE(d, resp.length)
// 1 byte cmd, 1 lock byte, 4 / 8 bytes block size, 2 crc // 1 byte cmd, 1 lock byte, 4 / 8 bytes block size, 2 crc
if (resp.length > (1 + (blockcnt * (blocksize + 1)) + 2)) { if (resp.length > (1 + ((blockcnt + 1) * (blocksize + 1)) + 2)) {
PrintAndLogEx(WARNING, "got longer response. Check block size!"); PrintAndLogEx(WARNING, "got longer response. Check block size!");
} }
@ -2336,10 +2344,10 @@ static int CmdHF15Readblock(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
bool unaddressed = arg_get_lit(ctx, 2); bool unaddressed = arg_get_lit(ctx, 2);
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter. bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
@ -2393,11 +2401,11 @@ static int CmdHF15Readblock(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { } else {
reverse_array(uid, HF15_UID_LENGTH); reverse_array(uid, ISO15693_UID_LENGTH);
} }
// add UID (scan, uid) // add UID (scan, uid)
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
} else { } else {
PrintAndLogEx(INFO, "Using unaddressed mode"); PrintAndLogEx(INFO, "Using unaddressed mode");
@ -2490,8 +2498,8 @@ static int hf_15_write_blk(const uint8_t *pm3flags, uint16_t flags, const uint8_
// add UID // add UID
if (uid) { if (uid) {
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
packet->rawlen += HF15_UID_LENGTH; packet->rawlen += ISO15693_UID_LENGTH;
} }
packet->raw[packet->rawlen++] = blockno; packet->raw[packet->rawlen++] = blockno;
@ -2550,10 +2558,10 @@ static int CmdHF15Write(const char *Cmd) {
argtable[arglen++] = arg_param_end; argtable[arglen++] = arg_param_end;
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
bool unaddressed = arg_get_lit(ctx, 2); bool unaddressed = arg_get_lit(ctx, 2);
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter. bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
@ -2589,7 +2597,7 @@ static int CmdHF15Write(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { } else {
reverse_array(uid, HF15_UID_LENGTH); reverse_array(uid, ISO15693_UID_LENGTH);
} }
} else { } else {
PrintAndLogEx(INFO, "Using unaddressed mode"); PrintAndLogEx(INFO, "Using unaddressed mode");
@ -2624,7 +2632,7 @@ static int CmdHF15Restore(const char *Cmd) {
"hf 15 restore -u E011223344556677 -f hf-15-my-dump.bin" "hf 15 restore -u E011223344556677 -f hf-15-my-dump.bin"
); );
void *argtable[6 + 5] = {0}; void *argtable[6 + 4] = {0};
uint8_t arglen = arg_add_default(argtable); uint8_t arglen = arg_add_default(argtable);
argtable[arglen++] = arg_str0("f", "file", "<fn>", "Specify a filename for dump file"); argtable[arglen++] = arg_str0("f", "file", "<fn>", "Specify a filename for dump file");
argtable[arglen++] = arg_int0("r", "retry", "<dec>", "number of retries (def 3)"); argtable[arglen++] = arg_int0("r", "retry", "<dec>", "number of retries (def 3)");
@ -2632,7 +2640,7 @@ static int CmdHF15Restore(const char *Cmd) {
argtable[arglen++] = arg_param_end; argtable[arglen++] = arg_param_end;
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
@ -2662,7 +2670,7 @@ static int CmdHF15Restore(const char *Cmd) {
// default fallback to scan for tag. // default fallback to scan for tag.
// overriding unaddress parameter :) // overriding unaddress parameter :)
if (uidlen != HF15_UID_LENGTH) { if (uidlen != ISO15693_UID_LENGTH) {
scan = true; scan = true;
} }
@ -2674,7 +2682,7 @@ static int CmdHF15Restore(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { } else {
reverse_array(uid, HF15_UID_LENGTH); reverse_array(uid, ISO15693_UID_LENGTH);
} }
} else { } else {
PrintAndLogEx(INFO, "Using unaddressed mode"); PrintAndLogEx(INFO, "Using unaddressed mode");
@ -2713,8 +2721,11 @@ static int CmdHF15Restore(const char *Cmd) {
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) || ((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
(tag->pagesCount == 0) || (tag->pagesCount == 0) ||
(tag->bytesPerPage == 0)) { (tag->bytesPerPage == 0)) {
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d", PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
tag->pagesCount, tag->bytesPerPage); tag->pagesCount,
tag->bytesPerPage
);
free(tag); free(tag);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2745,8 +2756,8 @@ static int CmdHF15Restore(const char *Cmd) {
for (tried = 0; tried < retries; tried++) { for (tried = 0; tried < retries; tried++) {
retval = hf_15_write_blk(&pm3flags, flags, uid, fast retval = hf_15_write_blk(&pm3flags, flags, uid, fast, i, data, tag->bytesPerPage);
, i, data, tag->bytesPerPage);
if (retval == PM3_SUCCESS) { if (retval == PM3_SUCCESS) {
PrintAndLogEx(INPLACE, "blk %3d", i); PrintAndLogEx(INPLACE, "blk %3d", i);
@ -2809,7 +2820,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
struct { struct {
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
} PACKED payload; } PACKED payload;
int uidlen = 0; int uidlen = 0;
@ -2817,7 +2828,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
bool use_v2 = arg_get_lit(ctx, 2); bool use_v2 = arg_get_lit(ctx, 2);
CLIParserFree(ctx); CLIParserFree(ctx);
if (uidlen != HF15_UID_LENGTH) { if (uidlen != ISO15693_UID_LENGTH) {
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got " _RED_("%i"), uidlen); PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got " _RED_("%i"), uidlen);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2831,7 +2842,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
PrintAndLogEx(INFO, "Get current tag"); PrintAndLogEx(INFO, "Get current tag");
uint8_t carduid[HF15_UID_LENGTH] = {0x00}; uint8_t carduid[ISO15693_UID_LENGTH] = {0x00};
if (getUID(true, false, carduid) != PM3_SUCCESS) { if (getUID(true, false, carduid) != PM3_SUCCESS) {
PrintAndLogEx(FAILED, "no tag found"); PrintAndLogEx(FAILED, "no tag found");
return PM3_ESOFT; return PM3_ESOFT;
@ -2861,10 +2872,10 @@ static int CmdHF15CSetUID(const char *Cmd) {
} }
// reverse cardUID to compare // reverse cardUID to compare
uint8_t revuid[HF15_UID_LENGTH] = {0}; uint8_t revuid[ISO15693_UID_LENGTH] = {0};
reverse_array_copy(carduid, sizeof(carduid), revuid); reverse_array_copy(carduid, sizeof(carduid), revuid);
if (memcmp(revuid, payload.uid, HF15_UID_LENGTH) == 0) { if (memcmp(revuid, payload.uid, ISO15693_UID_LENGTH) == 0) {
PrintAndLogEx(SUCCESS, "Setting new UID ( " _GREEN_("ok") " )"); PrintAndLogEx(SUCCESS, "Setting new UID ( " _GREEN_("ok") " )");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;; return PM3_SUCCESS;;
@ -3478,8 +3489,11 @@ static int CmdHF15View(const char *Cmd) {
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) || ((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
(tag->pagesCount == 0) || (tag->pagesCount == 0) ||
(tag->bytesPerPage == 0)) { (tag->bytesPerPage == 0)) {
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d", PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
tag->pagesCount, tag->bytesPerPage); tag->pagesCount,
tag->bytesPerPage
);
free(tag); free(tag);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -3498,15 +3512,15 @@ static int CmdHF15Wipe(const char *Cmd) {
); );
void *argtable[6 + 3] = {0}; void *argtable[6 + 3] = {0};
uint8_t arglen = arg_add_default(argtable); uint8_t arglen = arg_add_default(argtable);
argtable[arglen++] = arg_int0(NULL, "bs", "<dec>", "block size (def 4)"), argtable[arglen++] = arg_int0(NULL, "bs", "<dec>", "block size (def 4)");
argtable[arglen++] = arg_lit0("v", "verbose", "verbose output"); argtable[arglen++] = arg_lit0("v", "verbose", "verbose output");
argtable[arglen++] = arg_param_end; argtable[arglen++] = arg_param_end;
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t uid[HF15_UID_LENGTH]; uint8_t uid[ISO15693_UID_LENGTH];
int uidlen = 0; int uidlen = 0;
CLIGetHexWithReturn(ctx, 1, uid, &uidlen); CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
bool unaddressed = arg_get_lit(ctx, 2); bool unaddressed = arg_get_lit(ctx, 2);
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter. bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
@ -3538,7 +3552,7 @@ static int CmdHF15Wipe(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} else { } else {
reverse_array(uid, HF15_UID_LENGTH); reverse_array(uid, ISO15693_UID_LENGTH);
} }
} else { } else {
PrintAndLogEx(INFO, "Using unaddressed mode"); PrintAndLogEx(INFO, "Using unaddressed mode");

View file

@ -20,9 +20,24 @@
#define CMDHF15_H__ #define CMDHF15_H__
#include "common.h" #include "common.h"
#include "crc16.h"
#include "iso15.h" // typedef structs / enum
#ifndef Crc15
# define Crc15(data, len) Crc16ex(CRC_15693, (data), (len))
#endif
#ifndef CheckCrc15
# define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len))
#endif
#ifndef AddCrc15
#define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1)
#endif
#ifndef ISO15_RAW_LEN
#define ISO15_RAW_LEN(x) (sizeof(iso15_raw_cmd_t) + (x))
#endif
int CmdHF15(const char *Cmd); int CmdHF15(const char *Cmd);
bool readHF15Uid(bool loop, bool verbose); bool readHF15Uid(bool loop, bool verbose);
#endif #endif

View file

@ -1888,7 +1888,8 @@ static int CmdHFCipurseDefault(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help."}, {"help", CmdHelp, AlwaysAvailable, "This help."},
{"info", CmdHFCipurseInfo, IfPm3Iso14443a, "Get info about CIPURSE tag"}, {"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("Operations") " -------------------"},
{"info", CmdHFCipurseInfo, IfPm3Iso14443a, "Tag information"},
{"select", CmdHFCipurseSelect, IfPm3Iso14443a, "Select CIPURSE application or file"}, {"select", CmdHFCipurseSelect, IfPm3Iso14443a, "Select CIPURSE application or file"},
{"auth", CmdHFCipurseAuth, IfPm3Iso14443a, "Authenticate CIPURSE tag"}, {"auth", CmdHFCipurseAuth, IfPm3Iso14443a, "Authenticate CIPURSE tag"},
{"read", CmdHFCipurseReadFile, IfPm3Iso14443a, "Read binary file"}, {"read", CmdHFCipurseReadFile, IfPm3Iso14443a, "Read binary file"},

View file

@ -2449,8 +2449,9 @@ static int CmdHFeMRTDList(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"-----------", CmdHelp, IfPm3Iso14443, "------------------- " _CYAN_("Operations") " -------------------"},
{"dump", CmdHFeMRTDDump, IfPm3Iso14443, "Dump eMRTD files to binary files"}, {"dump", CmdHFeMRTDDump, IfPm3Iso14443, "Dump eMRTD files to binary files"},
{"info", CmdHFeMRTDInfo, AlwaysAvailable, "Display info about an eMRTD"}, {"info", CmdHFeMRTDInfo, AlwaysAvailable, "Tag information"},
{"list", CmdHFeMRTDList, AlwaysAvailable, "List ISO 14443A/7816 history"}, {"list", CmdHFeMRTDList, AlwaysAvailable, "List ISO 14443A/7816 history"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -1803,7 +1803,7 @@ static int CmdHFFelicaSniff(const char *Cmd) {
for (;;) { for (;;) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
PrintAndLogEx(DEBUG, "User aborted"); PrintAndLogEx(DEBUG, "\naborted via keyboard!");
msleep(300); msleep(300);
break; break;
} }
@ -1851,7 +1851,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) {
for (;;) { for (;;) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
PrintAndLogEx(DEBUG, "User aborted"); PrintAndLogEx(DEBUG, "\naborted via keyboard!");
msleep(300); msleep(300);
break; break;
} }
@ -2054,7 +2054,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
PrintAndLogEx(DEBUG, "User aborted"); PrintAndLogEx(DEBUG, "\naborted via keyboard!");
return PM3_EOPABORTED; return PM3_EOPABORTED;
} }

View file

@ -913,7 +913,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help."}, {"help", CmdHelp, AlwaysAvailable, "This help."},
{"list", CmdHFFidoList, AlwaysAvailable, "List ISO 14443A history"}, {"list", CmdHFFidoList, AlwaysAvailable, "List ISO 14443A history"},
{"info", CmdHFFidoInfo, IfPm3Iso14443a, "Info about FIDO tag."}, {"-----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("Operations") " -------------------"},
{"info", CmdHFFidoInfo, IfPm3Iso14443a, "Tag information"},
{"reg", CmdHFFidoRegister, IfPm3Iso14443a, "FIDO U2F Registration Message."}, {"reg", CmdHFFidoRegister, IfPm3Iso14443a, "FIDO U2F Registration Message."},
{"auth", CmdHFFidoAuthenticate, IfPm3Iso14443a, "FIDO U2F Authentication Message."}, {"auth", CmdHFFidoAuthenticate, IfPm3Iso14443a, "FIDO U2F Authentication Message."},
{"make", CmdHFFido2MakeCredential, IfPm3Iso14443a, "FIDO2 MakeCredential command."}, {"make", CmdHFFido2MakeCredential, IfPm3Iso14443a, "FIDO2 MakeCredential command."},

File diff suppressed because it is too large Load diff

View file

@ -584,7 +584,7 @@ static int CmdHF14AJookiSim(const char *Cmd) {
for (;;) { for (;;) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
PrintAndLogEx(DEBUG, "User aborted"); PrintAndLogEx(DEBUG, "\naborted via keyboard!");
break; break;
} }

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