mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-06 13:01:37 -07:00
Compare commits
406 commits
Author | SHA1 | Date | |
---|---|---|---|
|
7717dfc04d | ||
|
53b2dc7d4b | ||
|
75c3ce61dd | ||
|
33c3988a94 | ||
|
594f127adf | ||
|
66b7e27dec | ||
|
fa2d52205b | ||
|
7ad3f6eaf2 | ||
|
baf22054f8 | ||
|
f5e61410c6 | ||
|
24d80f51a9 | ||
|
03a3abfc64 | ||
|
f5820999b4 | ||
|
8e4b9b46a0 | ||
|
649de11a9a | ||
|
f8bd0b4bae | ||
|
875ceab8a7 | ||
|
02a4594a1b | ||
|
d39b32997f | ||
|
ea2796dc6c | ||
|
7373c38388 | ||
|
dab49248b4 | ||
|
0662c1a9c1 | ||
|
a440fbabda | ||
|
630708c3eb | ||
|
21bae5c73f | ||
|
95814cc5b8 | ||
|
4268fe3ce1 | ||
|
7e2aa07b27 | ||
|
16cbb4a446 | ||
|
5b37fe8af6 | ||
|
fbdc85d6ad | ||
|
c63c62167e | ||
|
22b46a4923 | ||
|
a33ea4dc6e | ||
|
6c402791f1 | ||
|
3625ee318a | ||
|
89465db4b1 | ||
|
f94a2cb964 | ||
|
5de4dd68e5 | ||
|
488f7aa01e | ||
|
883415fc99 | ||
|
091c539a8d | ||
|
217edd1e74 | ||
|
ba14a611e0 | ||
|
f9bce6e21b | ||
|
61a993de82 | ||
|
43943ce9a5 | ||
|
c729c88f1d | ||
|
cfe9c39b89 | ||
|
f5254880b9 | ||
|
c504d43398 | ||
|
e0b1b5b4f8 | ||
|
67fbd6abba | ||
|
37166d6c73 | ||
|
b74b52f01a | ||
|
16a7e4fba5 | ||
|
47648c541c | ||
|
f6aa71b10e | ||
|
2ed0c9a301 | ||
|
80a86e741c | ||
|
570b1fcc40 | ||
|
b6d826410d | ||
|
65607fc727 | ||
|
0e87f01ab9 | ||
|
545e49201f | ||
|
fe92f55653 | ||
|
cc17db26bf | ||
|
7fa9f7bdfe | ||
|
fc9f70c436 | ||
|
79400d0779 | ||
|
35493f5b2c | ||
|
7a9b3383d4 | ||
|
e97d521f8c | ||
|
237d3b6ce7 | ||
|
cc8ea65679 | ||
|
52b00fa653 | ||
|
508c8943e7 | ||
|
1f718683b3 | ||
|
9fa173c727 | ||
|
0792d05efa | ||
|
1bebaf6aee | ||
|
f06c2fafbe | ||
|
67da1c8ca5 | ||
|
63392baa40 | ||
|
640b4a5f3b | ||
|
eb31bcad07 | ||
|
eb5aa9e08e | ||
|
25932cafb7 | ||
|
22555cc5da | ||
|
4547d4ba7c | ||
|
3515370185 | ||
|
9a75cbe169 | ||
|
86d36a3be3 | ||
|
a7dfd06354 | ||
|
a5d02c6ba2 | ||
|
3210384ef9 | ||
|
b00e5d3a22 | ||
|
ee674405bc | ||
|
5cb19b0645 | ||
|
16fab8bd44 | ||
|
dc44d0fda5 | ||
|
e917491d4a | ||
|
4725ae5c22 | ||
|
6ba00b7bee | ||
|
0378d91595 | ||
|
2ca43e0e2d | ||
|
92c288ab85 | ||
|
c1729ca264 | ||
|
f7f0605207 | ||
|
2dfb0706fa | ||
|
4f682501f1 | ||
|
c4e019ec60 | ||
|
2108ab6101 | ||
|
646f1a5b97 | ||
|
24d6013f10 | ||
|
2699060eeb | ||
|
076158cc15 | ||
|
d143d9a65c | ||
|
8156274007 | ||
|
cd14990dc5 | ||
|
5b7e013f1a | ||
|
7fb5716ea3 | ||
|
af7aa26c14 | ||
|
9b37250453 | ||
|
b5e6d21128 | ||
|
69a2cc1ff0 | ||
|
4dcf12fd8d | ||
|
31b1117a51 | ||
|
86bac8fe8c | ||
|
0a4b67bd7e | ||
|
b70d462a06 | ||
|
5f2edb9bb8 | ||
|
15fbfafac1 | ||
|
1fa5e28a38 | ||
|
1a6c38ab20 | ||
|
7fd5730d89 | ||
|
ec26b6d84f | ||
|
add2eb8e9d | ||
|
3d8a15d361 | ||
|
8c880e4a3f | ||
|
bcec294606 | ||
|
27aa9a2085 | ||
|
387009ab6a | ||
|
2d610b8dc0 | ||
|
911d4f9df2 | ||
|
990e7b5e1f | ||
|
d4c281ff17 | ||
|
80e1c7f0d4 | ||
|
d83196fb35 | ||
|
73be29db44 | ||
|
fd3a644289 | ||
|
3a8c3174a8 | ||
|
88593f9b8b | ||
|
6fbb13ba41 | ||
|
9a2395d40f | ||
|
f49bc8ebaa | ||
|
606f65496c | ||
|
9c672d8289 | ||
|
b4edcb9510 | ||
|
32e29d9340 | ||
|
5558db3019 | ||
|
082bea661d | ||
|
94794f7519 | ||
|
53e1e32409 | ||
|
23338b3f39 | ||
|
f41d6fad53 | ||
|
27ce314051 | ||
|
e68be39a41 | ||
|
edcd9b4ca9 | ||
|
566d9957a8 | ||
|
6a9c3d4dcd | ||
|
a79b1b9e82 | ||
|
411c684e6a | ||
|
e2a1f30b40 | ||
|
fd098ba12f | ||
|
7acf507826 | ||
|
ab84cb459a | ||
|
b46930394a | ||
|
f3404d841c | ||
|
083a9ce945 | ||
|
5c5ce2144d | ||
|
82268b9a69 | ||
|
fd5e79b991 | ||
|
3ef1486e79 | ||
|
186ed6fb07 | ||
|
fb13d52e7c | ||
|
7225ea6ac4 | ||
|
81d7ac1f59 | ||
|
a5ee3f50b6 | ||
|
d654f6e78f | ||
|
0fc3d533e6 | ||
|
320646c573 | ||
|
4e5b514315 | ||
|
cb131c2718 | ||
|
9701c6f0c3 | ||
|
a04fa57f86 | ||
|
be67eb123b | ||
|
0871dfe99a | ||
|
e9241a8462 | ||
|
f9fbc2cf41 | ||
|
13d8a3570b | ||
|
f861f2d438 | ||
|
296c375092 | ||
|
34ddd4a75c | ||
|
810eaeac25 | ||
|
9be3473864 | ||
|
91a16e4d9e | ||
|
4acc370dbf | ||
|
2b2a1cc0a2 | ||
|
749c23a6b5 | ||
|
359469c0a5 | ||
|
23d9783b26 | ||
|
be65279475 | ||
|
2105dbc379 | ||
|
db9667d0fb | ||
|
c32f655023 | ||
|
04cfe2a43e | ||
|
83837699e1 | ||
|
804acfbefa | ||
|
f0022e4280 | ||
|
90210fe588 | ||
|
7b9fe29cf3 | ||
|
18e4c072e7 | ||
|
a223570dbf | ||
|
0479a1b82e | ||
|
b2e587afa5 | ||
|
79e72fc8bf | ||
|
490c211361 | ||
|
9287e872f1 | ||
|
ce0431601a | ||
|
503c03caa2 | ||
|
bbd6f51586 | ||
|
ada340de94 | ||
|
01e57db5f1 | ||
|
585670d55c | ||
|
4e07fc2b31 | ||
|
e35a4e292d | ||
|
176b543069 | ||
|
744107035f | ||
|
b378a369d1 | ||
|
ee16112d29 | ||
|
23928b4041 | ||
|
66c57e8652 | ||
|
8c3d0c7957 | ||
|
b8e8c41f28 | ||
|
3ff2f28305 | ||
|
1349b6d282 | ||
|
d5fb619308 | ||
|
eecdad7ac8 | ||
|
8d3e301b55 | ||
|
4b92118f1f | ||
|
428ee718d3 | ||
|
d402903db5 | ||
|
4da2a9a496 | ||
|
dcec8d6e71 | ||
|
74f1936132 | ||
|
96c58db8e8 | ||
|
607f1bb26c | ||
|
bb0445d886 | ||
|
36e7736603 | ||
|
b6a39768a1 | ||
|
00c5af4256 | ||
|
c312bae516 | ||
|
0d8bb030d1 | ||
|
473b5679e2 | ||
|
a2f9012e13 | ||
|
841828eb48 | ||
|
fd129df163 | ||
|
45ae30fe88 | ||
|
ad50e59738 | ||
|
d4bc190dd4 | ||
|
8be79bb781 | ||
|
335c1444bd | ||
|
d078680bb6 | ||
|
2119e46701 | ||
|
07bfef1550 | ||
|
6e517a40f5 | ||
|
1ca356531e | ||
|
fbbfeaa977 | ||
|
c716467a7e | ||
|
047b94fbaa | ||
|
4f2b35872d | ||
|
f9322dfe6c | ||
|
6765c2294c | ||
|
a753485054 | ||
|
d5beb66508 | ||
|
3b5ee30e05 | ||
|
74c66d89ff | ||
|
84b565bec4 | ||
|
b90348e66b | ||
|
a021ada83f | ||
|
59e4875e6c | ||
|
1287454781 | ||
|
c156e33ad9 | ||
|
67fb546887 | ||
|
70275e3d56 | ||
|
23232f8aa3 | ||
|
fe4ee76ff9 | ||
|
3c35a87dee | ||
|
a3d7cfcf4a | ||
|
a9244b8ea4 | ||
|
814c86d078 | ||
|
5b9039d825 | ||
|
a33ba30092 | ||
|
dc772aae6b | ||
|
55cab29364 | ||
|
0cbf42e0ec | ||
|
8227834730 | ||
|
2a895383c9 | ||
|
d06a152c69 | ||
|
9744f8afbb | ||
|
2163d78126 | ||
|
0655b6389e | ||
|
2ed6c90e28 | ||
|
b36b61feb0 | ||
|
b2983ba025 | ||
|
c847896a15 | ||
|
42cdd34e59 | ||
|
cb4a0e2333 | ||
|
45ce045276 | ||
|
c2cba6eadd | ||
|
bb08fd2b42 | ||
|
4746e4a2be | ||
|
03c44244bf | ||
|
1a69d609d0 | ||
|
d052a64a47 | ||
|
7068d59f6a | ||
|
e31276199f | ||
|
4f55fbe4e4 | ||
|
8314077fe9 | ||
|
2965aa0d45 | ||
|
3be06e21aa | ||
|
62a7b1a6dd | ||
|
ac0ad3e7c3 | ||
|
76d8fa060c | ||
|
bf6d9f3531 | ||
|
48812b9bf2 | ||
|
3f43c061d7 | ||
|
ed97f94e2f | ||
|
b5b14e246b | ||
|
c3a7a11ae7 | ||
|
e86e5fd293 | ||
|
d64ee17c93 | ||
|
812c58f601 | ||
|
430d5cd3b9 | ||
|
3550f11726 | ||
|
49521078e5 | ||
|
a8a1c77343 | ||
|
50b12485a1 | ||
|
3ca7fe8bce | ||
|
8f4d3026cb | ||
|
8dbfd018a3 | ||
|
bfbc2fd09d | ||
|
0970558491 | ||
|
19789381df | ||
|
eb2324ed93 | ||
|
cf3cb6e03a | ||
|
013a7a4caf | ||
|
a8fa5dae1a | ||
|
bc1c47e81b | ||
|
926fbe5354 | ||
|
dfc40a2ea3 | ||
|
55327112a8 | ||
|
cccf4f440c | ||
|
216cd09635 | ||
|
6f10a6d9d7 | ||
|
14a58a7427 | ||
|
65f8bdfe31 | ||
|
56336d9d82 | ||
|
2aa1c8361a | ||
|
d326f99a36 | ||
|
cd5fb7add7 | ||
|
c00b25e89e | ||
|
22bff9e85b | ||
|
3f705650c0 | ||
|
a790c49348 | ||
|
9d36ae9cd5 | ||
|
59d17c236c | ||
|
30708b4553 | ||
|
7c6cebb6c3 | ||
|
c56b7a2903 | ||
|
899e571957 | ||
|
853e2bd9ff | ||
|
ec4dccb12b | ||
|
59839f1107 | ||
|
145ee3baa7 | ||
|
ec6f9e78b6 | ||
|
67b1752748 | ||
|
932780bcb5 | ||
|
a641b67edd | ||
|
631cdc62b3 | ||
|
7bc8c85626 | ||
|
0f53e9a0cb | ||
|
74a3920c0d | ||
|
f448ed5c51 | ||
|
05fb168e0b | ||
|
82a3aa90e0 | ||
|
42b5602692 | ||
|
a8604e3ff9 | ||
|
c99249a169 | ||
|
55d3f441be | ||
|
bfe3c26277 | ||
|
c827b4e582 | ||
|
124c415679 | ||
|
6ed1853320 |
249 changed files with 11146 additions and 4210 deletions
|
@ -31,9 +31,13 @@ Run `tools/release_tests.sh` on:
|
|||
- [ ] Kali
|
||||
- [ ] Debian Stable
|
||||
- [ ] Debian Testing
|
||||
- [ ] Ubuntu 22
|
||||
- [ ] Ubuntu 24.04 (LTS)
|
||||
- [ ] Ubuntu 24.10
|
||||
- [ ] Ubuntu 25.04
|
||||
- [ ] ParrotOS
|
||||
- [ ] Fedora 37
|
||||
- [ ] Fedora 41 (till 2025-11-19)
|
||||
- [ ] Fedora 42 (till 2026-05-13)
|
||||
- [ ] Fedora 43 (till 2026-12-02)
|
||||
- [ ] OpenSuse Leap
|
||||
- [ ] OpenSuse Tumbleweed
|
||||
- [ ] OSX (MacPorts)
|
||||
|
|
68
CHANGELOG.md
68
CHANGELOG.md
|
@ -2,11 +2,62 @@
|
|||
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...
|
||||
|
||||
## [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)
|
||||
- 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)
|
||||
- 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)
|
||||
- Updated aid and mad json files (@iceman1001)
|
||||
- Changed `hf 14a apdu` - now can be interrupted and dynamically adds time (@iceman1001)
|
||||
|
@ -40,7 +91,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- Changed `hf mf info` - now differentiates between full USCUID and cut down ZUID chips (@nvx)
|
||||
- Changed `lf hitag chk` - added key counter, client side abort and minor delay (@iceman1001)
|
||||
- Added `hf seos sam` - Added support for HID SAM SEOS communications (@jkramarz)
|
||||
- Changed (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 `lf em 410x sim` to use default gap value of 0 and extended help (@piotrva)
|
||||
- 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)
|
||||
- Fixed DESFire D40 secure channel crypto (@nvx)
|
||||
- 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 SPI flash detection to calculate the size instead of table lookup, updated spi_flash_decode.py script with more ICs (@ANTodorov)
|
||||
- Changed `hf_mf_ultimatecard` - it now automatically set maximum read/write block when using predefined types (@piotrva)
|
||||
- Changed SPI flash detection to calculate the size instead of table lookup (@ANTodorov)
|
||||
- Changed `spi_flash_decode.py` script with more ICs (@ANTodorov)
|
||||
- Fixed `hf/lf tune` segfault when called from script (@doegox)
|
||||
- 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 special iclass legacy config cards in `hf iclass configcard` (@antiklesys)
|
||||
- Added simulation function to `hf iclass legrec` (@antiklesys)
|
||||
- Changed `hf iclass configcard` - added special iclass legacy config cards (@antiklesys)
|
||||
- Changed `hf iclass legrec` - added simulation function (@antiklesys)
|
||||
- Added keys from Momentum firmware projects. (@onovy)
|
||||
- Added Dutch Statistics Agency default key (@eagle00789)
|
||||
- Fixed Wiegand decode with hex input dropping the first bit (@emilyastranova)
|
||||
|
|
16
Makefile
16
Makefile
|
@ -32,6 +32,9 @@ endif
|
|||
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfc_card_only/% mfc_card_reader/% mfd_aes_brute/% fpga_compress/% cryptorf/%
|
||||
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
|
||||
#all clean install uninstall check: %: hitag2crack/%
|
||||
clean: %: hitag2crack/%
|
||||
find . -type d -name __pycache__ -exec rm -rfv \{\} +
|
||||
|
||||
|
||||
INSTALLTOOLS=mfc/pm3_eml2lower.sh mfc/pm3_eml2upper.sh mfc/pm3_mfdread.py mfc/pm3_mfd2eml.py mfc/pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py
|
||||
INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt sim014.bin sim014.sha512.txt
|
||||
|
@ -204,7 +207,7 @@ help:
|
|||
@echo "+ fpga_compress - Make tools/fpga_compress"
|
||||
@echo
|
||||
@echo "+ style - Apply some automated source code formatting rules"
|
||||
@echo "+ commands - Regenerate commands documentation files and autocompletion data
|
||||
@echo "+ commands - Regenerate commands documentation files and autocompletion data"
|
||||
@echo "+ check - Run offline tests. Set CHECKARGS to pass arguments to the test script"
|
||||
@echo "+ .../check - Run offline tests against specific target. See above."
|
||||
@echo "+ miscchecks - Detect various encoding issues in source code"
|
||||
|
@ -264,8 +267,11 @@ ifeq ($(PLATFORM_CHANGED),true)
|
|||
$(Q)$(MAKE) --no-print-directory -C bootrom clean
|
||||
$(Q)$(MAKE) --no-print-directory -C armsrc clean
|
||||
$(Q)$(MAKE) --no-print-directory -C recovery clean
|
||||
$(Q)$(MAKE) --no-print-directory -C client clean
|
||||
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress clean
|
||||
# clean the client only if PLATFORM got changed from or to PM3ICOPYX
|
||||
ifeq (PM3ICOPYX,$(filter PM3ICOPYX, $(PLATFORM) $(CACHED_PLATFORM)))
|
||||
$(Q)$(MAKE) --no-print-directory -C client clean
|
||||
endif
|
||||
$(Q)$(ECHO) CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache
|
||||
$(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache
|
||||
$(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache
|
||||
|
@ -366,10 +372,12 @@ release:
|
|||
@echo "# - Release Tag: $(VERSION)"
|
||||
@echo "# - Release Name: $(RELEASE_NAME)"
|
||||
# - Removing -Werror...
|
||||
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
|
||||
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
|
||||
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" -or -path "./client/deps/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
|
||||
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" -or -path "./client/experimental_lib/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
|
||||
# - Changing banner...
|
||||
@sed -i "s/^#define BANNERMSG2 .*/#define BANNERMSG2 \" -----------------------------------\"/" client/src/proxmark3.c
|
||||
@sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c
|
||||
@echo -n "# ";grep "^#define BANNERMSG2" client/src/proxmark3.c
|
||||
@echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
|
||||
# - Committing temporarily...
|
||||
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"
|
||||
|
|
|
@ -112,8 +112,8 @@ ifeq ($(DEBUG),1)
|
|||
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
|
||||
DEFLDFLAGS =
|
||||
else
|
||||
DEFCXXFLAGS = -Wall -O3 -pipe
|
||||
DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe
|
||||
DEFCXXFLAGS = -Wall -Werror -O3 -pipe
|
||||
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
|
||||
DEFLDFLAGS =
|
||||
endif
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ PLATFORM=PM3RDV4
|
|||
#PLATFORM=PM3ICOPYX
|
||||
#PLATFORM_EXTRAS=FLASH
|
||||
|
||||
# For PM3 Ultimate:
|
||||
# uncomment the line below
|
||||
#PLATFORM=PM3ULTIMATE
|
||||
|
||||
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
|
||||
#PLATFORM_EXTRAS=BTADDON
|
||||
|
@ -27,6 +30,10 @@ PLATFORM=PM3RDV4
|
|||
# Only available with PLATFORM=PM3GENERIC
|
||||
#LED_ORDER=PM3EASY
|
||||
|
||||
# Uncomment a line below to change default USART baud rate
|
||||
# defaults to 115200 used by HC-05 in Blueshark
|
||||
#USART_BAUD_RATE=19200
|
||||
|
||||
# Uncomment the lines below in order to make a 256KB image
|
||||
# and comment out the lines above
|
||||
|
||||
|
|
|
@ -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**: see also [icopyx-community repos](https://github.com/iCopy-X-Community/) for upstream sources, reversed hw etc.
|
||||
- **Note**: Uses DRM to lock down tags, ignores the open source licences. Use on your own risk.
|
||||
- ⚠ Proxmark3 Ultimate
|
||||
- **Note**: unknown device hw
|
||||
- **Note**: FPGA images is building for it. Use on your own risk.
|
||||
|
||||
**Unknown support status**
|
||||
- ⚠ VX
|
||||
- **Note**: unknown device hw
|
||||
- ⚠ Proxmark3 Ultimate
|
||||
- **Note**: unknown device hw
|
||||
|
||||
|
||||
When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.
|
||||
|
||||
|
@ -180,10 +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.
|
||||
|
||||
|
||||
## Supported operative systems
|
||||
## Supported operating systems
|
||||
|
||||
This repo compiles nicely on
|
||||
- WSL1 on Windows 10
|
||||
- WSL2 on Windows 10/11
|
||||
- Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases)
|
||||
- Windows/MinGW environment
|
||||
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian
|
||||
|
|
|
@ -121,7 +121,7 @@ void BigBuf_Clear_ext(bool verbose) {
|
|||
memset(BigBuf, 0, s_bigbuf_size);
|
||||
clear_trace();
|
||||
if (verbose) {
|
||||
Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||
#define MAX_MIFARE_FRAME_SIZE 19 // biggest Mifare frame is UL AES answer to AUTH (1 + 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 19 parity bits for the 19 Byte above. 3 Bytes are enough to store these
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
// For now we're storing FM11RF08S nonces in the upper 1k of CARD_MEMORY_SIZE
|
||||
// but we might have to allocate extra space if one day we've to support sth like a FM11RF32S
|
||||
|
|
|
@ -186,7 +186,7 @@ showinfo:
|
|||
# version_pm3.c should be checked on every time fullimage.stage1.elf should be remade
|
||||
version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
|
||||
$(info [-] CHECK $@)
|
||||
$(Q)$(CP) $< $@
|
||||
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
|
||||
|
||||
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
|
||||
$(info [-] GEN $@)
|
||||
|
|
|
@ -119,6 +119,9 @@ define KNOWN_STANDALONE_DEFINITIONS
|
|||
| HF_REBLAY | 14A Relay over BT |
|
||||
| (RDV4 only) | - Salvador Mendoza |
|
||||
+----------------------------------------------------------+
|
||||
| HF_ST25_TEAROFF | Store/restore ST25TB tags with |
|
||||
| | tear-off for counters - SecLabz |
|
||||
+----------------------------------------------------------+
|
||||
| HF_TCPRST | IKEA Rothult read/sim/dump/emul |
|
||||
| | - Nick Draffen |
|
||||
+----------------------------------------------------------+
|
||||
|
@ -139,11 +142,11 @@ endef
|
|||
|
||||
STANDALONE_MODES := LF_SKELETON
|
||||
STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_MULTIHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE
|
||||
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_15SIM HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_UNISNIFF HF_YOUNG
|
||||
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_15SIM HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_ST25_TEAROFF HF_TCPRST HF_TMUDFORD HF_UNISNIFF HF_YOUNG
|
||||
STANDALONE_MODES += DANKARMULTI
|
||||
STANDALONE_MODES_REQ_BT := HF_CARDHOPPER HF_REBLAY
|
||||
STANDALONE_MODES_REQ_SMARTCARD :=
|
||||
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM
|
||||
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM HF_ST25_TEAROFF
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
|
||||
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)
|
||||
|
|
|
@ -157,6 +157,10 @@ endif
|
|||
ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS)))
|
||||
SRC_STANDALONE = hf_young.c
|
||||
endif
|
||||
# WITH_STANDALONE_HF_ST25_TEAROFF
|
||||
ifneq (,$(findstring WITH_STANDALONE_HF_ST25_TEAROFF,$(APP_CFLAGS)))
|
||||
SRC_STANDALONE = hf_st25_tearoff.c
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS)))
|
||||
SRC_STANDALONE = dankarmulti.c
|
||||
|
|
|
@ -157,7 +157,7 @@ void RunMod(void) {
|
|||
if (button_pressed != BUTTON_NO_CLICK || data_available())
|
||||
break;
|
||||
else if (state == STATE_SEARCH) {
|
||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, true)) {
|
||||
if (iso14443a_select_card(NULL, &card, NULL, true, 0, true) == 0) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelay(500);
|
||||
|
@ -246,7 +246,7 @@ void RunMod(void) {
|
|||
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||
|
||||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0);
|
||||
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0, false, false);
|
||||
|
||||
// Go back to search state if user presses pm3-button
|
||||
state = STATE_SEARCH;
|
||||
|
|
|
@ -59,7 +59,7 @@ static const uint8_t magicCARD[4] = "CARD";
|
|||
static const uint8_t magicEND [4] = "\xff" "END";
|
||||
static const uint8_t magicRSRT[7] = "RESTART";
|
||||
static const uint8_t magicERR [4] = "\xff" "ERR";
|
||||
static uint8_t magicACK [1] = "\xfe"; // is constant, but must be passed to API that doesn't like that
|
||||
static const uint8_t magicACK [1] = "\xfe";
|
||||
|
||||
// Forward declarations
|
||||
static void become_reader(void);
|
||||
|
@ -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 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 *);
|
||||
|
||||
|
@ -146,7 +146,7 @@ static void become_reader(void) {
|
|||
packet_t packet = { 0 };
|
||||
packet_t *rx = &packet;
|
||||
packet_t *tx = &packet;
|
||||
uint8_t toCard[256] = { 0 };
|
||||
uint8_t toCard[MAX_FRAME_SIZE] = { 0 };
|
||||
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
|
||||
|
||||
while (1) {
|
||||
|
@ -178,11 +178,15 @@ static void become_reader(void) {
|
|||
AddCrc14A(toCard, rx->len);
|
||||
ReaderTransmit(toCard, rx->len + 2, NULL);
|
||||
|
||||
tx->len = ReaderReceive(tx->dat, sizeof(tx->dat), parity);
|
||||
if (tx->len == 0) {
|
||||
// read to toCard instead of tx->dat directly to allow the extra byte for the CRC
|
||||
uint16_t fromCardLen = ReaderReceive(toCard, sizeof(toCard), parity);
|
||||
if (fromCardLen <= 2) {
|
||||
tx->len = sizeof(magicERR);
|
||||
memcpy(tx->dat, magicERR, sizeof(magicERR));
|
||||
} else tx->len -= 2; // cut off the CRC
|
||||
} else {
|
||||
tx->len = fromCardLen - 2; // cut off the CRC
|
||||
memcpy(tx->dat, toCard, tx->len);
|
||||
}
|
||||
|
||||
write_packet(tx);
|
||||
}
|
||||
|
@ -229,14 +233,15 @@ static void become_card(void) {
|
|||
|
||||
tag_response_info_t *canned;
|
||||
uint32_t cuid;
|
||||
uint32_t counters[3] = { 0 };
|
||||
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
|
||||
uint8_t pages;
|
||||
SimulateIso14443aInit(tagType, flags, data, 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");
|
||||
int fromReaderLen;
|
||||
uint8_t fromReaderDat[256] = { 0 };
|
||||
uint8_t fromReaderDat[MAX_FRAME_SIZE] = { 0 };
|
||||
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
|
||||
packet_t packet = { 0 };
|
||||
packet_t *tx = &packet;
|
||||
|
@ -277,8 +282,14 @@ static void become_card(void) {
|
|||
memcpy(tx->dat, fromReaderDat, tx->len);
|
||||
write_packet(tx);
|
||||
|
||||
if (no_reply) {
|
||||
// since the RATS reply has already been sent waiting here will can result in missing the next reader command
|
||||
// if we do get a reply later on while waiting for the next reader message it will be safely ignored
|
||||
continue;
|
||||
}
|
||||
|
||||
read_packet(rx);
|
||||
if (!no_reply && rx->len > 0) {
|
||||
if (rx->len > 0) {
|
||||
reply_with_packet(rx);
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +355,13 @@ static void cook_ats(packet_t *ats, uint8_t fwi, uint8_t sfgi) {
|
|||
|
||||
uint8_t orig_t0 = ats->dat[1];
|
||||
// Update FSCI in T0 from the received ATS
|
||||
t0 |= orig_t0 & 0x0F;
|
||||
uint8_t fsci = orig_t0 & 0x0F;
|
||||
if (fsci > 8) {
|
||||
// our packet length maxes out at 255 bytes, an FSCI of 8 requires 256 bytes
|
||||
// but since we drop the 2 byte CRC16 we're safe capping this at 8
|
||||
fsci = 8;
|
||||
}
|
||||
t0 |= fsci;
|
||||
|
||||
uint8_t len = ats->len - 2;
|
||||
uint8_t *orig_ats_ptr = &ats->dat[2];
|
||||
|
@ -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_modulationBuffer[1024] = { 0 };
|
||||
static uint8_t g_responseBuffer [MAX_FRAME_SIZE] = { 0 };
|
||||
|
||||
static void reply_with_packet(packet_t *packet) {
|
||||
tag_response_info_t response = { 0 };
|
||||
response.response = g_responseBuffer;
|
||||
response.modulation = g_modulationBuffer;
|
||||
|
||||
memcpy(response.response, packet->dat, packet->len);
|
||||
AddCrc14A(response.response, packet->len);
|
||||
response.response_n = packet->len + 2;
|
||||
|
||||
prepare_tag_modulation(&response, sizeof(g_modulationBuffer));
|
||||
EmSendPrecompiledCmd(&response);
|
||||
memcpy(g_responseBuffer, packet->dat, packet->len);
|
||||
AddCrc14A(g_responseBuffer, packet->len);
|
||||
EmSendCmd(g_responseBuffer, packet->len + 2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -496,19 +505,27 @@ static void read_packet(packet_t *packet) {
|
|||
|
||||
// clear any remaining buffered data
|
||||
while (cardhopper_data_available()) {
|
||||
cardhopper_read(packet->dat, 255);
|
||||
cardhopper_read(packet->dat, sizeof(packet->dat));
|
||||
}
|
||||
|
||||
packet->len = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet->len > (MAX_FRAME_SIZE - 2)) {
|
||||
// this will overrun MAX_FRAME_SIZE once we re-add the CRC
|
||||
// in theory this should never happen but better to be defensive
|
||||
packet->len = 0;
|
||||
cardhopper_write(magicERR, sizeof(magicERR));
|
||||
} else {
|
||||
cardhopper_write(magicACK, sizeof(magicACK));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void write_packet(packet_t *packet) {
|
||||
cardhopper_write((uint8_t *) packet, packet->len + 1);
|
||||
static void write_packet(const packet_t *packet) {
|
||||
cardhopper_write((const uint8_t *) packet, packet->len + 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -498,7 +498,7 @@ failtag:
|
|||
SpinOff(50);
|
||||
LED_A_ON();
|
||||
|
||||
while (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||
while (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
||||
WDT_HIT();
|
||||
if (BUTTON_HELD(10) == BUTTON_HOLD) {
|
||||
WDT_HIT();
|
||||
|
@ -785,7 +785,7 @@ static int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
|||
|
||||
bool isOK = true;
|
||||
|
||||
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
||||
isOK = false;
|
||||
}
|
||||
|
||||
|
@ -844,8 +844,7 @@ static int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTr
|
|||
for (uint8_t i = 0; i < keyCount; i++) {
|
||||
|
||||
/* no need for anticollision. just verify tag is still here */
|
||||
// if (!iso14443a_fast_select_card(colin_cjuid, 0)) {
|
||||
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
||||
cjSetCursLeft();
|
||||
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
|
||||
break;
|
||||
|
@ -963,7 +962,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, const
|
|||
|
||||
// get UID from chip
|
||||
if (workFlags & 0x01) {
|
||||
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
||||
DbprintfEx(FLAG_NEWLINE, "Can't select card");
|
||||
break;
|
||||
};
|
||||
|
|
|
@ -89,22 +89,22 @@ void RunMod(void) {
|
|||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||
if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 1k");
|
||||
SimulateIso14443aTag(1, flags, card.uid, 0, 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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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 {
|
||||
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
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "mifaresim.h" // mifare1ksim
|
||||
#include "mifareutil.h"
|
||||
#include "proxmark3_arm.h"
|
||||
#include "spiffs.h"
|
||||
#include "standalone.h" // standalone definitions
|
||||
#include "string.h"
|
||||
#include "ticks.h"
|
||||
|
@ -534,7 +535,14 @@ void RunMod(void) {
|
|||
SpinErr(LED_D, 50, 8);
|
||||
partialEmulation = true;
|
||||
} else {
|
||||
DbpString("[" _GREEN_("+") "] " _GREEN_("Emulator memory filled completely."));
|
||||
#ifdef WITH_FLASH
|
||||
DbpString("[" _GREEN_("+") "] " _GREEN_("Emulator memory filled completely. Start storing card in spiff memory."));
|
||||
uint8_t *emCARD = BigBuf_get_EM_addr();
|
||||
char dumpFileName[30] = {0};
|
||||
sprintf(dumpFileName, DUMP_FILE, mattyrun_card.uid[0], mattyrun_card.uid[1], mattyrun_card.uid[2], mattyrun_card.uid[3]);
|
||||
rdv40_spiffs_write(dumpFileName, emCARD, 1024, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
Dbprintf("[" _GREEN_("+") "] " _GREEN_("Stored card on %s"), dumpFileName);
|
||||
#endif
|
||||
}
|
||||
|
||||
state = STATE_EMULATE;
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
|
||||
// Filename to store the card info in spiff memory
|
||||
#define DUMP_FILE "hf_mattyrun_dump_%02x%02x%02x%02x.bin"
|
||||
|
||||
// Set of standard keys to be used
|
||||
static uint64_t const MATTYRUN_MFC_DEFAULT_KEYS[] = {
|
||||
0xFFFFFFFFFFFF, // Default key
|
||||
|
|
|
@ -379,7 +379,7 @@ void RunMod(void) {
|
|||
BigBuf_free_keep_EM();
|
||||
|
||||
// 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();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
DbpString(_RED_("Error initializing the emulation process!"));
|
||||
|
|
|
@ -268,7 +268,7 @@ void RunMod() {
|
|||
BigBuf_free_keep_EM();
|
||||
|
||||
// 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();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
DbpString(_RED_("Error initializing the emulation process!"));
|
||||
|
|
1170
armsrc/Standalone/hf_st25_tearoff.c
Normal file
1170
armsrc/Standalone/hf_st25_tearoff.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -118,8 +118,6 @@ void RunMod(void) {
|
|||
uint8_t tagType = 10; // 10 = ST25TA IKEA Rothult
|
||||
tag_response_info_t *responses;
|
||||
uint32_t cuid = 0;
|
||||
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
|
||||
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
|
||||
uint8_t pages = 0;
|
||||
|
||||
// command buffers
|
||||
|
@ -193,7 +191,7 @@ void RunMod(void) {
|
|||
|
||||
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();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
||||
|
@ -371,7 +369,7 @@ void RunMod(void) {
|
|||
|
||||
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();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
||||
|
|
|
@ -96,7 +96,7 @@ void RunMod(void) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true)) {
|
||||
if (iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true) == 0) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelay(500);
|
||||
|
@ -253,25 +253,25 @@ void RunMod(void) {
|
|||
|
||||
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
|
||||
DbpString("Mifare Classic 1k");
|
||||
SimulateIso14443aTag(1, flags, data, 0, 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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
||||
SimulateIso14443aTag(3, flags, data, 0, NULL, 0);
|
||||
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
|
||||
} else {
|
||||
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
||||
SimulateIso14443aTag(1, flags, data, 0, NULL, 0);
|
||||
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
|
||||
}
|
||||
|
||||
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
||||
|
|
|
@ -99,12 +99,13 @@ int tearoff_hook(void) {
|
|||
if (g_tearoff_enabled) {
|
||||
if (g_tearoff_delay_us == 0) {
|
||||
Dbprintf(_RED_("No tear-off delay configured!"));
|
||||
g_tearoff_enabled = false;
|
||||
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
|
||||
}
|
||||
SpinDelayUsPrecision(g_tearoff_delay_us);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
g_tearoff_enabled = false;
|
||||
Dbprintf(_YELLOW_("Tear-off triggered!"));
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf(_YELLOW_("Tear-off triggered!"));
|
||||
return PM3_ETEAROFF;
|
||||
} else {
|
||||
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
|
||||
|
@ -254,7 +255,7 @@ static uint32_t MeasureAntennaTuningLfData(void) {
|
|||
void print_stack_usage(void) {
|
||||
for (uint32_t *p = _stack_start; ; ++p) {
|
||||
if (*p != 0xdeadbeef) {
|
||||
Dbprintf(" Max stack usage......... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
|
||||
Dbprintf(" Max stack usage..... %d / %d bytes", (uint32_t)_stack_end - (uint32_t)p, (uint32_t)_stack_end - (uint32_t)_stack_start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -365,7 +366,7 @@ static void print_debug_level(void) {
|
|||
sprintf(dbglvlstr, "extended");
|
||||
break;
|
||||
}
|
||||
Dbprintf(" Debug log level......... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
|
||||
Dbprintf(" Debug log level..... %d ( " _YELLOW_("%s")" )", g_dbglevel, dbglvlstr);
|
||||
}
|
||||
|
||||
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
|
||||
|
@ -421,11 +422,11 @@ static void SendStatus(uint32_t wait) {
|
|||
print_debug_level();
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
Dbprintf(" ToSendMax............... %d", ts->max);
|
||||
Dbprintf(" ToSend BUFFERSIZE....... %d", TOSEND_BUFFER_SIZE);
|
||||
Dbprintf(" ToSendMax........... %d", ts->max);
|
||||
Dbprintf(" ToSend BUFFERSIZE... %d", TOSEND_BUFFER_SIZE);
|
||||
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
|
||||
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks
|
||||
Dbprintf(" Slow clock.............. %d Hz", (16 * MAINCK) / mainf);
|
||||
Dbprintf(" Slow clock.......... %d Hz", (16 * MAINCK) / mainf);
|
||||
uint32_t delta_time = 0;
|
||||
uint32_t start_time = GetTickCount();
|
||||
#define SLCK_CHECK_MS 50
|
||||
|
@ -449,10 +450,11 @@ static void SendStatus(uint32_t wait) {
|
|||
} else {
|
||||
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 {
|
||||
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)) {
|
||||
|
@ -460,10 +462,11 @@ static void SendStatus(uint32_t wait) {
|
|||
} else {
|
||||
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 {
|
||||
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)) {
|
||||
|
@ -471,11 +474,38 @@ static void SendStatus(uint32_t wait) {
|
|||
} else {
|
||||
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 {
|
||||
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
|
||||
DbpString("");
|
||||
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
|
||||
|
@ -1664,13 +1694,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_GET_CONFIG: {
|
||||
hf14a_config *hf14aconfig = getHf14aConfig();
|
||||
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)hf14aconfig, sizeof(hf14a_config));
|
||||
hf14a_config_t *c = getHf14aConfig();
|
||||
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(hf14a_config_t));
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_SET_CONFIG: {
|
||||
hf14a_config c;
|
||||
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config));
|
||||
hf14a_config_t c;
|
||||
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config_t));
|
||||
setHf14aConfig(&c);
|
||||
break;
|
||||
}
|
||||
|
@ -1719,10 +1749,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
uint8_t uid[10];
|
||||
uint8_t exitAfter;
|
||||
uint8_t rats[20];
|
||||
bool ulc_p1;
|
||||
bool ulc_p2;
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid,
|
||||
payload->exitAfter, 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;
|
||||
}
|
||||
case CMD_HF_ISO14443A_SIM_AID: {
|
||||
|
@ -1806,7 +1839,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
struct p {
|
||||
bool turn_off_field;
|
||||
uint8_t keyno;
|
||||
uint8_t key[18];
|
||||
uint8_t key[16];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
MifareUL_AES_Auth(payload->turn_off_field, payload->keyno, payload->key);
|
||||
|
@ -1969,7 +2002,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
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) {
|
||||
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
|
||||
return;
|
||||
|
@ -2226,6 +2259,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
iclass_credit_epurse((iclass_credit_epurse_t *)packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_TEARBL: {
|
||||
iClass_TearBlock((iclass_tearblock_req_t *)packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_HFSNIFF
|
||||
|
@ -2354,7 +2391,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
|
||||
uint16_t available;
|
||||
uint16_t pre_available = 0;
|
||||
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
|
||||
uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
|
||||
uint32_t wait = payload->waittime;
|
||||
|
||||
StartTicks();
|
||||
|
@ -2398,7 +2435,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
|
||||
uint16_t available;
|
||||
uint16_t pre_available = 0;
|
||||
uint8_t *dest = BigBuf_malloc(USART_FIFOLEN);
|
||||
uint8_t *dest = BigBuf_calloc(USART_FIFOLEN);
|
||||
uint32_t wait = payload->waittime;
|
||||
|
||||
StartTicks();
|
||||
|
@ -2694,7 +2731,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
|
||||
uint32_t size = packet->oldarg[1];
|
||||
|
||||
uint8_t *buff = BigBuf_malloc(size);
|
||||
uint8_t *buff = BigBuf_calloc(size);
|
||||
if (buff == NULL) {
|
||||
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Failed to allocate memory");
|
||||
// Trigger a finish downloading signal with an PM3_EMALLOC
|
||||
|
@ -2899,7 +2936,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
case CMD_FLASHMEM_DOWNLOAD: {
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *mem = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||
uint8_t *mem = BigBuf_calloc(PM3_CMD_DATA_SIZE);
|
||||
uint32_t startidx = packet->oldarg[0];
|
||||
uint32_t numofbytes = packet->oldarg[1];
|
||||
// arg0 = startindex
|
||||
|
@ -2931,7 +2968,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
case CMD_FLASHMEM_INFO: {
|
||||
|
||||
LED_B_ON();
|
||||
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
|
||||
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_calloc(sizeof(rdv40_validation_t));
|
||||
|
||||
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
|
||||
|
||||
|
|
|
@ -102,9 +102,7 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
void print_result(const char *name, const uint8_t *d, size_t
|
||||
|
||||
n) {
|
||||
void print_result(const char *name, const uint8_t *d, size_t n) {
|
||||
|
||||
const uint8_t *p = d;
|
||||
uint16_t tmp = n & 0xFFF0;
|
||||
|
|
|
@ -748,7 +748,7 @@ void em4x50_chk(const char *filename, bool ledcontrol) {
|
|||
uint16_t pwd_count = 0;
|
||||
uint32_t size = size_in_spiffs(filename);
|
||||
pwd_count = size / 4;
|
||||
uint8_t *pwds = BigBuf_malloc(size);
|
||||
uint8_t *pwds = BigBuf_calloc(size);
|
||||
|
||||
rdv40_spiffs_read_as_filetype(filename, pwds, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#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);
|
||||
// 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 };
|
||||
|
||||
|
||||
|
@ -905,8 +905,7 @@ static bool create_legacy_em4x70_bitstream_for_cmd_id(em4x70_command_bitstream_t
|
|||
bool result = true;
|
||||
memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t));
|
||||
out_cmd_bitstream->command = EM4X70_COMMAND_ID;
|
||||
//uint8_t cmd = with_command_parity ? 0x3u : 0x1u;
|
||||
uint8_t cmd = 0x3u;
|
||||
uint8_t cmd = 0x3u; // CMD + Parity bit == 0b001'1
|
||||
result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false);
|
||||
out_cmd_bitstream->to_receive.bitcount = 32;
|
||||
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;
|
||||
memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t));
|
||||
out_cmd_bitstream->command = EM4X70_COMMAND_UM1;
|
||||
//uint8_t cmd = with_command_parity ? 0x5u : 0x2u;
|
||||
uint8_t cmd = 0x5u;
|
||||
uint8_t cmd = 0x5u; // CMD + Parity bit == 0b010'1
|
||||
result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false);
|
||||
out_cmd_bitstream->to_receive.bitcount = 32;
|
||||
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;
|
||||
memset(out_cmd_bitstream, 0, sizeof(em4x70_command_bitstream_t));
|
||||
out_cmd_bitstream->command = EM4X70_COMMAND_UM2;
|
||||
//uint8_t cmd = with_command_parity ? 0xFu : 0x7u;
|
||||
uint8_t cmd = 0xFu;
|
||||
uint8_t cmd = 0xFu; // CMD + Parity bit == 0b111'1
|
||||
result = result && add_nibble_to_bitstream(&out_cmd_bitstream->to_send, cmd, false);
|
||||
out_cmd_bitstream->to_receive.bitcount = 64;
|
||||
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;
|
||||
|
||||
// uint8_t cmd = with_command_parity ? 0x6u : 0x3u;
|
||||
uint8_t cmd = 0x6u; // HACK - always sent with cmd parity
|
||||
uint8_t cmd = 0x6u; // CMD + Parity bit == 0b011'0
|
||||
result = result && add_nibble_to_bitstream(s, cmd, false);
|
||||
|
||||
// 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;
|
||||
|
||||
//uint8_t cmd = with_command_parity ? 0x9u : 0x4u;
|
||||
uint8_t cmd = 0x9u; // HACK - always sent with cmd parity, with extra zero bit in RM?
|
||||
uint8_t cmd = 0x9u; // CMD + Parity bit == 0b100'1
|
||||
result = result && add_nibble_to_bitstream(s, cmd, false);
|
||||
|
||||
// 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;
|
||||
|
||||
//uint8_t cmd = with_command_parity ? 0xAu : 0x5u;
|
||||
uint8_t cmd = 0xAu; // HACK - always sent with cmd parity, with extra zero bit in RM?
|
||||
uint8_t cmd = 0xAu; // CMD + Parity bit == 0b101'0
|
||||
result = result && add_nibble_to_bitstream(s, cmd, false);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
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) {
|
||||
em4x70_command_bitstream_t send_pin_cmd;
|
||||
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);
|
||||
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;
|
||||
|
||||
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);
|
||||
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) {
|
||||
em4x70_command_bitstream_t read_id_cmd;
|
||||
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);
|
||||
if (result) {
|
||||
|
@ -1300,7 +1294,7 @@ static bool em4x70_read_id(void) {
|
|||
static bool em4x70_read_um1(void) {
|
||||
em4x70_command_bitstream_t read_um1_cmd;
|
||||
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);
|
||||
if (result) {
|
||||
|
@ -1319,7 +1313,7 @@ static bool em4x70_read_um1(void) {
|
|||
static bool em4x70_read_um2(void) {
|
||||
em4x70_command_bitstream_t read_um2_cmd;
|
||||
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);
|
||||
if (result) {
|
||||
|
@ -1435,7 +1429,7 @@ void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
bool success_with_UM2 = false;
|
||||
|
||||
// Support tags with and without command parity bits
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
init_tag();
|
||||
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) {
|
||||
int status = PM3_ESOFT;
|
||||
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
// 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."));
|
||||
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
|
||||
// return;
|
||||
|
@ -1499,7 +1493,7 @@ void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
|
||||
int status = PM3_ESOFT;
|
||||
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
init_tag();
|
||||
em4x70_setup_read();
|
||||
|
@ -1534,10 +1528,10 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
|
||||
uint8_t response[3] = {0};
|
||||
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
// 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."));
|
||||
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
|
||||
// return;
|
||||
|
@ -1562,10 +1556,10 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
int status = PM3_ESOFT;
|
||||
uint8_t response[2] = {0};
|
||||
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
// 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."));
|
||||
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
|
||||
// return;
|
||||
|
@ -1590,10 +1584,10 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
|
||||
int status = PM3_ESOFT;
|
||||
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
// 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."));
|
||||
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
|
||||
// return;
|
||||
|
@ -1639,10 +1633,10 @@ void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
|
||||
int status = PM3_ESOFT;
|
||||
|
||||
g_command_parity = etd->parity;
|
||||
g_deprecated_command_parity = false;
|
||||
|
||||
// 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."));
|
||||
// reply_ng(CMD_LF_EM4X70_WRITE, PM3_ENOTIMPL, NULL, 0);
|
||||
// return;
|
||||
|
|
|
@ -857,7 +857,7 @@ void SmartCardRaw(const smart_card_raw_t *p) {
|
|||
LED_D_ON();
|
||||
|
||||
uint16_t len = 0;
|
||||
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
// check if alloacted...
|
||||
smartcard_command_t flags = p->flags;
|
||||
|
||||
|
@ -937,7 +937,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
|||
bool isOK = true;
|
||||
uint16_t length = arg0, pos = 0;
|
||||
const uint8_t *fwdata = BigBuf_get_addr();
|
||||
uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE);
|
||||
uint8_t *verfiydata = BigBuf_calloc(I2C_BLOCK_SIZE);
|
||||
|
||||
while (length) {
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
// 8051 speaks with smart card.
|
||||
// 1000*50*3.07 = 153.5ms
|
||||
// 1 byte transfer == 1ms with max frame being 256 bytes
|
||||
#define SIM_WAIT_DELAY 88000 // about 270ms delay // 109773 -- about 337.7ms delay
|
||||
#define SIM_WAIT_DELAY 150000 // about 270ms delay // 109773 -- about 337.7ms delay
|
||||
|
||||
|
||||
void I2C_recovery(void);
|
||||
|
|
|
@ -40,7 +40,7 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
|||
LED_D_ON();
|
||||
|
||||
uint16_t len = 0;
|
||||
uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *resp = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
resp[0] = prepend;
|
||||
// check if alloacted...
|
||||
smartcard_command_t flags = p->flags;
|
||||
|
|
968
armsrc/iclass.c
968
armsrc/iclass.c
File diff suppressed because it is too large
Load diff
|
@ -34,6 +34,7 @@
|
|||
// times in samples @ 212kHz when acting as reader
|
||||
#define ICLASS_READER_TIMEOUT_ACTALL 330 // 1558us, nominal 330us + 7slots*160us = 1450us
|
||||
#define ICLASS_READER_TIMEOUT_UPDATE 3390 // 16000us, nominal 4-15ms
|
||||
#define ICLASS_READER_TIMEOUT_UPDATE_FAST 1500 // A copy of ICLASS_READER_TIMEOUT_UPDATE with reduced timeout values
|
||||
#define ICLASS_READER_TIMEOUT_OTHERS 80 // 380us, nominal 330us
|
||||
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
|
@ -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_Recover(iclass_recover_req_t *msg);
|
||||
void iClass_TearBlock(iclass_tearblock_req_t *msg);
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -125,8 +125,8 @@ typedef enum {
|
|||
#endif
|
||||
|
||||
void printHf14aConfig(void);
|
||||
void setHf14aConfig(const hf14a_config *hc);
|
||||
hf14a_config *getHf14aConfig(void);
|
||||
void setHf14aConfig(const hf14a_config_t *hc);
|
||||
hf14a_config_t *getHf14aConfig(void);
|
||||
void iso14a_set_timeout(uint32_t timeout);
|
||||
uint32_t iso14a_get_timeout(void);
|
||||
|
||||
|
@ -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 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,
|
||||
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,
|
||||
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);
|
||||
void iso14443a_antifuzz(uint32_t flags);
|
||||
void ReaderIso14443a(PacketCommandNG *c);
|
||||
void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
|
||||
void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
|
||||
void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
|
||||
void ReaderTransmit(const uint8_t *frame, uint16_t len, uint32_t *timing);
|
||||
void ReaderTransmitBitsPar(const uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
|
||||
void ReaderTransmitPar(const uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
|
||||
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_maxlen, uint8_t *par);
|
||||
|
||||
void iso14443a_setup(uint8_t fpga_minor_mode);
|
||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res);
|
||||
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
|
||||
int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats, iso14a_polling_parameters_t *polling_parameters);
|
||||
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
|
||||
int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr,
|
||||
bool anticollision, uint8_t num_cascades, bool no_rats,
|
||||
const iso14a_polling_parameters_t *polling_parameters, bool force_rats);
|
||||
int iso14443a_select_card_for_magic(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
|
||||
int iso14443a_fast_select_card(const uint8_t *uid_ptr, uint8_t num_cascades);
|
||||
void iso14a_set_trigger(bool enable);
|
||||
|
||||
int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen);
|
||||
|
@ -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_tag_modulation(tag_response_info_t *response_info, size_t max_buffer_size);
|
||||
|
||||
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
|
||||
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
||||
bool EmLogTrace(const uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime,
|
||||
uint32_t reader_EndTime, const uint8_t *reader_Parity, const uint8_t *tag_data,
|
||||
uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, const uint8_t *tag_Parity);
|
||||
|
||||
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
|
||||
void DetectNACKbug(void);
|
||||
|
|
|
@ -1585,7 +1585,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len, bool framing) {
|
|||
/*
|
||||
* Convenience function to encode, transmit and trace iso 14443b comms
|
||||
*/
|
||||
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) {
|
||||
void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) {
|
||||
const tosend_t *ts = get_tosend();
|
||||
CodeIso14443bAsReader(cmd, len, framing);
|
||||
TransmitFor14443b_AsReader(start_time);
|
||||
|
@ -1800,7 +1800,7 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
|
|||
/**
|
||||
* SRx Initialise.
|
||||
*/
|
||||
static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
||||
int iso14443b_select_srx_card(iso14b_card_select_t *card) {
|
||||
// INITIATE command: wake up the tag using the INITIATE
|
||||
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
|
||||
uint8_t r_init[3] = { 0x00 };
|
||||
|
@ -2135,6 +2135,9 @@ static int iso14443b_select_picopass_card(picopass_hdr_t *hdr) {
|
|||
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
|
||||
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY };
|
||||
static uint8_t read_conf[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x01, 0xfa, 0x22 };
|
||||
|
||||
// ICLASS_CMD_SELECT 0x81 tells ISO14443b/BPSK coding/106 kbits/s
|
||||
// ICLASS_CMD_SELECT 0x41 tells ISO14443b/BPSK coding/423 kbits/s
|
||||
uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t read_aia[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x05, 0xde, 0x64};
|
||||
uint8_t read_check_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
|
||||
|
@ -2307,7 +2310,7 @@ void iso14443b_setup(void) {
|
|||
//
|
||||
// I tried to be systematic and check every answer of the tag, every CRC, etc...
|
||||
//-----------------------------------------------------------------------------
|
||||
static int read_14b_srx_block(uint8_t blocknr, uint8_t *block) {
|
||||
int read_14b_srx_block(uint8_t blocknr, uint8_t *block) {
|
||||
|
||||
uint8_t cmd[] = {ISO14443B_READ_BLK, blocknr, 0x00, 0x00};
|
||||
AddCrc14B(cmd, 2);
|
||||
|
|
|
@ -45,8 +45,11 @@ int iso14443b_select_card(iso14b_card_select_t *card);
|
|||
|
||||
void SimulateIso14443bTag(const uint8_t *pupi);
|
||||
void read_14b_st_block(uint8_t blocknr);
|
||||
int read_14b_srx_block(uint8_t blocknr, uint8_t *block);
|
||||
int iso14443b_select_srx_card(iso14b_card_select_t *card);
|
||||
void SniffIso14443b(void);
|
||||
void SendRawCommand14443B(iso14b_raw_cmd_t *p);
|
||||
void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing);
|
||||
|
||||
// States for 14B SIM command
|
||||
#define SIM_POWER_OFF 0
|
||||
|
|
|
@ -985,10 +985,11 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
|||
DecodeTagFSK_t dtfm = { 0 };
|
||||
DecodeTagFSK_t *dtf = &dtfm;
|
||||
|
||||
if (fsk)
|
||||
if (fsk) {
|
||||
DecodeTagFSKInit(dtf, response, max_len);
|
||||
else
|
||||
} else {
|
||||
DecodeTagInit(dt, response, max_len);
|
||||
}
|
||||
|
||||
// wait for last transfer to complete
|
||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
|
||||
|
@ -1014,8 +1015,9 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
|||
for (;;) {
|
||||
|
||||
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
|
||||
if (behindBy == 0)
|
||||
if (behindBy == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
samples++;
|
||||
if (samples == 1) {
|
||||
|
@ -2657,7 +2659,7 @@ void BruteforceIso15693Afi(uint32_t flags) {
|
|||
Dbprintf("AFI = %i UID = %s", i, iso15693_sprintUID(NULL, recv + 2));
|
||||
}
|
||||
|
||||
aborted = (BUTTON_PRESS() && data_available());
|
||||
aborted = (BUTTON_PRESS() || data_available());
|
||||
if (aborted) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -236,8 +236,13 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) {
|
|||
FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
|
||||
|
||||
// When in reader mode, give the field a bit of time to settle.
|
||||
// 313T0 = 313 * 8us = 2504us = 2.5ms Hitag2 tags needs to be fully powered.
|
||||
SpinDelay(10);
|
||||
// Optimal timing window for LF ADC measurements to be performed:
|
||||
// minimum: 313T0 = 313 * 8us = 2504us = 2.50ms - Hitag2 tag internal powerup time
|
||||
// 280T0 = 280 * 8us = 2240us = 2.24ms - HitagS minimum time before the first command (powerup time)
|
||||
// maximum: 545T0 = 545 * 8us = 4360us = 4.36ms - Hitag2 command waiting time before it starts transmitting in public mode (if configured so)
|
||||
// 565T0 = 565 * 8us = 4520us = 4.52ms - HitagS waiting time before entering TTF mode (if configured so)
|
||||
// Thus (2.50 ms + 4.36 ms) / 2 ~= 3 ms (rounded down to integer), should be a good timing for both tag models
|
||||
SpinDelay(3);
|
||||
|
||||
// Steal this pin from the SSP (SPI communication channel with fpga) and use it to control the modulation
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
|
|
|
@ -83,14 +83,14 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
|
|||
break;
|
||||
}
|
||||
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");
|
||||
return false;
|
||||
};
|
||||
break;
|
||||
}
|
||||
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");
|
||||
return false;
|
||||
};
|
||||
|
@ -274,7 +274,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) {
|
|||
return;
|
||||
};
|
||||
|
||||
if (!mifare_ultra_auth(keybytes)) {
|
||||
if (mifare_ultra_auth(keybytes) == 0) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
|
||||
OnError(1);
|
||||
return;
|
||||
|
@ -304,7 +304,7 @@ void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes) {
|
|||
return;
|
||||
};
|
||||
|
||||
if (!mifare_ultra_aes_auth(keyno, keybytes)) {
|
||||
if (mifare_ultra_aes_auth(keyno, keybytes) == 0) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
|
||||
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
|
||||
return;
|
||||
|
@ -344,7 +344,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
|||
uint8_t key[16] = {0x00};
|
||||
memcpy(key, datain, sizeof(key));
|
||||
|
||||
if (!mifare_ultra_auth(key)) {
|
||||
if (mifare_ultra_auth(key) == 0) {
|
||||
OnError(1);
|
||||
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
|
||||
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) {
|
||||
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 {
|
||||
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
|
||||
datain = dictkeys;
|
||||
keyCount = key_mem_available;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2908,7 +2909,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
|||
}
|
||||
|
||||
// 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");
|
||||
errormsg = 0;
|
||||
break;
|
||||
|
@ -3021,9 +3022,10 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
|
|||
|
||||
// reset card
|
||||
mf_reset_card();
|
||||
|
||||
res = iso14443a_select_card(uid, card, &cuid, true, 0, false);
|
||||
// Use special magic detection function that always attempts RATS regardless of SAK
|
||||
res = iso14443a_select_card_for_magic(uid, card, &cuid, true, 0);
|
||||
if (res) {
|
||||
mf_reset_card();
|
||||
if (cuid == 0xAA55C396) {
|
||||
flag |= MAGIC_FLAG_GEN_UNFUSED;
|
||||
}
|
||||
|
@ -3219,7 +3221,7 @@ void MifareHasStaticNonce(void) {
|
|||
}
|
||||
|
||||
if (counter) {
|
||||
Dbprintf("Static nonce......... " _YELLOW_("%08x"), nt);
|
||||
Dbprintf("Static nonce....... " _YELLOW_("%08x"), nt);
|
||||
data[0] = NONCE_STATIC;
|
||||
} else {
|
||||
data[0] = NONCE_NORMAL;
|
||||
|
@ -3514,7 +3516,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
|
|||
|
||||
int retval = PM3_SUCCESS;
|
||||
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);
|
||||
|
||||
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;
|
||||
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");
|
||||
retval = PM3_ESOFT;
|
||||
goto OUT;
|
||||
|
@ -3560,13 +3562,13 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
|
|||
AddCrc14A(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE);
|
||||
|
||||
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;
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
|
||||
retval = DoGen3Cmd(cmd, sizeof(block_cmd) + MAX_MIFARE_FRAME_SIZE);
|
||||
retval = DoGen3Cmd(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE + CRC16_SIZE);
|
||||
}
|
||||
|
||||
OUT:
|
||||
|
|
|
@ -60,7 +60,7 @@ bool InitDesfireCard(void) {
|
|||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(true);
|
||||
|
||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||
if (iso14443a_select_card(NULL, &card, NULL, true, 0, false) == 0) {
|
||||
if (g_dbglevel >= DBG_ERROR) DbpString("Can't select card");
|
||||
OnError(1);
|
||||
return false;
|
||||
|
@ -157,7 +157,7 @@ void MifareDesfireGetInformation(void) {
|
|||
pcb_blocknum = 0;
|
||||
|
||||
// card select - information
|
||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||
if (iso14443a_select_card(NULL, &card, NULL, true, 0, false) == 0) {
|
||||
if (g_dbglevel >= DBG_ERROR) {
|
||||
DbpString("Can't select card");
|
||||
}
|
||||
|
|
|
@ -579,21 +579,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
|||
counter++;
|
||||
}
|
||||
|
||||
/*
|
||||
// find reader field
|
||||
if (cardSTATE == MFEMUL_NOFIELD) {
|
||||
|
||||
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||
|
||||
if (vHf > MF_MINFIELDV) {
|
||||
cardSTATE_TO_IDLE();
|
||||
LED_A_ON();
|
||||
}
|
||||
button_pushed = BUTTON_PRESS();
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
FpgaEnableTracing();
|
||||
//Now, get data
|
||||
int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par);
|
||||
|
@ -760,10 +745,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
|||
// WORK
|
||||
case MFEMUL_WORK: {
|
||||
|
||||
if (g_dbglevel >= DBG_EXTENDED) {
|
||||
// Dbprintf("[MFEMUL_WORK] Enter in case");
|
||||
}
|
||||
|
||||
if (receivedCmd_len == 0) {
|
||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
||||
break;
|
||||
|
@ -1039,8 +1020,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
|||
}
|
||||
}
|
||||
AddCrc14A(response, MIFARE_BLOCK_SIZE);
|
||||
mf_crypto1_encrypt(pcs, response, MAX_MIFARE_FRAME_SIZE, response_par);
|
||||
EmSendCmdPar(response, MAX_MIFARE_FRAME_SIZE, response_par);
|
||||
mf_crypto1_encrypt(pcs, response, MIFARE_BLOCK_SIZE + CRC16_SIZE, response_par);
|
||||
EmSendCmdPar(response, MIFARE_BLOCK_SIZE + CRC16_SIZE, response_par);
|
||||
FpgaDisableTracing();
|
||||
|
||||
if (g_dbglevel >= DBG_EXTENDED) {
|
||||
|
@ -1052,7 +1033,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
|||
numReads++;
|
||||
|
||||
if (exitAfterNReads > 0 && numReads == exitAfterNReads) {
|
||||
Dbprintf("[MFEMUL_WORK] %d reads done, exiting", numReads);
|
||||
Dbprintf("[MFEMUL_WORK] " _YELLOW_("%u") " reads done, exiting", numReads);
|
||||
finished = true;
|
||||
}
|
||||
break;
|
||||
|
@ -1309,7 +1290,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
|||
// WRITE BL2
|
||||
case MFEMUL_WRITEBL2: {
|
||||
|
||||
if (receivedCmd_len == MAX_MIFARE_FRAME_SIZE) {
|
||||
if (receivedCmd_len == MIFARE_BLOCK_SIZE + CRC16_SIZE) {
|
||||
|
||||
mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, receivedCmd_dec);
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
|
|||
uint16_t pos;
|
||||
uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
|
||||
uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t par[1] = {0x00}; // 1 Byte parity is enough here
|
||||
uint8_t par[MAX_MIFARE_PARITY_SIZE] = {0x00}; // used for cmd and answer
|
||||
AddCrc14A(dcmd, 2);
|
||||
memcpy(ecmd, dcmd, sizeof(dcmd));
|
||||
|
||||
|
@ -440,21 +440,17 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
|
|||
uint8_t key[16] = { 0 };
|
||||
memcpy(key, keybytes, sizeof(key));
|
||||
|
||||
uint16_t len = 0;
|
||||
|
||||
// 1 cmd + 16 bytes + 2 crc
|
||||
uint8_t resp[19] = {0x00};
|
||||
uint8_t respPar[5] = {0};
|
||||
|
||||
|
||||
// setup AES
|
||||
mbedtls_aes_context actx;
|
||||
mbedtls_aes_init(&actx);
|
||||
mbedtls_aes_init(&actx);
|
||||
mbedtls_aes_setkey_dec(&actx, key, 128);
|
||||
|
||||
// Send REQUEST AUTHENTICATION / receive tag nonce
|
||||
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, sizeof(resp), respPar, NULL);
|
||||
uint16_t len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, sizeof(resp), respPar, NULL);
|
||||
if (len != 19) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
|
||||
return 0;
|
||||
|
|
|
@ -218,17 +218,19 @@ out:
|
|||
*
|
||||
* @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;
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
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;
|
||||
|
||||
uint8_t payload[] = {
|
||||
0xa0, 0x02, // <- SAM command
|
||||
0xa0, // <- SAM command
|
||||
0x02, // <- Length
|
||||
0x82, 0x00 // <- get version
|
||||
};
|
||||
uint16_t payload_len = sizeof(payload);
|
||||
|
@ -252,8 +254,9 @@ int sam_get_version(void) {
|
|||
// 82 01
|
||||
// 01
|
||||
// 90 00
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_get_version");
|
||||
}
|
||||
|
||||
if (response[5] != 0xbd) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
uint8_t *sam_build_an = sam_find_asn1_node(sam_response_an, 0x81);
|
||||
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;
|
||||
}
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
DbpString("SAM get version successful");
|
||||
Dbprintf("Firmware version: %X.%X", sam_version_an[2], sam_version_an[3]);
|
||||
Dbprintf("Firmware ID: ");
|
||||
if (g_dbglevel >= DBG_INFO || info) {
|
||||
DbpString(_BLUE_("-- SAM Information --"));
|
||||
Dbprintf(_YELLOW_("Firmware version: ")"%d.%d", sam_version_an[2], sam_version_an[3]);
|
||||
Dbprintf(_YELLOW_("Firmware ID: "));
|
||||
Dbhexdump(sam_build_an[1], sam_build_an + 2, false);
|
||||
}
|
||||
goto out;
|
||||
|
@ -289,8 +292,79 @@ error:
|
|||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_get_version");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int sam_get_serial_number(void) {
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("start sam_get_serial_number");
|
||||
}
|
||||
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
uint8_t payload[] = {
|
||||
0xa0, // <- SAM command
|
||||
0x02, // <- Length
|
||||
0x96, 0x00 // <- get serial number
|
||||
};
|
||||
uint16_t payload_len = sizeof(payload);
|
||||
|
||||
sam_send_payload(
|
||||
0x44, 0x0a, 0x44,
|
||||
payload,
|
||||
&payload_len,
|
||||
response,
|
||||
&response_len
|
||||
);
|
||||
|
||||
//resp:
|
||||
//c1 64 00 00 00
|
||||
// bd 0e <- SAM response
|
||||
// 8a 0c <- get serial number response
|
||||
// 61 01 13 51 22 66 6e 15 3e 1b ff ff
|
||||
//90 00
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_get_serial_number");
|
||||
}
|
||||
|
||||
if (response[5] != 0xbd) {
|
||||
Dbprintf("Invalid SAM response");
|
||||
goto error;
|
||||
} else {
|
||||
uint8_t *sam_response_an = sam_find_asn1_node(response + 5, 0x8a);
|
||||
if (sam_response_an == NULL) {
|
||||
if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM: get response failed"));
|
||||
goto error;
|
||||
}
|
||||
uint8_t *sam_serial_an = sam_response_an + 2;
|
||||
if (sam_serial_an == NULL) {
|
||||
if (g_dbglevel >= DBG_ERROR) DbpString(_RED_("SAM get serial number failed"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
Dbprintf(_YELLOW_("Serial Number: "));
|
||||
Dbhexdump(sam_response_an[1], sam_serial_an, false);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
error:
|
||||
res = PM3_ESOFT;
|
||||
|
||||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_get_serial_number");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -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) {
|
||||
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
uint8_t payload[] = {
|
||||
0xa0, 0
|
||||
};
|
||||
uint8_t payload[] = { 0xa0, 0 };
|
||||
uint16_t payload_len = sizeof(payload);
|
||||
|
||||
sam_send_payload(
|
||||
|
|
|
@ -39,7 +39,8 @@ int sam_send_payload(
|
|||
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);
|
||||
void sam_append_asn1_node(const uint8_t *root, const uint8_t *node, uint8_t type, const uint8_t *const data, uint8_t len);
|
||||
|
|
|
@ -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) {
|
||||
int res = PM3_SUCCESS;
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("start sam_send_request_iso14a");
|
||||
}
|
||||
|
||||
uint8_t *buf1 = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *buf2 = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *buf1 = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *buf2 = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
if (buf1 == NULL || buf2 == NULL) {
|
||||
res = PM3_EMALLOC;
|
||||
goto out;
|
||||
|
@ -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);
|
||||
|
||||
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) {
|
||||
|
||||
memcpy(response, nfc_tx_buf, nfc_tx_len);
|
||||
*response_len = nfc_tx_len;
|
||||
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
DbpString("NR-MAC: ");
|
||||
Dbhexdump((*response_len) - 1, response + 1, false);
|
||||
|
@ -114,7 +118,8 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
|
|||
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) {
|
||||
// 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
|
||||
// 90 00
|
||||
if (request_len == 0) {
|
||||
if (
|
||||
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0x8a && sam_rx_buf[5 + 4] == 0x03)
|
||||
&&
|
||||
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)
|
||||
) {
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
|
||||
if (!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0x8a && sam_rx_buf[5 + 4] == 0x03) &&
|
||||
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)) {
|
||||
|
||||
if (g_dbglevel >= DBG_ERROR) {
|
||||
Dbprintf("No PACS data in SAM response");
|
||||
}
|
||||
res = PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
goto out;
|
||||
|
@ -255,10 +269,10 @@ out:
|
|||
*/
|
||||
static int sam_set_card_detected_picopass(const picopass_hdr_t *card_select) {
|
||||
int res = PM3_SUCCESS;
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
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;
|
||||
|
||||
// a0 12
|
||||
|
@ -314,8 +328,9 @@ error:
|
|||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_set_card_detected");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -336,11 +351,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
|||
const bool breakOnNrMac = !!(flags & BITMASK(2));
|
||||
const bool preventEpurseUpdate = !!(flags & BITMASK(3));
|
||||
const bool shallow_mod = !!(flags & BITMASK(4));
|
||||
const bool info = !!(flags & BITMASK(5));
|
||||
|
||||
uint8_t *cmd = c->data.asBytes + 1;
|
||||
uint16_t cmd_len = c->length - 1;
|
||||
|
||||
int res = PM3_EFAILED;
|
||||
uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 };
|
||||
uint8_t sam_response_len = 0;
|
||||
|
||||
clear_trace();
|
||||
I2C_Reset_EnterMainProgram();
|
||||
|
@ -349,16 +367,21 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
|||
StartTicks();
|
||||
|
||||
// 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
|
||||
picopass_hdr_t card_a_info;
|
||||
uint32_t eof_time = 0;
|
||||
|
||||
// implicit StartSspClk() happens here
|
||||
Iso15693InitReader();
|
||||
if (!select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod)) {
|
||||
if (select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod) == false) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -369,14 +392,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
|||
}
|
||||
|
||||
// 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);
|
||||
if (res != PM3_SUCCESS) {
|
||||
goto err;
|
||||
}
|
||||
if (g_dbglevel >= DBG_INFO)
|
||||
|
||||
if (g_dbglevel >= DBG_INFO) {
|
||||
print_result("Response data", sam_response, sam_response_len);
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -51,13 +51,14 @@
|
|||
*/
|
||||
static int sam_set_card_detected_seos(iso14a_card_select_t *card_select) {
|
||||
int res = PM3_SUCCESS;
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
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;
|
||||
|
||||
uint8_t *response = BigBuf_malloc(ISO7816_MAX_FRAME);
|
||||
uint8_t *response = BigBuf_calloc(ISO7816_MAX_FRAME);
|
||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
const uint8_t payload[] = {
|
||||
|
@ -107,8 +108,9 @@ error:
|
|||
out:
|
||||
BigBuf_free();
|
||||
|
||||
if (g_dbglevel >= DBG_DEBUG)
|
||||
if (g_dbglevel >= DBG_DEBUG) {
|
||||
DbpString("end sam_set_card_detected");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -280,7 +282,7 @@ int sam_seos_get_pacs(PacketCommandNG *c) {
|
|||
StartTicks();
|
||||
|
||||
// step 1: ping SAM
|
||||
sam_get_version();
|
||||
sam_get_version(false);
|
||||
|
||||
if (skipDetect == false) {
|
||||
// step 2: get card information
|
||||
|
|
|
@ -312,7 +312,7 @@ static int is_valid_filename(const char *filename) {
|
|||
*/
|
||||
static void copy_in_spiffs(const char *src, const char *dst) {
|
||||
uint32_t size = size_in_spiffs(src);
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
uint8_t *mem = BigBuf_calloc(size);
|
||||
read_from_spiffs(src, (uint8_t *)mem, size);
|
||||
write_to_spiffs(dst, (uint8_t *)mem, size);
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) {
|
|||
}
|
||||
|
||||
// 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
|
||||
// (and check next bank too, in case there will be a usart_writebuffer_async)
|
||||
|
|
|
@ -25,7 +25,7 @@ extern uint32_t g_usart_baudrate;
|
|||
extern uint8_t g_usart_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);
|
||||
uint16_t usart_rxdata_available(void);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19
|
|||
# version_pm3.c should be checked on every compilation
|
||||
version_pm3.c: default_version_pm3.c .FORCE
|
||||
$(info [=] CHECK $@)
|
||||
$(Q)$(CP) $< $@
|
||||
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
|
||||
|
||||
all: showinfo $(OBJS)
|
||||
|
||||
|
|
|
@ -434,7 +434,7 @@ set (TARGET_SOURCES
|
|||
|
||||
add_custom_command(
|
||||
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
|
||||
)
|
||||
|
||||
|
@ -692,7 +692,7 @@ add_executable(proxmark3
|
|||
${ADDITIONAL_SRC}
|
||||
)
|
||||
|
||||
target_compile_options(proxmark3 PUBLIC -Wall -O3)
|
||||
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
|
||||
if (EMBED_READLINE)
|
||||
if (NOT SKIPREADLINE EQUAL 1)
|
||||
add_dependencies(proxmark3 ncurses readline)
|
||||
|
|
|
@ -446,7 +446,7 @@ endif
|
|||
|
||||
PM3CFLAGS += -DHAVE_SNPRINTF
|
||||
|
||||
CXXFLAGS ?= -Wall
|
||||
CXXFLAGS ?= -Wall -Werror
|
||||
CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES)
|
||||
|
||||
PM3CXXFLAGS = $(CXXFLAGS)
|
||||
|
@ -889,11 +889,19 @@ endif
|
|||
ifneq (,$(INSTALLSHARE))
|
||||
$(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||
# 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
|
||||
$(Q)sed -i 's|^DICTS_PATH \?= \?None|DICTS_PATH="$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/dictionaries"|' pyscripts/pm3_resources.py
|
||||
ifeq ($(platform),Darwin)
|
||||
$(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)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
|
||||
endif
|
||||
endif
|
||||
@true
|
||||
|
||||
|
@ -987,7 +995,7 @@ src/pm3_pywrap.c: pm3.i
|
|||
# version_pm3.c should be checked on every compilation
|
||||
src/version_pm3.c: default_version_pm3.c .FORCE
|
||||
$(info [=] CHECK $@)
|
||||
$(Q)$(CP) $< $@
|
||||
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
|
||||
|
||||
# easy printing of MAKE VARIABLES
|
||||
print-%: ; @echo $* = $($*)
|
||||
|
|
|
@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE
|
|||
m
|
||||
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)
|
||||
|
||||
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool
|
||||
|
|
|
@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE
|
|||
../../include
|
||||
../src)
|
||||
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)
|
||||
|
|
|
@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT
|
|||
hardnested/hardnested_bf_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)
|
||||
|
||||
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_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
|
||||
-mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||
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_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
|
||||
-mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||
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_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
|
||||
-mmmx -msse2 -mavx -mno-avx2 -mno-avx512f)
|
||||
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_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
|
||||
-mmmx -msse2 -mavx -mavx2 -mno-avx512f)
|
||||
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_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
|
||||
-mmmx -msse2 -mavx -mavx2 -mavx512f)
|
||||
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_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)
|
||||
|
||||
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_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
|
||||
-mfpu=neon)
|
||||
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
|
||||
$<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd>
|
||||
${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)
|
||||
target_include_directories(pm3rrg_rdv4_hardnested PRIVATE
|
||||
../../common
|
||||
|
|
|
@ -177,14 +177,15 @@ crack_states_thread(void *x) {
|
|||
|
||||
char progress_text[80];
|
||||
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);
|
||||
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
|
||||
PrintAndLogEx(INFO, "---------+---------+---------------------------------------------------------+-----------------+-------");
|
||||
break;
|
||||
} else if (keys_found) {
|
||||
break;
|
||||
} else {
|
||||
if (!thread_arg->silent) {
|
||||
if (thread_arg->silent == false) {
|
||||
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));
|
||||
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;
|
||||
for (statelist_t *p = candidates; p != NULL; p = p->next) {
|
||||
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!");
|
||||
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;
|
||||
pthread_create(&threads[i], NULL, crack_states_thread, (void *)&thread_args[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_brute_force_threads; i++) {
|
||||
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;
|
||||
|
||||
if (bf_rate != NULL)
|
||||
if (bf_rate != NULL) {
|
||||
*bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0);
|
||||
}
|
||||
|
||||
if (keys_found > 0)
|
||||
if (keys_found > 0) {
|
||||
*found_key = found_bs_key;
|
||||
}
|
||||
|
||||
return (keys_found != 0);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ add_library(pm3rrg_rdv4_id48 STATIC
|
|||
id48/id48_generator.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 INTERFACE id48)
|
||||
set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
|
|
@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC
|
|||
|
||||
target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H)
|
||||
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)
|
||||
|
|
|
@ -52,5 +52,5 @@ if (NOT MINGW)
|
|||
endif (NOT MINGW)
|
||||
|
||||
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)
|
||||
|
|
|
@ -49,5 +49,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
|
|||
|
||||
target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common)
|
||||
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)
|
||||
|
|
|
@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE
|
|||
../src
|
||||
../../include)
|
||||
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)
|
||||
|
|
|
@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC
|
|||
|
||||
target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor)
|
||||
# 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)
|
||||
|
|
|
@ -179,7 +179,9 @@
|
|||
#ifndef unlikely
|
||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
#ifndef unreachable
|
||||
# define unreachable() __builtin_unreachable()
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
# define likely(x) (x)
|
||||
# define unlikely(x) (x)
|
||||
|
|
|
@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c)
|
|||
|
||||
target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED)
|
||||
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)
|
||||
|
|
|
@ -1905,15 +1905,14 @@ FF16014FEFC7
|
|||
# Food GEM
|
||||
6686FADE5566
|
||||
#
|
||||
# Samsung Data Systems (SDS) — Electronic Locks
|
||||
# Gen 1 S10 KA/KB is FFFFFFFFFFFF, incompatible with Gen 2 locks
|
||||
#
|
||||
# SDS Gen 2 S10 KB
|
||||
# Samsung Data Systems (SDS)
|
||||
# 10-11 A/B (Gen 2)
|
||||
9B7C25052FC3
|
||||
C22E04247D9A
|
||||
6C4F77534170
|
||||
704153564F6C
|
||||
#
|
||||
# Data from Discord, French pool
|
||||
# SDS Gen 2 S10 KA
|
||||
9B7C25052FC3
|
||||
494446555455
|
||||
#
|
||||
# Data from Discord, seems to be related to ASSA
|
||||
|
@ -3108,3 +3107,80 @@ AB921CF0752C
|
|||
265A5F32DE73
|
||||
567D734C403C
|
||||
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
|
||||
|
|
|
@ -4,10 +4,12 @@ ffffffffffffffff
|
|||
0011223344556677
|
||||
1122334455667788
|
||||
a0a1a2a3a4a5a6a7
|
||||
d3f7d3f7d3f7d3f7
|
||||
00000000000000000000000000000000 #NXP Default 3DES/AES
|
||||
000000000000000000000000000000000000000000000000 #NXP Default 3K3DES
|
||||
00112233445566778899AABBCCDDEEFF0102030405060708
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7
|
||||
425245414B4D454946594F5543414E21 # default UL-C key
|
||||
00112233445566778899AABBCCDDEEFF #TI TRF7970A sloa213
|
||||
79702553797025537970255379702553 #TI TRF7970A sloa213
|
||||
|
|
|
@ -434,7 +434,7 @@ set (TARGET_SOURCES
|
|||
|
||||
add_custom_command(
|
||||
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
|
||||
)
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ local function perform_check(uid, numsectors)
|
|||
for sector = 0, #keys do
|
||||
-- Check if user aborted
|
||||
if core.kbd_enter_pressed() then
|
||||
print('Aborted by user')
|
||||
print('Aborted via keyboard!')
|
||||
break
|
||||
end
|
||||
|
||||
|
|
357
client/luascripts/hf_mfu_ultra.lua
Normal file
357
client/luascripts/hf_mfu_ultra.lua
Normal 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)
|
747
client/luascripts/kybercrystals.lua
Normal file
747
client/luascripts/kybercrystals.lua
Normal 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()
|
|
@ -299,7 +299,7 @@ local function main(args)
|
|||
if answer == 'n' then
|
||||
core.console('clear')
|
||||
print( string.rep('--',39) )
|
||||
print(ac.red..' USER ABORTED'..ac.reset)
|
||||
print(ac.red..' Aborted via keyboard!'..ac.reset)
|
||||
print( string.rep('--',39) )
|
||||
break
|
||||
end
|
||||
|
|
|
@ -198,7 +198,7 @@ local function main(args)
|
|||
core.console('lf em 410x reader')
|
||||
end
|
||||
else
|
||||
print(ac.red..'User aborted'..ac.reset)
|
||||
print(ac.red..'aborted via keyboard!'..ac.reset)
|
||||
low = i
|
||||
break
|
||||
end
|
||||
|
|
|
@ -28,6 +28,7 @@ Full license text: <https://www.gnu.org/licenses/gpl-3.0.html>
|
|||
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
|
@ -100,24 +101,33 @@ def send_proxmark_command(command):
|
|||
|
||||
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 = 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
|
||||
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)
|
||||
print(auth_response)
|
||||
# print("DEBUG: Raw Proxmark response:\n", repr(auth_response))
|
||||
|
||||
# Check for Proxmark failure messages
|
||||
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
|
||||
|
||||
while True:
|
||||
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
|
||||
# Regex to match valid 6-character hex AIDs
|
||||
|
@ -144,7 +154,8 @@ def authenticate_and_menu():
|
|||
print("3. Delete an AID")
|
||||
print("4. Format PICC")
|
||||
print("5. Show free memory")
|
||||
print("6. Exit")
|
||||
print("6. Change keys")
|
||||
print("7. Exit")
|
||||
|
||||
choice = input("Enter your choice: ").strip()
|
||||
|
||||
|
@ -157,32 +168,39 @@ def authenticate_and_menu():
|
|||
selected_aid = aids[selected_index]
|
||||
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)
|
||||
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
|
||||
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":
|
||||
create_aid(key_type, key)
|
||||
create_aid(key_type, key, com_mode)
|
||||
|
||||
elif choice == "3":
|
||||
delete_aid(key_type, key)
|
||||
delete_aid(key_type, key, com_mode)
|
||||
|
||||
elif choice == "4":
|
||||
format_picc(key_type, key)
|
||||
format_picc(key_type, key, com_mode)
|
||||
|
||||
elif choice == "5":
|
||||
free_memory(key_type, key)
|
||||
free_memory(key_type, key, com_mode)
|
||||
|
||||
elif choice == "6":
|
||||
change_key(key_type, key, com_mode)
|
||||
|
||||
elif choice == "7":
|
||||
print("Exiting...")
|
||||
break
|
||||
else:
|
||||
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:
|
||||
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("3. Create a File")
|
||||
print("4. Write to a File")
|
||||
print("5. Delete a File")
|
||||
print("6. Exit")
|
||||
print("5. Edit File Restrictions")
|
||||
print("6. Delete a File")
|
||||
print("7. Back")
|
||||
|
||||
choice = input("Enter your choice: ").strip()
|
||||
|
||||
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":
|
||||
read_file(selected_aid, key_type, key)
|
||||
read_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
|
||||
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":
|
||||
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":
|
||||
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":
|
||||
delete_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key)
|
||||
elif choice == "7":
|
||||
print("Returning to AID selection...")
|
||||
break
|
||||
else:
|
||||
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()
|
||||
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()
|
||||
|
||||
create_command = f"hf mfdes createapp -n 0 --aid {aid} --fid {iso_fid} --dstalgo {dstalgo} -t {key_type} -k {key} -a"
|
||||
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"
|
||||
response = send_proxmark_command(create_command)
|
||||
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()
|
||||
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)
|
||||
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()
|
||||
|
||||
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)
|
||||
print(response)
|
||||
elif confirm == "n":
|
||||
|
@ -242,9 +262,9 @@ def format_picc(key_type, key):
|
|||
else:
|
||||
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)
|
||||
|
||||
for line in response.splitlines():
|
||||
|
@ -254,10 +274,54 @@ def free_memory(key_type, key):
|
|||
|
||||
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...")
|
||||
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)
|
||||
|
||||
# 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.")
|
||||
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()
|
||||
|
||||
|
@ -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_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)
|
||||
|
||||
# Extract and display file content
|
||||
|
@ -299,7 +364,7 @@ def read_file(aid, key_type, key):
|
|||
|
||||
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
|
||||
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}")
|
||||
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)
|
||||
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()
|
||||
|
||||
# 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)
|
||||
|
||||
# Extract the file size from the response
|
||||
|
@ -376,15 +442,49 @@ def write_to_file(aid, key_type, key):
|
|||
else:
|
||||
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)
|
||||
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()
|
||||
|
||||
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)
|
||||
print(response)
|
||||
|
||||
|
|
|
@ -90,13 +90,14 @@ def lprint(s='', end='\n', flush=False, prompt="[" + color("=", fg="yellow") +
|
|||
- logfile (R)
|
||||
"""
|
||||
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:
|
||||
global logbuffer
|
||||
if logfile is not None:
|
||||
with open(logfile, 'a') as f:
|
||||
f.write(s + end)
|
||||
with open(logfile, 'a', encoding='utf-8') as f:
|
||||
f.write(safe_s + end)
|
||||
else:
|
||||
# buffering
|
||||
logbuffer += s + end
|
||||
|
|
|
@ -226,6 +226,7 @@ def recovery(init_check=False, final_check=False, keep=False, no_oob=False,
|
|||
dict_dnwd = None
|
||||
def_nt = ["" for _ in range(NUM_SECTORS)]
|
||||
if supply_chain:
|
||||
default_nonces = ''
|
||||
try:
|
||||
default_nonces = f'{save_path}hf-mf-{uid:04X}-default_nonces.json'
|
||||
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:
|
||||
keyfile = line[line.index("`"):].strip("`")
|
||||
else:
|
||||
show()
|
||||
show(color("found keys:", fg="green"), prompt=plus)
|
||||
show(prompt=plus)
|
||||
show("-----+-----+--------------+---+--------------+----", prompt=plus)
|
||||
show(" Sec | Blk | key A |res| key B |res", prompt=plus)
|
||||
|
|
|
@ -211,6 +211,37 @@ def Describe_Usage_2_1(Usage, ContractMediumEndDate, Certificate):
|
|||
print(' left... :', Usage.nom_bits_left())
|
||||
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):
|
||||
EventDateStamp = Usage.nom(10)
|
||||
EventTimeStamp = Usage.nom(11)
|
||||
|
@ -258,6 +289,7 @@ ISO_Countries = {
|
|||
|
||||
FRA_OrganizationalAuthority_Contract_Provider = {
|
||||
0x000: {
|
||||
1: InterticHelper('Valenciennes', 'Transvilles / 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),
|
||||
},
|
||||
|
@ -273,6 +305,9 @@ FRA_OrganizationalAuthority_Contract_Provider = {
|
|||
0x021: {
|
||||
1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1),
|
||||
},
|
||||
0x040: {
|
||||
28: InterticHelper('Colmar', 'Trace / Keolis', Describe_Usage_1_1),
|
||||
},
|
||||
0x057: {
|
||||
1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), # Strange usage ?, kept on generic 1
|
||||
},
|
||||
|
@ -289,7 +324,7 @@ FRA_OrganizationalAuthority_Contract_Provider = {
|
|||
0x502: {
|
||||
83: InterticHelper('Annecy', 'Sibra', Describe_Usage_2),
|
||||
84: InterticHelper('Bourg-en-Bresse', 'Rubis / Keolis'),
|
||||
10: InterticHelper('Clermont-Ferrand', 'T2C'),
|
||||
10: InterticHelper('Clermont-Ferrand', 'T2C', Describe_Usage_2_2),
|
||||
},
|
||||
0x907: {
|
||||
1: InterticHelper('Dijon', 'Divia / Keolis'),
|
||||
|
@ -315,6 +350,9 @@ FRA_OrganizationalAuthority_Contract_Provider = {
|
|||
4: InterticHelper('Angers', 'Irigo / RATP', Describe_Usage_1_2),
|
||||
7: InterticHelper('Saint-Nazaire', 'Stran'),
|
||||
},
|
||||
0x920: {
|
||||
9: InterticHelper('Aix-en-Provence', 'Aixenbus / Keolis', Describe_Usage_2_1),
|
||||
},
|
||||
}
|
||||
|
||||
MAR_OrganizationalAuthority_Contract_Provider = {
|
||||
|
|
|
@ -36,7 +36,7 @@ DIR_PATH = os.path.dirname(os.path.abspath(__file__))
|
|||
if TOOLS_PATH is None:
|
||||
if os.path.basename(os.path.dirname(DIR_PATH)) == 'client':
|
||||
# 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):
|
||||
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.
|
||||
"""
|
||||
if TOOLS_PATH is not None:
|
||||
tool = os.path.join(TOOLS_PATH, tool_name)
|
||||
if os.path.isfile(tool):
|
||||
return tool
|
||||
elif os.path.isfile(tool + ".exe"):
|
||||
return tool + ".exe"
|
||||
for root, _, files in os.walk(TOOLS_PATH):
|
||||
if tool_name in files:
|
||||
return os.path.join(root, tool_name)
|
||||
elif tool_name + ".exe" in files:
|
||||
return os.path.join(root, tool_name + ".exe")
|
||||
# if not found, search in the user PATH
|
||||
for path in os.environ["PATH"].split(os.pathsep):
|
||||
env_tool = os.path.join(path, tool_name)
|
||||
|
|
|
@ -391,12 +391,20 @@
|
|||
"Description": "Key as a Service // FID 01: Standard Data",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F51780",
|
||||
"Vendor": "ASSA ABLOY",
|
||||
"Country": "SE",
|
||||
"Name": "SMARTair",
|
||||
"Description": "SMARTair Credential",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F51BC0",
|
||||
"Vendor": "STid Group",
|
||||
"Country": "FR",
|
||||
"Name": "CCT Card / DTA Tag / PCG Fob",
|
||||
"Description": "STid Easyline / Architect Access Credetials",
|
||||
"Description": "STid Easyline / Architect Access Credentials",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -887,12 +895,20 @@
|
|||
"Description": "car2go - Member Card // Multi Functional Badge / Private Application #1",
|
||||
"Type": "carsharing"
|
||||
},
|
||||
{
|
||||
"AID": "000005",
|
||||
"Vendor": "Transports Metropolitans de Barcelona (TMB)",
|
||||
"Country": "ES",
|
||||
"Name": "T-mobilitat (BCN)",
|
||||
"Description": "BCN T-mobilitat",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "000001",
|
||||
"Vendor": "Invalid / Reserved",
|
||||
"Country": "",
|
||||
"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"
|
||||
},
|
||||
{
|
||||
|
@ -915,7 +931,7 @@
|
|||
"AID": "010000",
|
||||
"Vendor": "Consorcio Regional de Transportes Publicos Regulares de Madrid (CRTM)",
|
||||
"Country": "ES",
|
||||
"Name": "Tarjeta Transporte Publico (MAD) (Alternative Endian)",
|
||||
"Name": "Tarjeta Transporte Publico (MAD)",
|
||||
"Description": "MAD Public Transport Card",
|
||||
"Type": "transport"
|
||||
},
|
||||
|
@ -1183,6 +1199,22 @@
|
|||
"Description": "DUB Leap Card // Transport for Ireland // FIDs: 01,1F: Backup Data; 02-0A: Standard Data",
|
||||
"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",
|
||||
"Vendor": "Delhi Metro Rail Corporation Limited",
|
||||
|
@ -1255,6 +1287,14 @@
|
|||
"Description": "FIDs: 00-07: Standard Data",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"Vendor": "Doha Metro and Lusail Tram via Qatar Rail",
|
||||
|
@ -1303,6 +1351,14 @@
|
|||
"Description": "Umo Mobility Card",
|
||||
"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",
|
||||
"Vendor": "Roads & Transport Authority (Government of Dubai)",
|
||||
|
@ -1527,6 +1583,14 @@
|
|||
"Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data",
|
||||
"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",
|
||||
"Vendor": "ITSO Ltd",
|
||||
|
|
8
client/resources/iceman.txt
Normal file
8
client/resources/iceman.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
[38;2;0;57;27m$[38;2;1;57;26m$[38;2;3;58;26m$[38;2;4;58;26m$[38;2;6;59;26m$[38;2;8;60;25m$[38;2;9;60;25m\ [38;2;14;62;24m$[38;2;16;63;24m$[38;2;18;63;24m$[38;2;19;64;24m$[38;2;21;64;23m$[38;2;23;65;23m$[38;2;24;66;23m\ [38;2;29;67;22m$[38;2;31;68;22m$[38;2;33;69;22m$[38;2;34;69;22m$[38;2;36;70;21m$[38;2;37;70;21m$[38;2;39;71;21m$[38;2;41;72;21m$[38;2;42;72;20m\ [38;2;46;73;20m$[38;2;47;74;20m$[38;2;49;75;20m\ [38;2;61;79;18m$[38;2;62;79;18m$[38;2;64;80;17m\ [38;2;69;82;17m$[38;2;70;82;16m$[38;2;72;83;16m$[38;2;74;84;16m$[38;2;75;84;16m$[38;2;77;85;16m$[38;2;79;85;15m\ [38;2;84;87;15m$[38;2;85;88;14m$[38;2;87;88;14m\ [38;2;94;91;13m$[38;2;95;91;13m$[38;2;97;92;13m\ [0m
|
||||
[38;2;9;60;25m\_$$ _[38;2;11;61;25m|[38;2;13;61;25m$[38;2;14;62;24m$ [38;2;19;64;24m_[38;2;21;64;23m_[38;2;23;65;23m$[38;2;24;66;23m$[38;2;26;66;23m\ [38;2;29;67;22m$[38;2;31;68;22m$ [38;2;36;70;21m_[38;2;37;70;21m_[38;2;39;71;21m_[38;2;41;72;21m_[38;2;42;72;20m_[38;2;44;73;20m|[38;2;46;73;20m$[38;2;47;74;20m$[38;2;49;75;20m$[38;2;51;75;19m\ [38;2;59;78;18m$[38;2;61;79;18m$[38;2;62;79;18m$ [38;2;66;81;17m|[38;2;67;81;17m$[38;2;69;82;17m$ [38;2;74;84;16m_[38;2;75;84;16m_[38;2;77;85;16m$[38;2;79;85;15m$[38;2;80;86;15m\ [38;2;84;87;15m$[38;2;85;88;14m$[38;2;87;88;14m$[38;2;89;89;14m\ [38;2;94;91;13m$[38;2;95;91;13m$ [38;2;99;93;13m|[0m
|
||||
[38;2;18;63;24m$$ | $$ / [38;2;23;65;23m\[38;2;24;66;23m_[38;2;26;66;23m_[38;2;28;67;23m|[38;2;29;67;22m$[38;2;31;68;22m$ [38;2;34;69;22m| [38;2;46;73;20m$[38;2;47;74;20m$[38;2;49;75;20m$[38;2;51;75;19m$[38;2;52;76;19m\ [38;2;57;78;18m$[38;2;59;78;18m$[38;2;61;79;18m$[38;2;62;79;18m$ [38;2;66;81;17m|[38;2;67;81;17m$[38;2;69;82;17m$ [38;2;72;83;16m/ [38;2;77;85;16m$[38;2;79;85;15m$ [38;2;82;87;15m|[38;2;84;87;15m$[38;2;85;88;14m$[38;2;87;88;14m$[38;2;89;89;14m$[38;2;90;90;14m\ [38;2;94;91;13m$[38;2;95;91;13m$ [38;2;99;93;13m|[0m
|
||||
[38;2;26;66;23m$$ | $$ | [38;2;29;67;22m$[38;2;31;68;22m$[38;2;33;69;22m$[38;2;34;69;22m$[38;2;36;70;21m$[38;2;37;70;21m\ [38;2;46;73;20m$[38;2;47;74;20m$[38;2;49;75;20m\[38;2;51;75;19m$[38;2;52;76;19m$[38;2;54;76;19m\[38;2;56;77;19m$[38;2;57;78;18m$ [38;2;61;79;18m$[38;2;62;79;18m$ [38;2;66;81;17m|[38;2;67;81;17m$[38;2;69;82;17m$[38;2;70;82;16m$[38;2;72;83;16m$[38;2;74;84;16m$[38;2;75;84;16m$[38;2;77;85;16m$[38;2;79;85;15m$ [38;2;82;87;15m|[38;2;84;87;15m$[38;2;85;88;14m$ [38;2;89;89;14m$[38;2;90;90;14m$[38;2;92;90;13m\[38;2;94;91;13m$[38;2;95;91;13m$ [38;2;99;93;13m|[0m
|
||||
[38;2;36;70;21m$$ | $$ | $$ _[38;2;37;70;21m_[38;2;39;71;21m| [38;2;46;73;20m$[38;2;47;74;20m$ [38;2;51;75;19m\[38;2;52;76;19m$[38;2;54;76;19m$[38;2;56;77;19m$ [38;2;61;79;18m$[38;2;62;79;18m$ [38;2;66;81;17m|[38;2;67;81;17m$[38;2;69;82;17m$ [38;2;74;84;16m_[38;2;75;84;16m_[38;2;77;85;16m$[38;2;79;85;15m$ [38;2;82;87;15m|[38;2;84;87;15m$[38;2;85;88;14m$ [38;2;89;89;14m\[38;2;90;90;14m$[38;2;92;90;13m$[38;2;94;91;13m$[38;2;95;91;13m$ [38;2;99;93;13m|[0m
|
||||
[38;2;45;73;20m$$ | $$ | $$\ $$ | [38;2;46;73;20m$[38;2;47;74;20m$ [38;2;51;75;19m|[38;2;52;76;19m\[38;2;54;76;19m$ [38;2;59;78;18m/[38;2;61;79;18m$[38;2;62;79;18m$ [38;2;66;81;17m|[38;2;67;81;17m$[38;2;69;82;17m$ [38;2;72;83;16m| [38;2;77;85;16m$[38;2;79;85;15m$ [38;2;82;87;15m|[38;2;84;87;15m$[38;2;85;88;14m$ [38;2;89;89;14m|[38;2;90;90;14m\[38;2;92;90;13m$[38;2;94;91;13m$[38;2;95;91;13m$ [38;2;99;93;13m|[0m
|
||||
[38;2;53;76;19m$$$$$$\ \$$$$$$ |$$$$$$$$\ $$ | [38;2;54;76;19m\[38;2;56;77;19m_[38;2;57;78;18m/ [38;2;61;79;18m$[38;2;62;79;18m$ [38;2;66;81;17m|[38;2;67;81;17m$[38;2;69;82;17m$ [38;2;72;83;16m| [38;2;77;85;16m$[38;2;79;85;15m$ [38;2;82;87;15m|[38;2;84;87;15m$[38;2;85;88;14m$ [38;2;89;89;14m| [38;2;92;90;13m\[38;2;94;91;13m$[38;2;95;91;13m$ [38;2;99;93;13m|[0m
|
||||
[38;2;63;79;18m\______| \______/ \________|\__| \_[38;2;64;80;17m_[38;2;66;81;17m|[38;2;67;81;17m\[38;2;69;82;17m_[38;2;70;82;16m_[38;2;72;83;16m| [38;2;77;85;16m\[38;2;79;85;15m_[38;2;80;86;15m_[38;2;82;87;15m|[38;2;84;87;15m\[38;2;85;88;14m_[38;2;87;88;14m_[38;2;89;89;14m| [38;2;94;91;13m\[38;2;95;91;13m_[38;2;97;92;13m_[38;2;99;93;13m|[0m
|
File diff suppressed because it is too large
Load diff
|
@ -192,21 +192,24 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
|||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "mem load",
|
||||
"Loads binary file into flash memory on device\n"
|
||||
"Warning: mem area to be written must have been wiped first\n"
|
||||
"( dictionaries are serviced as files in spiffs so no wipe is needed )",
|
||||
"Warning! - mem area to be written must have been wiped first\n\n"
|
||||
"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 -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 iclass_default_keys -i -> upload iCLASS keys\n"
|
||||
"mem load -f mfulc_default_keys --ulc -> upload MIFARE UL-C keys\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int0("o", "offset", "<dec>", "offset in memory"),
|
||||
arg_lit0("m", "mifare,mfc", "upload 6 bytes keys (mifare key dictionary)"),
|
||||
arg_lit0("i", "iclass", "upload 8 bytes keys (iClass key dictionary)"),
|
||||
arg_lit0("t", "t55xx", "upload 4 bytes keys (password dictionary)"),
|
||||
arg_lit0("m", "mfc", "upload 6 bytes keys (MIFARE Classic dictionary)"),
|
||||
arg_lit0("i", "iclass", "upload 8 bytes keys (iClass 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_param_end
|
||||
};
|
||||
|
@ -216,28 +219,35 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
|||
bool is_mfc = arg_get_lit(ctx, 2);
|
||||
bool is_iclass = arg_get_lit(ctx, 3);
|
||||
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;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
char spiffsDest[32] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
Dictionary_t d = DICTIONARY_NONE;
|
||||
if (is_mfc) {
|
||||
d = DICTIONARY_MIFARE;
|
||||
PrintAndLogEx(INFO, "treating file as MIFARE Classic keys");
|
||||
PrintAndLogEx(INFO, "Treating file as MIFARE Classic keys");
|
||||
} else if (is_iclass) {
|
||||
d = DICTIONARY_ICLASS;
|
||||
PrintAndLogEx(INFO, "treating file as iCLASS keys");
|
||||
PrintAndLogEx(INFO, "Treating file as iCLASS keys");
|
||||
} else if (is_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;
|
||||
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -246,6 +256,8 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
|||
uint8_t keylen = 0;
|
||||
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE_P(spi_flash_pages), sizeof(uint8_t));
|
||||
|
||||
char spiffsDest[32] = {0};
|
||||
|
||||
switch (d) {
|
||||
case DICTIONARY_MIFARE: {
|
||||
keylen = MF_KEY_LENGTH;
|
||||
|
@ -292,6 +304,36 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
|||
strcpy(spiffsDest, ICLASS_KEYS_FILE);
|
||||
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: {
|
||||
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
|
||||
if (res != PM3_SUCCESS) {
|
||||
|
@ -330,7 +372,12 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
|||
free(data);
|
||||
return res;
|
||||
}
|
||||
|
||||
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_MOUNT, NULL, 0);
|
||||
} else {
|
||||
|
@ -729,6 +776,7 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "{ SPI File system }"},
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"-----------", CmdHelp, IfPm3Flash, "------------------- " _CYAN_("Operations") " -------------------"},
|
||||
{"baudrate", CmdFlashmemSpiBaud, IfPm3Flash, "Set Flash memory Spi baudrate"},
|
||||
{"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"},
|
||||
{"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"},
|
||||
|
|
|
@ -26,7 +26,9 @@ typedef enum {
|
|||
DICTIONARY_NONE = 0,
|
||||
DICTIONARY_MIFARE,
|
||||
DICTIONARY_T55XX,
|
||||
DICTIONARY_ICLASS
|
||||
DICTIONARY_ICLASS,
|
||||
DICTIONARY_MIFARE_ULC,
|
||||
DICTIONARY_MIFARE_ULAES,
|
||||
} Dictionary_t;
|
||||
|
||||
int CmdFlashMem(const char *Cmd);
|
||||
|
|
|
@ -576,10 +576,11 @@ static int CmdFlashMemSpiFFSView(const char *Cmd) {
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"-----------", CmdHelp, IfPm3Flash, "------------------- " _CYAN_("Operations") " -------------------"},
|
||||
{"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS file system"},
|
||||
{"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented 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"},
|
||||
{"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS file system"},
|
||||
{"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS file system"},
|
||||
|
|
|
@ -231,11 +231,13 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
*/
|
||||
|
||||
DropField();
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, _RED_("No known/supported 13.56 MHz tags found"));
|
||||
res = PM3_ESOFT;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
|
||||
// no need to print 14A hints, since it will print itself
|
||||
|
||||
|
@ -282,9 +284,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
if (success[PROTO_CRYPTORF]) {
|
||||
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n");
|
||||
}
|
||||
}
|
||||
|
||||
DropField();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -477,7 +477,7 @@ int CmdHFSniff(const char *Cmd) {
|
|||
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(INFO, "User aborted");
|
||||
PrintAndLogEx(WARNING, "\naborted via keyboard!");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -600,7 +600,7 @@ static command_t CommandTable[] = {
|
|||
{"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"},
|
||||
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm 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
|
||||
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,7 +20,7 @@
|
|||
#define CMDHF14A_H__
|
||||
|
||||
#include "common.h"
|
||||
#include "pm3_cmd.h" //hf14a_config
|
||||
#include "pm3_cmd.h" //hf14a_config_t
|
||||
#include "mifare.h" // structs
|
||||
|
||||
// structure and database for uid -> tagtype lookups
|
||||
|
@ -36,6 +36,16 @@ typedef struct {
|
|||
const char *hint;
|
||||
} 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 {
|
||||
MTNONE = 0,
|
||||
MTCLASSIC = 1,
|
||||
|
@ -49,6 +59,9 @@ typedef enum {
|
|||
MTFUDAN = 256,
|
||||
MTISO18092 = 512,
|
||||
MT424 = 1024,
|
||||
MTULTRALIGHT_C = 2048,
|
||||
MTDUOX = 4096,
|
||||
MTNTAG = 8192,
|
||||
} nxp_mifare_type_t;
|
||||
|
||||
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 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 hf14a_setconfig(hf14a_config *config, bool verbose);
|
||||
int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status,
|
||||
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 infoHF14A4Applications(bool verbose);
|
||||
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 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_WithParameters(bool disconnect, bool verbose, iso14a_card_select_t *card, iso14a_polling_parameters_t *polling_parameters);
|
||||
|
||||
bool Get_apdu_in_framing(void);
|
||||
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
|
||||
|
|
|
@ -1411,7 +1411,7 @@ static bool HF14B_ask_ct_reader(bool verbose) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool HF14B_picopass_reader(bool verbose, bool info) {
|
||||
static bool HF14B_picopass_reader(bool verbose) {
|
||||
|
||||
iso14b_raw_cmd_t packet = {
|
||||
.flags = (ISO14B_CONNECT | ISO14B_SELECT_PICOPASS | ISO14B_DISCONNECT),
|
||||
|
@ -1437,10 +1437,8 @@ bool HF14B_picopass_reader(bool verbose, bool info) {
|
|||
return false;
|
||||
}
|
||||
memcpy(card, resp.data.asBytes, sizeof(picopass_hdr_t));
|
||||
if (info) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, "iCLASS / Picopass CSN: " _GREEN_("%s"), sprint_hex(card->csn, sizeof(card->csn)));
|
||||
}
|
||||
free(card);
|
||||
return true;
|
||||
}
|
||||
|
@ -3029,14 +3027,15 @@ int infoHF14B(bool verbose, bool do_aid_search) {
|
|||
|
||||
// try unknown 14b read commands (to be identified later)
|
||||
// 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;
|
||||
}
|
||||
|
||||
// get and print general info about all known 14b chips
|
||||
int readHF14B(bool loop, bool verbose, bool read_plot) {
|
||||
bool found = false;
|
||||
bool info = true;
|
||||
int res = PM3_SUCCESS;
|
||||
do {
|
||||
found = false;
|
||||
|
@ -3052,7 +3051,7 @@ int readHF14B(bool loop, bool verbose, bool read_plot) {
|
|||
goto plot;
|
||||
|
||||
// Picopass
|
||||
found |= HF14B_picopass_reader(verbose, info);
|
||||
found |= HF14B_picopass_reader(verbose);
|
||||
if (found)
|
||||
goto plot;
|
||||
|
||||
|
|
|
@ -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 readHF14B(bool loop, bool verbose, bool read_plot);
|
||||
bool HF14B_picopass_reader(bool verbose, bool info);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,22 +50,6 @@
|
|||
#define Logic1 Iso15693Logic1
|
||||
#define FrameEOF Iso15693FrameEOF
|
||||
#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
|
||||
#define ISO15_ERROR_HANDLING_RESPONSE { \
|
||||
|
@ -98,6 +82,11 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t lock;
|
||||
uint8_t block[8];
|
||||
} t15memory_t;
|
||||
|
||||
// structure and database for uid -> tagtype lookups
|
||||
typedef struct {
|
||||
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) {
|
||||
|
||||
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) {
|
||||
reason = 1;
|
||||
} else {
|
||||
// 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) {
|
||||
reason = 2;
|
||||
} else {
|
||||
// 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) {
|
||||
reason = 3;
|
||||
} else {
|
||||
// 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) {
|
||||
reason = 3;
|
||||
}
|
||||
|
@ -474,7 +463,7 @@ static int getUID(bool verbose, bool loop, uint8_t *buf) {
|
|||
|
||||
// used with 'hf search'
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -665,7 +654,7 @@ static int NxpTestEAS(const uint8_t *uid) {
|
|||
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);
|
||||
if (packet == NULL) {
|
||||
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++] = 0x04; // IC manufacturer code
|
||||
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); // add UID
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH); // add UID
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
|
||||
AddCrc15(packet->raw, packet->rawlen);
|
||||
packet->rawlen += 2;
|
||||
|
@ -720,7 +709,7 @@ static int NxpCheckSig(uint8_t *uid) {
|
|||
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);
|
||||
if (packet == NULL) {
|
||||
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++] = 0x04; // IC manufacturer code
|
||||
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); // add UID
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH); // add UID
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
|
||||
AddCrc15(packet->raw, packet->rawlen);
|
||||
packet->rawlen += 2;
|
||||
|
@ -787,7 +776,7 @@ static int NxpSysInfo(uint8_t *uid) {
|
|||
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
||||
|
||||
memcpy(packet->raw + 3, uid, 8); // add UID
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
|
||||
AddCrc15(packet->raw, packet->rawlen);
|
||||
packet->rawlen += 2;
|
||||
|
@ -900,11 +889,11 @@ static int StCheckSig(uint8_t *uid) {
|
|||
}
|
||||
|
||||
// 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;
|
||||
// add UID (scan, uid)
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
packet->flags = (ISO15_CONNECT | ISO15_READ_RESPONSE | ISO15_NO_DISCONNECT);
|
||||
uint16_t blkoff = packet->rawlen;
|
||||
char signature_hex[65] = {0};
|
||||
|
@ -943,9 +932,9 @@ static int StCheckSig(uint8_t *uid) {
|
|||
uint8_t signature[16];
|
||||
size_t signature_len;
|
||||
hexstr_to_byte_array(signature_hex, signature, &signature_len);
|
||||
uint8_t uid_swap[HF15_UID_LENGTH];
|
||||
reverse_array_copy(uid, HF15_UID_LENGTH, uid_swap);
|
||||
int index = originality_check_verify_ex(uid_swap, HF15_UID_LENGTH, signature, signature_len, PK_ST25TV, false, true);
|
||||
uint8_t uid_swap[ISO15693_UID_LENGTH];
|
||||
reverse_array_copy(uid, ISO15693_UID_LENGTH, uid_swap);
|
||||
int index = originality_check_verify_ex(uid_swap, ISO15693_UID_LENGTH, signature, signature_len, PK_ST25TV, false, true);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return originality_check_print(signature, signature_len, index);
|
||||
}
|
||||
|
@ -970,7 +959,7 @@ static int CmdHF15Info(const char *Cmd) {
|
|||
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
int uidlen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||
bool unaddressed = arg_get_lit(ctx, 2);
|
||||
|
@ -987,7 +976,7 @@ static int CmdHF15Info(const char *Cmd) {
|
|||
}
|
||||
|
||||
// default fallback to scan for tag.
|
||||
if (unaddressed == false && uidlen != HF15_UID_LENGTH) {
|
||||
if (unaddressed == false && uidlen != ISO15693_UID_LENGTH) {
|
||||
scan = true;
|
||||
}
|
||||
|
||||
|
@ -1014,10 +1003,10 @@ static int CmdHF15Info(const char *Cmd) {
|
|||
free(packet);
|
||||
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)
|
||||
memcpy(packet->raw + packet->rawlen, uid, uidlen);
|
||||
packet->rawlen += uidlen;
|
||||
|
@ -1251,8 +1240,11 @@ static int CmdHF15ELoad(const char *Cmd) {
|
|||
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
||||
(tag->pagesCount == 0) ||
|
||||
(tag->bytesPerPage == 0)) {
|
||||
|
||||
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
||||
tag->pagesCount, tag->bytesPerPage);
|
||||
tag->pagesCount,
|
||||
tag->bytesPerPage
|
||||
);
|
||||
free(tag);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -1486,7 +1478,7 @@ static int CmdHF15Sim(const char *Cmd) {
|
|||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
struct {
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
uint8_t block_size;
|
||||
} PACKED payload;
|
||||
memset(&payload, 0, sizeof(payload));
|
||||
|
@ -1497,7 +1489,7 @@ static int CmdHF15Sim(const char *Cmd) {
|
|||
CLIParserFree(ctx);
|
||||
|
||||
// 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);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -1624,7 +1616,7 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
|||
struct {
|
||||
uint8_t pwd[4];
|
||||
bool use_pwd;
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
bool use_uid;
|
||||
uint8_t afi;
|
||||
} PACKED payload;
|
||||
|
@ -1645,7 +1637,7 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
|||
}
|
||||
|
||||
payload.use_uid = false;
|
||||
if (uidlen == HF15_UID_LENGTH) {
|
||||
if (uidlen == ISO15693_UID_LENGTH) {
|
||||
payload.use_uid = true;
|
||||
}
|
||||
|
||||
|
@ -1703,7 +1695,7 @@ static int CmdHF15WriteDsfid(const char *Cmd) {
|
|||
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH] = {0};
|
||||
uint8_t uid[ISO15693_UID_LENGTH] = {0};
|
||||
int uidlen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||
|
||||
|
@ -1742,10 +1734,10 @@ static int CmdHF15WriteDsfid(const char *Cmd) {
|
|||
free(packet);
|
||||
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)
|
||||
memcpy(packet->raw + packet->rawlen, uid, uidlen);
|
||||
packet->rawlen += uidlen;
|
||||
|
@ -1807,7 +1799,7 @@ static int CmdHF15Dump(const char *Cmd) {
|
|||
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH] = {0};
|
||||
uint8_t uid[ISO15693_UID_LENGTH] = {0};
|
||||
int uidlen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||
|
||||
|
@ -1838,7 +1830,7 @@ static int CmdHF15Dump(const char *Cmd) {
|
|||
}
|
||||
|
||||
// default fallback to scan for tag.
|
||||
if (uidlen != HF15_UID_LENGTH && !unaddressed) {
|
||||
if (uidlen != ISO15693_UID_LENGTH && !unaddressed) {
|
||||
scan = true;
|
||||
}
|
||||
|
||||
|
@ -1874,11 +1866,11 @@ static int CmdHF15Dump(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
} else {
|
||||
reverse_array(uid, HF15_UID_LENGTH);
|
||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
||||
}
|
||||
// add UID (scan, uid)
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
used_uid = true;
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||
|
@ -1915,33 +1907,47 @@ static int CmdHF15Dump(const char *Cmd) {
|
|||
uint8_t dCpt = 10;
|
||||
|
||||
int res = iso15_error_handling_card_response(d, resp.length);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (res == PM3_ECRC) {
|
||||
free(tag);
|
||||
free(packet);
|
||||
return res;
|
||||
}
|
||||
|
||||
memcpy(tag->uid, &d[2], 8);
|
||||
if (res == PM3_SUCCESS) {
|
||||
memcpy(tag->uid, d + 2, 8);
|
||||
|
||||
if (d[1] & 0x01) {
|
||||
tag->dsfid = d[dCpt++];
|
||||
tag->dsfid = d[dCpt];
|
||||
}
|
||||
dCpt++;
|
||||
|
||||
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;
|
||||
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++];
|
||||
tag->ic = d[dCpt];
|
||||
}
|
||||
dCpt++;
|
||||
|
||||
} else {
|
||||
tag->uid[0] = 0xE0;
|
||||
tag->dsfid = 0;
|
||||
tag->afi = 0;
|
||||
// Set tag memory layout values (if can't be read in SYSINFO)
|
||||
tag->bytesPerPage = blocksize;
|
||||
tag->pagesCount = 128;
|
||||
}
|
||||
|
||||
// add length for blockno (1)
|
||||
|
@ -2178,10 +2184,10 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
|||
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH] = {0x00};
|
||||
uint8_t uid[ISO15693_UID_LENGTH] = {0x00};
|
||||
int uidlen = 0;
|
||||
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 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;
|
||||
}
|
||||
} else {
|
||||
reverse_array(uid, HF15_UID_LENGTH);
|
||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
||||
}
|
||||
// add UID (scan, uid)
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||
|
@ -2255,7 +2261,9 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
|||
|
||||
// 0 means 1 page,
|
||||
// 1 means 2 pages, ...
|
||||
if (blockcnt > 0) blockcnt--;
|
||||
if (blockcnt > 0) {
|
||||
blockcnt--;
|
||||
}
|
||||
|
||||
packet->raw[packet->rawlen++] = blockno;
|
||||
packet->raw[packet->rawlen++] = blockcnt;
|
||||
|
@ -2285,7 +2293,7 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
|||
ISO15_ERROR_HANDLING_CARD_RESPONSE(d, resp.length)
|
||||
|
||||
// 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!");
|
||||
}
|
||||
|
||||
|
@ -2336,10 +2344,10 @@ static int CmdHF15Readblock(const char *Cmd) {
|
|||
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
int uidlen = 0;
|
||||
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 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;
|
||||
}
|
||||
} else {
|
||||
reverse_array(uid, HF15_UID_LENGTH);
|
||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
||||
}
|
||||
// add UID (scan, uid)
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
|
||||
} else {
|
||||
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
|
||||
if (uid) {
|
||||
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||
packet->rawlen += HF15_UID_LENGTH;
|
||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
||||
packet->rawlen += ISO15693_UID_LENGTH;
|
||||
}
|
||||
|
||||
packet->raw[packet->rawlen++] = blockno;
|
||||
|
@ -2550,10 +2558,10 @@ static int CmdHF15Write(const char *Cmd) {
|
|||
argtable[arglen++] = arg_param_end;
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
int uidlen = 0;
|
||||
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 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;
|
||||
}
|
||||
} else {
|
||||
reverse_array(uid, HF15_UID_LENGTH);
|
||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
||||
}
|
||||
} else {
|
||||
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"
|
||||
);
|
||||
|
||||
void *argtable[6 + 5] = {0};
|
||||
void *argtable[6 + 4] = {0};
|
||||
uint8_t arglen = arg_add_default(argtable);
|
||||
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)");
|
||||
|
@ -2632,7 +2640,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
|||
argtable[arglen++] = arg_param_end;
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
int uidlen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||
|
||||
|
@ -2662,7 +2670,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
|||
|
||||
// default fallback to scan for tag.
|
||||
// overriding unaddress parameter :)
|
||||
if (uidlen != HF15_UID_LENGTH) {
|
||||
if (uidlen != ISO15693_UID_LENGTH) {
|
||||
scan = true;
|
||||
}
|
||||
|
||||
|
@ -2674,7 +2682,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
} else {
|
||||
reverse_array(uid, HF15_UID_LENGTH);
|
||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
||||
}
|
||||
} else {
|
||||
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 == 0) ||
|
||||
(tag->bytesPerPage == 0)) {
|
||||
|
||||
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
||||
tag->pagesCount, tag->bytesPerPage);
|
||||
tag->pagesCount,
|
||||
tag->bytesPerPage
|
||||
);
|
||||
free(tag);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -2745,8 +2756,8 @@ static int CmdHF15Restore(const char *Cmd) {
|
|||
|
||||
for (tried = 0; tried < retries; tried++) {
|
||||
|
||||
retval = hf_15_write_blk(&pm3flags, flags, uid, fast
|
||||
, i, data, tag->bytesPerPage);
|
||||
retval = hf_15_write_blk(&pm3flags, flags, uid, fast, i, data, tag->bytesPerPage);
|
||||
|
||||
if (retval == PM3_SUCCESS) {
|
||||
PrintAndLogEx(INPLACE, "blk %3d", i);
|
||||
|
||||
|
@ -2809,7 +2820,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
|||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
struct {
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
} PACKED payload;
|
||||
|
||||
int uidlen = 0;
|
||||
|
@ -2817,7 +2828,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
|||
bool use_v2 = arg_get_lit(ctx, 2);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (uidlen != HF15_UID_LENGTH) {
|
||||
if (uidlen != ISO15693_UID_LENGTH) {
|
||||
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got " _RED_("%i"), uidlen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -2831,7 +2842,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
|||
|
||||
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) {
|
||||
PrintAndLogEx(FAILED, "no tag found");
|
||||
return PM3_ESOFT;
|
||||
|
@ -2861,10 +2872,10 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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(NORMAL, "");
|
||||
return PM3_SUCCESS;;
|
||||
|
@ -3478,8 +3489,11 @@ static int CmdHF15View(const char *Cmd) {
|
|||
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
||||
(tag->pagesCount == 0) ||
|
||||
(tag->bytesPerPage == 0)) {
|
||||
|
||||
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
||||
tag->pagesCount, tag->bytesPerPage);
|
||||
tag->pagesCount,
|
||||
tag->bytesPerPage
|
||||
);
|
||||
free(tag);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -3498,15 +3512,15 @@ static int CmdHF15Wipe(const char *Cmd) {
|
|||
);
|
||||
void *argtable[6 + 3] = {0};
|
||||
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_param_end;
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint8_t uid[HF15_UID_LENGTH];
|
||||
uint8_t uid[ISO15693_UID_LENGTH];
|
||||
int uidlen = 0;
|
||||
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 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;
|
||||
}
|
||||
} else {
|
||||
reverse_array(uid, HF15_UID_LENGTH);
|
||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||
|
|
|
@ -20,9 +20,24 @@
|
|||
#define CMDHF15_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);
|
||||
|
||||
bool readHF15Uid(bool loop, bool verbose);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1888,7 +1888,8 @@ static int CmdHFCipurseDefault(const char *Cmd) {
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"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"},
|
||||
{"auth", CmdHFCipurseAuth, IfPm3Iso14443a, "Authenticate CIPURSE tag"},
|
||||
{"read", CmdHFCipurseReadFile, IfPm3Iso14443a, "Read binary file"},
|
||||
|
|
|
@ -2449,8 +2449,9 @@ static int CmdHFeMRTDList(const char *Cmd) {
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"-----------", CmdHelp, IfPm3Iso14443, "------------------- " _CYAN_("Operations") " -------------------"},
|
||||
{"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"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
|
|
@ -1803,7 +1803,7 @@ static int CmdHFFelicaSniff(const char *Cmd) {
|
|||
for (;;) {
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
||||
msleep(300);
|
||||
break;
|
||||
}
|
||||
|
@ -1851,7 +1851,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) {
|
|||
for (;;) {
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
||||
msleep(300);
|
||||
break;
|
||||
}
|
||||
|
@ -2054,7 +2054,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
|
|||
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
||||
return PM3_EOPABORTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -913,7 +913,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help."},
|
||||
{"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."},
|
||||
{"auth", CmdHFFidoAuthenticate, IfPm3Iso14443a, "FIDO U2F Authentication Message."},
|
||||
{"make", CmdHFFido2MakeCredential, IfPm3Iso14443a, "FIDO2 MakeCredential command."},
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -584,7 +584,7 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
|||
for (;;) {
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -358,7 +358,7 @@ end:
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"select", CmdHFKSX6924Select, IfPm3Iso14443a, "Select application, and leave field up"},
|
||||
{"info", CmdHFKSX6924Info, IfPm3Iso14443a, "Get info about a KS X 6924 (T-Money, Snapper+) transit card"},
|
||||
{"info", CmdHFKSX6924Info, IfPm3Iso14443a, "Tag information"},
|
||||
{"balance", CmdHFKSX6924Balance, IfPm3Iso14443a, "Get current purse balance"},
|
||||
{"init", CmdHFKSX6924Initialize, IfPm3Iso14443a, "Perform transaction initialization with Mpda"},
|
||||
{"prec", CmdHFKSX6924PRec, IfPm3Iso14443a, "Send proprietary get record command (CLA=90, INS=4C)"},
|
||||
|
|
|
@ -560,7 +560,7 @@ static int CmdLegicSim(const char *Cmd) {
|
|||
for (;;) {
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
PrintAndLogEx(DEBUG, "Aborted via keyboard!");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16
|
|||
SendCommandMIX(CMD_HF_ISO14443A_READER, arg0, arg1, 0, cmd, len);
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) {
|
||||
if (verbose) PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
|
1082
client/src/cmdhfmf.c
1082
client/src/cmdhfmf.c
File diff suppressed because it is too large
Load diff
|
@ -35,9 +35,13 @@ void printKeyTable(size_t sectorscnt, sector_t *e_sector);
|
|||
void printKeyTableEx(size_t sectorscnt, sector_t *e_sector, uint8_t start_sector);
|
||||
// void printKeyTableEx(size_t sectorscnt, sector_t *e_sector, uint8_t start_sector, bool singel_sector);
|
||||
|
||||
|
||||
bool mfc_value(const uint8_t *d, int32_t *val);
|
||||
void mf_print_sector_hdr(uint8_t sector);
|
||||
void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose);
|
||||
|
||||
int mf_print_keys(uint16_t n, uint8_t *d);
|
||||
void mf_print_blocks(uint16_t n, uint8_t *d, bool verbose);
|
||||
|
||||
int mfc_ev1_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len);
|
||||
#endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue