mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Compare commits
192 commits
Author | SHA1 | Date | |
---|---|---|---|
|
6ee974b935 | ||
|
b443f6327c | ||
|
e578d75e66 | ||
|
4af87a2f91 | ||
|
833eea49ec |
||
|
63b4612f18 |
||
|
c9f9fcb198 | ||
|
7085e8ff7f |
||
|
b1a03ec27e |
||
|
160eb44fcc |
||
|
515d8c76fa | ||
|
b09e3614da | ||
|
8ab2f2b5a0 | ||
|
d75b170cd4 | ||
|
72e47e4fcb | ||
|
2279d415a4 |
||
|
50972c0232 |
||
|
30689f7d3c |
||
|
a0df90af18 | ||
|
09c4446f78 | ||
|
ce82c85684 |
||
|
989dad18cc | ||
|
6bb377667a |
||
|
dccfb391aa | ||
|
9448a41e7d | ||
|
595517bfed | ||
|
0e95c62add |
||
|
52c9d90d64 | ||
|
60982bb53f | ||
|
72d475f484 | ||
|
ac0f747104 | ||
|
948dce9230 | ||
|
d48ba1177c |
||
|
a8d74d6d60 |
||
|
13053e14d1 |
||
|
ddaa6de5cf |
||
|
d824040441 |
||
|
5a627381af |
||
|
a1e9b4716c |
||
|
4f77c18ab4 |
||
|
ee2f5595ee | ||
|
c997805117 | ||
|
79d1e102af | ||
|
0dacfb996f | ||
|
ec144c5198 |
||
|
7e7fe1837e |
||
|
b7bf392297 |
||
|
ab6e203560 |
||
|
9ce9031516 |
||
|
9dd6e4a85f |
||
|
928ab8e027 |
||
|
e94921c1af | ||
|
8014aa0361 | ||
|
4090828ebc | ||
|
3b88dd45a3 | ||
|
c74d04bfe7 | ||
|
83c54bb174 | ||
|
90d766a811 | ||
|
e7cbf9ff63 | ||
|
06a9a67aae | ||
|
48724e44b4 | ||
|
47b7827982 | ||
|
f943a38558 |
||
|
7472217aeb |
||
|
008693635f |
||
|
12e68d7a28 | ||
|
43a012b613 |
||
|
b3b24855d0 |
||
|
e1598cd620 |
||
|
ae8b71197d |
||
|
95759a13ba |
||
|
e0e7de2853 |
||
|
b2939332c2 |
||
|
77bae8a9cb |
||
|
c32a55eabc |
||
|
d933e329c4 | ||
|
7c187b0ad5 |
||
|
ed84b1fcf4 | ||
|
64111a43ea | ||
|
8de424410f | ||
|
53595e0a3a | ||
|
8f9bb379ad | ||
|
ef372a5ef0 | ||
|
ca6dbc5251 | ||
|
0dc80263e8 | ||
|
58690ed24e | ||
|
e509967abf |
||
|
134d76f60d | ||
|
7cf206030d | ||
|
c8219a6030 | ||
|
66fc610a66 | ||
|
c25dbf8f21 | ||
|
c216fbeeaf | ||
|
49a45519b8 |
||
|
2d3ad38853 |
||
|
2597c7576e | ||
|
cb8bb8d520 |
||
|
3e0127086b |
||
|
c39e18a014 | ||
|
ac6916777f |
||
|
36f5a0c69b |
||
|
815d445382 | ||
|
931e93a11b | ||
|
fa59b9cb6b | ||
|
a3c2d2b815 | ||
|
c7cf62fcf1 | ||
|
138039b232 |
||
|
09bdb0c566 |
||
|
732cc1b82e |
||
|
ed504a76ca |
||
|
7717dfc04d | ||
|
53b2dc7d4b |
||
|
b27d3edb1a |
||
|
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 | ||
|
1199710644 |
||
|
2eb9d7f661 |
202 changed files with 10426 additions and 1483 deletions
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -2,7 +2,34 @@
|
|||
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...
|
||||
|
||||
## [Daddy Iceman][2025-06-16]
|
||||
## [unreleased][unreleased]
|
||||
- Changed from Bigbuf malloc to Bigbuf calloc calls on device side (@iceman1001)
|
||||
- Added `lf t55xx view` - now viewing of T55XX dump files is possible (@iceman1001)
|
||||
- Fixed `lf indala cone` - now writing the right bits when using `--fc` and `--cn`
|
||||
- Changed readline hack logic for async dbg msg to be ready for readline 8.3 (@doegox)
|
||||
- Improved To avoid conflicts with ModemManager on Linux, is recommended to masking the service (@grugnoymeme)
|
||||
- Changed `data crypto` - now also handles AES-256 (@iceman1001)
|
||||
- Changed `hf mfdes info` - add recognition of Swissbit iShield Key Mifare (@ah01)
|
||||
- Changed `hf mf info` - add detection for unknown backdoor keys and for some backdoor variants (@doegox)
|
||||
- Changed `mqtt` commnands - now honors preference settings (@iceman1001)
|
||||
- Changed `prefs` - now handles MQTT settings too (@iceman1001)
|
||||
- Fixed `mqtt` segfault and gdb warning under windows (proper thread stopping and socket handling). (@virtyvoid)
|
||||
- Added `mqtt` - the pm3 client can now send and receive MQTT messages or json files. (@iceman1001)
|
||||
- Changed `hf iclass wrbl` - replay behavior to use privilege escalation if the macs field is not passed empty(@antiklesys)
|
||||
- Changed `hf iclass restore` - it now supports privilege escalation to restore card content using replay (@antiklesys)
|
||||
- Fixed `hf 15 dump` - now reads sysinfo response correct (@iceman1001)
|
||||
- Changed `make clean` - it now removes all __pycache__ folders (@iceman1001)
|
||||
- Fixed `hf 15 readmulti` - fix block calculations (@iceman1001)
|
||||
- Changed `mem load` - now handles UL-C and UL-AES dictionary files (@iceman1001)
|
||||
- Changed `hf mfu sim` - now support UL-C simulation (@iceman1001)
|
||||
- Added `!` - run system commands from inside the client. Potentially dangerous if running client as SUDO, SU, ROOT (@iceman1001)
|
||||
- Implemented `hf felica scsvcode` - now dumps all service and area codes. (@zinongli)
|
||||
- Added `hf felica liteauth` - now support FeliCa Lite-S authentication(@q0jt)
|
||||
- Added `he felica dump` - partial support for dumping all blocks from unauth readable services (@zinongli)
|
||||
- Changed `hf 14b calypso` - now don't break the file id loop when one file can't be selected or read. Add new file ids to iterate through (@zinongli)
|
||||
|
||||
|
||||
## [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)
|
||||
|
|
9
Makefile
9
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
|
||||
|
@ -369,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
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Comment the line below and uncomment further down according to which device you have
|
||||
PLATFORM=PM3RDV4
|
||||
|
||||
# For PM3 Easy:
|
||||
# For PM3 RDV1, RDV2, Easy or rysccorps etc
|
||||
# uncomment the line below
|
||||
#PLATFORM=PM3GENERIC
|
||||
|
||||
|
@ -22,8 +22,8 @@ PLATFORM=PM3RDV4
|
|||
#PLATFORM_EXTRAS=BTADDON
|
||||
#PLATFORM_EXTRAS=FLASH
|
||||
#PLATFORM_EXTRAS=SMARTCARD
|
||||
#PLATFORM_EXTRAS=BTADDON FLASH
|
||||
#STANDALONE=LF_SAMYRUN
|
||||
#PLATFORM_EXTRAS=BTADDON FPC_USART_DEV FLASH
|
||||
#STANDALONE=HF_UNISNIFF
|
||||
|
||||
|
||||
# Uncomment the line below to set the correct LED order on board Proxmark3 Easy
|
||||
|
|
12
README.md
12
README.md
|
@ -60,7 +60,8 @@ The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the
|
|||
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)|[Notes on Magic UID cards](/doc/magic_cards_notes.md)|
|
||||
|[Notes on Color usage](/doc/colors_notes.md)|[Makefile vs CMake](/doc/md/Development/Makefile-vs-CMake.md)|[Notes on Cloner guns](/doc/cloner_notes.md)|
|
||||
|[Notes on cliparser usage](/doc/cliparser.md)|[Notes on clocks](/doc/clocks.md)|[Notes on MIFARE DESFire](/doc/desfire.md)|
|
||||
|[Notes on CIPURSE](/doc/cipurse.md)|[Notes on NDEF type4a](/doc/ndef_type4a.md)|[Notes on downgrade attacks](/doc/hid_downgrade.md)|
|
||||
|[Notes on CIPURSE](/doc/cipurse.md)|[Notes on NDEF type4a](/doc/ndef_type4a.md)|[Unofficial MIFARE DESFire bible](/doc/unofficial_desfire_bible.md)|
|
||||
[Notes on downgrade attacks](/doc/hid_downgrade.md)|||
|
||||
|
||||
# How to build?
|
||||
|
||||
|
@ -96,12 +97,14 @@ We define generic Proxmark3 platforms as following devices.
|
|||
- **Note**: currently incompatible with iCopy-X GUI as Proxmark client commands using different syntax
|
||||
- **Note**: see also [icopyx-community repos](https://github.com/iCopy-X-Community/) for upstream sources, reversed hw etc.
|
||||
- **Note**: Uses DRM to lock down tags, ignores the open source licences. Use on your own risk.
|
||||
- ⚠ Proxmark3 Ultimate
|
||||
- **Note**: unknown device hw
|
||||
- **Note**: FPGA images is building for it. Use on your own risk.
|
||||
|
||||
**Unknown support status**
|
||||
- ⚠ VX
|
||||
- **Note**: unknown device hw
|
||||
- ⚠ Proxmark3 Ultimate
|
||||
- **Note**: unknown device hw
|
||||
|
||||
|
||||
When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.
|
||||
|
||||
|
@ -180,10 +183,11 @@ We usually merge your contributions fast since we do like the idea of getting a
|
|||
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
|
||||
|
||||
|
||||
## Supported operative systems
|
||||
## Supported operating systems
|
||||
|
||||
This repo compiles nicely on
|
||||
- WSL1 on Windows 10
|
||||
- WSL2 on Windows 10/11
|
||||
- Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases)
|
||||
- Windows/MinGW environment
|
||||
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian
|
||||
|
|
|
@ -354,7 +354,7 @@ int emlGet(uint8_t *out, uint32_t offset, uint32_t length) {
|
|||
tosend_t *get_tosend(void) {
|
||||
|
||||
if (s_toSend.buf == NULL) {
|
||||
s_toSend.buf = BigBuf_malloc(TOSEND_BUFFER_SIZE);
|
||||
s_toSend.buf = BigBuf_calloc(TOSEND_BUFFER_SIZE);
|
||||
}
|
||||
return &s_toSend;
|
||||
}
|
||||
|
@ -377,8 +377,9 @@ void tosend_stuffbit(int b) {
|
|||
s_toSend.bit = 0;
|
||||
}
|
||||
|
||||
if (b)
|
||||
if (b) {
|
||||
s_toSend.buf[s_toSend.max] |= (1 << (7 - s_toSend.bit));
|
||||
}
|
||||
|
||||
s_toSend.bit++;
|
||||
|
||||
|
@ -389,15 +390,14 @@ void tosend_stuffbit(int b) {
|
|||
|
||||
dmabuf16_t *get_dma16(void) {
|
||||
if (s_dma_16.buf == NULL) {
|
||||
s_dma_16.buf = (uint16_t *)BigBuf_malloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
|
||||
s_dma_16.buf = (uint16_t *)BigBuf_calloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
return &s_dma_16;
|
||||
}
|
||||
|
||||
dmabuf8_t *get_dma8(void) {
|
||||
if (s_dma_8.buf == NULL)
|
||||
s_dma_8.buf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
|
||||
if (s_dma_8.buf == NULL) {
|
||||
s_dma_8.buf = BigBuf_calloc(DMA_BUFFER_SIZE);
|
||||
}
|
||||
return &s_dma_8;
|
||||
}
|
||||
|
|
|
@ -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 $@)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -63,18 +63,18 @@ static void RAMFUNC SniffAndStore(uint8_t param) {
|
|||
set_tracing(true);
|
||||
|
||||
// Array to store the authpwds
|
||||
uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION);
|
||||
uint8_t *capturedPwds = BigBuf_calloc(4 * MAX_PWDS_PER_SESSION);
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *receivedResp = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedRespPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
uint8_t *dmaBuf = BigBuf_calloc(DMA_BUFFER_SIZE);
|
||||
uint8_t *data = dmaBuf;
|
||||
|
||||
uint8_t previous_data = 0;
|
||||
|
|
|
@ -234,7 +234,7 @@ static void become_card(void) {
|
|||
tag_response_info_t *canned;
|
||||
uint32_t cuid;
|
||||
uint8_t pages;
|
||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, &pages) == false) {
|
||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, &pages, NULL) == false) {
|
||||
DbpString(_RED_("Error initializing the emulation process!"));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ static char *ReadSchemasFromSPIFFS(char *filename) {
|
|||
|
||||
int changed = rdv40_spiffs_lazy_mount();
|
||||
uint32_t size = size_in_spiffs((char *)filename);
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
uint8_t *mem = BigBuf_calloc(size);
|
||||
rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
if (changed) {
|
||||
|
@ -292,7 +292,7 @@ static void ReadLastTagFromFlash(void) {
|
|||
DbprintfEx(FLAG_NEWLINE, "Button HELD ! Using LAST Known TAG for Simulation...");
|
||||
cjSetCursLeft();
|
||||
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
uint8_t *mem = BigBuf_calloc(size);
|
||||
|
||||
// this one will handle filetype (symlink or not) and resolving by itself
|
||||
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
@ -445,11 +445,11 @@ void RunMod(void) {
|
|||
};
|
||||
|
||||
// Can remember something like that in case of Bigbuf
|
||||
keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
|
||||
keyBlock = BigBuf_calloc(ARRAYLEN(mfKeys) * MF_KEY_LENGTH);
|
||||
int mfKeysCnt = ARRAYLEN(mfKeys);
|
||||
|
||||
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
|
||||
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
|
||||
num_to_bytes(mfKeys[mfKeyCounter], MF_KEY_LENGTH, (uint8_t *)(keyBlock + (mfKeyCounter * MF_KEY_LENGTH)));
|
||||
}
|
||||
|
||||
// TODO : remember why we actually had need to initialize this array in such specific case
|
||||
|
@ -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
|
||||
|
|
|
@ -238,7 +238,7 @@ static int reader_attack_mode(void) {
|
|||
|
||||
BigBuf_free();
|
||||
uint16_t mac_response_len = 0;
|
||||
uint8_t *mac_responses = BigBuf_malloc(MAC_RESPONSES_SIZE);
|
||||
uint8_t *mac_responses = BigBuf_calloc(MAC_RESPONSES_SIZE);
|
||||
|
||||
iclass_simulate(ICLASS_SIM_MODE_READER_ATTACK, NUM_CSNS, false, csns, mac_responses, &mac_response_len);
|
||||
|
||||
|
@ -250,7 +250,7 @@ static int reader_attack_mode(void) {
|
|||
|
||||
size_t dumplen = NUM_CSNS * 24;
|
||||
|
||||
uint8_t *dump = BigBuf_malloc(dumplen);
|
||||
uint8_t *dump = BigBuf_calloc(dumplen);
|
||||
if (dump == false) {
|
||||
Dbprintf("Failed to allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
|
@ -305,6 +305,7 @@ static int reader_dump_mode(void) {
|
|||
BigBuf_free();
|
||||
|
||||
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
|
||||
// Don't use calloc since we set allocated memory to 0xFF's
|
||||
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
|
||||
|
||||
if (BUTTON_PRESS()) {
|
||||
|
@ -442,6 +443,7 @@ static int dump_sim_mode(void) {
|
|||
BigBuf_free();
|
||||
|
||||
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
|
||||
// Don't use calloc since we set allocated memory to 0xFF's
|
||||
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
|
||||
|
||||
if (BUTTON_PRESS()) {
|
||||
|
|
|
@ -247,7 +247,7 @@ void RunMod(void) {
|
|||
// usb_disable();
|
||||
|
||||
// Allocate dictionary buffer
|
||||
uint64_t *const mfcKeys = (uint64_t *)BigBuf_malloc(
|
||||
uint64_t *const mfcKeys = (uint64_t *)BigBuf_calloc(
|
||||
sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) +
|
||||
ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) +
|
||||
MIFARE_4K_MAXSECTOR * 2));
|
||||
|
|
|
@ -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) == 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) == 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!"));
|
||||
|
|
|
@ -191,7 +191,7 @@ void RunMod(void) {
|
|||
|
||||
memcpy(data, stuid, sizeof(stuid));
|
||||
|
||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &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!");
|
||||
|
@ -369,7 +369,7 @@ void RunMod(void) {
|
|||
|
||||
memcpy(data, stuid, sizeof(stuid));
|
||||
|
||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &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) {
|
||||
|
|
|
@ -199,7 +199,7 @@ static uint32_t IceIOdemod(void) {
|
|||
|
||||
size_t size = MIN(12000, BigBuf_max_traceLen());
|
||||
|
||||
// uint8_t *dest = BigBuf_malloc(size);
|
||||
// uint8_t *dest = BigBuf_calloc(size);
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
//fskdemod and get start index
|
||||
|
@ -243,7 +243,7 @@ static uint32_t IceHIDDemod(void) {
|
|||
// large enough to catch 2 sequences of largest format
|
||||
// size_t size = 50 * 128 * 2; // 12800 bytes
|
||||
size_t size = MIN(12800, BigBuf_max_traceLen());
|
||||
//uint8_t *dest = BigBuf_malloc(size);
|
||||
//uint8_t *dest = BigBuf_calloc(size);
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
// FSK demodulator
|
||||
|
|
|
@ -103,9 +103,9 @@ static bool get_input_data_from_file(uint32_t *tag, char *inputfile) {
|
|||
if (exists_in_spiffs(inputfile)) {
|
||||
|
||||
uint32_t size = size_in_spiffs(inputfile);
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
uint8_t *mem = BigBuf_calloc(size);
|
||||
|
||||
Dbprintf(_YELLOW_("found input file %s"), inputfile);
|
||||
Dbprintf("found input file `" _YELLOW_("%s") "`", inputfile);
|
||||
|
||||
rdv40_spiffs_read_as_filetype(inputfile, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
|
|
|
@ -480,6 +480,32 @@ static void SendStatus(uint32_t wait) {
|
|||
} else {
|
||||
Dbprintf(" iClass... "_RED_("%u")" keys - "_RED_("%s"), num, ICLASS_KEYS_FILE);
|
||||
}
|
||||
|
||||
if (exists_in_spiffs(MFULC_KEYS_FILE)) {
|
||||
num = size_in_spiffs(MFULC_KEYS_FILE) / MFULC_KEY_LENGTH;
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Dbprintf(" UL-C..... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MFULC_KEYS_FILE);
|
||||
} else {
|
||||
Dbprintf(" UL-C..... "_RED_("%u")" keys - "_RED_("%s"), num, MFULC_KEYS_FILE);
|
||||
}
|
||||
|
||||
if (exists_in_spiffs(MFULAES_KEYS_FILE)) {
|
||||
num = size_in_spiffs(MFULAES_KEYS_FILE) / MFULAES_KEY_LENGTH;
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Dbprintf(" UL-AES... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MFULAES_KEYS_FILE);
|
||||
} else {
|
||||
Dbprintf(" UL-AES... "_RED_("%u")" keys - "_RED_("%s"), num, MFULAES_KEYS_FILE);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
DbpString("");
|
||||
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
|
||||
|
@ -1723,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: {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -334,7 +334,7 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le
|
|||
return;
|
||||
}
|
||||
|
||||
uint8_t *buffer = BigBuf_malloc(padded_data_length(len, kbs));
|
||||
uint8_t *buffer = BigBuf_calloc(padded_data_length(len, kbs));
|
||||
|
||||
memcpy(buffer, data, len);
|
||||
|
||||
|
|
|
@ -497,7 +497,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
|||
BigBuf_Clear_ext(false);
|
||||
|
||||
// Initialize Demod and Uart structs
|
||||
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||
// DemodInit(BigBuf_calloc(MAX_FRAME_SIZE));
|
||||
FelicaFrameinit(BigBuf_calloc(FELICA_MAX_FRAME_SIZE));
|
||||
|
||||
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
|
||||
|
|
|
@ -523,10 +523,11 @@ void FpgaDownloadAndGo(int bitstream_target) {
|
|||
lz4_stream_t compressed_fpga_stream;
|
||||
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
|
||||
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
|
||||
uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
|
||||
uint8_t *output_buffer = BigBuf_calloc(FPGA_RING_BUFFER_BYTES);
|
||||
|
||||
if (!reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer))
|
||||
if (reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t bitstream_length;
|
||||
if (bitparse_find_section(bitstream_target, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "nprintf.h"
|
||||
|
||||
#include "BigBuf.h"
|
||||
#define malloc(X) BigBuf_malloc(X)
|
||||
#define malloc(X) BigBuf_calloc(X)
|
||||
#define free(X)
|
||||
|
||||
#if !defined(WEAK)
|
||||
|
|
|
@ -107,7 +107,7 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint
|
|||
SpinDelay(100);
|
||||
|
||||
*len = BigBuf_max_traceLen();
|
||||
uint8_t *mem = BigBuf_malloc(*len);
|
||||
uint8_t *mem = BigBuf_calloc(*len);
|
||||
|
||||
uint32_t trigger_cnt = 0;
|
||||
uint16_t r = 0, interval = 0;
|
||||
|
|
129
armsrc/iclass.c
129
armsrc/iclass.c
|
@ -917,8 +917,9 @@ send:
|
|||
|
||||
LEDsoff();
|
||||
|
||||
if (button_pressed)
|
||||
if (button_pressed) {
|
||||
DbpString("button pressed");
|
||||
}
|
||||
|
||||
return button_pressed;
|
||||
}
|
||||
|
@ -1857,8 +1858,39 @@ static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, b
|
|||
return true;
|
||||
}
|
||||
|
||||
uint8_t credit_key[8] = {0xFD, 0xCB, 0x5A, 0x52, 0xEA, 0x8F, 0x30, 0x90};
|
||||
|
||||
static bool do_privilege_escalation(uint8_t *read_check_cc, size_t cc_len, uint32_t *eof_time) {
|
||||
|
||||
int priv_esc_tries = 5;
|
||||
|
||||
while (priv_esc_tries--) {
|
||||
|
||||
uint16_t resp_len = 0;
|
||||
uint8_t resp[10] = {0};
|
||||
//The privilege escalation is done with a readcheck and not just a normal read!
|
||||
uint32_t start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
|
||||
iclass_send_as_reader(read_check_cc, cc_len, &start_time, eof_time, false);
|
||||
// expect a 8-byte response here
|
||||
int res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
|
||||
if (res == PM3_SUCCESS && resp_len == 8) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_dbglevel == DBG_INFO) {
|
||||
DbpString("");
|
||||
DbpString(_RED_("Unable to complete privilege escalation! Stopping."));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// turn off afterwards
|
||||
void iClass_WriteBlock(uint8_t *msg) {
|
||||
bool priv_esc = false;
|
||||
uint8_t read_check_cc[] = { 0x10 | ICLASS_CMD_READCHECK, 0x18 };
|
||||
uint8_t div_cc[8] = {0};
|
||||
|
||||
LED_A_ON();
|
||||
|
||||
|
@ -1878,6 +1910,9 @@ void iClass_WriteBlock(uint8_t *msg) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
iclass_calc_div_key(hdr.csn, credit_key, div_cc, false);
|
||||
read_check_cc[1] = hdr.conf.app_limit + 1; //first block of AA2
|
||||
|
||||
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
|
||||
uint8_t mac[4] = {0};
|
||||
|
@ -1904,7 +1939,7 @@ void iClass_WriteBlock(uint8_t *msg) {
|
|||
write_len -= 2;
|
||||
} else {
|
||||
|
||||
if (payload->req.use_replay) {
|
||||
if (payload->req.use_replay && (memcmp(payload->mac, "\x00\x00\x00\x00", 4) != 0)) {
|
||||
memcpy(write + 10, payload->mac, sizeof(payload->mac));
|
||||
} else {
|
||||
// Secure tags uses MAC
|
||||
|
@ -1912,10 +1947,17 @@ void iClass_WriteBlock(uint8_t *msg) {
|
|||
wb[0] = payload->req.blockno;
|
||||
memcpy(wb + 1, payload->data, PICOPASS_BLOCK_SIZE);
|
||||
|
||||
if (payload->req.use_credit_key)
|
||||
if (payload->req.use_credit_key) {
|
||||
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
||||
else
|
||||
} else if (payload->req.use_replay) {
|
||||
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
||||
if (priv_esc == false) {
|
||||
goto out;
|
||||
}
|
||||
doMAC_N(wb, sizeof(wb), div_cc, mac);
|
||||
} else {
|
||||
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
||||
}
|
||||
|
||||
memcpy(write + 10, mac, sizeof(mac));
|
||||
}
|
||||
|
@ -2553,6 +2595,9 @@ out:
|
|||
}
|
||||
|
||||
void iClass_Restore(iclass_restore_req_t *msg) {
|
||||
bool priv_esc = false;
|
||||
uint8_t read_check_cc[] = { 0x10 | ICLASS_CMD_READCHECK, 0x18 };
|
||||
uint8_t div_cc[8] = {0};
|
||||
|
||||
// sanitation
|
||||
if (msg == NULL) {
|
||||
|
@ -2581,7 +2626,9 @@ void iClass_Restore(iclass_restore_req_t *msg) {
|
|||
if (res == false) {
|
||||
goto out;
|
||||
}
|
||||
iclass_calc_div_key(hdr.csn, credit_key, div_cc, false);
|
||||
|
||||
read_check_cc[1] = hdr.conf.app_limit + 1; //first block of AA2
|
||||
// authenticate
|
||||
uint8_t mac[4] = {0};
|
||||
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
|
@ -2611,11 +2658,18 @@ void iClass_Restore(iclass_restore_req_t *msg) {
|
|||
wb[0] = item.blockno;
|
||||
memcpy(wb + 1, item.data, 8);
|
||||
|
||||
if (msg->req.use_credit_key)
|
||||
if (msg->req.use_credit_key) {
|
||||
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
||||
else
|
||||
} else if (msg->req.use_replay) {
|
||||
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
||||
if (priv_esc == false) {
|
||||
goto out;
|
||||
}
|
||||
doMAC_N(wb, sizeof(wb), div_cc, mac);
|
||||
} else {
|
||||
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
||||
}
|
||||
}
|
||||
|
||||
// data + mac
|
||||
if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac, shallow_mod)) {
|
||||
|
@ -2722,10 +2776,10 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
uint8_t original_mac[8] = {0};
|
||||
uint8_t mac1[4] = {0};
|
||||
|
||||
while (!card_select || !card_auth) {
|
||||
while ((card_select == false) || (card_auth == false)) {
|
||||
|
||||
Iso15693InitReader(); //has to be at the top as it starts tracing
|
||||
if (!msg->debug) {
|
||||
if (msg->debug == false) {
|
||||
set_tracing(false); //disable tracing to prevent crashes - set to true for debugging
|
||||
} else {
|
||||
if (loops == 1) {
|
||||
|
@ -2741,7 +2795,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
}
|
||||
|
||||
//Step 0A - The read_check_cc block has to be in AA2, set it by checking the card configuration
|
||||
read_check_cc[1] = ((uint8_t *)&hdr.conf)[0] + 1; //first block of AA2
|
||||
read_check_cc[1] = hdr.conf.app_limit + 1; //first block of AA2
|
||||
|
||||
//Step1 Authenticate with AA1 using trace
|
||||
if (card_select) {
|
||||
|
@ -2753,10 +2807,12 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
card_auth = true;
|
||||
}
|
||||
}
|
||||
if (!card_auth || !card_select) {
|
||||
|
||||
if ((card_select == false) || (card_auth == false)) {
|
||||
reinit_tentatives++;
|
||||
switch_off();
|
||||
}
|
||||
|
||||
if (reinit_tentatives == 5) {
|
||||
DbpString("");
|
||||
DbpString(_RED_("Unable to select or authenticate with card multiple times! Stopping."));
|
||||
|
@ -2767,11 +2823,8 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
while (bits_found == -1) {
|
||||
|
||||
reinit_tentatives = 0;
|
||||
int res2;
|
||||
uint8_t resp[10] = {0};
|
||||
uint8_t mac2[4] = {0};
|
||||
res = false;
|
||||
uint16_t resp_len = 0;
|
||||
|
||||
if (BUTTON_PRESS() || loops > msg->loop) {
|
||||
if (loops > msg->loop) {
|
||||
|
@ -2787,13 +2840,13 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
|
||||
if (msg->test) {
|
||||
Dbprintf(_YELLOW_("*Cycled Reader*") " TEST Index - Loops: "_YELLOW_("%3d / %3d") " *", loops, msg->loop);
|
||||
} else if (msg->debug || (!card_select && !card_auth)) {
|
||||
} else if (msg->debug || ((card_select == false) && (card_auth == false))) {
|
||||
Dbprintf(_YELLOW_("*Cycled Reader*") " Index: "_RED_("%3d")" Loops: "_YELLOW_("%3d / %3d") " *", index, loops, msg->loop);
|
||||
} else {
|
||||
DbprintfEx(FLAG_INPLACE, "[" _BLUE_("#") "] Index: "_CYAN_("%3d")" Loops: "_YELLOW_("%3d / %3d")" ", index, loops, msg->loop);
|
||||
}
|
||||
|
||||
while (!card_select || !card_auth) {
|
||||
while ((card_select == false) || (card_auth == false)) {
|
||||
|
||||
Iso15693InitReader(); // has to be at the top as it starts tracing
|
||||
set_tracing(false); // disable tracing to prevent crashes - set to true for debugging
|
||||
|
@ -2815,10 +2868,12 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
card_auth = true;
|
||||
}
|
||||
}
|
||||
if (!card_auth || !card_select) {
|
||||
|
||||
if ((card_select == false) || (card_auth == false)) {
|
||||
reinit_tentatives++;
|
||||
switch_off();
|
||||
}
|
||||
|
||||
if (reinit_tentatives == 5) {
|
||||
DbpString("");
|
||||
DbpString(_RED_("Unable to select or authenticate with card multiple times! Stopping."));
|
||||
|
@ -2827,25 +2882,15 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
}
|
||||
|
||||
// Step2 Privilege Escalation: attempt to read AA2 with credentials for AA1
|
||||
int priv_esc_tries = 0;
|
||||
while (!priv_esc) {
|
||||
//The privilege escalation is done with a readcheck and not just a normal read!
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||
// expect a 8-byte response here
|
||||
res2 = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, &eof_time, false, true, &resp_len);
|
||||
if (res2 != PM3_SUCCESS || resp_len != 8) {
|
||||
priv_esc_tries++;
|
||||
if (priv_esc == false) {
|
||||
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
||||
if (priv_esc) {
|
||||
status_message = 3;
|
||||
} else {
|
||||
status_message = 3; //privilege escalation successful
|
||||
priv_esc = true;
|
||||
}
|
||||
if (priv_esc_tries == 5) {
|
||||
DbpString("");
|
||||
DbpString(_RED_("Unable to complete privilege escalation! Stopping."));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv_esc && status_message != 3) {
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||
|
@ -2859,15 +2904,18 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
}
|
||||
|
||||
if (msg->fast) { // if we're skipping restoring the original key to gain speed, xor the new index key with the previous index key and update the difference and track restore values differently
|
||||
|
||||
if (index > 0 && loops > 1) {
|
||||
generate_single_key_block_inverted_opt(zero_key, index - 1, fast_previous_key);
|
||||
} else {
|
||||
memcpy(fast_previous_key, zero_key, PICOPASS_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
|
||||
fast_current_key[i] = genkeyblock[i] ^ fast_previous_key[i];
|
||||
fast_restore_key[i] = fast_restore_key[i] ^ fast_current_key[i];
|
||||
}
|
||||
|
||||
memcpy(genkeyblock, fast_current_key, PICOPASS_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
@ -2880,12 +2928,14 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
doMAC_N(wb, sizeof(wb), div_key2, mac2);
|
||||
bool written = false;
|
||||
bool write_error = false;
|
||||
|
||||
while (written == false && write_error == false) {
|
||||
// Step5 Perform Write
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time, short_delay)) {
|
||||
status_message = 4; // wrote new key on the card - unverified
|
||||
}
|
||||
if (!msg->fast) { //if we're going slow we check at every write that the write actually happened
|
||||
if (msg->fast == false) { // if we're going slow we check at every write that the write actually happened
|
||||
// Reset cypher state
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||
|
@ -2941,7 +2991,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
}
|
||||
} else {
|
||||
// if we're NOT going fast, regardless of bits being found, restore the original key and verify it
|
||||
while (!reverted) {
|
||||
while (reverted == false) {
|
||||
// Regain privilege escalation with a readcheck
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||
|
@ -2952,9 +3002,11 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
// Do a readcheck first to reset the cypher state
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||
|
||||
// need to craft the authentication payload accordingly
|
||||
memcpy(msg->req.key, original_mac, 8);
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
|
||||
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
||||
if (res == true) {
|
||||
status_message = 7; // restore of original key verified - card usable again
|
||||
|
@ -2974,8 +3026,6 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (msg->debug) {
|
||||
|
@ -3025,27 +3075,33 @@ fast_restore:
|
|||
wb[0] = blockno;
|
||||
bool reverted = false;
|
||||
uint8_t revert_retries = 0;
|
||||
while (!reverted) {
|
||||
|
||||
while (reverted == false) {
|
||||
// Regain privilege escalation with a readcheck
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||
memcpy(wb + 1, fast_restore_key, 8);
|
||||
doMAC_N(wb, sizeof(wb), div_key2, mac2);
|
||||
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
if (iclass_writeblock_sp(blockno, fast_restore_key, mac2, shallow_mod, &start_time, &eof_time, short_delay)) {
|
||||
status_message = 6; // restore of original key successful but unverified
|
||||
}
|
||||
|
||||
// Do a readcheck first to reset the cypher state
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||
|
||||
// need to craft the authentication payload accordingly
|
||||
memcpy(msg->req.key, original_mac, 8);
|
||||
|
||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
||||
if (res == true) {
|
||||
status_message = 7; // restore of original key verified - card usable again
|
||||
reverted = true;
|
||||
}
|
||||
|
||||
revert_retries++;
|
||||
if (revert_retries >= 7) { // must always be an odd number!
|
||||
DbpString("");
|
||||
|
@ -3095,5 +3151,4 @@ out:
|
|||
} else {
|
||||
reply_ng(CMD_HF_ICLASS_RECOVER, PM3_ESOFT, NULL, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -370,16 +370,16 @@ tUart14a *GetUart14a(void) {
|
|||
|
||||
void Uart14aReset(void) {
|
||||
Uart.state = STATE_14A_UNSYNCD;
|
||||
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
|
||||
Uart.bitCount = 0;
|
||||
Uart.len = 0; // number of decoded data bytes
|
||||
Uart.parityLen = 0; // number of decoded parity bytes
|
||||
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
|
||||
Uart.parityBits = 0; // holds 8 parity bits
|
||||
Uart.startTime = 0;
|
||||
Uart.endTime = 0;
|
||||
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
||||
Uart.posCnt = 0;
|
||||
Uart.syncBit = 9999;
|
||||
Uart.parityBits = 0; // holds 8 parity bits
|
||||
Uart.parityLen = 0; // number of decoded parity bytes
|
||||
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
||||
Uart.startTime = 0;
|
||||
Uart.endTime = 0;
|
||||
}
|
||||
|
||||
void Uart14aInit(uint8_t *d, uint16_t n, uint8_t *par) {
|
||||
|
@ -697,6 +697,9 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
|
|||
static RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) {
|
||||
|
||||
if (Demod.len == Demod.output_len) {
|
||||
// Flush last parity bits
|
||||
Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1185,9 +1188,24 @@ bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_
|
|||
}
|
||||
}
|
||||
|
||||
static void Simulate_reread_ulc_key(uint8_t *ulc_key) {
|
||||
// copy UL-C key from emulator memory
|
||||
|
||||
mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr();
|
||||
|
||||
memcpy(ulc_key, mfu_header->data + (0x2D * 4), 4);
|
||||
memcpy(ulc_key + 4, mfu_header->data + (0x2C * 4), 4);
|
||||
memcpy(ulc_key + 8, mfu_header->data + (0x2F * 4), 4);
|
||||
memcpy(ulc_key + 12, mfu_header->data + (0x2E * 4), 4);
|
||||
|
||||
reverse_array(ulc_key, 4);
|
||||
reverse_array(ulc_key + 4, 4);
|
||||
reverse_array(ulc_key + 8, 4);
|
||||
reverse_array(ulc_key + 12, 4);
|
||||
}
|
||||
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
|
||||
uint32_t *cuid, uint8_t *pages) {
|
||||
uint32_t *cuid, uint8_t *pages, uint8_t *ulc_key) {
|
||||
uint8_t sak = 0;
|
||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||
static uint8_t rATQA[2] = { 0x00 };
|
||||
|
@ -1337,6 +1355,38 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
sak = 0x20;
|
||||
break;
|
||||
}
|
||||
case 13: { // MIFARE Ultralight-C
|
||||
|
||||
rATQA[0] = 0x44;
|
||||
sak = 0x00;
|
||||
|
||||
// some first pages of UL/NTAG dump is special data
|
||||
mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr();
|
||||
*pages = MAX(mfu_header->pages, 47);
|
||||
|
||||
// copy UL-C key from emulator memory
|
||||
memcpy(ulc_key, mfu_header->data + (0x2D * 4), 4);
|
||||
memcpy(ulc_key + 4, mfu_header->data + (0x2C * 4), 4);
|
||||
memcpy(ulc_key + 8, mfu_header->data + (0x2F * 4), 4);
|
||||
memcpy(ulc_key + 12, mfu_header->data + (0x2E * 4), 4);
|
||||
|
||||
reverse_array(ulc_key, 4);
|
||||
reverse_array(ulc_key + 4, 4);
|
||||
reverse_array(ulc_key + 8, 4);
|
||||
reverse_array(ulc_key + 12, 4);
|
||||
|
||||
/*
|
||||
Dbprintf("UL-C Pages....... %u ( 47 )", *pages);
|
||||
DbpString("UL-C 3des key... ");
|
||||
Dbhexdump(16, ulc_key, false);
|
||||
*/
|
||||
|
||||
if (IS_FLAG_UID_IN_DATA(flags, 7)) {
|
||||
DbpString("UL-C UID........ ");
|
||||
Dbhexdump(7, data, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
||||
return false;
|
||||
|
@ -1362,7 +1412,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
|
||||
// if uid not supplied then get from emulator memory
|
||||
if ((memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10) == 0) || IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
if (tagType == 2 || tagType == 7) {
|
||||
if (tagType == 2 || tagType == 7 || tagType == 13) {
|
||||
uint16_t start = MFU_DUMP_PREFIX_LENGTH;
|
||||
uint8_t emdata[8];
|
||||
emlGet(emdata, start, sizeof(emdata));
|
||||
|
@ -1529,13 +1579,18 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
// 'hf 14a sim'
|
||||
//-----------------------------------------------------------------------------
|
||||
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) {
|
||||
|
||||
#define ATTACK_KEY_COUNT 16
|
||||
#define ULC_TAG_NONCE "\x01\x02\x03\x04\x05\x06\x07\x08"
|
||||
|
||||
tag_response_info_t *responses;
|
||||
uint32_t cuid = 0;
|
||||
uint32_t nonce = 0;
|
||||
/// Ultralight-C 3des2k
|
||||
uint8_t ulc_key[16] = { 0x00 };
|
||||
uint8_t ulc_iv[8] = { 0x00 };
|
||||
bool ulc_reread_key = false;
|
||||
uint8_t pages = 0;
|
||||
|
||||
// Here, we collect CUID, block1, keytype1, NT1, NR1, AR1, CUID, block2, keytyp2, NT2, NR2, AR2
|
||||
|
@ -1579,7 +1634,9 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
.modulation_n = 0
|
||||
};
|
||||
|
||||
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len, &responses, &cuid, &pages) == false) {
|
||||
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len
|
||||
, &responses, &cuid, &pages
|
||||
, ulc_key) == false) {
|
||||
BigBuf_free_keep_EM();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
return;
|
||||
|
@ -1667,7 +1724,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
order = ORDER_NONE; // back to work state
|
||||
p_response = NULL;
|
||||
|
||||
} else if (order == ORDER_AUTH && len == 8) {
|
||||
} else if (order == ORDER_AUTH && len == 8 && tagType != 2 && tagType != 7 && tagType != 13) {
|
||||
// Received {nr] and {ar} (part of authentication)
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
uint32_t nr = bytes_to_num(receivedCmd, 4);
|
||||
|
@ -1757,7 +1814,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK && len == 4) { // Received a (plain) READ
|
||||
uint8_t block = receivedCmd[1];
|
||||
// if Ultralight or NTAG (4 byte blocks)
|
||||
if (tagType == 7 || tagType == 2) {
|
||||
if (tagType == 7 || tagType == 2 || tagType == 13) {
|
||||
if (block > pages) {
|
||||
// send NACK 0x0 == invalid argument
|
||||
EmSend4bit(CARD_NACK_IV);
|
||||
|
@ -1806,7 +1863,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
EmSendCmd(emdata, len + 2);
|
||||
}
|
||||
p_response = NULL;
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7)) { // Received a WRITE
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7 || tagType == 13)) { // Received a WRITE
|
||||
|
||||
p_response = NULL;
|
||||
|
||||
|
@ -1844,12 +1901,15 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
// send ACK
|
||||
EmSend4bit(CARD_ACK);
|
||||
|
||||
if (tagType == 13 && block >= 0x2c && block <= 0x2F) {
|
||||
ulc_reread_key = true;
|
||||
}
|
||||
} else {
|
||||
// send NACK 0x1 == crc/parity error
|
||||
EmSend4bit(CARD_NACK_PA);
|
||||
}
|
||||
goto jump;
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7)) {
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7 || tagType == 13)) {
|
||||
// cmd + block + 2 bytes crc
|
||||
if (CheckCrc14A(receivedCmd, len)) {
|
||||
wrblock = receivedCmd[1];
|
||||
|
@ -1923,7 +1983,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
p_response = &responses[RESP_INDEX_VERSION];
|
||||
} else if (receivedCmd[0] == MFDES_GET_VERSION && len == 4 && (tagType == 3)) {
|
||||
p_response = &responses[RESP_INDEX_VERSION];
|
||||
} else if ((receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) && len == 4 && tagType != 2 && tagType != 7) { // Received an authentication request
|
||||
} else if ((receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) && len == 4 && tagType != 2 && tagType != 7 && tagType != 13) { // Received an authentication request
|
||||
cardAUTHKEY = receivedCmd[0] - 0x60;
|
||||
cardAUTHSC = receivedCmd[1] / 4; // received block num
|
||||
|
||||
|
@ -1942,9 +2002,77 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
|||
} else {
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
}
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_1) { // ULC authentication, or Desfire Authentication
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
p_response = NULL;
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_1 && len == 4 && tagType == 13) { // ULC authentication, or Desfire Authentication
|
||||
|
||||
// reset IV to all zeros
|
||||
memset(ulc_iv, 0x00, 8);
|
||||
|
||||
if (ulc_reread_key) {
|
||||
Simulate_reread_ulc_key(ulc_key);
|
||||
ulc_reread_key = false;
|
||||
}
|
||||
|
||||
dynamic_response_info.response[0] = MIFARE_ULC_AUTH_2;
|
||||
|
||||
// our very random TAG NONCE
|
||||
memcpy(dynamic_response_info.response + 1, ULC_TAG_NONCE, 8);
|
||||
|
||||
if (ulc_part1) {
|
||||
memset(dynamic_response_info.response + 1, 0, 8);
|
||||
} else {
|
||||
// encrypt TAG NONCE
|
||||
tdes_nxp_send(dynamic_response_info.response + 1, dynamic_response_info.response + 1, 8, ulc_key, ulc_iv, 2);
|
||||
}
|
||||
|
||||
// Add CRC
|
||||
AddCrc14A(dynamic_response_info.response, 9);
|
||||
|
||||
// prepare to send
|
||||
dynamic_response_info.response_n = 1 + 8 + 2;
|
||||
prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE);
|
||||
p_response = &dynamic_response_info;
|
||||
order = ORDER_AUTH;
|
||||
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_2 && len == 19 && tagType == 13) { // ULC authentication, or Desfire Authentication
|
||||
|
||||
uint8_t enc_rnd_ab[16] = { 0x00 };
|
||||
uint8_t rnd_ab[16] = { 0x00 };
|
||||
|
||||
// copy reader response
|
||||
memcpy(enc_rnd_ab, receivedCmd + 1, 16);
|
||||
|
||||
// decrypt
|
||||
tdes_nxp_receive(enc_rnd_ab, rnd_ab, 16, ulc_key, ulc_iv, 2);
|
||||
|
||||
ror(rnd_ab + 8, 8);
|
||||
|
||||
if (memcmp(rnd_ab + 8, ULC_TAG_NONCE, 8) != 0) {
|
||||
Dbprintf("failed authentication");
|
||||
}
|
||||
|
||||
// OK response
|
||||
dynamic_response_info.response[0] = 0x00;
|
||||
|
||||
if (ulc_part2) {
|
||||
// try empty auth but with correct CRC and 0x00 command
|
||||
memset(dynamic_response_info.response + 1, 0, 8);
|
||||
} else {
|
||||
// rol RndA
|
||||
rol(rnd_ab, 8);
|
||||
|
||||
// encrypt RndA
|
||||
tdes_nxp_send(rnd_ab, dynamic_response_info.response + 1, 8, ulc_key, ulc_iv, 2);
|
||||
}
|
||||
|
||||
// Add CRC
|
||||
AddCrc14A(dynamic_response_info.response, 9);
|
||||
|
||||
dynamic_response_info.response_n = 1 + 8 + 2;
|
||||
|
||||
prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE);
|
||||
p_response = &dynamic_response_info;
|
||||
order = ORDER_NONE;
|
||||
|
||||
} else if (receivedCmd[0] == MIFARE_ULEV1_AUTH && len == 7 && tagType == 7) { // NTAG / EV-1
|
||||
uint8_t pwd[4] = {0, 0, 0, 0};
|
||||
emlGet(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd));
|
||||
|
@ -2125,13 +2253,16 @@ jump:
|
|||
// of bits specified in the delay parameter.
|
||||
static void PrepareDelayedTransfer(uint16_t delay) {
|
||||
delay &= 0x07;
|
||||
if (!delay) return;
|
||||
if (delay == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t bitmask = 0;
|
||||
uint8_t bits_shifted = 0;
|
||||
|
||||
for (uint16_t i = 0; i < delay; i++)
|
||||
for (uint16_t i = 0; i < delay; i++) {
|
||||
bitmask |= (0x01 << i);
|
||||
}
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
|
@ -2160,6 +2291,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
|
|||
Dbprintf("Warning: HF field is off");
|
||||
return;
|
||||
}
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||
|
||||
if (timing) {
|
||||
|
@ -2334,7 +2466,7 @@ int EmGetCmd(uint8_t *received, uint16_t received_max_len, uint16_t *len, uint8_
|
|||
// button press, takes a bit time, might mess with simualtion
|
||||
if (checker-- == 0) {
|
||||
if (BUTTON_PRESS()) {
|
||||
Dbprintf("----------- " _GREEN_("Breaking / User aborted") " ----------");
|
||||
Dbprintf("----------- " _GREEN_("Button pressed, user aborted") " ----------");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2512,9 +2644,9 @@ int EmSendPrecompiledCmd(tag_response_info_t *p_response) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
// we cannot exactly measure the end and start of a received command from reader. However we know that the delay from
|
||||
// end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp.
|
||||
|
@ -2836,9 +2968,13 @@ static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, const is
|
|||
|
||||
|
||||
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) {
|
||||
return iso14443a_select_cardEx(uid_ptr, p_card, cuid_ptr, anticollision, num_cascades, no_rats, NULL);
|
||||
return iso14443a_select_cardEx(uid_ptr, p_card, cuid_ptr, anticollision, num_cascades, no_rats, NULL, false);
|
||||
}
|
||||
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) {
|
||||
// Bug fix: When SAK is 0x00, `iso14443a_select_cardEx` would return too early at
|
||||
// line "if (hf14aconfig.forcerats == 0)".`force_rats` is used to force RATS execution and ATS retrieval.
|
||||
return iso14443a_select_cardEx(uid_ptr, p_card, cuid_ptr, anticollision, num_cascades, false, NULL, true);
|
||||
}
|
||||
|
||||
|
||||
// performs iso14443a anticollision (optional) and card select procedure
|
||||
// fills the uid and cuid pointer unless NULL
|
||||
|
@ -2848,7 +2984,7 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
|
|||
// requests ATS unless no_rats is true
|
||||
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) {
|
||||
const iso14a_polling_parameters_t *polling_parameters, bool force_rats) {
|
||||
|
||||
uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller
|
||||
|
||||
|
@ -2903,9 +3039,10 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
|
|||
|
||||
if (anticollision) {
|
||||
// clear uid
|
||||
if (uid_ptr)
|
||||
if (uid_ptr) {
|
||||
memset(uid_ptr, 0, 10);
|
||||
}
|
||||
}
|
||||
|
||||
if (hf14aconfig.forceanticol == 0) {
|
||||
// check for proprietary anticollision:
|
||||
|
@ -3065,18 +3202,18 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
|
|||
p_card->sak = sak;
|
||||
}
|
||||
|
||||
if (hf14aconfig.forcerats == 0) {
|
||||
if (hf14aconfig.forcerats == 0 && force_rats == false) {
|
||||
// PICC compliant with iso14443a-4 ---> (SAK & 0x20 != 0)
|
||||
if ((sak & 0x20) == 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
} else if (hf14aconfig.forcerats == 2) {
|
||||
} else if (hf14aconfig.forcerats == 2 && force_rats == false) {
|
||||
if ((sak & 0x20) != 0) Dbprintf("Skipping RATS according to hf 14a config");
|
||||
return 2;
|
||||
} // else force RATS
|
||||
|
||||
if ((sak & 0x20) == 0) Dbprintf("Forcing RATS according to hf 14a config");
|
||||
if ((sak & 0x20) == 0 && force_rats == false) Dbprintf("Forcing RATS according to hf 14a config");
|
||||
|
||||
// RATS, Request for answer to select
|
||||
if (no_rats == false) {
|
||||
|
@ -3102,7 +3239,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
|
|||
return 1;
|
||||
}
|
||||
|
||||
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) {
|
||||
int iso14443a_fast_select_card(const uint8_t *uid_ptr, uint8_t num_cascades) {
|
||||
uint8_t resp[3] = { 0 }; // theoretically. max 1 Byte SAK, 2 Byte CRC, 3 bytes is enough
|
||||
uint8_t resp_par[1] = {0};
|
||||
|
||||
|
@ -3342,7 +3479,8 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
|||
true,
|
||||
0,
|
||||
((param & ISO14A_NO_RATS) == ISO14A_NO_RATS),
|
||||
((param & ISO14A_USE_CUSTOM_POLLING) == ISO14A_USE_CUSTOM_POLLING) ? (iso14a_polling_parameters_t *)cmd : NULL
|
||||
((param & ISO14A_USE_CUSTOM_POLLING) == ISO14A_USE_CUSTOM_POLLING) ? (iso14a_polling_parameters_t *)cmd : NULL,
|
||||
false
|
||||
);
|
||||
// TODO: Improve by adding a cmd parser pointer and moving it by struct length to allow combining data with polling params
|
||||
FpgaDisableTracing();
|
||||
|
@ -3520,17 +3658,23 @@ OUT:
|
|||
// Therefore try in alternating directions.
|
||||
static int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
||||
|
||||
if (nt1 == nt2) return 0;
|
||||
if (nt1 == nt2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t nttmp1 = nt1;
|
||||
uint32_t nttmp2 = nt2;
|
||||
|
||||
for (uint16_t i = 1; i < 32768; i++) {
|
||||
nttmp1 = prng_successor(nttmp1, 1);
|
||||
if (nttmp1 == nt2) return i;
|
||||
if (nttmp1 == nt2) {
|
||||
return i;
|
||||
}
|
||||
|
||||
nttmp2 = prng_successor(nttmp2, 1);
|
||||
if (nttmp2 == nt1) return -i;
|
||||
if (nttmp2 == nt1) {
|
||||
return -i;
|
||||
}
|
||||
}
|
||||
|
||||
return (-99999); // either nt1 or nt2 are invalid nonces
|
||||
|
@ -3538,8 +3682,8 @@ static int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
|||
|
||||
|
||||
#define PRNG_SEQUENCE_LENGTH (1 << 16)
|
||||
#define MAX_UNEXPECTED_RANDOM 4 // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up.
|
||||
#define MAX_SYNC_TRIES 32
|
||||
#define MAX_UNEXPECTED_RANDOM (4) // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up.
|
||||
#define MAX_SYNC_TRIES (32)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Recover several bits of the cypher stream. This implements (first stages of)
|
||||
|
@ -3669,8 +3813,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
||||
|
||||
// Receive the (4 Byte) "random" TAG nonce
|
||||
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 4)
|
||||
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
previous_nt = nt;
|
||||
nt = bytes_to_num(receivedAnswer, 4);
|
||||
|
@ -3693,9 +3838,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
|
||||
// we didn't calibrate our clock yet,
|
||||
// iceman: has to be calibrated every time.
|
||||
if (previous_nt && !nt_attacked) {
|
||||
if (previous_nt && (nt_attacked == 0)) {
|
||||
|
||||
int nt_distance = dist_nt(previous_nt, nt);
|
||||
int32_t nt_distance = dist_nt(previous_nt, nt);
|
||||
|
||||
// if no distance between, then we are in sync.
|
||||
if (nt_distance == 0) {
|
||||
|
@ -3721,7 +3866,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
sync_cycles = (sync_cycles - nt_distance) / elapsed_prng_sequences;
|
||||
|
||||
// no negative sync_cycles, and too small sync_cycles will result in continuous misses
|
||||
if (sync_cycles <= 10) sync_cycles += PRNG_SEQUENCE_LENGTH;
|
||||
if (sync_cycles <= 10) {
|
||||
sync_cycles += PRNG_SEQUENCE_LENGTH;
|
||||
}
|
||||
|
||||
// reset sync_cycles
|
||||
if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2) {
|
||||
|
@ -3729,8 +3876,14 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
sync_time = GetCountSspClk() & 0xfffffff8;
|
||||
}
|
||||
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles);
|
||||
if (g_dbglevel >= DBG_EXTENDED) {
|
||||
Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n"
|
||||
, i
|
||||
, nt_distance
|
||||
, elapsed_prng_sequences
|
||||
, sync_cycles
|
||||
);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -3760,8 +3913,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
} else {
|
||||
sync_cycles += catch_up_cycles;
|
||||
|
||||
if (g_dbglevel >= DBG_EXTENDED)
|
||||
if (g_dbglevel >= DBG_EXTENDED) {
|
||||
Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles);
|
||||
}
|
||||
|
||||
last_catch_up = 0;
|
||||
catch_up_cycles = 0;
|
||||
|
@ -3774,8 +3928,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
if (received_nack) {
|
||||
catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
|
||||
|
||||
if (nt_diff == 0)
|
||||
if (nt_diff == 0) {
|
||||
par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
|
||||
}
|
||||
|
||||
par_list[nt_diff] = reflect8(par[0]);
|
||||
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream
|
||||
|
@ -3794,12 +3949,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
|||
} else {
|
||||
// No NACK.
|
||||
if (nt_diff == 0 && first_try) {
|
||||
|
||||
par[0]++;
|
||||
|
||||
if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK.
|
||||
isOK = 2;
|
||||
return_status = PM3_ESOFT;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Why this?
|
||||
par[0] = ((par[0] & 0x1F) + 1) | par_low;
|
||||
|
@ -3850,7 +4008,7 @@ void DetectNACKbug(void) {
|
|||
uint8_t uid[10] = { 0x00 };
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = { 0x00 };
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = { 0x00 };
|
||||
uint8_t par[1] = {0x00 }; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
||||
uint8_t par[2] = {0x00 }; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
||||
|
||||
uint32_t nt = 0, previous_nt = 0, nt_attacked = 0, cuid = 0;
|
||||
int32_t catch_up_cycles = 0, last_catch_up = 0;
|
||||
|
@ -3901,9 +4059,9 @@ void DetectNACKbug(void) {
|
|||
++checkbtn_cnt;
|
||||
|
||||
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
||||
if (!have_uid) { // need a full select cycle to get the uid first
|
||||
if (have_uid == false) { // need a full select cycle to get the uid first
|
||||
iso14a_card_select_t card_info;
|
||||
if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
|
||||
if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Mifare: Can't select card (ALL)");
|
||||
i = 0;
|
||||
continue;
|
||||
|
@ -3925,7 +4083,7 @@ void DetectNACKbug(void) {
|
|||
}
|
||||
have_uid = true;
|
||||
} else { // no need for anticollision. We can directly select the card
|
||||
if (!iso14443a_fast_select_card(uid, cascade_levels)) {
|
||||
if (iso14443a_fast_select_card(uid, cascade_levels) == 0) {
|
||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Mifare: Can't select card (UID)");
|
||||
i = 0;
|
||||
have_uid = false;
|
||||
|
@ -4139,7 +4297,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
|||
.modulation_n = 0
|
||||
};
|
||||
|
||||
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, &pages) == false) {
|
||||
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, &pages, NULL) == false) {
|
||||
BigBuf_free_keep_EM();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
return;
|
||||
|
|
|
@ -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,7 +152,8 @@ 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, 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);
|
||||
|
@ -165,8 +166,11 @@ uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_maxlen, uint8_t
|
|||
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);
|
||||
|
|
|
@ -786,14 +786,14 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
|||
|
||||
// prepare "ATQB" tag answer (encoded):
|
||||
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
||||
uint8_t *encodedATQB = BigBuf_malloc(ts->max);
|
||||
uint8_t *encodedATQB = BigBuf_calloc(ts->max);
|
||||
uint16_t encodedATQBLen = ts->max;
|
||||
memcpy(encodedATQB, ts->buf, ts->max);
|
||||
|
||||
|
||||
// prepare "OK" tag answer (encoded):
|
||||
CodeIso14443bAsTag(respOK, sizeof(respOK));
|
||||
uint8_t *encodedOK = BigBuf_malloc(ts->max);
|
||||
uint8_t *encodedOK = BigBuf_calloc(ts->max);
|
||||
uint16_t encodedOKLen = ts->max;
|
||||
memcpy(encodedOK, ts->buf, ts->max);
|
||||
|
||||
|
@ -988,18 +988,18 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) {
|
|||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
||||
|
||||
// prepare "ATQB" tag answer (encoded):
|
||||
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
||||
uint8_t *encodedATQB = BigBuf_malloc(ts->max);
|
||||
uint8_t *encodedATQB = BigBuf_calloc(ts->max);
|
||||
uint16_t encodedATQBLen = ts->max;
|
||||
memcpy(encodedATQB, ts->buf, ts->max);
|
||||
|
||||
|
||||
// prepare "OK" tag answer (encoded):
|
||||
CodeIso14443bAsTag(respOK, sizeof(respOK));
|
||||
uint8_t *encodedOK = BigBuf_malloc(ts->max);
|
||||
uint8_t *encodedOK = BigBuf_calloc(ts->max);
|
||||
uint16_t encodedOKLen = ts->max;
|
||||
memcpy(encodedOK, ts->buf, ts->max);
|
||||
|
||||
|
@ -2405,8 +2405,8 @@ void SniffIso14443b(void) {
|
|||
uint8_t ua_buf[MAX_FRAME_SIZE] = {0};
|
||||
Uart14bInit(ua_buf);
|
||||
|
||||
//Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE), MAX_FRAME_SIZE);
|
||||
//Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||
//Demod14bInit(BigBuf_calloc(MAX_FRAME_SIZE));
|
||||
//Uart14bInit(BigBuf_calloc(MAX_FRAME_SIZE));
|
||||
|
||||
// Set FPGA in the appropriate mode
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_SNIFF_IQ);
|
||||
|
|
|
@ -180,8 +180,7 @@ static void CodeIso15693AsReaderEOF(void) {
|
|||
|
||||
static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) {
|
||||
|
||||
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
||||
uint8_t *answer = BigBuf_calloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||
|
||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||
|
||||
|
@ -985,10 +984,11 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
|||
DecodeTagFSK_t dtfm = { 0 };
|
||||
DecodeTagFSK_t *dtf = &dtfm;
|
||||
|
||||
if (fsk)
|
||||
if (fsk) {
|
||||
DecodeTagFSKInit(dtf, response, max_len);
|
||||
else
|
||||
} else {
|
||||
DecodeTagInit(dt, response, max_len);
|
||||
}
|
||||
|
||||
// wait for last transfer to complete
|
||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
|
||||
|
@ -1014,8 +1014,9 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
|||
for (;;) {
|
||||
|
||||
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
|
||||
if (behindBy == 0)
|
||||
if (behindBy == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
samples++;
|
||||
if (samples == 1) {
|
||||
|
@ -1482,7 +1483,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
|||
bool gotFrame = false;
|
||||
|
||||
// the decoder data structure
|
||||
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_malloc(sizeof(DecodeReader_t));
|
||||
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_calloc(sizeof(DecodeReader_t));
|
||||
DecodeReaderInit(dr, received, max_len, 0, NULL);
|
||||
|
||||
// wait for last transfer to complete
|
||||
|
@ -1587,7 +1588,7 @@ void AcquireRawAdcSamplesIso15693(void) {
|
|||
|
||||
LED_A_ON();
|
||||
|
||||
uint8_t *dest = BigBuf_malloc(4000);
|
||||
uint8_t *dest = BigBuf_calloc(4096);
|
||||
|
||||
// switch field on
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
|
||||
|
@ -2029,7 +2030,7 @@ void ReaderIso15693(iso15_card_select_t *p_card) {
|
|||
LED_A_ON();
|
||||
set_tracing(true);
|
||||
|
||||
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||
uint8_t *answer = BigBuf_calloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
||||
|
||||
// FIRST WE RUN AN INVENTORY TO GET THE TAG UID
|
||||
|
|
|
@ -340,7 +340,7 @@ t55xx_configurations_t *getT55xxConfig(void) {
|
|||
void loadT55xxConfig(void) {
|
||||
#ifdef WITH_FLASH
|
||||
|
||||
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
|
||||
uint8_t *buf = BigBuf_calloc(T55XX_CONFIG_LEN);
|
||||
|
||||
uint32_t size = 0;
|
||||
if (exists_in_spiffs(T55XX_CONFIG_FILE)) {
|
||||
|
@ -2912,7 +2912,7 @@ void Cotag(uint32_t arg0, bool ledcontrol) {
|
|||
break;
|
||||
}
|
||||
case 1: {
|
||||
uint8_t *dest = BigBuf_malloc(COTAG_BITS);
|
||||
uint8_t *dest = BigBuf_calloc(COTAG_BITS);
|
||||
uint16_t bits = doCotagAcquisitionManchester(dest, COTAG_BITS);
|
||||
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, dest, bits);
|
||||
break;
|
||||
|
|
|
@ -149,7 +149,7 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
|
|||
data.buffer = BigBuf_get_addr();
|
||||
} else {
|
||||
*sample_size = MIN(*sample_size, BigBuf_max_traceLen());
|
||||
data.buffer = BigBuf_malloc(*sample_size);
|
||||
data.buffer = BigBuf_calloc(*sample_size);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -669,7 +669,7 @@ void doT55x7Acquisition(size_t sample_size, bool ledcontrol) {
|
|||
void doCotagAcquisition(void) {
|
||||
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
uint8_t *dest = BigBuf_malloc(bufsize);
|
||||
uint8_t *dest = BigBuf_calloc(bufsize);
|
||||
|
||||
dest[0] = 0;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -2252,7 +2252,7 @@ OUT:
|
|||
bar |= ((uint16_t)(found[m] & 1) << j++);
|
||||
}
|
||||
|
||||
uint8_t *tmp = BigBuf_malloc(480 + 10);
|
||||
uint8_t *tmp = BigBuf_calloc(480 + 10);
|
||||
memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t));
|
||||
num_to_bytes(foo, 8, tmp + 480);
|
||||
tmp[488] = bar & 0xFF;
|
||||
|
@ -2409,7 +2409,7 @@ void MifareChkKeys_file(uint8_t *fn) {
|
|||
|
||||
int changed = rdv40_spiffs_lazy_mount();
|
||||
uint32_t size = size_in_spiffs((char *)fn);
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
uint8_t *mem = BigBuf_calloc(size);
|
||||
|
||||
rdv40_spiffs_read_as_filetype((char *)fn, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
|
@ -3022,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;
|
||||
}
|
||||
|
@ -3220,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;
|
||||
|
@ -3561,7 +3562,7 @@ 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;
|
||||
}
|
||||
|
@ -3608,13 +3609,13 @@ void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) {
|
|||
int res = 0;
|
||||
int retval = PM3_SUCCESS;
|
||||
|
||||
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE);
|
||||
if (buf == NULL) {
|
||||
retval = PM3_EMALLOC;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *par = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
if (par == NULL) {
|
||||
retval = PM3_EMALLOC;
|
||||
goto OUT;
|
||||
|
@ -3684,7 +3685,7 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t work
|
|||
int res = 0;
|
||||
int retval = PM3_SUCCESS;
|
||||
|
||||
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE);
|
||||
if (buf == NULL) {
|
||||
retval = PM3_EMALLOC;
|
||||
goto OUT;
|
||||
|
@ -3696,7 +3697,7 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t work
|
|||
goto OUT;
|
||||
}
|
||||
|
||||
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
uint8_t *par = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||
if (par == NULL) {
|
||||
retval = PM3_EMALLOC;
|
||||
goto 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");
|
||||
}
|
||||
|
|
|
@ -459,7 +459,7 @@ bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag
|
|||
// 53 * 8 data bits, 53 * 1 parity bits, 18 start bits, 18 stop bits, 18 correction bits -> need 571 bytes buffer
|
||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 571
|
||||
|
||||
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||
uint8_t *free_buffer = BigBuf_calloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||
// modulation buffer pointer and current buffer free space size
|
||||
uint8_t *free_buffer_pointer = free_buffer;
|
||||
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
||||
|
@ -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;
|
||||
|
@ -809,10 +790,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
|||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] KEY %c: %012" PRIx64, (cardAUTHKEY == 0) ? 'A' : 'B', emlGetKey(cardAUTHSC, cardAUTHKEY));
|
||||
|
||||
// sector out of range - do not respond
|
||||
if (cardAUTHSC >= cardMaxSEC) {
|
||||
if ((cardAUTHSC >= cardMaxSEC) && (flags & FLAG_MF_ALLOW_OOB_AUTH) == 0) {
|
||||
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
||||
cardSTATE_TO_IDLE();
|
||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Out of range sector %d(0x%02x)", cardAUTHSC, cardAUTHSC);
|
||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Out of range sector %d(0x%02x) >= %d(0x%02x)", cardAUTHSC, cardAUTHSC, cardMaxSEC, cardMaxSEC);
|
||||
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,8 @@ int sam_get_version(bool info) {
|
|||
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);
|
||||
|
@ -278,7 +279,7 @@ int sam_get_version(bool info) {
|
|||
}
|
||||
if (g_dbglevel >= DBG_INFO || info) {
|
||||
DbpString(_BLUE_("-- SAM Information --"));
|
||||
Dbprintf(_YELLOW_("Firmware version: ")"%X.%X", sam_version_an[2], sam_version_an[3]);
|
||||
Dbprintf(_YELLOW_("Firmware version: ")"%d.%d", sam_version_an[2], sam_version_an[3]);
|
||||
Dbprintf(_YELLOW_("Firmware ID: "));
|
||||
Dbhexdump(sam_build_an[1], sam_build_an + 2, false);
|
||||
}
|
||||
|
@ -309,7 +310,8 @@ int sam_get_serial_number(void) {
|
|||
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||
|
||||
uint8_t payload[] = {
|
||||
0xa0, 0x02, // <- SAM command
|
||||
0xa0, // <- SAM command
|
||||
0x02, // <- Length
|
||||
0x96, 0x00 // <- get serial number
|
||||
};
|
||||
uint16_t payload_len = sizeof(payload);
|
||||
|
|
|
@ -103,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);
|
||||
|
@ -115,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
|
||||
|
||||
|
@ -223,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;
|
||||
|
@ -361,14 +374,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!skipDetect) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -383,8 +396,10 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
|||
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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -402,6 +402,7 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/cmdlfvisa2000.c
|
||||
${PM3_ROOT}/client/src/cmdlfzx8211.c
|
||||
${PM3_ROOT}/client/src/cmdmain.c
|
||||
${PM3_ROOT}/client/src/cmdmqtt.c
|
||||
${PM3_ROOT}/client/src/cmdnfc.c
|
||||
${PM3_ROOT}/client/src/cmdparser.c
|
||||
${PM3_ROOT}/client/src/cmdpiv.c
|
||||
|
@ -434,7 +435,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 +693,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)
|
||||
|
@ -772,6 +773,7 @@ target_link_libraries(proxmark3 PRIVATE
|
|||
pm3rrg_rdv4_reveng
|
||||
pm3rrg_rdv4_hardnested
|
||||
pm3rrg_rdv4_id48
|
||||
pm3rrg_rdv4_mqtt
|
||||
${ADDITIONAL_LNK})
|
||||
|
||||
if (NOT SKIPPTHREAD EQUAL 1)
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
ifeq ($(PLTNAME),)
|
||||
-include ../Makefile.platform
|
||||
-include ../.Makefile.options.cache
|
||||
# Default platform if no platform specified
|
||||
PLATFORM?=PM3RDV4
|
||||
ifneq ($(PLATFORM), $(CACHED_PLATFORM))
|
||||
$(error platform definitions have been changed, please "make clean" at the root of the project)
|
||||
endif
|
||||
|
@ -131,6 +133,12 @@ WHEREAMILIBINC = -I$(WHEREAMILIBPATH)
|
|||
WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a
|
||||
WHEREAMILIBLD =
|
||||
|
||||
## MQTT
|
||||
MQTTLIBPATH = ./deps/mqtt
|
||||
MQTTLIBINC = -I$(MQTTLIBPATH)
|
||||
MQTTLIB = $(MQTTLIBPATH)/mqtt.a
|
||||
MQTTLIBLD =
|
||||
|
||||
##########################
|
||||
# common local libraries #
|
||||
##########################
|
||||
|
@ -239,6 +247,12 @@ STATICLIBS += $(WHEREAMILIB)
|
|||
LDLIBS += $(WHEREAMILIBLD)
|
||||
PM3INCLUDES += $(WHEREAMILIBINC)
|
||||
|
||||
## MQTT
|
||||
# not distributed as system library
|
||||
STATICLIBS += $(MQTTLIB)
|
||||
LDLIBS += $(MQTTLIBLD)
|
||||
PM3INCLUDES += $(MQTTLIBINC)
|
||||
|
||||
####################
|
||||
# system libraries #
|
||||
####################
|
||||
|
@ -440,13 +454,14 @@ endif
|
|||
ifeq ($(SWIG_LUA_FOUND),1)
|
||||
PM3CFLAGS += -DHAVE_LUA_SWIG
|
||||
endif
|
||||
|
||||
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||
PM3CFLAGS += -DHAVE_PYTHON_SWIG
|
||||
endif
|
||||
|
||||
PM3CFLAGS += -DHAVE_SNPRINTF
|
||||
|
||||
CXXFLAGS ?= -Wall
|
||||
CXXFLAGS ?= -Wall -Werror
|
||||
CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES)
|
||||
|
||||
PM3CXXFLAGS = $(CXXFLAGS)
|
||||
|
@ -582,6 +597,7 @@ endif
|
|||
ifeq ($(SWIG_LUA_FOUND),1)
|
||||
$(info Lua SWIG: wrapper found)
|
||||
endif
|
||||
|
||||
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||
$(info Python SWIG: wrapper found)
|
||||
endif
|
||||
|
@ -682,6 +698,7 @@ SRCS = mifare/aiddesfire.c \
|
|||
cmdlfvisa2000.c \
|
||||
cmdlfzx8211.c \
|
||||
cmdmain.c \
|
||||
cmdmqtt.c \
|
||||
cmdnfc.c \
|
||||
cmdparser.c \
|
||||
cmdpiv.c \
|
||||
|
@ -877,6 +894,7 @@ endif
|
|||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MQTTLIBPATH) clean
|
||||
@# Just in case someone compiled within these dirs:
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
||||
|
||||
|
@ -974,6 +992,10 @@ ifneq ($(WHEREAMI_FOUND),1)
|
|||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
||||
endif
|
||||
|
||||
$(MQTTLIB): .FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MQTTLIBPATH) all
|
||||
|
||||
########
|
||||
# SWIG #
|
||||
########
|
||||
|
@ -995,7 +1017,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 $* = $($*)
|
||||
|
|
|
@ -31,3 +31,6 @@ endif()
|
|||
if (NOT TARGET pm3rrg_rdv4_whereami)
|
||||
include(whereami.cmake)
|
||||
endif()
|
||||
if (NOT TARGET pm3rrg_rdv4_mqtt)
|
||||
include(mqtt.cmake)
|
||||
endif()
|
|
@ -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)
|
||||
|
|
|
@ -440,33 +440,32 @@ int json_dumpfd(const json_t *json, int output, size_t flags) {
|
|||
}
|
||||
|
||||
int json_dump_file(const json_t *json, const char *path, size_t flags) {
|
||||
int result;
|
||||
|
||||
FILE *output = fopen(path, "w");
|
||||
if (!output)
|
||||
return -1;
|
||||
|
||||
result = json_dumpf(json, output, flags);
|
||||
|
||||
if (fclose(output) != 0)
|
||||
return -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags) {
|
||||
int res;
|
||||
hashtable_t parents_set;
|
||||
|
||||
if (!(flags & JSON_ENCODE_ANY)) {
|
||||
if (!json_is_array(json) && !json_is_object(json))
|
||||
FILE *f = fopen(path, "w");
|
||||
if (f == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hashtable_init(&parents_set))
|
||||
int res = json_dumpf(json, f, flags);
|
||||
|
||||
if (fclose(f) != 0)
|
||||
return -1;
|
||||
res = do_dump(json, flags, 0, &parents_set, callback, data);
|
||||
hashtable_close(&parents_set);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags) {
|
||||
if (!(flags & JSON_ENCODE_ANY)) {
|
||||
if (!json_is_array(json) && !json_is_object(json)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
hashtable_t parents_set;
|
||||
if (hashtable_init(&parents_set)) {
|
||||
return -1;
|
||||
}
|
||||
int res = do_dump(json, flags, 0, &parents_set, callback, data);
|
||||
hashtable_close(&parents_set);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
9
client/deps/mqtt.cmake
Normal file
9
client/deps/mqtt.cmake
Normal file
|
@ -0,0 +1,9 @@
|
|||
add_library(pm3rrg_rdv4_mqtt STATIC
|
||||
mqtt/mqtt.c
|
||||
mqtt/mqtt_pal.c
|
||||
)
|
||||
|
||||
target_compile_definitions(pm3rrg_rdv4_mqtt PRIVATE WAI_PM3_TUNED)
|
||||
target_include_directories(pm3rrg_rdv4_mqtt INTERFACE mqtt)
|
||||
target_compile_options(pm3rrg_rdv4_mqtt PRIVATE -Wall -Werror -O3)
|
||||
set_property(TARGET pm3rrg_rdv4_mqtt PROPERTY POSITION_INDEPENDENT_CODE ON)
|
21
client/deps/mqtt/LICENSE
Normal file
21
client/deps/mqtt/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Liam Bindle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
14
client/deps/mqtt/Makefile
Normal file
14
client/deps/mqtt/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
|||
MYSRCPATHS =
|
||||
MYINCLUDES =
|
||||
MYCFLAGS = -Wno-bad-function-cast -Wno-switch-enum
|
||||
MYDEFS = -DWAI_PM3_TUNED
|
||||
MYSRCS = \
|
||||
mqtt.c \
|
||||
mqtt_pal.c \
|
||||
|
||||
LIB_A = mqtt.a
|
||||
|
||||
# Transition: remove old directories and objects
|
||||
MYCLEANOLDPATH = ../../mqtt
|
||||
|
||||
include ../../../Makefile.host
|
152
client/deps/mqtt/mbedtls_sockets.h
Normal file
152
client/deps/mqtt/mbedtls_sockets.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
#if !defined(__MBEDTLS_SOCKET_TEMPLATE_H__)
|
||||
#define __MBEDTLS_SOCKET_TEMPLATE_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/net_sockets.h>
|
||||
#include <mbedtls/ssl.h>
|
||||
|
||||
#if !defined(MBEDTLS_NET_POLL_READ)
|
||||
/* compat for older mbedtls */
|
||||
#define MBEDTLS_NET_POLL_READ 1
|
||||
#define MBEDTLS_NET_POLL_WRITE 1
|
||||
|
||||
int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout) {
|
||||
/* XXX this is not ideal but good enough for an example */
|
||||
msleep(300);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct mbedtls_context {
|
||||
mbedtls_net_context net_ctx;
|
||||
mbedtls_ssl_context ssl_ctx;
|
||||
mbedtls_ssl_config ssl_conf;
|
||||
mbedtls_x509_crt ca_crt;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
};
|
||||
|
||||
void failed(const char *fn, int rv);
|
||||
void cert_verify_failed(uint32_t rv);
|
||||
void open_nb_socket(struct mbedtls_context *ctx,
|
||||
const char *hostname,
|
||||
const char *port,
|
||||
const char *ca_file);
|
||||
|
||||
|
||||
void failed(const char *fn, int rv) {
|
||||
char buf[100];
|
||||
mbedtls_strerror(rv, buf, sizeof(buf));
|
||||
printf("%s failed with %x (%s)\n", fn, -rv, buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void cert_verify_failed(uint32_t rv) {
|
||||
char buf[512];
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), "\t", rv);
|
||||
printf("Certificate verification failed (%0" PRIx32 ")\n%s\n", rv, buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
A template for opening a non-blocking mbed TLS connection.
|
||||
*/
|
||||
void open_nb_socket(struct mbedtls_context *ctx,
|
||||
const char *hostname,
|
||||
const char *port,
|
||||
const char *ca_file) {
|
||||
|
||||
const unsigned char *additional = (const unsigned char *)"Pm3 Client";
|
||||
size_t additional_len = 6;
|
||||
int rv;
|
||||
|
||||
mbedtls_net_context *net_ctx = &ctx->net_ctx;
|
||||
mbedtls_ssl_context *ssl_ctx = &ctx->ssl_ctx;
|
||||
mbedtls_ssl_config *ssl_conf = &ctx->ssl_conf;
|
||||
mbedtls_x509_crt *ca_crt = &ctx->ca_crt;
|
||||
mbedtls_entropy_context *entropy = &ctx->entropy;
|
||||
mbedtls_ctr_drbg_context *ctr_drbg = &ctx->ctr_drbg;
|
||||
|
||||
mbedtls_entropy_init(entropy);
|
||||
mbedtls_ctr_drbg_init(ctr_drbg);
|
||||
rv = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy,
|
||||
additional, additional_len);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ctr_drbg_seed", rv);
|
||||
}
|
||||
|
||||
mbedtls_x509_crt_init(ca_crt);
|
||||
rv = mbedtls_x509_crt_parse_file(ca_crt, ca_file);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_x509_crt_parse_file", rv);
|
||||
}
|
||||
|
||||
mbedtls_ssl_config_init(ssl_conf);
|
||||
rv = mbedtls_ssl_config_defaults(ssl_conf, MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_config_defaults", rv);
|
||||
}
|
||||
mbedtls_ssl_conf_ca_chain(ssl_conf, ca_crt, NULL);
|
||||
mbedtls_ssl_conf_authmode(ssl_conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
mbedtls_ssl_conf_rng(ssl_conf, mbedtls_ctr_drbg_random, ctr_drbg);
|
||||
|
||||
mbedtls_net_init(net_ctx);
|
||||
rv = mbedtls_net_connect(net_ctx, hostname, port, MBEDTLS_NET_PROTO_TCP);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_net_connect", rv);
|
||||
}
|
||||
rv = mbedtls_net_set_nonblock(net_ctx);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_net_set_nonblock", rv);
|
||||
}
|
||||
|
||||
mbedtls_ssl_init(ssl_ctx);
|
||||
rv = mbedtls_ssl_setup(ssl_ctx, ssl_conf);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_setup", rv);
|
||||
}
|
||||
rv = mbedtls_ssl_set_hostname(ssl_ctx, hostname);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_set_hostname", rv);
|
||||
}
|
||||
mbedtls_ssl_set_bio(ssl_ctx, net_ctx,
|
||||
mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
|
||||
for (;;) {
|
||||
rv = mbedtls_ssl_handshake(ssl_ctx);
|
||||
uint32_t want = 0;
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
want |= MBEDTLS_NET_POLL_READ;
|
||||
} else if (rv == MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
want |= MBEDTLS_NET_POLL_WRITE;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
rv = mbedtls_net_poll(net_ctx, want, (uint32_t) -1);
|
||||
if (rv < 0) {
|
||||
failed("mbedtls_net_poll", rv);
|
||||
}
|
||||
}
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_handshake", rv);
|
||||
}
|
||||
uint32_t result = mbedtls_ssl_get_verify_result(ssl_ctx);
|
||||
if (result != 0) {
|
||||
if (result == (uint32_t) -1) {
|
||||
failed("mbedtls_ssl_get_verify_result", (int)result);
|
||||
} else {
|
||||
cert_verify_failed(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
1770
client/deps/mqtt/mqtt.c
Normal file
1770
client/deps/mqtt/mqtt.c
Normal file
File diff suppressed because it is too large
Load diff
1640
client/deps/mqtt/mqtt.h
Normal file
1640
client/deps/mqtt/mqtt.h
Normal file
File diff suppressed because it is too large
Load diff
235
client/deps/mqtt/mqtt_pal.c
Normal file
235
client/deps/mqtt/mqtt_pal.c
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2018 Liam Bindle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mqtt.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Implements @ref mqtt_pal_sendall and @ref mqtt_pal_recvall and
|
||||
* any platform-specific helpers you'd like.
|
||||
* @cond Doxygen_Suppress
|
||||
*/
|
||||
|
||||
#if defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
|
||||
/*
|
||||
* In case of MQTT_USE_CUSTOM_SOCKET_HANDLE, a pal implemantation is
|
||||
* provided by the user.
|
||||
*/
|
||||
|
||||
/* Note: Some toolchains complain on an object without symbols */
|
||||
|
||||
int _mqtt_pal_dummy;
|
||||
|
||||
#else /* defined(MQTT_USE_CUSTOM_SOCKET_HANDLE) */
|
||||
|
||||
#if defined(MQTT_USE_MBEDTLS)
|
||||
#include <mbedtls/ssl.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags) {
|
||||
enum MQTTErrors error = 0;
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
int rv = mbedtls_ssl_write(fd, (const unsigned char *)buf + sent, len - sent);
|
||||
if (rv < 0) {
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rv == MBEDTLS_ERR_SSL_WANT_WRITE
|
||||
#if defined(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
|
||||
#endif
|
||||
#if defined(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
|
||||
#endif
|
||||
) {
|
||||
/* should call mbedtls_ssl_write later again */
|
||||
break;
|
||||
}
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Note: rv can be 0 here eg. when mbedtls just flushed
|
||||
* the previous incomplete record.
|
||||
*
|
||||
* Note: we never send an empty TLS record.
|
||||
*/
|
||||
sent += (size_t) rv;
|
||||
}
|
||||
if (sent == 0) {
|
||||
return error;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags) {
|
||||
const void *const start = buf;
|
||||
enum MQTTErrors error = 0;
|
||||
int rv;
|
||||
do {
|
||||
rv = mbedtls_ssl_read(fd, (unsigned char *)buf, bufsz);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* Note: mbedtls_ssl_read returns 0 when the underlying
|
||||
* transport was closed without CloseNotify.
|
||||
*
|
||||
* Raise an error to trigger a reconnect.
|
||||
*/
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rv == MBEDTLS_ERR_SSL_WANT_WRITE
|
||||
#if defined(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
|
||||
#endif
|
||||
#if defined(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
|
||||
#endif
|
||||
) {
|
||||
/* should call mbedtls_ssl_read later again */
|
||||
break;
|
||||
}
|
||||
/* Note: MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is handled here. */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
buf = (char *)buf + rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} while (bufsz > 0);
|
||||
if (buf == start) {
|
||||
return error;
|
||||
}
|
||||
return (const char *)buf - (const char *)start;
|
||||
}
|
||||
|
||||
#elif defined(__unix__) || defined(__APPLE__) || defined(__NuttX__)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags) {
|
||||
enum MQTTErrors error = 0;
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
ssize_t rv = send(fd, (const char *)buf + sent, len - sent, flags);
|
||||
if (rv < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
/* should call send later again */
|
||||
break;
|
||||
}
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv == 0) {
|
||||
/* is this possible? maybe OS bug. */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
sent += (size_t) rv;
|
||||
}
|
||||
if (sent == 0) {
|
||||
return error;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags) {
|
||||
const void *const start = buf;
|
||||
enum MQTTErrors error = 0;
|
||||
ssize_t rv;
|
||||
do {
|
||||
rv = recv(fd, buf, bufsz, flags);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* recv returns 0 when the socket is (half) closed by the peer.
|
||||
*
|
||||
* Raise an error to trigger a reconnect.
|
||||
*/
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
/* should call recv later again */
|
||||
break;
|
||||
}
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
buf = (char *)buf + rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} while (bufsz > 0);
|
||||
if (buf == start) {
|
||||
return error;
|
||||
}
|
||||
return (char *)buf - (const char *)start;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) || defined(WIN32)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags) {
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
ssize_t tmp = send(fd, (char *)buf + sent, len - sent, flags);
|
||||
if (tmp < 1) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
sent += (size_t) tmp;
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags) {
|
||||
const char *const start = buf;
|
||||
ssize_t rv;
|
||||
do {
|
||||
rv = recv(fd, buf, bufsz, flags);
|
||||
if (rv > 0) {
|
||||
/* successfully read bytes from the socket */
|
||||
buf = (char *)buf + rv;
|
||||
bufsz -= rv;
|
||||
} else if (rv < 0) {
|
||||
int err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
} while (rv > 0 && bufsz > 0);
|
||||
|
||||
return (ssize_t)((char *)buf - start);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error No PAL!
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* defined(MQTT_USE_CUSTOM_SOCKET_HANDLE) */
|
||||
|
||||
/** @endcond */
|
173
client/deps/mqtt/mqtt_pal.h
Normal file
173
client/deps/mqtt/mqtt_pal.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
#if !defined(__MQTT_PAL_H__)
|
||||
#define __MQTT_PAL_H__
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2018 Liam Bindle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Includes/supports the types/calls required by the MQTT-C client.
|
||||
*
|
||||
* @note This is the \em only file included in mqtt.h, and mqtt.c. It is therefore
|
||||
* responsible for including/supporting all the required types and calls.
|
||||
*
|
||||
* @defgroup pal Platform abstraction layer
|
||||
* @brief Documentation of the types and calls required to port MQTT-C to a new platform.
|
||||
*
|
||||
* mqtt_pal.h is the \em only header file included in mqtt.c. Therefore, to port MQTT-C to a
|
||||
* new platform the following types, functions, constants, and macros must be defined in
|
||||
* mqtt_pal.h:
|
||||
* - Types:
|
||||
* - \c size_t, \c ssize_t
|
||||
* - \c uint8_t, \c uint16_t, \c uint32_t
|
||||
* - \c va_list
|
||||
* - \c mqtt_pal_time_t : return type of \c MQTT_PAL_TIME()
|
||||
* - \c mqtt_pal_mutex_t : type of the argument that is passed to \c MQTT_PAL_MUTEX_LOCK and
|
||||
* \c MQTT_PAL_MUTEX_RELEASE
|
||||
* - Functions:
|
||||
* - \c memcpy, \c strlen
|
||||
* - \c va_start, \c va_arg, \c va_end
|
||||
* - Constants:
|
||||
* - \c INT_MIN
|
||||
*
|
||||
* Additionally, three macro's are required:
|
||||
* - \c MQTT_PAL_HTONS(s) : host-to-network endian conversion for uint16_t.
|
||||
* - \c MQTT_PAL_NTOHS(s) : network-to-host endian conversion for uint16_t.
|
||||
* - \c MQTT_PAL_TIME() : returns [type: \c mqtt_pal_time_t] current time in seconds.
|
||||
* - \c MQTT_PAL_MUTEX_LOCK(mtx_pointer) : macro that locks the mutex pointed to by \c mtx_pointer.
|
||||
* - \c MQTT_PAL_MUTEX_RELEASE(mtx_pointer) : macro that unlocks the mutex pointed to by
|
||||
* \c mtx_pointer.
|
||||
*
|
||||
* Lastly, \ref mqtt_pal_sendall and \ref mqtt_pal_recvall, must be implemented in mqtt_pal.c
|
||||
* for sending and receiving data using the platforms socket calls.
|
||||
*/
|
||||
|
||||
|
||||
/* UNIX-like platform support */
|
||||
#if defined(__unix__) || defined(__APPLE__) || defined(__NuttX__)
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MQTT_PAL_HTONS(s) htons(s)
|
||||
#define MQTT_PAL_NTOHS(s) ntohs(s)
|
||||
|
||||
#define MQTT_PAL_TIME() time(NULL)
|
||||
|
||||
typedef time_t mqtt_pal_time_t;
|
||||
typedef pthread_mutex_t mqtt_pal_mutex_t;
|
||||
|
||||
#define MQTT_PAL_MUTEX_INIT(mtx_ptr) pthread_mutex_init(mtx_ptr, NULL)
|
||||
#define MQTT_PAL_MUTEX_LOCK(mtx_ptr) pthread_mutex_lock(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_UNLOCK(mtx_ptr) pthread_mutex_unlock(mtx_ptr)
|
||||
|
||||
#if !defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
#if defined(MQTT_USE_MBEDTLS)
|
||||
struct mbedtls_ssl_context;
|
||||
typedef struct mbedtls_ssl_context *mqtt_pal_socket_handle;
|
||||
#else
|
||||
typedef int mqtt_pal_socket_handle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) || defined(WIN32)
|
||||
#include <limits.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef SSIZE_T ssize_t;
|
||||
#define MQTT_PAL_HTONS(s) htons(s)
|
||||
#define MQTT_PAL_NTOHS(s) ntohs(s)
|
||||
|
||||
#define MQTT_PAL_TIME() time(NULL)
|
||||
|
||||
typedef time_t mqtt_pal_time_t;
|
||||
typedef CRITICAL_SECTION mqtt_pal_mutex_t;
|
||||
|
||||
#define MQTT_PAL_MUTEX_INIT(mtx_ptr) InitializeCriticalSection(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_LOCK(mtx_ptr) EnterCriticalSection(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_UNLOCK(mtx_ptr) LeaveCriticalSection(mtx_ptr)
|
||||
|
||||
|
||||
#if !defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
typedef SOCKET mqtt_pal_socket_handle;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Sends all the bytes in a buffer.
|
||||
* @ingroup pal
|
||||
*
|
||||
* @param[in] fd The file-descriptor (or handle) of the socket.
|
||||
* @param[in] buf A pointer to the first byte in the buffer to send.
|
||||
* @param[in] len The number of bytes to send (starting at \p buf).
|
||||
* @param[in] flags Flags which are passed to the underlying socket.
|
||||
*
|
||||
* @returns The number of bytes sent if successful, an \ref MQTTErrors otherwise.
|
||||
*
|
||||
* Note about the error handling:
|
||||
* - On an error, if some bytes have been processed already,
|
||||
* this function should return the number of bytes successfully
|
||||
* processed. (partial success)
|
||||
* - Otherwise, if the error is an equivalent of EAGAIN, return 0.
|
||||
* - Otherwise, return MQTT_ERROR_SOCKET_ERROR.
|
||||
*/
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags);
|
||||
|
||||
/**
|
||||
* @brief Non-blocking receive all the byte available.
|
||||
* @ingroup pal
|
||||
*
|
||||
* @param[in] fd The file-descriptor (or handle) of the socket.
|
||||
* @param[in] buf A pointer to the receive buffer.
|
||||
* @param[in] bufsz The max number of bytes that can be put into \p buf.
|
||||
* @param[in] flags Flags which are passed to the underlying socket.
|
||||
*
|
||||
* @returns The number of bytes received if successful, an \ref MQTTErrors otherwise.
|
||||
*
|
||||
* Note about the error handling:
|
||||
* - On an error, if some bytes have been processed already,
|
||||
* this function should return the number of bytes successfully
|
||||
* processed. (partial success)
|
||||
* - Otherwise, if the error is an equivalent of EAGAIN, return 0.
|
||||
* - Otherwise, return MQTT_ERROR_SOCKET_ERROR.
|
||||
*/
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
73
client/deps/mqtt/posix_sockets.h
Normal file
73
client/deps/mqtt/posix_sockets.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#if !defined(__POSIX_SOCKET_TEMPLATE_H__)
|
||||
#define __POSIX_SOCKET_TEMPLATE_H__
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// A template for opening a non-blocking POSIX socket.
|
||||
|
||||
void close_nb_socket(int sockfd);
|
||||
int open_nb_socket(const char *addr, const char *port);
|
||||
|
||||
int open_nb_socket(const char *addr, const char *port) {
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */
|
||||
hints.ai_socktype = SOCK_STREAM; /* Must be TCP */
|
||||
|
||||
struct addrinfo *p, *servinfo;
|
||||
|
||||
/* get address information */
|
||||
int rv = getaddrinfo(addr, port, &hints, &servinfo);
|
||||
if (rv != 0) {
|
||||
fprintf(stderr, "Failed to open socket (getaddrinfo): %s\n", gai_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the first possible socket */
|
||||
int sockfd = -1;
|
||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||
if (sockfd == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* connect to server */
|
||||
rv = connect(sockfd, p->ai_addr, p->ai_addrlen);
|
||||
if (rv == -1) {
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// free servinfo
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
// make non-blocking
|
||||
if (sockfd != -1) {
|
||||
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
void close_nb_socket(int sockfd) {
|
||||
if (sockfd != -1) {
|
||||
close(sockfd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
15
client/deps/mqtt/readme.md
Normal file
15
client/deps/mqtt/readme.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
# Information
|
||||
Source: https://github.com/LiamBindle/MQTT-C
|
||||
License: MIT
|
||||
Authors:
|
||||
|
||||
MQTT-C was initially developed as a CMPT 434 (Winter Term, 2018) final project at the University of Saskatchewan by:
|
||||
|
||||
- Liam Bindle
|
||||
- Demilade Adeoye
|
||||
|
||||
|
||||
# about
|
||||
MQTT-C is an MQTT v3.1.1 client written in C. MQTT is a lightweight publisher-subscriber-based messaging protocol that is commonly used in IoT and networking applications where high-latency and low data-rate links are expected. The purpose of MQTT-C is to provide a portable MQTT client, written in C, for embedded systems and PC's alike. MQTT-C does this by providing a transparent Platform Abstraction Layer (PAL) which makes porting to new platforms easy. MQTT-C is completely thread-safe but can also run perfectly fine on single-threaded systems making MQTT-C well-suited for embedded systems and microcontrollers. Finally, MQTT-C is small; there are only two source files totalling less than 2000 lines.
|
||||
|
92
client/deps/mqtt/win32_sockets.h
Normal file
92
client/deps/mqtt/win32_sockets.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
#if !defined(__WIN32_SOCKET_TEMPLATE_H__)
|
||||
#define __WIN32_SOCKET_TEMPLATE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
void close_nb_socket(mqtt_pal_socket_handle sockfd);
|
||||
mqtt_pal_socket_handle open_nb_socket(const char *addr, const char *port);
|
||||
|
||||
mqtt_pal_socket_handle open_nb_socket(const char *addr, const char *port) {
|
||||
|
||||
WSADATA wsaData;
|
||||
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (res != 0) {
|
||||
fprintf(stderr, "error: WSAStartup failed with error: %i", res);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
|
||||
hints.ai_socktype = SOCK_STREAM; // Must be TCP
|
||||
hints.ai_protocol = IPPROTO_TCP; //
|
||||
|
||||
struct addrinfo *p, *servinfo;
|
||||
// get address information
|
||||
int rv = getaddrinfo(addr, port, &hints, &servinfo);
|
||||
if (rv != 0) {
|
||||
fprintf(stderr, "error: getaddrinfo: %s", gai_strerror(rv));
|
||||
WSACleanup();
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/* open the first possible socket */
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||
hSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||
|
||||
if (hSocket == INVALID_SOCKET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// connect to server
|
||||
if (connect(hSocket, p->ai_addr, (int)p->ai_addrlen) != INVALID_SOCKET) {
|
||||
break;
|
||||
}
|
||||
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
|
||||
}
|
||||
|
||||
// free servinfo
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
if (p == NULL) { // No address succeeded
|
||||
fprintf(stderr, "error: Could not connect");
|
||||
WSACleanup();
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// make non-blocking
|
||||
if (hSocket != INVALID_SOCKET) {
|
||||
u_long mode = 1; // FIONBIO returns size on 32b
|
||||
ioctlsocket(hSocket, FIONBIO, &mode);
|
||||
}
|
||||
|
||||
int flag = 1;
|
||||
res = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
|
||||
if (res != 0) {
|
||||
closesocket(hSocket);
|
||||
WSACleanup();
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return hSocket;
|
||||
}
|
||||
|
||||
void close_nb_socket(mqtt_pal_socket_handle sockfd) {
|
||||
if (sockfd != INVALID_SOCKET) {
|
||||
closesocket(sockfd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -2542,7 +2542,7 @@ FAB943906E9C
|
|||
# R.A.T.T transport card key A/B
|
||||
AA034F342A55
|
||||
456776908C48
|
||||
|
||||
#
|
||||
# BusFacil - Brazilian public transport card for some cities
|
||||
fae9b14365a9
|
||||
c567dd4a6004
|
||||
|
@ -3108,6 +3108,32 @@ AB921CF0752C
|
|||
567D734C403C
|
||||
2426217B3B3B
|
||||
#
|
||||
# German Aral Gas Station Car-Wash cards
|
||||
080507020706
|
||||
0100815D8D00
|
||||
2459514AED5B
|
||||
5D493F6B0352
|
||||
1CEC0F0ACC0E
|
||||
922B5D1BF2BC
|
||||
2D7E76C7B8EC
|
||||
5E59896806FF
|
||||
097EEA4FE51B
|
||||
688FC86BAB79
|
||||
C01D1DBEEE79
|
||||
2529BF8544C2
|
||||
C6052FBAA150
|
||||
A1D7B3A95605
|
||||
00D0BF748E77
|
||||
C082C0F35CE6
|
||||
3C86C78541A7
|
||||
5632DCC517E1
|
||||
9310191C338F
|
||||
2761858C02D7
|
||||
8C64B49C7638
|
||||
B1BA3E778930
|
||||
2037627D9260
|
||||
28C4D7170FCD
|
||||
#
|
||||
# Card keys from Andalusian public transport system (Consorcio de Transportes)
|
||||
1848A8D1E4C5
|
||||
16EE1FE134E4
|
||||
|
|
|
@ -9,6 +9,7 @@ d3f7d3f7d3f7d3f7
|
|||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,7 +4,16 @@ local ac = require('ansicolors')
|
|||
local os = require('os')
|
||||
local dash = string.rep('--', 32)
|
||||
local dir = os.getenv('HOME') .. '/.proxmark3/logs/'
|
||||
local logfile = (io.popen('dir /a-d /o-d /tw /b/s "' .. dir .. '" 2>nul:'):read("*a"):match("%C+"))
|
||||
local logfilecmd
|
||||
|
||||
--Determine platform for logfile handling (Windows vs Unix/Linux)
|
||||
if package.config:sub(1,1) == "\\" then
|
||||
logfilecmd = 'dir /a-d /o-d /tw /b/s "' .. dir .. '" 2>nul:'
|
||||
else
|
||||
logfilecmd = 'find "' .. dir .. '" -type f -printf "%T@ %p\\n" | sort -nr | cut -d" " -f2-'
|
||||
end
|
||||
|
||||
local logfile = (io.popen(logfilecmd):read("*a"):match("%C+"))
|
||||
local log_file_path = dir .. "Paxton_log.txt"
|
||||
local nam = ""
|
||||
local pm3 = require('pm3')
|
||||
|
|
|
@ -216,7 +216,7 @@ def recovery(init_check=False, final_check=False, keep=False, no_oob=False,
|
|||
with open(dict_path, 'r', encoding='utf-8') as file:
|
||||
for line in file:
|
||||
if line[0] != '#' and len(line) >= 12:
|
||||
DEFAULT_KEYS.add(line[:12])
|
||||
DEFAULT_KEYS.add(line[:12].lower())
|
||||
show(f"Loaded {dict_def}")
|
||||
except FileNotFoundError:
|
||||
show(f"Warning, {dict_def} not found.")
|
||||
|
@ -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)
|
||||
|
|
|
@ -305,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
|
||||
},
|
||||
|
@ -335,6 +338,7 @@ FRA_OrganizationalAuthority_Contract_Provider = {
|
|||
},
|
||||
0x912: {
|
||||
3: InterticHelper('Le Havre', 'Lia / Transdev', Describe_Usage_1_1),
|
||||
29: InterticHelper('Caen', 'Twisto / RATP', Describe_Usage_2),
|
||||
35: InterticHelper('Cherbourg-en-Cotentin', 'Cap Cotentin / Transdev'),
|
||||
},
|
||||
0x913: {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -44,7 +44,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -52,7 +52,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -60,7 +60,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -68,7 +68,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -76,7 +76,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -84,7 +84,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -92,7 +92,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -100,7 +100,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -108,7 +108,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -116,7 +116,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -124,7 +124,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -132,7 +132,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Unused Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Unused Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -140,7 +140,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Unused Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Unused Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -148,7 +148,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Unused Cardax Card Data Application (Alternative Endian)",
|
||||
"Description": "Unused Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -156,7 +156,7 @@
|
|||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Card Application Directory (CAD) (Alternative Endian)",
|
||||
"Description": "Card Application Directory (CAD)",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
|
@ -223,134 +223,6 @@
|
|||
"Description": "Securitron DESFire EV2 Credential",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48120",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48121",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48122",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48123",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48124",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48125",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48126",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48127",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48128",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F48129",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F4812A",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F4812B",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F4812C",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Unused Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F4812D",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Unused Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F4812E",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Unused Cardax Card Data Application",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F4812F",
|
||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||
"Country": "NZ",
|
||||
"Name": "Gallagher Security Credential",
|
||||
"Description": "Card Application Directory (CAD)",
|
||||
"Type": "pacs"
|
||||
},
|
||||
{
|
||||
"AID": "F484D1",
|
||||
"Vendor": "HID",
|
||||
|
@ -895,14 +767,6 @@
|
|||
"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",
|
||||
|
@ -911,6 +775,14 @@
|
|||
"Description": "Used by ATL Breeze, PHL FREEDOM, and YVR Compass",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "000005",
|
||||
"Vendor": "Transports Metropolitans de Barcelona (TMB)",
|
||||
"Country": "ES",
|
||||
"Name": "T-mobilitat (BCN)",
|
||||
"Description": "BCN T-mobilitat",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "0000F0",
|
||||
"Vendor": "Metropolitan Transportation Authority (MTA) / Bayerische Motoren Werke (BMW) AG",
|
||||
|
@ -921,7 +793,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "002000",
|
||||
"Vendor": "Metrolinx",
|
||||
"Vendor": "Metrolinx via Accenture",
|
||||
"Country": "CA",
|
||||
"Name": "PRESTO Card (YYZ/YHM/YOW)",
|
||||
"Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data",
|
||||
|
@ -1209,7 +1081,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "415431",
|
||||
"Vendor": "Athens Urban Transport Organization (OASA)",
|
||||
"Vendor": "Athens Urban Transport Organisation (OASA)",
|
||||
"Country": "GR",
|
||||
"Name": "ATH.ENA CARD (ATH)",
|
||||
"Description": "ATH ATH.ENA CARD",
|
||||
|
@ -1281,7 +1153,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "4F5931",
|
||||
"Vendor": "Transport for London (TfL)",
|
||||
"Vendor": "Transport for London (TfL) via Cubic Transportation Systems",
|
||||
"Country": "UK",
|
||||
"Name": "Oyster Card (LHR)",
|
||||
"Description": "FIDs: 00-07: Standard Data",
|
||||
|
@ -1297,7 +1169,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "534531",
|
||||
"Vendor": "Transport for New South Wales (TfNSW)",
|
||||
"Vendor": "Transport for New South Wales (TfNSW) via Pearl Consortium",
|
||||
"Country": "AU",
|
||||
"Name": "Opal Card (SYD)",
|
||||
"Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History",
|
||||
|
@ -1305,7 +1177,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "554000",
|
||||
"Vendor": "Auckland Transport",
|
||||
"Vendor": "Auckland Transport via Thales Group",
|
||||
"Country": "NZ",
|
||||
"Name": "AT HOP Card (AKL)",
|
||||
"Description": "FIDs: 00: Backup Data; 08/09/0A",
|
||||
|
@ -1391,6 +1263,14 @@
|
|||
"Description": "Umo Mobility Card",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "C1B1A1",
|
||||
"Vendor": "AHORROBUS via MOBILITY ADO",
|
||||
"Country": "MX",
|
||||
"Name": "AHORROBUS Card (MEX)",
|
||||
"Description": "MEX AHORROBUS Card",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "C65B80",
|
||||
"Vendor": "Umo Mobility via Cubic Transportation Systems",
|
||||
|
@ -1465,7 +1345,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "F21050",
|
||||
"Vendor": "Metro Christchurch via INIT / Arc",
|
||||
"Vendor": "Metro Christchurch via INIT / Arc via Vix Technologies",
|
||||
"Country": "NZ / CA",
|
||||
"Name": "Metrocard (CHC) / Arc (YEG)",
|
||||
"Description": "CHC FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance",
|
||||
|
@ -1473,7 +1353,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "F210E0",
|
||||
"Vendor": "TriMet",
|
||||
"Vendor": "TriMet via INIT",
|
||||
"Country": "US",
|
||||
"Name": "hop fastpass (PDX)",
|
||||
"Description": "PDX hop fastpass Card",
|
||||
|
@ -1521,7 +1401,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "F21201",
|
||||
"Vendor": "Green Bay Metro Transit via Genfare / Winnipeg Transit",
|
||||
"Vendor": "Green Bay Metro Transit via Genfare / Winnipeg Transit via Genfare",
|
||||
"Country": "US / CA",
|
||||
"Name": "Tap-N-Go Card (GRB) / peggo card (YWG)",
|
||||
"Description": "GRB Tap-N-Go Card / YWG peggo card",
|
||||
|
@ -1537,7 +1417,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "F212A0",
|
||||
"Vendor": "CTtransit",
|
||||
"Vendor": "CTtransit via Genfare",
|
||||
"Country": "US",
|
||||
"Name": "Go CT Card (BDL)",
|
||||
"Description": "BDL Go CT Card",
|
||||
|
@ -1545,7 +1425,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "F21360",
|
||||
"Vendor": "INIT",
|
||||
"Vendor": "The City and County of Honolulu via INIT",
|
||||
"Country": "US",
|
||||
"Name": "HOLO Card (HNL)",
|
||||
"Description": "HNL HOLO Card",
|
||||
|
@ -1561,7 +1441,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "F21390",
|
||||
"Vendor": "Multiple NZ Transit Agencies via Otago Regional Council",
|
||||
"Vendor": "Otago Regional Council via INIT",
|
||||
"Country": "NZ",
|
||||
"Name": "Bee Card (DUD)",
|
||||
"Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance",
|
||||
|
@ -1583,6 +1463,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",
|
||||
|
@ -1617,7 +1505,7 @@
|
|||
},
|
||||
{
|
||||
"AID": "FF30FF",
|
||||
"Vendor": "Metrolinx",
|
||||
"Vendor": "Metrolinx via Accenture",
|
||||
"Country": "CA",
|
||||
"Name": "PRESTO Card (YYZ/YHM/YOW)",
|
||||
"Description": "FID 08: Standard Data",
|
||||
|
|
|
@ -1247,14 +1247,6 @@
|
|||
"Description": "PIV End Point Applet. Last 2 bytes designate version",
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
"AID": "A000000308000010000100",
|
||||
"Vendor": "National Institute of Standards and Technology",
|
||||
"Country": "United States",
|
||||
"Name": "Personal Identity Verification (PIV) / ID-ONE PIV BIO",
|
||||
"Description": "PIV End Point Applet. Last 2 bytes designate version",
|
||||
"Type": ""
|
||||
},
|
||||
{
|
||||
"AID": "A00000031510100528",
|
||||
"Vendor": "Currence Holding/PIN BV",
|
||||
|
@ -2470,5 +2462,37 @@
|
|||
"Name": "Navigo",
|
||||
"Description": "CALYPSO-based transit card",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
"AID": "A0000000791000",
|
||||
"Vendor": "HID Global",
|
||||
"Country": "",
|
||||
"Name": "Crescendo ACA",
|
||||
"Description": "HID Crescendo ACA",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A0000000792300",
|
||||
"Vendor": "HID Global",
|
||||
"Country": "",
|
||||
"Name": "Crescendo OATH #0 (HOTP)",
|
||||
"Description": "HID Crescendo Key OATH instance 0 (default HOTP slot)",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A0000000792301",
|
||||
"Vendor": "HID Global",
|
||||
"Country": "",
|
||||
"Name": "Crescendo OATH #1",
|
||||
"Description": "HID Crescendo Key OATH instance 1",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A0000000792302",
|
||||
"Vendor": "HID Global",
|
||||
"Country": "",
|
||||
"Name": "Crescendo OATH #2",
|
||||
"Description": "HID Crescendo Key OATH instance 2",
|
||||
"Type": "access"
|
||||
}
|
||||
]
|
||||
|
|
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
|
|
@ -4130,6 +4130,13 @@
|
|||
"service_provider": "HID Corporation",
|
||||
"system_integrator": "HID Corporation"
|
||||
},
|
||||
{
|
||||
"application": "Access Control (SIO Elite)",
|
||||
"company": "HID Global",
|
||||
"mad": "0x3D05",
|
||||
"service_provider": "HID Corporation",
|
||||
"system_integrator": "HID Corporation"
|
||||
},
|
||||
{
|
||||
"application": "City transport, prepaid ticket, cardholder, servicespass",
|
||||
"company": "Ridango AS",
|
||||
|
|
|
@ -3527,8 +3527,8 @@ static int CmdAtrLookup(const char *Cmd) {
|
|||
static int CmdCryptography(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "data crypto",
|
||||
"Encrypt data, right here, right now. Or decrypt.",
|
||||
"Supply data, key, IV (needed for des MAC or aes), and cryptography action.\n"
|
||||
"This command lets you encrypt or decrypt data using DES/3DES/AES.\n"
|
||||
"Supply data, key, IV (needed for des MAC or aes), and cryptography action.\n",
|
||||
"To calculate a MAC for FMCOS, supply challenge as IV, data as data, and session/line protection key as key.\n"
|
||||
"To calculate a MAC for FeliCa, supply first RC as IV, BLE+data as data and session key as key.\n"
|
||||
"data crypto -d 04D6850E06AABB80 -k FFFFFFFFFFFFFFFF --iv 9EA0401A00000000 --des -> Calculate a MAC for FMCOS chip. The result should be ED3A0133\n"
|
||||
|
@ -3544,76 +3544,97 @@ static int CmdCryptography(const char *Cmd) {
|
|||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t dati[250] = {0};
|
||||
uint8_t dato[250] = {0};
|
||||
int datilen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, dati, &datilen);
|
||||
uint8_t key[25] = {0};
|
||||
|
||||
uint8_t key[33] = {0};
|
||||
int keylen = 0;
|
||||
CLIGetHexWithReturn(ctx, 2, key, &keylen);
|
||||
int type = 0;
|
||||
if (arg_get_lit(ctx, 3)) type ^= 8;
|
||||
if (arg_get_lit(ctx, 4)) type ^= 4;
|
||||
if (arg_get_lit(ctx, 5)) type ^= 2;
|
||||
|
||||
uint8_t type = 0;
|
||||
if (arg_get_lit(ctx, 3)) {
|
||||
type ^= 0x08;
|
||||
}
|
||||
|
||||
if (arg_get_lit(ctx, 4)) {
|
||||
type ^= 0x04;
|
||||
}
|
||||
|
||||
if (arg_get_lit(ctx, 5)) {
|
||||
type ^= 0x02;
|
||||
}
|
||||
|
||||
uint8_t iv[250] = {0};
|
||||
int ivlen = 0;
|
||||
CLIGetHexWithReturn(ctx, 6, iv, &ivlen);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// Do data length check
|
||||
if ((type & 0x4) >> 2) { // Use AES(0) or DES(1)?
|
||||
if ((type & 0x04) == 0x04) { // Use AES(0) or DES(1)?
|
||||
|
||||
if (datilen % 8 != 0) {
|
||||
PrintAndLogEx(ERR, "<data> length must be a multiple of 8. Got %d", datilen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (keylen != 8 && keylen != 16 && keylen != 24) {
|
||||
PrintAndLogEx(ERR, "<key> must be 8, 16 or 24 bytes. Got %d", keylen);
|
||||
if (keylen != 8 && keylen != 16 && keylen != 24 && keylen != 32) {
|
||||
PrintAndLogEx(ERR, "<key> must be 8, 16, 24, 32 bytes. Got %d", keylen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (datilen % 16 != 0 && ((type & 0x2) >> 1 == 0)) {
|
||||
if (datilen % 16 != 0 && ((type & 0x02) == 0)) {
|
||||
PrintAndLogEx(ERR, "<data> length must be a multiple of 16. Got %d", datilen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (keylen != 16) {
|
||||
PrintAndLogEx(ERR, "<key> must be 16 bytes. Got %d", keylen);
|
||||
if (keylen != 16 && keylen != 32) {
|
||||
PrintAndLogEx(ERR, "<key> must be 16 or 32 bytes. Got %d", keylen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt(0) or decrypt(1)?
|
||||
if ((type & 0x8) >> 3) {
|
||||
if ((type & 0x08) == 0x08) {
|
||||
|
||||
if ((type & 0x4) >> 2) { // AES or DES?
|
||||
if ((type & 0x04) == 0x04) { // AES or DES?
|
||||
|
||||
if (keylen > 8) {
|
||||
|
||||
PrintAndLogEx(INFO, "Called 3DES decrypt");
|
||||
des3_decrypt(dato, dati, key, keylen / 8);
|
||||
PrintAndLogEx(INFO, "3DES decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
|
||||
} else {
|
||||
|
||||
PrintAndLogEx(INFO, "Called DES decrypt");
|
||||
|
||||
if (ivlen == 0) {
|
||||
// If there's an IV, use CBC
|
||||
des_decrypt_ecb(dato, dati, datilen, key);
|
||||
PrintAndLogEx(INFO, "DES ECB decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
} else {
|
||||
des_decrypt_cbc(dato, dati, datilen, key, iv);
|
||||
PrintAndLogEx(INFO, "DES CBC decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Called AES decrypt");
|
||||
aes_decode(iv, key, dati, dato, datilen);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (type & 0x4) { // AES or DES?
|
||||
if (type & 0x02) { // If we will calculate a MAC
|
||||
if (keylen == 32) {
|
||||
aes256_decode(iv, key, dati, dato, datilen);
|
||||
PrintAndLogEx(INFO, "AES-256 decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
} else {
|
||||
aes_decode(iv, key, dati, dato, datilen);
|
||||
PrintAndLogEx(INFO, "AES-128 decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((type & 0x04) == 0x04) { // AES or DES?
|
||||
if ((type & 0x02) == 0x02) { // If we will calculate a MAC
|
||||
/*PrintAndLogEx(INFO, "Called FeliCa MAC");
|
||||
// For DES all I know useful is the felica and fudan MAC algorithm.This is just des-cbc, but felica needs it in its way.
|
||||
for (int i = 0; i < datilen; i+=8){ // For all 8 byte sequences
|
||||
|
@ -3637,37 +3658,42 @@ static int CmdCryptography(const char *Cmd) {
|
|||
} else {
|
||||
|
||||
if (keylen > 8) {
|
||||
PrintAndLogEx(INFO, "Called 3DES encrypt keysize: %i", keylen / 8);
|
||||
des3_encrypt(dato, dati, key, keylen / 8);
|
||||
PrintAndLogEx(INFO, "3DES encrypt keysize ( %d )... " _YELLOW_("%s"), (keylen / 8), sprint_hex_inrow(dato, datilen));
|
||||
} else {
|
||||
|
||||
PrintAndLogEx(INFO, "Called DES encrypt");
|
||||
|
||||
if (ivlen == 0) {
|
||||
// If there's an IV, use ECB
|
||||
des_encrypt_ecb(dato, dati, datilen, key);
|
||||
PrintAndLogEx(INFO, "DES ECB encrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
} else {
|
||||
des_encrypt_cbc(dato, dati, datilen, key, iv);
|
||||
char pad[250];
|
||||
memset(pad, ' ', 4 + 8 + (datilen - 8) * 3);
|
||||
pad[8 + (datilen - 8) * 3] = 0; // Make a padding to insert FMCOS macing algorithm guide
|
||||
PrintAndLogEx(INFO, "%sVV VV VV VV FMCOS MAC", pad);
|
||||
PrintAndLogEx(INFO, "DES CBC encrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (type & 0x02) {
|
||||
PrintAndLogEx(INFO, "Called AES CMAC");
|
||||
if ((type & 0x02) == 0x02) {
|
||||
// If we will calculate a MAC
|
||||
aes_cmac8(iv, key, dati, dato, datilen);
|
||||
PrintAndLogEx(INFO, "AES CMAC... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
} else {
|
||||
if (keylen == 32) {
|
||||
aes256_encode(iv, key, dati, dato, datilen);
|
||||
PrintAndLogEx(INFO, "AES-256 encrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Called AES encrypt");
|
||||
aes_encode(iv, key, dati, dato, datilen);
|
||||
PrintAndLogEx(INFO, "AES-128 encrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
||||
}
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Result: %s", sprint_hex(dato, datilen));
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ int CmdLtrim(const char *Cmd);
|
|||
int CmdNorm(const char *Cmd); // used by cmd lf data (!)
|
||||
int CmdPlot(const char *Cmd); // used by cmd lf cotag
|
||||
int CmdSave(const char *Cmd); // used by cmd auto
|
||||
int CmdTuneSamples(const char *Cmd); // used by cmd lf hw
|
||||
|
||||
int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose); // used by cmd lf em4x, lf fdxb, lf guard, lf jablotron, lf nedap, lf t55xx
|
||||
int ASKDemod(int clk, int invert, int maxErr, size_t maxlen, bool amplify, bool verbose, bool emSearch, uint8_t askType); // used by cmd lf em4x, lf t55xx, lf viking
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -880,6 +880,7 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
"hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"
|
||||
"hf 14a sim -t 11 -> Javacard (JCOP)\n"
|
||||
"hf 14a sim -t 12 -> 4K Seos card\n"
|
||||
"hf 14a sim -t 13 -> MIFARE Ultralight C"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
|
@ -890,6 +891,8 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
arg_lit0("x", NULL, "Performs the 'reader attack', nr/ar attack against a reader"),
|
||||
arg_lit0(NULL, "sk", "Fill simulator keys from found keys"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_lit0(NULL, "c1", "UL-C Auth - all zero handshake part 1"),
|
||||
arg_lit0(NULL, "c2", "UL-C Auth - all zero handshake part 2"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
@ -923,9 +926,12 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
bool setEmulatorMem = arg_get_lit(ctx, 5);
|
||||
bool verbose = arg_get_lit(ctx, 6);
|
||||
|
||||
bool ulc_p1 = arg_get_lit(ctx, 7);
|
||||
bool ulc_p2 = arg_get_lit(ctx, 8);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (tagtype > 12) {
|
||||
if (tagtype > 13) {
|
||||
PrintAndLogEx(ERR, "Undefined tag %d", tagtype);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -939,11 +945,16 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
uint16_t flags;
|
||||
uint8_t uid[10];
|
||||
uint8_t exitAfter;
|
||||
uint8_t rats[20];
|
||||
bool ulc_p1;
|
||||
bool ulc_p2;
|
||||
} PACKED payload;
|
||||
|
||||
payload.tagtype = tagtype;
|
||||
payload.flags = flags;
|
||||
payload.exitAfter = exitAfterNReads;
|
||||
payload.ulc_p1 = ulc_p1;
|
||||
payload.ulc_p2 = ulc_p2;
|
||||
memcpy(payload.uid, uid, uid_len);
|
||||
|
||||
clearCommandBuffer();
|
||||
|
@ -957,14 +968,17 @@ int CmdHF14ASim(const char *Cmd) {
|
|||
bool keypress = kbd_enter_pressed();
|
||||
while (keypress == false) {
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == false)
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS)
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK)
|
||||
if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) {
|
||||
break;
|
||||
}
|
||||
|
||||
const nonces_t *data = (nonces_t *)resp.data.asBytes;
|
||||
readerAttack(k_sector, k_sectors_cnt, data[0], setEmulatorMem, verbose);
|
||||
|
@ -1316,7 +1330,7 @@ static int CmdExchangeAPDU(bool chainingin, const uint8_t *datain, int datainlen
|
|||
|
||||
// Button pressed / user cancelled
|
||||
if (iLen == -3) {
|
||||
PrintAndLogEx(DEBUG, "ERR: APDU: User aborted");
|
||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
|
@ -3133,18 +3147,18 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
|||
if (isMifareClassic || isMifareMini) {
|
||||
res = detect_classic_static_nonce();
|
||||
if (res == NONCE_STATIC) {
|
||||
PrintAndLogEx(SUCCESS, "Static nonce......... " _YELLOW_("yes"));
|
||||
PrintAndLogEx(SUCCESS, "Static nonce....... " _YELLOW_("yes"));
|
||||
}
|
||||
|
||||
if (res == NONCE_NORMAL) {
|
||||
// not static
|
||||
res = detect_classic_prng();
|
||||
if (res == 1) {
|
||||
PrintAndLogEx(SUCCESS, "Prng detection....... " _GREEN_("weak"));
|
||||
PrintAndLogEx(SUCCESS, "Prng detection..... " _GREEN_("weak"));
|
||||
} else if (res == 0) {
|
||||
PrintAndLogEx(SUCCESS, "Prng detection....... " _YELLOW_("hard"));
|
||||
PrintAndLogEx(SUCCESS, "Prng detection..... " _YELLOW_("hard"));
|
||||
} else {
|
||||
PrintAndLogEx(FAILED, "Prng detection........ " _RED_("fail"));
|
||||
PrintAndLogEx(FAILED, "Prng detection...... " _RED_("fail"));
|
||||
}
|
||||
|
||||
if (do_nack_test) {
|
||||
|
|
|
@ -2708,25 +2708,32 @@ static int CmdHF14BCalypsoRead(const char *Cmd) {
|
|||
CLIParserFree(ctx);
|
||||
|
||||
transport_14b_apdu_t cmds[] = {
|
||||
{"01.Select ICC file", "\x94\xa4\x08\x00\x04\x3f\x00\x00\x02", 9},
|
||||
{"01.Select ICC ", "\x94\xa4\x08\x00\x04\x3f\x00\x00\x02", 9},
|
||||
{"02.ICC ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"03.Select EnvHol file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x01", 9},
|
||||
{"03.Select EnvHol ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x01", 9},
|
||||
{"04.EnvHol1 ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"05.Select EvLog file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x10", 9},
|
||||
{"05.Select EvLog ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x10", 9},
|
||||
{"06.EvLog1 ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"07.EvLog2 ", "\x94\xb2\x02\x04\x1d", 5},
|
||||
{"08.EvLog3 ", "\x94\xb2\x03\x04\x1d", 5},
|
||||
{"09.Select ConList file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x50", 9},
|
||||
{"09.Select ConList ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x50", 9},
|
||||
{"10.ConList ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"11.Select Contra file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x20", 9},
|
||||
{"11.Select Contra ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x20", 9},
|
||||
{"12.Contra1 ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"13.Contra2 ", "\x94\xb2\x02\x04\x1d", 5},
|
||||
{"14.Contra3 ", "\x94\xb2\x03\x04\x1d", 5},
|
||||
{"15.Contra4 ", "\x94\xb2\x04\x04\x1d", 5},
|
||||
{"16.Select Counter file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x69", 9},
|
||||
{"16.Select Counter ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x69", 9},
|
||||
{"17.Counter ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"18.Select SpecEv file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x40", 9},
|
||||
{"18.Select SpecEv ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x40", 9},
|
||||
{"19.SpecEv1 ", "\x94\xb2\x01\x04\x1d", 5},
|
||||
{"20.Select Purse ", "\x00\xa4\x00\x00\x02\x10\x15", 7},
|
||||
{"21.Purse1 ", "\x00\xb2\x01\x04\x1d", 5},
|
||||
{"22.Purse2 ", "\x00\xb2\x02\x04\x1d", 5},
|
||||
{"23.Purse3 ", "\x00\xb2\x03\x04\x1d", 5},
|
||||
{"24.Select Top Up ", "\x00\xa4\x00\x00\x02\x10\x14", 7},
|
||||
{"25.Topup1 ", "\x00\xb2\x01\x04\x1d", 5},
|
||||
{"26.Select 1TIC.ICA", "\x00\xa4\x04\x00\x08\x31\x54\x49\x43\x2e\x49\x43\x41", 13},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2780,9 +2787,8 @@ static int CmdHF14BCalypsoRead(const char *Cmd) {
|
|||
|
||||
uint16_t sw = get_sw(response, resplen);
|
||||
if (sw != ISO7816_OK) {
|
||||
PrintAndLogEx(ERR, "Sending command failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
switch_off_field_14b();
|
||||
return PM3_ESOFT;
|
||||
PrintAndLogEx(INFO, "%s - command failed (%04x - %s).", cmds[i].desc, sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
continue;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "%s - %s", cmds[i].desc, sprint_hex(response, resplen));
|
||||
|
@ -3073,7 +3079,7 @@ plot:
|
|||
}
|
||||
}
|
||||
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
if (verbose && found == false) {
|
||||
PrintAndLogEx(FAILED, "no ISO 14443-B tag found");
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
|
@ -232,8 +232,7 @@ int readHFCryptoRF(bool loop, bool verbose) {
|
|||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex_inrow(card.uid, card.uidlen));
|
||||
set_last_known_card(card);
|
||||
}
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
DropField();
|
||||
return res;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,5 +26,6 @@ int CmdHFFelica(const char *Cmd);
|
|||
int read_felica_uid(bool loop, bool verbose);
|
||||
int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose);
|
||||
int send_rd_plain(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_read_without_encryption_response_t *rd_noCry_resp);
|
||||
int send_dump_sv_plain(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose, felica_service_dump_response_t *dump_sv_resp, bool is_area);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -199,7 +199,7 @@ int read_fudan_uid(bool loop, bool verbose) {
|
|||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
|
||||
return PM3_SUCCESS;
|
||||
|
|
|
@ -1135,7 +1135,7 @@ int read_iclass_csn(bool loop, bool verbose, bool shallow_mod) {
|
|||
res = PM3_EMALLOC;
|
||||
}
|
||||
}
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
DropField();
|
||||
return res;
|
||||
|
@ -2130,9 +2130,10 @@ static int CmdHFiClassDump(const char *Cmd) {
|
|||
return PM3_EOPABORTED;
|
||||
}
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ICLASS_DUMP, &resp, 2000))
|
||||
if (WaitForResponseTimeout(CMD_HF_ICLASS_DUMP, &resp, 2000)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
|
@ -2328,7 +2329,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
|
|||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
||||
arg_lit0(NULL, "nr", "replay of NR/MAC block write or use privilege escalation if mac is empty"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
||||
arg_param_end
|
||||
|
@ -2568,6 +2569,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
|||
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
||||
arg_lit0(NULL, "nr", "replay of nr mac with privilege escalation"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
@ -2618,6 +2620,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
|||
bool rawkey = arg_get_lit(ctx, 8);
|
||||
bool verbose = arg_get_lit(ctx, 9);
|
||||
bool shallow_mod = arg_get_lit(ctx, 10);
|
||||
bool use_replay = arg_get_lit(ctx, 11);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
|
@ -2664,7 +2667,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
|||
payload->req.use_raw = rawkey;
|
||||
payload->req.use_elite = elite;
|
||||
payload->req.use_credit_key = use_credit_key;
|
||||
payload->req.use_replay = false;
|
||||
payload->req.use_replay = use_replay;
|
||||
payload->req.blockno = startblock;
|
||||
payload->req.send_reply = true;
|
||||
payload->req.do_auth = true;
|
||||
|
@ -4608,7 +4611,7 @@ static int iclass_recover(uint8_t key[8], uint32_t index_start, uint32_t loop, u
|
|||
repeat = false;
|
||||
} else if (resp.status == PM3_EOPABORTED) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(WARNING, "iCLASS Key Bits Recovery: " _YELLOW_("user aborted"));
|
||||
PrintAndLogEx(WARNING, "iCLASS Key Bits Recovery: " _YELLOW_("aborted via keyboard!"));
|
||||
repeat = false;
|
||||
} else if (resp.status == PM3_ESOFT) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -5057,6 +5060,24 @@ static int CmdHFiClassUnhash(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
//check if divkey respects hash0 rules (legacy format) or if it could be AES Based
|
||||
|
||||
int count_lsb0 = 0;
|
||||
int count_lsb1 = 0;
|
||||
|
||||
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
|
||||
if ((div_key[i] & 0x01) == 0) {
|
||||
count_lsb0++;
|
||||
} else {
|
||||
count_lsb1++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count_lsb0 != 4 || count_lsb1 != 4) {
|
||||
PrintAndLogEx(INFO, _RED_("Incorrect LSB Distribution, unable to unhash - the key might be AES based."));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Diversified key... %s", sprint_hex_inrow(div_key, sizeof(div_key)));
|
||||
PrintAndLogEx(INFO, "-----------------------------------");
|
||||
invert_hash0(div_key);
|
||||
|
@ -5209,7 +5230,7 @@ static int CmdHFiClassLookUp(const char *Cmd) {
|
|||
item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32);
|
||||
|
||||
if (item != NULL) {
|
||||
PrintAndLogEx(SUCCESS, "Found valid key " _GREEN_("%s"), sprint_hex(item->key, 8));
|
||||
PrintAndLogEx(SUCCESS, "Found valid key " _GREEN_("%s"), sprint_hex_inrow(item->key, 8));
|
||||
add_key(item->key);
|
||||
}
|
||||
|
||||
|
@ -5885,6 +5906,15 @@ static int CmdHFiClassConfigCard(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static bool match_with_wildcard(const uint8_t *data, const uint8_t *pattern, const bool *mask, size_t length) {
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (mask[i] && data[i] != pattern[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int CmdHFiClassSAM(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf iclass sam",
|
||||
|
@ -5904,6 +5934,7 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
|||
arg_lit0("p", "prevent", "fake epurse update"),
|
||||
arg_lit0(NULL, "shallow", "shallow mod"),
|
||||
arg_strx0("d", "data", "<hex>", "DER encoded command to send to SAM"),
|
||||
arg_lit0("s", "snmp", "data is in snmp format without headers"),
|
||||
arg_lit0(NULL, "info", "get SAM infos (version, serial number)"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -5916,7 +5947,8 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
|||
bool break_nrmac = arg_get_lit(ctx, 5);
|
||||
bool prevent = arg_get_lit(ctx, 6);
|
||||
bool shallow_mod = arg_get_lit(ctx, 7);
|
||||
bool info = arg_get_lit(ctx, 9);
|
||||
bool snmp_data = arg_get_lit(ctx, 9);
|
||||
bool info = arg_get_lit(ctx, 10);
|
||||
|
||||
uint8_t flags = 0;
|
||||
if (disconnect_after) {
|
||||
|
@ -5958,11 +5990,25 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
if (snmp_data) {
|
||||
uint8_t header[4] = {0xa0, cmdlen + 2, 0x94, cmdlen };
|
||||
memmove(data + 4, data, cmdlen + 1);
|
||||
data[0] = flags;
|
||||
memcpy(data + 1, header, 4);
|
||||
cmdlen += 4;
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_SAM_PICOPASS, data, cmdlen + 1);
|
||||
PacketResponseNG resp;
|
||||
WaitForResponse(CMD_HF_SAM_PICOPASS, &resp);
|
||||
|
||||
bool is_snmp = false;
|
||||
uint8_t snmp_pattern[] = {0xBD, 0x81, 0xFF, 0x8A, 0x81, 0xFF}; // SNMP Response header pattern, 0xFF is a wildcard value for message length
|
||||
bool snmp_mask[] = {true, true, false, true, true, false}; // false means wildcard value in that position
|
||||
uint8_t ok_pattern[] = {0xBD, 0xFF, 0x8A}; // Ok response header pattern, 0xFF is a wildcard value for message length
|
||||
bool ok_mask[] = {true, false, true}; // false means wildcard value in that position
|
||||
|
||||
switch (resp.status) {
|
||||
case PM3_SUCCESS:
|
||||
break;
|
||||
|
@ -6020,12 +6066,25 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Replay Nr-MAC to dump SIO:");
|
||||
PrintAndLogEx(SUCCESS, " hf iclass dump --nr -k %s", sprint_hex_inrow(d + 1, 8));
|
||||
}
|
||||
} else {
|
||||
//if it is an error decode it
|
||||
if (memcmp(d, "\xBE\x07\x80\x01", 4) == 0) { //if it the string is 0xbe 0x07 0x80 0x01 the next byte will indicate the error code
|
||||
PrintAndLogEx(ERR, _RED_("Sam Error Code: %02x"), d[4]);
|
||||
print_hex(d, resp.length);
|
||||
} else if (match_with_wildcard(d, snmp_pattern, snmp_mask, 6)) {
|
||||
is_snmp = true;
|
||||
PrintAndLogEx(SUCCESS, _YELLOW_("[samSNMPMessageResponse] ")"%s", sprint_hex(d + 6, resp.length - 6));
|
||||
} else if (match_with_wildcard(d, ok_pattern, ok_mask, 3)) {
|
||||
PrintAndLogEx(SUCCESS, _YELLOW_("[samResponseAcknowledge] ")"%s", sprint_hex(d + 4, resp.length - 4));
|
||||
} else {
|
||||
print_hex(d, resp.length);
|
||||
}
|
||||
}
|
||||
|
||||
if (decodeTLV) {
|
||||
if (decodeTLV && is_snmp == false) {
|
||||
asn1_print(d, d[1] + 2, " ");
|
||||
} else if (decodeTLV && is_snmp) {
|
||||
asn1_print(d + 6, resp.length - 6, " ");
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -781,17 +781,20 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces) {
|
|||
}
|
||||
int legic_get_type(legic_card_select_t *card) {
|
||||
|
||||
if (card == NULL)
|
||||
if (card == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_LEGIC_INFO, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_HF_LEGIC_INFO, &resp, 1500) == false)
|
||||
if (WaitForResponseTimeout(CMD_HF_LEGIC_INFO, &resp, 1500) == false) {
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS)
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
memcpy(card, resp.data.asBytes, sizeof(legic_card_select_t));
|
||||
return PM3_SUCCESS;
|
||||
|
@ -1527,7 +1530,7 @@ int readLegicUid(bool loop, bool verbose) {
|
|||
PrintAndLogEx(SUCCESS, " MSN: " _GREEN_("%s"), sprint_hex(card.uid + 1, sizeof(card.uid) - 1));
|
||||
legic_print_type(card.cardsize, 0);
|
||||
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -438,7 +438,7 @@ int reader_lto(bool loop, bool verbose) {
|
|||
PrintAndLogEx(INFO, "UID......... " _GREEN_("%s"), sprint_hex_inrow(serial, sizeof(serial)));
|
||||
}
|
||||
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
lto_switch_off_field();
|
||||
return ret;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -238,7 +238,7 @@ static char *getProtocolStr(uint8_t id, bool hw) {
|
|||
|
||||
static char *getVersionStr(uint8_t type, uint8_t major, uint8_t minor) {
|
||||
|
||||
static char buf[40] = {0x00};
|
||||
static char buf[60] = {0x00};
|
||||
char *retStr = buf;
|
||||
|
||||
if (type == 0x01 && major == 0x00)
|
||||
|
@ -255,6 +255,8 @@ static char *getVersionStr(uint8_t type, uint8_t major, uint8_t minor) {
|
|||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor);
|
||||
else if (type == 0x01 && major == 0x33 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV3") " )", major, minor);
|
||||
else if (type == 0x81 && major == 0x43 && minor == 0x01)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV3C implementation on P71D600") " )", major, minor); // Swisskey iShield Key
|
||||
else if (type == 0x01 && major == 0x30 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire Light") " )", major, minor);
|
||||
else if (type == 0x02 && major == 0x11 && minor == 0x00)
|
||||
|
@ -329,6 +331,9 @@ nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
|
|||
if (type == 0x01 && major == 0x33 && minor == 0x00)
|
||||
return DESFIRE_EV3;
|
||||
|
||||
if (type == 0x81 && major == 0x43 && minor == 0x01)
|
||||
return DESFIRE_EV3;
|
||||
|
||||
// Duox
|
||||
if (type == 0x01 && major == 0xA0 && minor == 0x00)
|
||||
return DUOX;
|
||||
|
@ -458,7 +463,7 @@ static void swap24(uint8_t *data) {
|
|||
|
||||
// default parameters
|
||||
static uint8_t defaultKeyNum = 0;
|
||||
static DesfireCryptoAlgorithm defaultAlgoId = T_DES;
|
||||
static DesfireCryptoAlgorithm defaultAlgoId = T_3DES; // Real DESFire cards seem to use 2TDEA by default
|
||||
static uint8_t defaultKey[DESFIRE_MAX_KEY_SIZE] = {0};
|
||||
static int defaultKdfAlgo = MFDES_KDF_ALGO_NONE;
|
||||
static int defaultKdfInputLen = 0;
|
||||
|
@ -474,6 +479,7 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext_t *d
|
|||
uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid,
|
||||
uint8_t appid,
|
||||
uint8_t appisoid,
|
||||
uint8_t dfnameid,
|
||||
int *securechannel,
|
||||
DesfireCommunicationMode defcommmode,
|
||||
uint32_t *id,
|
||||
|
@ -559,6 +565,22 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext_t *d
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
// Handle dfname parameter
|
||||
if (dfnameid && id) {
|
||||
uint8_t dfname_data[16] = {0};
|
||||
int dfname_len = 0;
|
||||
if (CLIParamHexToBuf(arg_get_str(ctx, dfnameid), dfname_data, sizeof(dfname_data), &dfname_len) == 0 && dfname_len > 0) {
|
||||
if (dfname_len <= 16) {
|
||||
DesfireSetDFName(dctx, dfname_data, dfname_len);
|
||||
if (selectway)
|
||||
*selectway = ISWDFName;
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "DF name length must be between 1-16 bytes, got %d", dfname_len);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appid && id) {
|
||||
*id = 0x000000;
|
||||
if (CLIGetUint32Hex(ctx, appid, 0x000000, id, NULL, 3, "AID must have 3 bytes length"))
|
||||
|
@ -612,7 +634,7 @@ static int CmdHF14ADesDefault(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, &securechann, DCMNone, NULL, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, &securechann, DCMNone, NULL, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -1027,7 +1049,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
|||
DesfireSetKeyNoClear(dctx, keyno, T_DES, deskeyList[curkey]);
|
||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||
if (res == PM3_SUCCESS) {
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found DES Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(deskeyList[curkey], 8));
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found DES Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex(deskeyList[curkey], 8));
|
||||
foundKeys[0][keyno][0] = 0x01;
|
||||
*result = true;
|
||||
memcpy(&foundKeys[0][keyno][1], deskeyList[curkey], 8);
|
||||
|
@ -1059,7 +1081,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
|||
DesfireSetKeyNoClear(dctx, keyno, T_3DES, aeskeyList[curkey]);
|
||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||
if (res == PM3_SUCCESS) {
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 2TDEA Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16));
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 2TDEA Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex_inrow(aeskeyList[curkey], 16));
|
||||
foundKeys[1][keyno][0] = 0x01;
|
||||
*result = true;
|
||||
memcpy(&foundKeys[1][keyno][1], aeskeyList[curkey], 16);
|
||||
|
@ -1091,7 +1113,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
|||
DesfireSetKeyNoClear(dctx, keyno, T_AES, aeskeyList[curkey]);
|
||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||
if (res == PM3_SUCCESS) {
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16));
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex_inrow(aeskeyList[curkey], 16));
|
||||
foundKeys[2][keyno][0] = 0x01;
|
||||
*result = true;
|
||||
memcpy(&foundKeys[2][keyno][1], aeskeyList[curkey], 16);
|
||||
|
@ -1123,7 +1145,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
|||
DesfireSetKeyNoClear(dctx, keyno, T_3K3DES, k3kkeyList[curkey]);
|
||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||
if (res == PM3_SUCCESS) {
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3TDEA Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24));
|
||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3TDEA Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex_inrow(k3kkeyList[curkey], 24));
|
||||
foundKeys[3][keyno][0] = 0x01;
|
||||
*result = true;
|
||||
memcpy(&foundKeys[3][keyno][1], k3kkeyList[curkey], 16);
|
||||
|
@ -1515,6 +1537,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_str0("f", "file", "<fn>", "Filename of dictionary"),
|
||||
arg_lit0(NULL, "save", "Save found key and parameters to defaults"),
|
||||
arg_param_end
|
||||
|
@ -1528,7 +1551,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -1536,13 +1559,13 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
|
||||
uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0};
|
||||
int dict_filenamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(ctx, 13), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
if (CLIParamStrToBuf(arg_get_str(ctx, 14), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
bool save = arg_get_lit(ctx, 14);
|
||||
bool save = arg_get_lit(ctx, 15);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
CLIParserFree(ctx);
|
||||
|
@ -1843,7 +1866,7 @@ static int CmdHF14aDesMAD(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMPlain, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2019,7 +2042,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMPlain, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2141,7 +2164,7 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &securechann, DCMNone, NULL, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &securechann, DCMNone, NULL, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2176,25 +2199,32 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
|
|||
|
||||
reverse_array(startAid, 3);
|
||||
reverse_array(endAid, 3);
|
||||
|
||||
uint32_t idStart = DesfireAIDByteToUint(startAid);
|
||||
uint32_t idEnd = DesfireAIDByteToUint(endAid);
|
||||
|
||||
if (idStart > idEnd) {
|
||||
PrintAndLogEx(ERR, "Start should be lower than end. start: %06x end: %06x", idStart, idEnd);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
PrintAndLogEx(INFO, "Bruteforce from %06x to %06x", idStart, idEnd);
|
||||
PrintAndLogEx(INFO, "Enumerating through all AIDs manually, this will take a while!");
|
||||
for (uint32_t id = idStart; id <= idEnd && id >= idStart; id += idIncrement) {
|
||||
if (kbd_enter_pressed()) break;
|
||||
|
||||
int progress = ((id - idStart) * 100) / ((idEnd - idStart));
|
||||
PrintAndLogEx(INPLACE, "Progress: %d %%, current AID: %06X", progress, id);
|
||||
PrintAndLogEx(INFO, "Bruteforce from " _YELLOW_("%06x") " to " _YELLOW_("%06x"), idStart, idEnd);
|
||||
PrintAndLogEx(INFO, "Enumerating through all AIDs manually, this will take a while!");
|
||||
|
||||
for (uint32_t id = idStart; id <= idEnd && id >= idStart; id += idIncrement) {
|
||||
|
||||
if (kbd_enter_pressed()) {
|
||||
break;
|
||||
}
|
||||
|
||||
float progress = ((id - idStart) / (idEnd - idStart));
|
||||
PrintAndLogEx(INPLACE, "Progress " _YELLOW_("%0.1f") " %% current AID: %06X", progress, id);
|
||||
|
||||
res = DesfireSelectAIDHexNoFieldOn(&dctx, id);
|
||||
|
||||
if (res == PM3_SUCCESS) {
|
||||
printf("\33[2K\r"); // clear current line before printing
|
||||
PrintAndLogEx(SUCCESS, "Got new APPID %06X", id);
|
||||
PrintAndLogEx(SUCCESS, "Got new APPID " _GREEN_("%06X"), id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2219,7 +2249,8 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
|||
"hf mfdes auth -n 0 -t des -k 0000000000000000 --kdf none -> select PICC level and authenticate with key num=0, key type=des, key=00..00 and key derivation = none\n"
|
||||
"hf mfdes auth -n 0 -t aes -k 00000000000000000000000000000000 -> select PICC level and authenticate with key num=0, key type=aes, key=00..00 and key derivation = none\n"
|
||||
"hf mfdes auth -n 0 -t des -k 0000000000000000 --save -> select PICC level and authenticate and in case of successful authentication - save channel parameters to defaults\n"
|
||||
"hf mfdes auth --aid 123456 -> select application 123456 and authenticate via parameters from `default` command");
|
||||
"hf mfdes auth --aid 123456 -> select application 123456 and authenticate via parameters from `default` command\n"
|
||||
"hf mfdes auth --dfname D2760000850100 -n 0 -t aes -k 00000000000000000000000000000000 -> select DF by name and authenticate");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -2235,6 +2266,7 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_lit0(NULL, "save", "saves channels parameters to defaults if authentication succeeds"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -2247,13 +2279,13 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMPlain, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMPlain, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool save = arg_get_lit(ctx, 13);
|
||||
bool save = arg_get_lit(ctx, 14);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
CLIParserFree(ctx);
|
||||
|
@ -2265,7 +2297,9 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
|||
return res;
|
||||
}
|
||||
|
||||
if (DesfireMFSelected(selectway, id))
|
||||
if (dctx.selectedDFNameLen > 0) {
|
||||
PrintAndLogEx(SUCCESS, "DF selected and authenticated " _GREEN_("successfully"));
|
||||
} else if (DesfireMFSelected(selectway, id))
|
||||
PrintAndLogEx(SUCCESS, "PICC selected and authenticated " _GREEN_("succesfully"));
|
||||
else
|
||||
PrintAndLogEx(SUCCESS, "Application " _CYAN_("%s") " selected and authenticated " _GREEN_("succesfully"), DesfireWayIDStr(selectway, id));
|
||||
|
@ -2343,7 +2377,7 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2458,7 +2492,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2621,7 +2655,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2784,7 +2818,7 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2822,7 +2856,8 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfdes getuid",
|
||||
"Get UID from card. Get the real UID if the random UID bit is on and get the same UID as in anticollision if not. Any card's key needs to be provided. ",
|
||||
"hf mfdes getuid -> execute with default factory setup\n"
|
||||
"hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings");
|
||||
"hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings\n"
|
||||
"hf mfdes getuid --dfname D2760000850100 -> select DF by name and get UID");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -2838,6 +2873,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -2849,7 +2885,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMEncrypted, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2927,7 +2963,7 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2974,6 +3010,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
|
|||
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -2985,7 +3022,9 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 12, &securechann, (noauth) ? DCMPlain : DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -2994,7 +3033,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
|
|||
SetAPDULogging(APDULogging);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, 0x000000, noauth, verbose);
|
||||
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, noauth, verbose);
|
||||
if (res != PM3_SUCCESS) {
|
||||
DropField();
|
||||
return res;
|
||||
|
@ -3047,7 +3086,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMEncrypted, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3094,7 +3133,8 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) {
|
|||
"--keynum parameter: App level: key number. PICC level: 00..0d - keys count, 21..23 vc keys, default 0x00.\n"\
|
||||
"hf mfdes getkeyversions --keynum 00 -> get picc master key version with default key/channel setup\n"\
|
||||
"hf mfdes getkeyversions --aid 123456 --keynum 0d -> get app 123456 all key versions with default key/channel setup\n"
|
||||
"hf mfdes getkeyversions --aid 123456 --keynum 0d --no-auth -> get key version without authentication");
|
||||
"hf mfdes getkeyversions --aid 123456 --keynum 0d --no-auth -> get key version without authentication\n"\
|
||||
"hf mfdes getkeyversions --dfname D2760000850100 --keynum 00 -> select DF by name and get key versions");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -3110,36 +3150,38 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "keynum", "<hex>", "Key number/count (1 hex byte). (def: 0x00)"),
|
||||
arg_str0(NULL, "keyset", "<hex>", "Keyset number (1 hex byte)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 15);
|
||||
bool noauth = arg_get_lit(ctx, 16);
|
||||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t keynum32 = 0x00;
|
||||
if (CLIGetUint32Hex(ctx, 13, 0x00, &keynum32, NULL, 1, "Key number must have 1 byte length")) {
|
||||
if (CLIGetUint32Hex(ctx, 14, 0x00, &keynum32, NULL, 1, "Key number must have 1 byte length")) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t keysetnum32 = 0x00;
|
||||
bool keysetpresent = false;
|
||||
if (CLIGetUint32Hex(ctx, 14, 0x00, &keysetnum32, &keysetpresent, 1, "Keyset number must have 1 byte length")) {
|
||||
if (CLIGetUint32Hex(ctx, 15, 0x00, &keysetnum32, &keysetpresent, 1, "Keyset number must have 1 byte length")) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -3196,7 +3238,8 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfdes getkeysettings",
|
||||
"Get key settings for card level or application level.",
|
||||
"hf mfdes getkeysettings -> get picc key settings with default key/channel setup\n"\
|
||||
"hf mfdes getkeysettings --aid 123456 -> get app 123456 key settings with default key/channel setup");
|
||||
"hf mfdes getkeysettings --aid 123456 -> get app 123456 key settings with default key/channel setup\n"\
|
||||
"hf mfdes getkeysettings --dfname D2760000850100 -> select DF by name and get key settings");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -3211,6 +3254,7 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
|
|||
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -3221,7 +3265,8 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 12, &securechann, DCMMACed, &appid, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3299,7 +3344,7 @@ static int CmdHF14ADesGetAIDs(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3371,7 +3416,7 @@ static int CmdHF14ADesGetAppNames(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3418,7 +3463,8 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfdes getfileids",
|
||||
"Get File IDs list from card. Master key needs to be provided or flag --no-auth set.",
|
||||
"hf mfdes getfileids --aid 123456 -> execute with defaults from `default` command\n"
|
||||
"hf mfdes getfileids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup");
|
||||
"hf mfdes getfileids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup\n"
|
||||
"hf mfdes getfileids --dfname D2760000850100 -> select DF by name and get file IDs");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -3434,6 +3480,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -3441,13 +3488,13 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
|||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 13);
|
||||
bool noauth = arg_get_lit(ctx, 14);
|
||||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3463,6 +3510,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t buflen = 0;
|
||||
|
||||
|
@ -3478,7 +3526,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
|||
for (int i = 0; i < buflen; i++)
|
||||
PrintAndLogEx(INFO, "File ID: %02x", buf[i]);
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "There is no files in the application %06x", id);
|
||||
PrintAndLogEx(INFO, "There are no files in the application %06x", id);
|
||||
}
|
||||
|
||||
DropField();
|
||||
|
@ -3492,7 +3540,8 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
|||
"hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n"
|
||||
"hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup\n"
|
||||
"hf mfdes getfileisoids --isoid df01 -> get iso file ids from Desfire Light with factory card settings\n"
|
||||
"hf mfdes getfileisoids --isoid df01 --schann lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication");
|
||||
"hf mfdes getfileisoids --isoid df01 --schann lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication\n"
|
||||
"hf mfdes getfileisoids --dfname D2760000850100 -> select DF by name and get file ISO IDs");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -3508,6 +3557,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -3515,13 +3565,13 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
|||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 13);
|
||||
bool noauth = arg_get_lit(ctx, 14);
|
||||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3552,7 +3602,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
|||
for (int i = 0; i < buflen; i += 2)
|
||||
PrintAndLogEx(INFO, "File ID: %04x", MemLeToUint2byte(&buf[i]));
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "There is no files in the application %06x", id);
|
||||
PrintAndLogEx(INFO, "There are no files in the application %06x", id);
|
||||
}
|
||||
|
||||
DropField();
|
||||
|
@ -3565,7 +3615,8 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
|||
"Get File Settings from file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
||||
"hf mfdes getfilesettings --aid 123456 --fid 01 -> execute with defaults from `default` command\n"
|
||||
"hf mfdes getfilesettings --isoid df01 --fid 00 --no-auth -> get file settings with select by iso id\n"
|
||||
"hf mfdes getfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup");
|
||||
"hf mfdes getfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup\n"
|
||||
"hf mfdes getfilesettings --dfname D2760000850100 --fid 01 -> select DF by name and get file settings");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -3581,6 +3632,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "fid", "<hex>", "File ID (1 hex byte). (def: 1)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_param_end
|
||||
|
@ -3589,20 +3641,20 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
|||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 14);
|
||||
bool noauth = arg_get_lit(ctx, 15);
|
||||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t fileid = 1;
|
||||
if (CLIGetUint32Hex(ctx, 13, 1, &fileid, NULL, 1, "File ID must have 1 byte length")) {
|
||||
if (CLIGetUint32Hex(ctx, 14, 1, &fileid, NULL, 1, "File ID must have 1 byte length")) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -3627,8 +3679,9 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "%s file %02x settings[%zu]: %s", DesfireWayIDStr(selectway, id), fileid, buflen, sprint_hex(buf, buflen));
|
||||
}
|
||||
|
||||
DesfirePrintFileSettings(buf, buflen);
|
||||
|
||||
|
@ -3771,7 +3824,7 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -3918,7 +3971,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -4022,7 +4075,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
|||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||
arg_lit0("v", "verbose", "Verbose output"),
|
||||
arg_int0("n", "keyno", "<dec>", "Key number"),
|
||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo (deft: 2TDEA)"),
|
||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
||||
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||
|
@ -4055,7 +4108,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -4182,7 +4235,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
|
|||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -4300,7 +4353,7 @@ static int CmdHF14ADesCreateTrMACFile(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -4407,7 +4460,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -4462,7 +4515,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
|
|||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||
arg_lit0("v", "verbose", "Verbose output"),
|
||||
arg_int0("n", "keyno", "<dec>", "Key number"),
|
||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo (deft: 2TDEA)"),
|
||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
||||
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||
|
@ -4487,7 +4540,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -4657,7 +4710,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -5067,7 +5120,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 0, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -5242,7 +5295,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
|||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 0, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -5542,7 +5595,8 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
|||
"This commands List files inside application AID / ISOID.\n"
|
||||
"Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
||||
"hf mfdes lsfiles --aid 123456 -> AID 123456, list files using `default` command creds\n"
|
||||
"hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light");
|
||||
"hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light\n"
|
||||
"hf mfdes lsfiles --dfname D2760000850100 -> select DF by name and list files");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -5558,6 +5612,7 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -5565,13 +5620,13 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
|||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 13);
|
||||
bool noauth = arg_get_lit(ctx, 14);
|
||||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -5597,9 +5652,9 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (filescount == 0) {
|
||||
PrintAndLogEx(INFO, "There is no files in the %s", DesfireWayIDStr(selectway, id));
|
||||
PrintAndLogEx(INFO, "There are no files in the %s", DesfireWayIDStr(selectway, id));
|
||||
DropField();
|
||||
return res;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "------------------------------------------ " _CYAN_("File list") " -----------------------------------------------------");
|
||||
|
@ -5615,7 +5670,8 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf mfdes lsapp",
|
||||
"Show application list. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
||||
"hf mfdes lsapp -> show application list with defaults from `default` command\n"
|
||||
"hf mfdes lsapp --files -> show application list and show each file type/settings/etc");
|
||||
"hf mfdes lsapp --files -> show application list and show each file type/settings/etc\n"
|
||||
"hf mfdes lsapp --dfname D2760000850100 -> list apps after selecting DF by name");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -5632,6 +5688,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
|||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_lit0(NULL, "no-deep", "not to check authentication commands that avail for any application"),
|
||||
arg_lit0(NULL, "files", "scan files and print file settings"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -5644,7 +5701,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 14, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -5696,6 +5753,7 @@ static int CmdHF14ADesDump(const char *Cmd) {
|
|||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "dfname", "<hex>", "Application ISO DF Name (5-16 hex bytes, big endian)"),
|
||||
arg_str0("l", "length", "<hex>", "Maximum length for read data files (3 hex bytes, big endian)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_param_end
|
||||
|
@ -5704,20 +5762,20 @@ static int CmdHF14ADesDump(const char *Cmd) {
|
|||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 14);
|
||||
bool noauth = arg_get_lit(ctx, 15);
|
||||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, (noauth) ? DCMPlain : DCMMACed, &id, &selectway);
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, (noauth) ? DCMPlain : DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t maxlength = 0;
|
||||
if (CLIGetUint32Hex(ctx, 13, 0, &maxlength, NULL, 3, "Length parameter must have 3 byte length")) {
|
||||
if (CLIGetUint32Hex(ctx, 14, 0, &maxlength, NULL, 3, "Length parameter must have 3 byte length")) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -5828,6 +5886,7 @@ static command_t CommandTable[] = {
|
|||
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("Files") " -----------------------"},
|
||||
{"getfileids", CmdHF14ADesGetFileIDs, IfPm3Iso14443a, "Get File IDs list"},
|
||||
{"getfileisoids", CmdHF14ADesGetFileISOIDs, IfPm3Iso14443a, "Get File ISO IDs list"},
|
||||
{"lsfile", CmdHF14ADesLsFiles, IfPm3Iso14443a, "Show all files list"},
|
||||
{"lsfiles", CmdHF14ADesLsFiles, IfPm3Iso14443a, "Show all files list"},
|
||||
{"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"},
|
||||
{"createfile", CmdHF14ADesCreateFile, IfPm3Iso14443a, "Create Standard/Backup File"},
|
||||
|
|
|
@ -127,7 +127,6 @@ static void print_progress_header(void) {
|
|||
get_SIMD_instruction_set(instr_set);
|
||||
snprintf(progress_text, sizeof(progress_text), "Start using " _YELLOW_("%d") " threads and " _YELLOW_("%s") " SIMD core", num_CPUs(), instr_set);
|
||||
|
||||
PrintAndLogEx(INFO, "Hardnested attack starting...");
|
||||
PrintAndLogEx(INFO, "---------+---------+---------------------------------------------------------+-----------------+-------");
|
||||
PrintAndLogEx(INFO, " | | | Expected to brute force");
|
||||
PrintAndLogEx(INFO, " Time | #nonces | Activity | #states | time ");
|
||||
|
@ -136,12 +135,16 @@ static void print_progress_header(void) {
|
|||
}
|
||||
|
||||
void hardnested_print_progress(uint32_t nonces, const char *activity, float brute_force, uint64_t min_diff_print_time) {
|
||||
|
||||
static uint64_t last_print_time = 0;
|
||||
|
||||
if (msclock() - last_print_time >= min_diff_print_time) {
|
||||
|
||||
last_print_time = msclock();
|
||||
uint64_t total_time = msclock() - start_time;
|
||||
float brute_force_time = brute_force / brute_force_per_second;
|
||||
char brute_force_time_string[20];
|
||||
|
||||
if (brute_force_time < 90) {
|
||||
snprintf(brute_force_time_string, sizeof(brute_force_time_string), "%2.0fs", brute_force_time);
|
||||
} else if (brute_force_time < 60 * 90) {
|
||||
|
@ -151,7 +154,24 @@ void hardnested_print_progress(uint32_t nonces, const char *activity, float brut
|
|||
} else {
|
||||
snprintf(brute_force_time_string, sizeof(brute_force_time_string), "%2.0fd", brute_force_time / (60 * 60 * 24));
|
||||
}
|
||||
PrintAndLogEx(INFO, " %7.0f | %7u | %-55s | %15.0f | %5s", (float)total_time / 1000.0, nonces, activity, brute_force, brute_force_time_string);
|
||||
|
||||
if (strlen(activity) > 67) {
|
||||
PrintAndLogEx(INFO, " %7.0f | %7u | %-82s | %15.0f | %5s"
|
||||
, (float)total_time / 1000.0
|
||||
, nonces
|
||||
, activity
|
||||
, brute_force
|
||||
, brute_force_time_string
|
||||
);
|
||||
} else {
|
||||
PrintAndLogEx(INFO, " %7.0f | %7u | %-55s | %15.0f | %5s"
|
||||
, (float)total_time / 1000.0
|
||||
, nonces
|
||||
, activity
|
||||
, brute_force
|
||||
, brute_force_time_string
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,8 +506,14 @@ static void init_bitflip_bitarrays(void) {
|
|||
effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker
|
||||
}
|
||||
{
|
||||
char progress_text[80];
|
||||
snprintf(progress_text, sizeof(progress_text), "Loaded %u RAW / %u LZ4 / %u BZ2 in %"PRIu64" ms", nraw, nlz4, nbz2, msclock() - init_bitflip_bitarrays_starttime);
|
||||
char progress_text[100];
|
||||
memset(progress_text, 0, sizeof(progress_text));
|
||||
snprintf(progress_text, sizeof(progress_text), "Loaded " _YELLOW_("%u") " RAW / " _YELLOW_("%u") " LZ4 / " _YELLOW_("%u") " BZ2 in %4"PRIu64" ms"
|
||||
, nraw
|
||||
, nlz4
|
||||
, nbz2
|
||||
, msclock() - init_bitflip_bitarrays_starttime
|
||||
);
|
||||
hardnested_print_progress(0, progress_text, (float)(1LL << 47), 0);
|
||||
}
|
||||
uint16_t i = 0;
|
||||
|
@ -2481,8 +2507,10 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
|||
free_candidates_memory(candidates);
|
||||
candidates = NULL;
|
||||
} else {
|
||||
|
||||
pre_XOR_nonces();
|
||||
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
||||
|
||||
for (uint8_t j = 0; j < NUM_SUMS && !key_found; j++) {
|
||||
float expected_brute_force = nonces[best_first_bytes[0]].expected_num_brute_force;
|
||||
snprintf(progress_text, sizeof(progress_text), "(%d. guess: Sum(a8) = %" PRIu16 ")", j + 1, sums[nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx]);
|
||||
|
@ -2544,7 +2572,9 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
|||
|
||||
int res;
|
||||
if (nonce_file_read) { // use pre-acquired data from file nonces.bin
|
||||
|
||||
res = read_nonce_file(filename);
|
||||
|
||||
if (res != PM3_SUCCESS) {
|
||||
free_bitflip_bitarrays();
|
||||
free_nonces_memory();
|
||||
|
@ -2554,12 +2584,16 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
|||
free_part_sum_bitarrays();
|
||||
return res;
|
||||
}
|
||||
|
||||
hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES;
|
||||
update_nonce_data(false);
|
||||
float brute_force_depth;
|
||||
shrink_key_space(&brute_force_depth);
|
||||
|
||||
} else { // acquire nonces.
|
||||
|
||||
res = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow, filename);
|
||||
|
||||
if (res != PM3_SUCCESS) {
|
||||
free_bitflip_bitarrays();
|
||||
free_nonces_memory();
|
||||
|
|
|
@ -315,7 +315,7 @@ static int mfp_load_keys(uint8_t **pkeyBlock, uint32_t *pkeycnt, uint8_t *userke
|
|||
|
||||
int len = hex_to_bytes(g_mifare_plus_default_keys[cnt], (uint8_t *)(*pkeyBlock + (*pkeycnt + cnt) * AES_KEY_LEN), AES_KEY_LEN);
|
||||
|
||||
PrintAndLogEx(DEBUG, _YELLOW_("%2d") " - %s", *pkeycnt + cnt, sprint_hex_inrow(*pkeyBlock + (*pkeycnt + cnt) * AES_KEY_LEN, AES_KEY_LEN));
|
||||
PrintAndLogEx(DEBUG, _YELLOW_("%2u") " - %s", *pkeycnt + cnt, sprint_hex_inrow(*pkeyBlock + (*pkeycnt + cnt) * AES_KEY_LEN, AES_KEY_LEN));
|
||||
if (len != AES_KEY_LEN) {
|
||||
break;
|
||||
}
|
||||
|
@ -1802,9 +1802,6 @@ static int CmdHFMFPChk(const char *Cmd) {
|
|||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(INFO, "\ntime in checkkeys " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, _GREEN_("found keys:"));
|
||||
|
||||
// print result
|
||||
char strA[46 + 1] = {0};
|
||||
char strB[46 + 1] = {0};
|
||||
|
|
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