mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Compare commits
No commits in common. "master" and "v4.20469" have entirely different histories.
202 changed files with 1471 additions and 10414 deletions
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -2,34 +2,7 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [Daddy Iceman][2025-06-16]
|
||||||
- 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)
|
- Fixed edge case in fm11rf08s key recovery tools (@doegox)
|
||||||
- Removed `--par` from `lf em 4x70` commands.
|
- Removed `--par` from `lf em 4x70` commands.
|
||||||
- Changed `hf 14a info` - refactored code to be able to detect card technology across the client easier (@iceman1001)
|
- Changed `hf 14a info` - refactored code to be able to detect card technology across the client easier (@iceman1001)
|
||||||
|
|
9
Makefile
9
Makefile
|
@ -32,9 +32,6 @@ endif
|
||||||
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfc_card_only/% mfc_card_reader/% mfd_aes_brute/% fpga_compress/% cryptorf/%
|
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfc_card_only/% mfc_card_reader/% mfd_aes_brute/% fpga_compress/% cryptorf/%
|
||||||
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
|
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
|
||||||
#all clean install uninstall check: %: hitag2crack/%
|
#all clean install uninstall check: %: hitag2crack/%
|
||||||
clean: %: hitag2crack/%
|
|
||||||
find . -type d -name __pycache__ -exec rm -rfv \{\} +
|
|
||||||
|
|
||||||
|
|
||||||
INSTALLTOOLS=mfc/pm3_eml2lower.sh mfc/pm3_eml2upper.sh mfc/pm3_mfdread.py mfc/pm3_mfd2eml.py mfc/pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py
|
INSTALLTOOLS=mfc/pm3_eml2lower.sh mfc/pm3_eml2upper.sh mfc/pm3_mfdread.py mfc/pm3_mfd2eml.py mfc/pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py
|
||||||
INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt sim014.bin sim014.sha512.txt
|
INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt sim014.bin sim014.sha512.txt
|
||||||
|
@ -372,12 +369,10 @@ release:
|
||||||
@echo "# - Release Tag: $(VERSION)"
|
@echo "# - Release Tag: $(VERSION)"
|
||||||
@echo "# - Release Name: $(RELEASE_NAME)"
|
@echo "# - Release Name: $(RELEASE_NAME)"
|
||||||
# - Removing -Werror...
|
# - Removing -Werror...
|
||||||
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" -or -path "./client/deps/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
|
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" \) -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//' {} \;
|
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
|
||||||
# - Changing banner...
|
# - Changing banner...
|
||||||
@sed -i "s/^#define BANNERMSG2 .*/#define BANNERMSG2 \" -----------------------------------\"/" client/src/proxmark3.c
|
|
||||||
@sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c
|
@sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c
|
||||||
@echo -n "# ";grep "^#define BANNERMSG2" client/src/proxmark3.c
|
|
||||||
@echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
|
@echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
|
||||||
# - Committing temporarily...
|
# - Committing temporarily...
|
||||||
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"
|
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"
|
||||||
|
|
|
@ -112,8 +112,8 @@ ifeq ($(DEBUG),1)
|
||||||
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
|
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
|
||||||
DEFLDFLAGS =
|
DEFLDFLAGS =
|
||||||
else
|
else
|
||||||
DEFCXXFLAGS = -Wall -Werror -O3 -pipe
|
DEFCXXFLAGS = -Wall -O3 -pipe
|
||||||
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
|
DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe
|
||||||
DEFLDFLAGS =
|
DEFLDFLAGS =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# Comment the line below and uncomment further down according to which device you have
|
# Comment the line below and uncomment further down according to which device you have
|
||||||
PLATFORM=PM3RDV4
|
PLATFORM=PM3RDV4
|
||||||
|
|
||||||
# For PM3 RDV1, RDV2, Easy or rysccorps etc
|
# For PM3 Easy:
|
||||||
# uncomment the line below
|
# uncomment the line below
|
||||||
#PLATFORM=PM3GENERIC
|
#PLATFORM=PM3GENERIC
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ PLATFORM=PM3RDV4
|
||||||
#PLATFORM_EXTRAS=BTADDON
|
#PLATFORM_EXTRAS=BTADDON
|
||||||
#PLATFORM_EXTRAS=FLASH
|
#PLATFORM_EXTRAS=FLASH
|
||||||
#PLATFORM_EXTRAS=SMARTCARD
|
#PLATFORM_EXTRAS=SMARTCARD
|
||||||
#PLATFORM_EXTRAS=BTADDON FPC_USART_DEV FLASH
|
#PLATFORM_EXTRAS=BTADDON FLASH
|
||||||
#STANDALONE=HF_UNISNIFF
|
#STANDALONE=LF_SAMYRUN
|
||||||
|
|
||||||
|
|
||||||
# Uncomment the line below to set the correct LED order on board Proxmark3 Easy
|
# Uncomment the line below to set the correct LED order on board Proxmark3 Easy
|
||||||
|
|
12
README.md
12
README.md
|
@ -60,8 +60,7 @@ 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)|
|
|[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 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 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)|[Unofficial MIFARE DESFire bible](/doc/unofficial_desfire_bible.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 downgrade attacks](/doc/hid_downgrade.md)|||
|
|
||||||
|
|
||||||
# How to build?
|
# How to build?
|
||||||
|
|
||||||
|
@ -97,14 +96,12 @@ We define generic Proxmark3 platforms as following devices.
|
||||||
- **Note**: currently incompatible with iCopy-X GUI as Proxmark client commands using different syntax
|
- **Note**: currently incompatible with iCopy-X GUI as Proxmark client commands using different syntax
|
||||||
- **Note**: see also [icopyx-community repos](https://github.com/iCopy-X-Community/) for upstream sources, reversed hw etc.
|
- **Note**: see also [icopyx-community repos](https://github.com/iCopy-X-Community/) for upstream sources, reversed hw etc.
|
||||||
- **Note**: Uses DRM to lock down tags, ignores the open source licences. Use on your own risk.
|
- **Note**: Uses DRM to lock down tags, ignores the open source licences. Use on your own risk.
|
||||||
- ⚠ Proxmark3 Ultimate
|
|
||||||
- **Note**: unknown device hw
|
|
||||||
- **Note**: FPGA images is building for it. Use on your own risk.
|
|
||||||
|
|
||||||
**Unknown support status**
|
**Unknown support status**
|
||||||
- ⚠ VX
|
- ⚠ VX
|
||||||
- **Note**: unknown device hw
|
- **Note**: unknown device hw
|
||||||
|
- ⚠ Proxmark3 Ultimate
|
||||||
|
- **Note**: unknown device hw
|
||||||
|
|
||||||
When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.
|
When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work.
|
||||||
|
|
||||||
|
@ -183,11 +180,10 @@ We usually merge your contributions fast since we do like the idea of getting a
|
||||||
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
|
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
|
||||||
|
|
||||||
|
|
||||||
## Supported operating systems
|
## Supported operative systems
|
||||||
|
|
||||||
This repo compiles nicely on
|
This repo compiles nicely on
|
||||||
- WSL1 on Windows 10
|
- WSL1 on Windows 10
|
||||||
- WSL2 on Windows 10/11
|
|
||||||
- Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases)
|
- Proxspace environment [release v3.xx](https://github.com/Gator96100/ProxSpace/releases)
|
||||||
- Windows/MinGW environment
|
- Windows/MinGW environment
|
||||||
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian
|
- Ubuntu, ParrotOS, Gentoo, Pentoo, Kali, NetHunter, Arch Linux, Fedora, Debian, Raspbian
|
||||||
|
|
|
@ -354,7 +354,7 @@ int emlGet(uint8_t *out, uint32_t offset, uint32_t length) {
|
||||||
tosend_t *get_tosend(void) {
|
tosend_t *get_tosend(void) {
|
||||||
|
|
||||||
if (s_toSend.buf == NULL) {
|
if (s_toSend.buf == NULL) {
|
||||||
s_toSend.buf = BigBuf_calloc(TOSEND_BUFFER_SIZE);
|
s_toSend.buf = BigBuf_malloc(TOSEND_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
return &s_toSend;
|
return &s_toSend;
|
||||||
}
|
}
|
||||||
|
@ -377,9 +377,8 @@ void tosend_stuffbit(int b) {
|
||||||
s_toSend.bit = 0;
|
s_toSend.bit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b) {
|
if (b)
|
||||||
s_toSend.buf[s_toSend.max] |= (1 << (7 - s_toSend.bit));
|
s_toSend.buf[s_toSend.max] |= (1 << (7 - s_toSend.bit));
|
||||||
}
|
|
||||||
|
|
||||||
s_toSend.bit++;
|
s_toSend.bit++;
|
||||||
|
|
||||||
|
@ -390,14 +389,15 @@ void tosend_stuffbit(int b) {
|
||||||
|
|
||||||
dmabuf16_t *get_dma16(void) {
|
dmabuf16_t *get_dma16(void) {
|
||||||
if (s_dma_16.buf == NULL) {
|
if (s_dma_16.buf == NULL) {
|
||||||
s_dma_16.buf = (uint16_t *)BigBuf_calloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
|
s_dma_16.buf = (uint16_t *)BigBuf_malloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
return &s_dma_16;
|
return &s_dma_16;
|
||||||
}
|
}
|
||||||
|
|
||||||
dmabuf8_t *get_dma8(void) {
|
dmabuf8_t *get_dma8(void) {
|
||||||
if (s_dma_8.buf == NULL) {
|
if (s_dma_8.buf == NULL)
|
||||||
s_dma_8.buf = BigBuf_calloc(DMA_BUFFER_SIZE);
|
s_dma_8.buf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
}
|
|
||||||
return &s_dma_8;
|
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 should be checked on every time fullimage.stage1.elf should be remade
|
||||||
version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
|
version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
|
||||||
$(info [-] CHECK $@)
|
$(info [-] CHECK $@)
|
||||||
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
|
$(Q)$(CP) $< $@
|
||||||
|
|
||||||
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
|
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
|
||||||
$(info [-] GEN $@)
|
$(info [-] GEN $@)
|
||||||
|
|
|
@ -157,7 +157,7 @@ void RunMod(void) {
|
||||||
if (button_pressed != BUTTON_NO_CLICK || data_available())
|
if (button_pressed != BUTTON_NO_CLICK || data_available())
|
||||||
break;
|
break;
|
||||||
else if (state == STATE_SEARCH) {
|
else if (state == STATE_SEARCH) {
|
||||||
if (iso14443a_select_card(NULL, &card, NULL, true, 0, true) == 0) {
|
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, true)) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
SpinDelay(500);
|
SpinDelay(500);
|
||||||
|
@ -246,7 +246,7 @@ void RunMod(void) {
|
||||||
FLAG_SET_UID_IN_DATA(flags, 7);
|
FLAG_SET_UID_IN_DATA(flags, 7);
|
||||||
|
|
||||||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||||
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0);
|
||||||
|
|
||||||
// Go back to search state if user presses pm3-button
|
// Go back to search state if user presses pm3-button
|
||||||
state = STATE_SEARCH;
|
state = STATE_SEARCH;
|
||||||
|
|
|
@ -63,18 +63,18 @@ static void RAMFUNC SniffAndStore(uint8_t param) {
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
// Array to store the authpwds
|
// Array to store the authpwds
|
||||||
uint8_t *capturedPwds = BigBuf_calloc(4 * MAX_PWDS_PER_SESSION);
|
uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION);
|
||||||
|
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
uint8_t *receivedCmdPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
|
|
||||||
// The response (tag -> reader) that we're receiving.
|
// The response (tag -> reader) that we're receiving.
|
||||||
uint8_t *receivedResp = BigBuf_calloc(MAX_FRAME_SIZE);
|
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
uint8_t *receivedRespPar = BigBuf_calloc(MAX_PARITY_SIZE);
|
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
uint8_t *dmaBuf = BigBuf_calloc(DMA_BUFFER_SIZE);
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
uint8_t *data = dmaBuf;
|
uint8_t *data = dmaBuf;
|
||||||
|
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
|
|
|
@ -234,7 +234,7 @@ static void become_card(void) {
|
||||||
tag_response_info_t *canned;
|
tag_response_info_t *canned;
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
uint8_t pages;
|
uint8_t pages;
|
||||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, &pages, NULL) == false) {
|
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, &pages) == false) {
|
||||||
DbpString(_RED_("Error initializing the emulation process!"));
|
DbpString(_RED_("Error initializing the emulation process!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,7 +250,7 @@ static char *ReadSchemasFromSPIFFS(char *filename) {
|
||||||
|
|
||||||
int changed = rdv40_spiffs_lazy_mount();
|
int changed = rdv40_spiffs_lazy_mount();
|
||||||
uint32_t size = size_in_spiffs((char *)filename);
|
uint32_t size = size_in_spiffs((char *)filename);
|
||||||
uint8_t *mem = BigBuf_calloc(size);
|
uint8_t *mem = BigBuf_malloc(size);
|
||||||
rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
@ -292,7 +292,7 @@ static void ReadLastTagFromFlash(void) {
|
||||||
DbprintfEx(FLAG_NEWLINE, "Button HELD ! Using LAST Known TAG for Simulation...");
|
DbprintfEx(FLAG_NEWLINE, "Button HELD ! Using LAST Known TAG for Simulation...");
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
|
|
||||||
uint8_t *mem = BigBuf_calloc(size);
|
uint8_t *mem = BigBuf_malloc(size);
|
||||||
|
|
||||||
// this one will handle filetype (symlink or not) and resolving by itself
|
// 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);
|
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
|
// Can remember something like that in case of Bigbuf
|
||||||
keyBlock = BigBuf_calloc(ARRAYLEN(mfKeys) * MF_KEY_LENGTH);
|
keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
|
||||||
int mfKeysCnt = ARRAYLEN(mfKeys);
|
int mfKeysCnt = ARRAYLEN(mfKeys);
|
||||||
|
|
||||||
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
|
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
|
||||||
num_to_bytes(mfKeys[mfKeyCounter], MF_KEY_LENGTH, (uint8_t *)(keyBlock + (mfKeyCounter * MF_KEY_LENGTH)));
|
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : remember why we actually had need to initialize this array in such specific case
|
// TODO : remember why we actually had need to initialize this array in such specific case
|
||||||
|
@ -498,7 +498,7 @@ failtag:
|
||||||
SpinOff(50);
|
SpinOff(50);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
while (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
while (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (BUTTON_HELD(10) == BUTTON_HOLD) {
|
if (BUTTON_HELD(10) == BUTTON_HOLD) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -785,7 +785,7 @@ static int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||||
|
|
||||||
bool isOK = true;
|
bool isOK = true;
|
||||||
|
|
||||||
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||||
isOK = false;
|
isOK = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,7 +844,8 @@ static int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTr
|
||||||
for (uint8_t i = 0; i < keyCount; i++) {
|
for (uint8_t i = 0; i < keyCount; i++) {
|
||||||
|
|
||||||
/* no need for anticollision. just verify tag is still here */
|
/* no need for anticollision. just verify tag is still here */
|
||||||
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
// if (!iso14443a_fast_select_card(colin_cjuid, 0)) {
|
||||||
|
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
|
||||||
break;
|
break;
|
||||||
|
@ -962,7 +963,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, const
|
||||||
|
|
||||||
// get UID from chip
|
// get UID from chip
|
||||||
if (workFlags & 0x01) {
|
if (workFlags & 0x01) {
|
||||||
if (iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true) == 0) {
|
if (!iso14443a_select_card(colin_cjuid, &colin_p_card, &colin_cjcuid, true, 0, true)) {
|
||||||
DbprintfEx(FLAG_NEWLINE, "Can't select card");
|
DbprintfEx(FLAG_NEWLINE, "Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,22 +89,22 @@ void RunMod(void) {
|
||||||
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state.");
|
||||||
if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) {
|
if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) {
|
||||||
DbpString("Mifare Classic 1k");
|
DbpString("Mifare Classic 1k");
|
||||||
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0);
|
||||||
} else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
|
} else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
|
||||||
DbpString("Mifare Classic 4k ");
|
DbpString("Mifare Classic 4k ");
|
||||||
SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0);
|
||||||
} else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
|
} else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) {
|
||||||
DbpString("Mifare Ultralight");
|
DbpString("Mifare Ultralight");
|
||||||
SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0);
|
||||||
} else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) {
|
} else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) {
|
||||||
DbpString("Mifare DESFire");
|
DbpString("Mifare DESFire");
|
||||||
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0);
|
||||||
} else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) {
|
} else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) {
|
||||||
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
||||||
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
||||||
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go back to search state if user presses pm3-button
|
// Go back to search state if user presses pm3-button
|
||||||
|
|
|
@ -238,7 +238,7 @@ static int reader_attack_mode(void) {
|
||||||
|
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
uint16_t mac_response_len = 0;
|
uint16_t mac_response_len = 0;
|
||||||
uint8_t *mac_responses = BigBuf_calloc(MAC_RESPONSES_SIZE);
|
uint8_t *mac_responses = BigBuf_malloc(MAC_RESPONSES_SIZE);
|
||||||
|
|
||||||
iclass_simulate(ICLASS_SIM_MODE_READER_ATTACK, NUM_CSNS, false, csns, mac_responses, &mac_response_len);
|
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;
|
size_t dumplen = NUM_CSNS * 24;
|
||||||
|
|
||||||
uint8_t *dump = BigBuf_calloc(dumplen);
|
uint8_t *dump = BigBuf_malloc(dumplen);
|
||||||
if (dump == false) {
|
if (dump == false) {
|
||||||
Dbprintf("Failed to allocate memory");
|
Dbprintf("Failed to allocate memory");
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
|
@ -305,7 +305,6 @@ static int reader_dump_mode(void) {
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
||||||
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
|
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);
|
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
|
||||||
|
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
|
@ -443,7 +442,6 @@ static int dump_sim_mode(void) {
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
||||||
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
|
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);
|
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
|
||||||
|
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
|
|
|
@ -247,7 +247,7 @@ void RunMod(void) {
|
||||||
// usb_disable();
|
// usb_disable();
|
||||||
|
|
||||||
// Allocate dictionary buffer
|
// Allocate dictionary buffer
|
||||||
uint64_t *const mfcKeys = (uint64_t *)BigBuf_calloc(
|
uint64_t *const mfcKeys = (uint64_t *)BigBuf_malloc(
|
||||||
sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) +
|
sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) +
|
||||||
ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) +
|
ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) +
|
||||||
MIFARE_4K_MAXSECTOR * 2));
|
MIFARE_4K_MAXSECTOR * 2));
|
||||||
|
|
|
@ -379,7 +379,7 @@ void RunMod(void) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
|
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
|
||||||
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL, NULL) == false) {
|
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_RED_("Error initializing the emulation process!"));
|
DbpString(_RED_("Error initializing the emulation process!"));
|
||||||
|
|
|
@ -268,7 +268,7 @@ void RunMod() {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
|
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
|
||||||
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL, NULL) == false) {
|
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_RED_("Error initializing the emulation process!"));
|
DbpString(_RED_("Error initializing the emulation process!"));
|
||||||
|
|
|
@ -191,7 +191,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
memcpy(data, stuid, sizeof(stuid));
|
memcpy(data, stuid, sizeof(stuid));
|
||||||
|
|
||||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages, NULL) == false) {
|
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
||||||
|
@ -369,7 +369,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
memcpy(data, stuid, sizeof(stuid));
|
memcpy(data, stuid, sizeof(stuid));
|
||||||
|
|
||||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages, NULL) == false) {
|
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, &pages) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
||||||
|
|
|
@ -96,7 +96,7 @@ void RunMod(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true) == 0) {
|
if (!iso14443a_select_card(NULL, &card[selected], NULL, true, 0, true)) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
SpinDelay(500);
|
SpinDelay(500);
|
||||||
|
@ -253,25 +253,25 @@ void RunMod(void) {
|
||||||
|
|
||||||
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
|
if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) {
|
||||||
DbpString("Mifare Classic 1k");
|
DbpString("Mifare Classic 1k");
|
||||||
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(1, flags, data, 0, NULL, 0);
|
||||||
} else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
|
} else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) {
|
||||||
DbpString("Mifare Classic 4k (4b uid)");
|
DbpString("Mifare Classic 4k (4b uid)");
|
||||||
SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(8, flags, data, 0, NULL, 0);
|
||||||
} else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
|
} else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
|
||||||
DbpString("Mifare Classic 4k (7b uid)");
|
DbpString("Mifare Classic 4k (7b uid)");
|
||||||
SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(8, flags, data, 0, NULL, 0);
|
||||||
} else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
|
} else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) {
|
||||||
DbpString("Mifare Ultralight");
|
DbpString("Mifare Ultralight");
|
||||||
SimulateIso14443aTag(2, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(2, flags, data, 0, NULL, 0);
|
||||||
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
|
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) {
|
||||||
DbpString("Mifare DESFire");
|
DbpString("Mifare DESFire");
|
||||||
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(3, flags, data, 0, NULL, 0);
|
||||||
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0x03) {
|
} else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0x03) {
|
||||||
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
DbpString("Mifare DESFire Ev1/Plus/JCOP");
|
||||||
SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(3, flags, data, 0, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
|
||||||
SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false);
|
SimulateIso14443aTag(1, flags, data, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
||||||
|
|
|
@ -199,7 +199,7 @@ static uint32_t IceIOdemod(void) {
|
||||||
|
|
||||||
size_t size = MIN(12000, BigBuf_max_traceLen());
|
size_t size = MIN(12000, BigBuf_max_traceLen());
|
||||||
|
|
||||||
// uint8_t *dest = BigBuf_calloc(size);
|
// uint8_t *dest = BigBuf_malloc(size);
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
//fskdemod and get start index
|
//fskdemod and get start index
|
||||||
|
@ -243,7 +243,7 @@ static uint32_t IceHIDDemod(void) {
|
||||||
// large enough to catch 2 sequences of largest format
|
// large enough to catch 2 sequences of largest format
|
||||||
// size_t size = 50 * 128 * 2; // 12800 bytes
|
// size_t size = 50 * 128 * 2; // 12800 bytes
|
||||||
size_t size = MIN(12800, BigBuf_max_traceLen());
|
size_t size = MIN(12800, BigBuf_max_traceLen());
|
||||||
//uint8_t *dest = BigBuf_calloc(size);
|
//uint8_t *dest = BigBuf_malloc(size);
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
// FSK demodulator
|
// FSK demodulator
|
||||||
|
|
|
@ -103,9 +103,9 @@ static bool get_input_data_from_file(uint32_t *tag, char *inputfile) {
|
||||||
if (exists_in_spiffs(inputfile)) {
|
if (exists_in_spiffs(inputfile)) {
|
||||||
|
|
||||||
uint32_t size = size_in_spiffs(inputfile);
|
uint32_t size = size_in_spiffs(inputfile);
|
||||||
uint8_t *mem = BigBuf_calloc(size);
|
uint8_t *mem = BigBuf_malloc(size);
|
||||||
|
|
||||||
Dbprintf("found input file `" _YELLOW_("%s") "`", inputfile);
|
Dbprintf(_YELLOW_("found input file %s"), inputfile);
|
||||||
|
|
||||||
rdv40_spiffs_read_as_filetype(inputfile, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_read_as_filetype(inputfile, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
|
||||||
|
|
|
@ -480,32 +480,6 @@ static void SendStatus(uint32_t wait) {
|
||||||
} else {
|
} else {
|
||||||
Dbprintf(" iClass... "_RED_("%u")" keys - "_RED_("%s"), num, ICLASS_KEYS_FILE);
|
Dbprintf(" iClass... "_RED_("%u")" keys - "_RED_("%s"), num, ICLASS_KEYS_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exists_in_spiffs(MFULC_KEYS_FILE)) {
|
|
||||||
num = size_in_spiffs(MFULC_KEYS_FILE) / MFULC_KEY_LENGTH;
|
|
||||||
} else {
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num > 0) {
|
|
||||||
Dbprintf(" UL-C..... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MFULC_KEYS_FILE);
|
|
||||||
} else {
|
|
||||||
Dbprintf(" UL-C..... "_RED_("%u")" keys - "_RED_("%s"), num, MFULC_KEYS_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exists_in_spiffs(MFULAES_KEYS_FILE)) {
|
|
||||||
num = size_in_spiffs(MFULAES_KEYS_FILE) / MFULAES_KEY_LENGTH;
|
|
||||||
} else {
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num > 0) {
|
|
||||||
Dbprintf(" UL-AES... "_YELLOW_("%u")" keys - "_GREEN_("%s"), num, MFULAES_KEYS_FILE);
|
|
||||||
} else {
|
|
||||||
Dbprintf(" UL-AES... "_RED_("%u")" keys - "_RED_("%s"), num, MFULAES_KEYS_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
DbpString("");
|
DbpString("");
|
||||||
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
|
||||||
|
@ -1749,13 +1723,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
uint8_t uid[10];
|
uint8_t uid[10];
|
||||||
uint8_t exitAfter;
|
uint8_t exitAfter;
|
||||||
uint8_t rats[20];
|
uint8_t rats[20];
|
||||||
bool ulc_p1;
|
|
||||||
bool ulc_p2;
|
|
||||||
} PACKED;
|
} PACKED;
|
||||||
struct p *payload = (struct p *) packet->data.asBytes;
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid,
|
SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid,
|
||||||
payload->exitAfter, payload->rats, sizeof(payload->rats),
|
payload->exitAfter, payload->rats, sizeof(payload->rats)); // ## Simulate iso14443a tag - pass tag type & UID
|
||||||
payload->ulc_p1, payload->ulc_p2); // ## Simulate iso14443a tag - pass tag type & UID
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ISO14443A_SIM_AID: {
|
case CMD_HF_ISO14443A_SIM_AID: {
|
||||||
|
|
|
@ -102,7 +102,9 @@ void Dbhexdump(int len, const uint8_t *d, bool bAsci) {
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
const uint8_t *p = d;
|
||||||
uint16_t tmp = n & 0xFFF0;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *buffer = BigBuf_calloc(padded_data_length(len, kbs));
|
uint8_t *buffer = BigBuf_malloc(padded_data_length(len, kbs));
|
||||||
|
|
||||||
memcpy(buffer, data, len);
|
memcpy(buffer, data, len);
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
// Initialize Demod and Uart structs
|
// Initialize Demod and Uart structs
|
||||||
// DemodInit(BigBuf_calloc(MAX_FRAME_SIZE));
|
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||||
FelicaFrameinit(BigBuf_calloc(FELICA_MAX_FRAME_SIZE));
|
FelicaFrameinit(BigBuf_calloc(FELICA_MAX_FRAME_SIZE));
|
||||||
|
|
||||||
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
|
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
|
||||||
|
|
|
@ -523,11 +523,10 @@ void FpgaDownloadAndGo(int bitstream_target) {
|
||||||
lz4_stream_t compressed_fpga_stream;
|
lz4_stream_t compressed_fpga_stream;
|
||||||
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
|
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
|
||||||
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
|
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
|
||||||
uint8_t *output_buffer = BigBuf_calloc(FPGA_RING_BUFFER_BYTES);
|
uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
|
||||||
|
|
||||||
if (reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer) == false) {
|
if (!reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t bitstream_length;
|
uint32_t bitstream_length;
|
||||||
if (bitparse_find_section(bitstream_target, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
if (bitparse_find_section(bitstream_target, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "nprintf.h"
|
#include "nprintf.h"
|
||||||
|
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#define malloc(X) BigBuf_calloc(X)
|
#define malloc(X) BigBuf_malloc(X)
|
||||||
#define free(X)
|
#define free(X)
|
||||||
|
|
||||||
#if !defined(WEAK)
|
#if !defined(WEAK)
|
||||||
|
|
|
@ -107,7 +107,7 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
|
|
||||||
*len = BigBuf_max_traceLen();
|
*len = BigBuf_max_traceLen();
|
||||||
uint8_t *mem = BigBuf_calloc(*len);
|
uint8_t *mem = BigBuf_malloc(*len);
|
||||||
|
|
||||||
uint32_t trigger_cnt = 0;
|
uint32_t trigger_cnt = 0;
|
||||||
uint16_t r = 0, interval = 0;
|
uint16_t r = 0, interval = 0;
|
||||||
|
|
209
armsrc/iclass.c
209
armsrc/iclass.c
|
@ -917,9 +917,8 @@ send:
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
if (button_pressed) {
|
if (button_pressed)
|
||||||
DbpString("button pressed");
|
DbpString("button pressed");
|
||||||
}
|
|
||||||
|
|
||||||
return button_pressed;
|
return button_pressed;
|
||||||
}
|
}
|
||||||
|
@ -1858,39 +1857,8 @@ static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, b
|
||||||
return true;
|
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
|
// turn off afterwards
|
||||||
void iClass_WriteBlock(uint8_t *msg) {
|
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();
|
LED_A_ON();
|
||||||
|
|
||||||
|
@ -1910,9 +1878,6 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
goto out;
|
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;
|
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
uint8_t mac[4] = {0};
|
uint8_t mac[4] = {0};
|
||||||
|
@ -1939,7 +1904,7 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
write_len -= 2;
|
write_len -= 2;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (payload->req.use_replay && (memcmp(payload->mac, "\x00\x00\x00\x00", 4) != 0)) {
|
if (payload->req.use_replay) {
|
||||||
memcpy(write + 10, payload->mac, sizeof(payload->mac));
|
memcpy(write + 10, payload->mac, sizeof(payload->mac));
|
||||||
} else {
|
} else {
|
||||||
// Secure tags uses MAC
|
// Secure tags uses MAC
|
||||||
|
@ -1947,17 +1912,10 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
wb[0] = payload->req.blockno;
|
wb[0] = payload->req.blockno;
|
||||||
memcpy(wb + 1, payload->data, PICOPASS_BLOCK_SIZE);
|
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);
|
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
||||||
} else if (payload->req.use_replay) {
|
else
|
||||||
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);
|
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(write + 10, mac, sizeof(mac));
|
memcpy(write + 10, mac, sizeof(mac));
|
||||||
}
|
}
|
||||||
|
@ -2595,9 +2553,6 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
void iClass_Restore(iclass_restore_req_t *msg) {
|
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
|
// sanitation
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
|
@ -2626,9 +2581,7 @@ void iClass_Restore(iclass_restore_req_t *msg) {
|
||||||
if (res == false) {
|
if (res == false) {
|
||||||
goto out;
|
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
|
// authenticate
|
||||||
uint8_t mac[4] = {0};
|
uint8_t mac[4] = {0};
|
||||||
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
|
@ -2658,18 +2611,11 @@ void iClass_Restore(iclass_restore_req_t *msg) {
|
||||||
wb[0] = item.blockno;
|
wb[0] = item.blockno;
|
||||||
memcpy(wb + 1, item.data, 8);
|
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);
|
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
||||||
} else if (msg->req.use_replay) {
|
else
|
||||||
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);
|
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// data + mac
|
// data + mac
|
||||||
if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac, shallow_mod)) {
|
if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac, shallow_mod)) {
|
||||||
|
@ -2692,7 +2638,7 @@ out:
|
||||||
static void generate_single_key_block_inverted_opt(const uint8_t *startingKey, uint32_t index, uint8_t *keyBlock) {
|
static void generate_single_key_block_inverted_opt(const uint8_t *startingKey, uint32_t index, uint8_t *keyBlock) {
|
||||||
|
|
||||||
uint8_t bits_index = index / 16383;
|
uint8_t bits_index = index / 16383;
|
||||||
uint8_t ending_bits[] = { // all possible 70 combinations of 4x0 and 4x1 as key ending bits
|
uint8_t ending_bits[] = { //all possible 70 combinations of 4x0 and 4x1 as key ending bits
|
||||||
0x0F, 0x17, 0x1B, 0x1D, 0x1E, 0x27, 0x2B, 0x2D, 0x2E, 0x33,
|
0x0F, 0x17, 0x1B, 0x1D, 0x1E, 0x27, 0x2B, 0x2D, 0x2E, 0x33,
|
||||||
0x35, 0x36, 0x39, 0x3A, 0x3C, 0x47, 0x4B, 0x4D, 0x4E, 0x53,
|
0x35, 0x36, 0x39, 0x3A, 0x3C, 0x47, 0x4B, 0x4D, 0x4E, 0x53,
|
||||||
0x55, 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x69, 0x6A,
|
0x55, 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x69, 0x6A,
|
||||||
|
@ -2776,10 +2722,10 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
uint8_t original_mac[8] = {0};
|
uint8_t original_mac[8] = {0};
|
||||||
uint8_t mac1[4] = {0};
|
uint8_t mac1[4] = {0};
|
||||||
|
|
||||||
while ((card_select == false) || (card_auth == false)) {
|
while (!card_select || !card_auth) {
|
||||||
|
|
||||||
Iso15693InitReader(); //has to be at the top as it starts tracing
|
Iso15693InitReader(); //has to be at the top as it starts tracing
|
||||||
if (msg->debug == false) {
|
if (!msg->debug) {
|
||||||
set_tracing(false); //disable tracing to prevent crashes - set to true for debugging
|
set_tracing(false); //disable tracing to prevent crashes - set to true for debugging
|
||||||
} else {
|
} else {
|
||||||
if (loops == 1) {
|
if (loops == 1) {
|
||||||
|
@ -2795,7 +2741,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
|
//Step 0A - The read_check_cc block has to be in AA2, set it by checking the card configuration
|
||||||
read_check_cc[1] = hdr.conf.app_limit + 1; //first block of AA2
|
read_check_cc[1] = ((uint8_t *)&hdr.conf)[0] + 1; //first block of AA2
|
||||||
|
|
||||||
//Step1 Authenticate with AA1 using trace
|
//Step1 Authenticate with AA1 using trace
|
||||||
if (card_select) {
|
if (card_select) {
|
||||||
|
@ -2807,12 +2753,10 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
card_auth = true;
|
card_auth = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!card_auth || !card_select) {
|
||||||
if ((card_select == false) || (card_auth == false)) {
|
|
||||||
reinit_tentatives++;
|
reinit_tentatives++;
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reinit_tentatives == 5) {
|
if (reinit_tentatives == 5) {
|
||||||
DbpString("");
|
DbpString("");
|
||||||
DbpString(_RED_("Unable to select or authenticate with card multiple times! Stopping."));
|
DbpString(_RED_("Unable to select or authenticate with card multiple times! Stopping."));
|
||||||
|
@ -2823,8 +2767,11 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
while (bits_found == -1) {
|
while (bits_found == -1) {
|
||||||
|
|
||||||
reinit_tentatives = 0;
|
reinit_tentatives = 0;
|
||||||
|
int res2;
|
||||||
|
uint8_t resp[10] = {0};
|
||||||
uint8_t mac2[4] = {0};
|
uint8_t mac2[4] = {0};
|
||||||
res = false;
|
res = false;
|
||||||
|
uint16_t resp_len = 0;
|
||||||
|
|
||||||
if (BUTTON_PRESS() || loops > msg->loop) {
|
if (BUTTON_PRESS() || loops > msg->loop) {
|
||||||
if (loops > msg->loop) {
|
if (loops > msg->loop) {
|
||||||
|
@ -2840,25 +2787,25 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
|
|
||||||
if (msg->test) {
|
if (msg->test) {
|
||||||
Dbprintf(_YELLOW_("*Cycled Reader*") " TEST Index - Loops: "_YELLOW_("%3d / %3d") " *", loops, msg->loop);
|
Dbprintf(_YELLOW_("*Cycled Reader*") " TEST Index - Loops: "_YELLOW_("%3d / %3d") " *", loops, msg->loop);
|
||||||
} else if (msg->debug || ((card_select == false) && (card_auth == false))) {
|
} else if (msg->debug || (!card_select && !card_auth)) {
|
||||||
Dbprintf(_YELLOW_("*Cycled Reader*") " Index: "_RED_("%3d")" Loops: "_YELLOW_("%3d / %3d") " *", index, loops, msg->loop);
|
Dbprintf(_YELLOW_("*Cycled Reader*") " Index: "_RED_("%3d")" Loops: "_YELLOW_("%3d / %3d") " *", index, loops, msg->loop);
|
||||||
} else {
|
} else {
|
||||||
DbprintfEx(FLAG_INPLACE, "[" _BLUE_("#") "] Index: "_CYAN_("%3d")" Loops: "_YELLOW_("%3d / %3d")" ", index, loops, msg->loop);
|
DbprintfEx(FLAG_INPLACE, "[" _BLUE_("#") "] Index: "_CYAN_("%3d")" Loops: "_YELLOW_("%3d / %3d")" ", index, loops, msg->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((card_select == false) || (card_auth == false)) {
|
while (!card_select || !card_auth) {
|
||||||
|
|
||||||
Iso15693InitReader(); // has to be at the top as it starts tracing
|
Iso15693InitReader(); //has to be at the top as it starts tracing
|
||||||
set_tracing(false); // disable tracing to prevent crashes - set to true for debugging
|
set_tracing(false); //disable tracing to prevent crashes - set to true for debugging
|
||||||
// Step0 Card Select Routine
|
//Step0 Card Select Routine
|
||||||
eof_time = 0; // reset eof time
|
eof_time = 0; //reset eof time
|
||||||
res = select_iclass_tag(&hdr, false, &eof_time, shallow_mod);
|
res = select_iclass_tag(&hdr, false, &eof_time, shallow_mod);
|
||||||
if (res) {
|
if (res) {
|
||||||
status_message = 1; // card select successful
|
status_message = 1; //card select successful
|
||||||
card_select = true;
|
card_select = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step1 Authenticate with AA1 using trace
|
//Step1 Authenticate with AA1 using trace
|
||||||
if (card_select) {
|
if (card_select) {
|
||||||
memcpy(original_mac, msg->req.key, 8);
|
memcpy(original_mac, msg->req.key, 8);
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
|
@ -2868,12 +2815,10 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
card_auth = true;
|
card_auth = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!card_auth || !card_select) {
|
||||||
if ((card_select == false) || (card_auth == false)) {
|
|
||||||
reinit_tentatives++;
|
reinit_tentatives++;
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reinit_tentatives == 5) {
|
if (reinit_tentatives == 5) {
|
||||||
DbpString("");
|
DbpString("");
|
||||||
DbpString(_RED_("Unable to select or authenticate with card multiple times! Stopping."));
|
DbpString(_RED_("Unable to select or authenticate with card multiple times! Stopping."));
|
||||||
|
@ -2881,45 +2826,52 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step2 Privilege Escalation: attempt to read AA2 with credentials for AA1
|
//Step2 Privilege Escalation: attempt to read AA2 with credentials for AA1
|
||||||
if (priv_esc == false) {
|
int priv_esc_tries = 0;
|
||||||
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
while (!priv_esc) {
|
||||||
if (priv_esc) {
|
//The privilege escalation is done with a readcheck and not just a normal read!
|
||||||
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);
|
||||||
|
// 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++;
|
||||||
} else {
|
} 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;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv_esc && status_message != 3) {
|
if (priv_esc && status_message != 3) {
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||||
status_message = 3;
|
status_message = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step3 Calculate New Key (Optimised Algo V2)
|
//Step3 Calculate New Key (Optimised Algo V2)
|
||||||
generate_single_key_block_inverted_opt(zero_key, index, genkeyblock);
|
generate_single_key_block_inverted_opt(zero_key, index, genkeyblock);
|
||||||
if (msg->test) {
|
if (msg->test) {
|
||||||
memcpy(genkeyblock, zero_key, PICOPASS_BLOCK_SIZE);
|
memcpy(genkeyblock, zero_key, PICOPASS_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (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) {
|
if (index > 0 && loops > 1) {
|
||||||
generate_single_key_block_inverted_opt(zero_key, index - 1, fast_previous_key);
|
generate_single_key_block_inverted_opt(zero_key, index - 1, fast_previous_key);
|
||||||
} else {
|
} else {
|
||||||
memcpy(fast_previous_key, zero_key, PICOPASS_BLOCK_SIZE);
|
memcpy(fast_previous_key, zero_key, PICOPASS_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
|
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
|
||||||
fast_current_key[i] = genkeyblock[i] ^ fast_previous_key[i];
|
fast_current_key[i] = genkeyblock[i] ^ fast_previous_key[i];
|
||||||
fast_restore_key[i] = fast_restore_key[i] ^ fast_current_key[i];
|
fast_restore_key[i] = fast_restore_key[i] ^ fast_current_key[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(genkeyblock, fast_current_key, PICOPASS_BLOCK_SIZE);
|
memcpy(genkeyblock, fast_current_key, PICOPASS_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step4 Calculate New Mac
|
//Step4 Calculate New Mac
|
||||||
|
|
||||||
uint8_t wb[9] = {0};
|
uint8_t wb[9] = {0};
|
||||||
uint8_t blockno = 3;
|
uint8_t blockno = 3;
|
||||||
|
@ -2928,18 +2880,16 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
doMAC_N(wb, sizeof(wb), div_key2, mac2);
|
doMAC_N(wb, sizeof(wb), div_key2, mac2);
|
||||||
bool written = false;
|
bool written = false;
|
||||||
bool write_error = false;
|
bool write_error = false;
|
||||||
|
|
||||||
while (written == false && write_error == false) {
|
while (written == false && write_error == false) {
|
||||||
// Step5 Perform Write
|
//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)) {
|
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
|
status_message = 4; //wrote new key on the card - unverified
|
||||||
}
|
}
|
||||||
if (msg->fast == false) { // if we're going slow we check at every write that the write actually happened
|
if (!msg->fast) { //if we're going slow we check at every write that the write actually happened
|
||||||
// Reset cypher state
|
//Reset cypher state
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||||
// try to authenticate with the original mac to verify the write happened
|
//try to authenticate with the original mac to verify the write happened
|
||||||
memcpy(msg->req.key, original_mac, 8);
|
memcpy(msg->req.key, original_mac, 8);
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
||||||
|
@ -2956,24 +2906,24 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (res) {
|
if (res) {
|
||||||
write_error = true; // failed to update the key, the card's key is the original one
|
write_error = true; //failed to update the key, the card's key is the original one
|
||||||
} else {
|
} else {
|
||||||
status_message = 5; // verified the card key was updated to the new one
|
status_message = 5; //verified the card key was updated to the new one
|
||||||
written = true;
|
written = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // if we're going fast we can skip the above checks as we're just xorring the key over and over
|
} else { //if we're going fast we can skip the above checks as we're just xorring the key over and over
|
||||||
status_message = 5;
|
status_message = 5;
|
||||||
written = true;
|
written = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_error == false) {
|
if (write_error == false) {
|
||||||
// Step6 Perform 8 authentication attempts + 1 to verify if we found the weak key
|
//Step6 Perform 8 authentication attempts + 1 to verify if we found the weak key
|
||||||
for (int i = 0; i < 8 ; ++i) {
|
for (int i = 0; i < 8 ; ++i) {
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||||
// need to craft the authentication payload accordingly
|
//need to craft the authentication payload accordingly
|
||||||
memcpy(msg->req.key, iclass_mac_table[i], 8);
|
memcpy(msg->req.key, iclass_mac_table[i], 8);
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1); //mac1 here shouldn't matter
|
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1); //mac1 here shouldn't matter
|
||||||
|
@ -2985,31 +2935,29 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
|
|
||||||
bool reverted = false;
|
bool reverted = false;
|
||||||
uint8_t revert_retries = 0;
|
uint8_t revert_retries = 0;
|
||||||
if (msg->fast) { // if we're going fast only restore the original key at the end
|
if (msg->fast) { //if we're going fast only restore the original key at the end
|
||||||
if (recovered) {
|
if (recovered) {
|
||||||
goto fast_restore;
|
goto fast_restore;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we're NOT going fast, regardless of bits being found, restore the original key and verify it
|
//if we're NOT going fast, regardless of bits being found, restore the original key and verify it
|
||||||
while (reverted == false) {
|
while (!reverted) {
|
||||||
// Regain privilege escalation with a readcheck
|
//Regain privilege escalation with a readcheck
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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)) {
|
if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time, short_delay)) {
|
||||||
status_message = 6; // restore of original key successful but unverified
|
status_message = 6; //restore of original key successful but unverified
|
||||||
}
|
}
|
||||||
// Do a readcheck first to reset the cypher state
|
//Do a readcheck first to reset the cypher state
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||||
|
//need to craft the authentication payload accordingly
|
||||||
// need to craft the authentication payload accordingly
|
|
||||||
memcpy(msg->req.key, original_mac, 8);
|
memcpy(msg->req.key, original_mac, 8);
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
||||||
if (res == true) {
|
if (res == true) {
|
||||||
status_message = 7; // restore of original key verified - card usable again
|
status_message = 7; //restore of original key verified - card usable again
|
||||||
reverted = true;
|
reverted = true;
|
||||||
if (recovered) {
|
if (recovered) {
|
||||||
goto restore;
|
goto restore;
|
||||||
|
@ -3017,7 +2965,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
revert_retries++;
|
revert_retries++;
|
||||||
if (revert_retries >= 7) { // must always be an odd number!
|
if (revert_retries >= 7) { //must always be an odd number!
|
||||||
DbpString("");
|
DbpString("");
|
||||||
DbpString(_CYAN_("Last Written Key: "));
|
DbpString(_CYAN_("Last Written Key: "));
|
||||||
Dbhexdump(8, genkeyblock, false);
|
Dbhexdump(8, genkeyblock, false);
|
||||||
|
@ -3026,6 +2974,8 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->debug) {
|
if (msg->debug) {
|
||||||
|
@ -3054,7 +3004,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_error && (msg->debug || msg->test)) { // if there was a write error, re-run the loop for the same key index
|
if (write_error && (msg->debug || msg->test)) { //if there was a write error, re-run the loop for the same key index
|
||||||
DbpString("Loop Error: "_RED_("Repeating Loop!"));
|
DbpString("Loop Error: "_RED_("Repeating Loop!"));
|
||||||
card_select = false;
|
card_select = false;
|
||||||
card_auth = false;
|
card_auth = false;
|
||||||
|
@ -3065,45 +3015,39 @@ void iClass_Recover(iclass_recover_req_t *msg) {
|
||||||
status_message = 2;
|
status_message = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}// end while
|
}//end while
|
||||||
|
|
||||||
fast_restore:
|
fast_restore:
|
||||||
;// empty statement for compilation
|
;//empty statement for compilation
|
||||||
uint8_t mac2[4] = {0};
|
uint8_t mac2[4] = {0};
|
||||||
uint8_t wb[9] = {0};
|
uint8_t wb[9] = {0};
|
||||||
uint8_t blockno = 3;
|
uint8_t blockno = 3;
|
||||||
wb[0] = blockno;
|
wb[0] = blockno;
|
||||||
bool reverted = false;
|
bool reverted = false;
|
||||||
uint8_t revert_retries = 0;
|
uint8_t revert_retries = 0;
|
||||||
|
while (!reverted) {
|
||||||
while (reverted == false) {
|
//Regain privilege escalation with a readcheck
|
||||||
// Regain privilege escalation with a readcheck
|
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, &eof_time, shallow_mod);
|
||||||
memcpy(wb + 1, fast_restore_key, 8);
|
memcpy(wb + 1, fast_restore_key, 8);
|
||||||
doMAC_N(wb, sizeof(wb), div_key2, mac2);
|
doMAC_N(wb, sizeof(wb), div_key2, mac2);
|
||||||
|
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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)) {
|
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
|
status_message = 6; //restore of original key successful but unverified
|
||||||
}
|
}
|
||||||
|
//Do a readcheck first to reset the cypher state
|
||||||
// Do a readcheck first to reset the cypher state
|
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
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);
|
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
|
||||||
|
//need to craft the authentication payload accordingly
|
||||||
// need to craft the authentication payload accordingly
|
|
||||||
memcpy(msg->req.key, original_mac, 8);
|
memcpy(msg->req.key, original_mac, 8);
|
||||||
|
|
||||||
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
|
||||||
if (res == true) {
|
if (res == true) {
|
||||||
status_message = 7; // restore of original key verified - card usable again
|
status_message = 7; //restore of original key verified - card usable again
|
||||||
reverted = true;
|
reverted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
revert_retries++;
|
revert_retries++;
|
||||||
if (revert_retries >= 7) { // must always be an odd number!
|
if (revert_retries >= 7) { //must always be an odd number!
|
||||||
DbpString("");
|
DbpString("");
|
||||||
DbpString(_CYAN_("Last Written Key (fast): "));
|
DbpString(_CYAN_("Last Written Key (fast): "));
|
||||||
Dbhexdump(8, fast_restore_key, false);
|
Dbhexdump(8, fast_restore_key, false);
|
||||||
|
@ -3117,7 +3061,7 @@ fast_restore:
|
||||||
}
|
}
|
||||||
|
|
||||||
restore:
|
restore:
|
||||||
;// empty statement for compilation
|
;//empty statement for compilation
|
||||||
uint8_t partialkey[PICOPASS_BLOCK_SIZE] = {0};
|
uint8_t partialkey[PICOPASS_BLOCK_SIZE] = {0};
|
||||||
|
|
||||||
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
|
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
|
||||||
|
@ -3128,11 +3072,11 @@ restore:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the bits decimal value
|
//Print the bits decimal value
|
||||||
DbpString("");
|
DbpString("");
|
||||||
DbpString(_RED_("--------------------------------------------------------"));
|
DbpString(_RED_("--------------------------------------------------------"));
|
||||||
Dbprintf("Decimal Value of last 3 bits: " _GREEN_("[%3d]"), bits_found);
|
Dbprintf("Decimal Value of last 3 bits: " _GREEN_("[%3d]"), bits_found);
|
||||||
// Print the 24 bits found from k1
|
//Print the 24 bits found from k1
|
||||||
DbpString(_RED_("--------------------------------------------------------"));
|
DbpString(_RED_("--------------------------------------------------------"));
|
||||||
DbpString(_RED_("SUCCESS! Raw Key Partial Bytes: "));
|
DbpString(_RED_("SUCCESS! Raw Key Partial Bytes: "));
|
||||||
Dbhexdump(8, partialkey, false);
|
Dbhexdump(8, partialkey, false);
|
||||||
|
@ -3151,4 +3095,5 @@ out:
|
||||||
} else {
|
} else {
|
||||||
reply_ng(CMD_HF_ICLASS_RECOVER, PM3_ESOFT, NULL, 0);
|
reply_ng(CMD_HF_ICLASS_RECOVER, PM3_ESOFT, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,16 +370,16 @@ tUart14a *GetUart14a(void) {
|
||||||
|
|
||||||
void Uart14aReset(void) {
|
void Uart14aReset(void) {
|
||||||
Uart.state = STATE_14A_UNSYNCD;
|
Uart.state = STATE_14A_UNSYNCD;
|
||||||
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
|
|
||||||
Uart.bitCount = 0;
|
Uart.bitCount = 0;
|
||||||
Uart.len = 0; // number of decoded data bytes
|
Uart.len = 0; // number of decoded data bytes
|
||||||
Uart.posCnt = 0;
|
|
||||||
Uart.syncBit = 9999;
|
|
||||||
Uart.parityBits = 0; // holds 8 parity bits
|
|
||||||
Uart.parityLen = 0; // number of decoded parity bytes
|
Uart.parityLen = 0; // number of decoded parity bytes
|
||||||
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
|
||||||
|
Uart.parityBits = 0; // holds 8 parity bits
|
||||||
Uart.startTime = 0;
|
Uart.startTime = 0;
|
||||||
Uart.endTime = 0;
|
Uart.endTime = 0;
|
||||||
|
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
||||||
|
Uart.posCnt = 0;
|
||||||
|
Uart.syncBit = 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Uart14aInit(uint8_t *d, uint16_t n, uint8_t *par) {
|
void Uart14aInit(uint8_t *d, uint16_t n, uint8_t *par) {
|
||||||
|
@ -697,9 +697,6 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
|
||||||
static RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) {
|
static RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) {
|
||||||
|
|
||||||
if (Demod.len == Demod.output_len) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1188,24 +1185,9 @@ 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,
|
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||||
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
|
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
|
||||||
uint32_t *cuid, uint8_t *pages, uint8_t *ulc_key) {
|
uint32_t *cuid, uint8_t *pages) {
|
||||||
uint8_t sak = 0;
|
uint8_t sak = 0;
|
||||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||||
static uint8_t rATQA[2] = { 0x00 };
|
static uint8_t rATQA[2] = { 0x00 };
|
||||||
|
@ -1355,38 +1337,6 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||||
sak = 0x20;
|
sak = 0x20;
|
||||||
break;
|
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: {
|
default: {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1412,7 +1362,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||||
|
|
||||||
// if uid not supplied then get from emulator memory
|
// 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 ((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 || tagType == 13) {
|
if (tagType == 2 || tagType == 7) {
|
||||||
uint16_t start = MFU_DUMP_PREFIX_LENGTH;
|
uint16_t start = MFU_DUMP_PREFIX_LENGTH;
|
||||||
uint8_t emdata[8];
|
uint8_t emdata[8];
|
||||||
emlGet(emdata, start, sizeof(emdata));
|
emlGet(emdata, start, sizeof(emdata));
|
||||||
|
@ -1579,18 +1529,13 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||||
// 'hf 14a sim'
|
// 'hf 14a sim'
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
||||||
uint8_t *ats, size_t ats_len, bool ulc_part1, bool ulc_part2) {
|
uint8_t *ats, size_t ats_len) {
|
||||||
|
|
||||||
#define ATTACK_KEY_COUNT 16
|
#define ATTACK_KEY_COUNT 16
|
||||||
#define ULC_TAG_NONCE "\x01\x02\x03\x04\x05\x06\x07\x08"
|
|
||||||
|
|
||||||
tag_response_info_t *responses;
|
tag_response_info_t *responses;
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
uint32_t nonce = 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;
|
uint8_t pages = 0;
|
||||||
|
|
||||||
// Here, we collect CUID, block1, keytype1, NT1, NR1, AR1, CUID, block2, keytyp2, NT2, NR2, AR2
|
// Here, we collect CUID, block1, keytype1, NT1, NR1, AR1, CUID, block2, keytyp2, NT2, NR2, AR2
|
||||||
|
@ -1634,9 +1579,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||||
.modulation_n = 0
|
.modulation_n = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len
|
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len, &responses, &cuid, &pages) == false) {
|
||||||
, &responses, &cuid, &pages
|
|
||||||
, ulc_key) == false) {
|
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -1724,7 +1667,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||||
order = ORDER_NONE; // back to work state
|
order = ORDER_NONE; // back to work state
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
|
|
||||||
} else if (order == ORDER_AUTH && len == 8 && tagType != 2 && tagType != 7 && tagType != 13) {
|
} else if (order == ORDER_AUTH && len == 8) {
|
||||||
// Received {nr] and {ar} (part of authentication)
|
// 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);
|
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);
|
uint32_t nr = bytes_to_num(receivedCmd, 4);
|
||||||
|
@ -1814,7 +1757,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
|
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK && len == 4) { // Received a (plain) READ
|
||||||
uint8_t block = receivedCmd[1];
|
uint8_t block = receivedCmd[1];
|
||||||
// if Ultralight or NTAG (4 byte blocks)
|
// if Ultralight or NTAG (4 byte blocks)
|
||||||
if (tagType == 7 || tagType == 2 || tagType == 13) {
|
if (tagType == 7 || tagType == 2) {
|
||||||
if (block > pages) {
|
if (block > pages) {
|
||||||
// send NACK 0x0 == invalid argument
|
// send NACK 0x0 == invalid argument
|
||||||
EmSend4bit(CARD_NACK_IV);
|
EmSend4bit(CARD_NACK_IV);
|
||||||
|
@ -1863,7 +1806,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||||
EmSendCmd(emdata, len + 2);
|
EmSendCmd(emdata, len + 2);
|
||||||
}
|
}
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7 || tagType == 13)) { // Received a WRITE
|
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7)) { // Received a WRITE
|
||||||
|
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
|
|
||||||
|
@ -1901,15 +1844,12 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||||
// send ACK
|
// send ACK
|
||||||
EmSend4bit(CARD_ACK);
|
EmSend4bit(CARD_ACK);
|
||||||
|
|
||||||
if (tagType == 13 && block >= 0x2c && block <= 0x2F) {
|
|
||||||
ulc_reread_key = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// send NACK 0x1 == crc/parity error
|
// send NACK 0x1 == crc/parity error
|
||||||
EmSend4bit(CARD_NACK_PA);
|
EmSend4bit(CARD_NACK_PA);
|
||||||
}
|
}
|
||||||
goto jump;
|
goto jump;
|
||||||
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7 || tagType == 13)) {
|
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7)) {
|
||||||
// cmd + block + 2 bytes crc
|
// cmd + block + 2 bytes crc
|
||||||
if (CheckCrc14A(receivedCmd, len)) {
|
if (CheckCrc14A(receivedCmd, len)) {
|
||||||
wrblock = receivedCmd[1];
|
wrblock = receivedCmd[1];
|
||||||
|
@ -1983,7 +1923,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||||
p_response = &responses[RESP_INDEX_VERSION];
|
p_response = &responses[RESP_INDEX_VERSION];
|
||||||
} else if (receivedCmd[0] == MFDES_GET_VERSION && len == 4 && (tagType == 3)) {
|
} else if (receivedCmd[0] == MFDES_GET_VERSION && len == 4 && (tagType == 3)) {
|
||||||
p_response = &responses[RESP_INDEX_VERSION];
|
p_response = &responses[RESP_INDEX_VERSION];
|
||||||
} else if ((receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) && len == 4 && tagType != 2 && tagType != 7 && tagType != 13) { // Received an authentication request
|
} else if ((receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) && len == 4 && tagType != 2 && tagType != 7) { // Received an authentication request
|
||||||
cardAUTHKEY = receivedCmd[0] - 0x60;
|
cardAUTHKEY = receivedCmd[0] - 0x60;
|
||||||
cardAUTHSC = receivedCmd[1] / 4; // received block num
|
cardAUTHSC = receivedCmd[1] / 4; // received block num
|
||||||
|
|
||||||
|
@ -2002,77 +1942,9 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin
|
||||||
} else {
|
} else {
|
||||||
p_response = &responses[RESP_INDEX_ATS];
|
p_response = &responses[RESP_INDEX_ATS];
|
||||||
}
|
}
|
||||||
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_1 && len == 4 && tagType == 13) { // ULC authentication, or Desfire Authentication
|
} 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);
|
||||||
// reset IV to all zeros
|
p_response = NULL;
|
||||||
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
|
} else if (receivedCmd[0] == MIFARE_ULEV1_AUTH && len == 7 && tagType == 7) { // NTAG / EV-1
|
||||||
uint8_t pwd[4] = {0, 0, 0, 0};
|
uint8_t pwd[4] = {0, 0, 0, 0};
|
||||||
emlGet(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd));
|
emlGet(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd));
|
||||||
|
@ -2253,16 +2125,13 @@ jump:
|
||||||
// of bits specified in the delay parameter.
|
// of bits specified in the delay parameter.
|
||||||
static void PrepareDelayedTransfer(uint16_t delay) {
|
static void PrepareDelayedTransfer(uint16_t delay) {
|
||||||
delay &= 0x07;
|
delay &= 0x07;
|
||||||
if (delay == 0) {
|
if (!delay) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t bitmask = 0;
|
uint8_t bitmask = 0;
|
||||||
uint8_t bits_shifted = 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);
|
bitmask |= (0x01 << i);
|
||||||
}
|
|
||||||
|
|
||||||
tosend_t *ts = get_tosend();
|
tosend_t *ts = get_tosend();
|
||||||
|
|
||||||
|
@ -2291,7 +2160,6 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
|
||||||
Dbprintf("Warning: HF field is off");
|
Dbprintf("Warning: HF field is off");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||||
|
|
||||||
if (timing) {
|
if (timing) {
|
||||||
|
@ -2466,7 +2334,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
|
// button press, takes a bit time, might mess with simualtion
|
||||||
if (checker-- == 0) {
|
if (checker-- == 0) {
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
Dbprintf("----------- " _GREEN_("Button pressed, user aborted") " ----------");
|
Dbprintf("----------- " _GREEN_("Breaking / User aborted") " ----------");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2644,9 +2512,9 @@ int EmSendPrecompiledCmd(tag_response_info_t *p_response) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmLogTrace(const uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime,
|
bool EmLogTrace(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,
|
uint32_t reader_EndTime, uint8_t *reader_Parity, uint8_t *tag_data,
|
||||||
uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, const uint8_t *tag_Parity) {
|
uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, 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
|
// 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.
|
// end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp.
|
||||||
|
@ -2968,14 +2836,10 @@ 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) {
|
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, false);
|
return iso14443a_select_cardEx(uid_ptr, p_card, cuid_ptr, anticollision, num_cascades, no_rats, NULL);
|
||||||
}
|
|
||||||
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
|
// performs iso14443a anticollision (optional) and card select procedure
|
||||||
// fills the uid and cuid pointer unless NULL
|
// fills the uid and cuid pointer unless NULL
|
||||||
// fills the card info record unless NULL
|
// fills the card info record unless NULL
|
||||||
|
@ -2984,7 +2848,7 @@ int iso14443a_select_card_for_magic(uint8_t *uid_ptr, iso14a_card_select_t *p_ca
|
||||||
// requests ATS unless no_rats is true
|
// 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,
|
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,
|
bool anticollision, uint8_t num_cascades, bool no_rats,
|
||||||
const iso14a_polling_parameters_t *polling_parameters, bool force_rats) {
|
iso14a_polling_parameters_t *polling_parameters) {
|
||||||
|
|
||||||
uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller
|
uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller
|
||||||
|
|
||||||
|
@ -3039,10 +2903,9 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
|
||||||
|
|
||||||
if (anticollision) {
|
if (anticollision) {
|
||||||
// clear uid
|
// clear uid
|
||||||
if (uid_ptr) {
|
if (uid_ptr)
|
||||||
memset(uid_ptr, 0, 10);
|
memset(uid_ptr, 0, 10);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (hf14aconfig.forceanticol == 0) {
|
if (hf14aconfig.forceanticol == 0) {
|
||||||
// check for proprietary anticollision:
|
// check for proprietary anticollision:
|
||||||
|
@ -3202,18 +3065,18 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
|
||||||
p_card->sak = sak;
|
p_card->sak = sak;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hf14aconfig.forcerats == 0 && force_rats == false) {
|
if (hf14aconfig.forcerats == 0) {
|
||||||
// PICC compliant with iso14443a-4 ---> (SAK & 0x20 != 0)
|
// PICC compliant with iso14443a-4 ---> (SAK & 0x20 != 0)
|
||||||
if ((sak & 0x20) == 0) {
|
if ((sak & 0x20) == 0) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (hf14aconfig.forcerats == 2 && force_rats == false) {
|
} else if (hf14aconfig.forcerats == 2) {
|
||||||
if ((sak & 0x20) != 0) Dbprintf("Skipping RATS according to hf 14a config");
|
if ((sak & 0x20) != 0) Dbprintf("Skipping RATS according to hf 14a config");
|
||||||
return 2;
|
return 2;
|
||||||
} // else force RATS
|
} // else force RATS
|
||||||
|
|
||||||
if ((sak & 0x20) == 0 && force_rats == false) Dbprintf("Forcing RATS according to hf 14a config");
|
if ((sak & 0x20) == 0) Dbprintf("Forcing RATS according to hf 14a config");
|
||||||
|
|
||||||
// RATS, Request for answer to select
|
// RATS, Request for answer to select
|
||||||
if (no_rats == false) {
|
if (no_rats == false) {
|
||||||
|
@ -3239,7 +3102,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso14443a_fast_select_card(const uint8_t *uid_ptr, uint8_t num_cascades) {
|
int iso14443a_fast_select_card(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[3] = { 0 }; // theoretically. max 1 Byte SAK, 2 Byte CRC, 3 bytes is enough
|
||||||
uint8_t resp_par[1] = {0};
|
uint8_t resp_par[1] = {0};
|
||||||
|
|
||||||
|
@ -3479,8 +3342,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
true,
|
true,
|
||||||
0,
|
0,
|
||||||
((param & ISO14A_NO_RATS) == ISO14A_NO_RATS),
|
((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
|
// TODO: Improve by adding a cmd parser pointer and moving it by struct length to allow combining data with polling params
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
|
@ -3658,23 +3520,17 @@ OUT:
|
||||||
// Therefore try in alternating directions.
|
// Therefore try in alternating directions.
|
||||||
static int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
static int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
||||||
|
|
||||||
if (nt1 == nt2) {
|
if (nt1 == nt2) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t nttmp1 = nt1;
|
uint32_t nttmp1 = nt1;
|
||||||
uint32_t nttmp2 = nt2;
|
uint32_t nttmp2 = nt2;
|
||||||
|
|
||||||
for (uint16_t i = 1; i < 32768; i++) {
|
for (uint16_t i = 1; i < 32768; i++) {
|
||||||
nttmp1 = prng_successor(nttmp1, 1);
|
nttmp1 = prng_successor(nttmp1, 1);
|
||||||
if (nttmp1 == nt2) {
|
if (nttmp1 == nt2) return i;
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
nttmp2 = prng_successor(nttmp2, 1);
|
nttmp2 = prng_successor(nttmp2, 1);
|
||||||
if (nttmp2 == nt1) {
|
if (nttmp2 == nt1) return -i;
|
||||||
return -i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (-99999); // either nt1 or nt2 are invalid nonces
|
return (-99999); // either nt1 or nt2 are invalid nonces
|
||||||
|
@ -3682,8 +3538,8 @@ static int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
||||||
|
|
||||||
|
|
||||||
#define PRNG_SEQUENCE_LENGTH (1 << 16)
|
#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_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_SYNC_TRIES 32
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Recover several bits of the cypher stream. This implements (first stages of)
|
// Recover several bits of the cypher stream. This implements (first stages of)
|
||||||
|
@ -3813,9 +3669,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
||||||
|
|
||||||
// Receive the (4 Byte) "random" TAG nonce
|
// Receive the (4 Byte) "random" TAG nonce
|
||||||
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 4) {
|
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 4)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
previous_nt = nt;
|
previous_nt = nt;
|
||||||
nt = bytes_to_num(receivedAnswer, 4);
|
nt = bytes_to_num(receivedAnswer, 4);
|
||||||
|
@ -3838,9 +3693,9 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
|
|
||||||
// we didn't calibrate our clock yet,
|
// we didn't calibrate our clock yet,
|
||||||
// iceman: has to be calibrated every time.
|
// iceman: has to be calibrated every time.
|
||||||
if (previous_nt && (nt_attacked == 0)) {
|
if (previous_nt && !nt_attacked) {
|
||||||
|
|
||||||
int32_t nt_distance = dist_nt(previous_nt, nt);
|
int nt_distance = dist_nt(previous_nt, nt);
|
||||||
|
|
||||||
// if no distance between, then we are in sync.
|
// if no distance between, then we are in sync.
|
||||||
if (nt_distance == 0) {
|
if (nt_distance == 0) {
|
||||||
|
@ -3866,9 +3721,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
sync_cycles = (sync_cycles - nt_distance) / elapsed_prng_sequences;
|
sync_cycles = (sync_cycles - nt_distance) / elapsed_prng_sequences;
|
||||||
|
|
||||||
// no negative sync_cycles, and too small sync_cycles will result in continuous misses
|
// no negative sync_cycles, and too small sync_cycles will result in continuous misses
|
||||||
if (sync_cycles <= 10) {
|
if (sync_cycles <= 10) sync_cycles += PRNG_SEQUENCE_LENGTH;
|
||||||
sync_cycles += PRNG_SEQUENCE_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset sync_cycles
|
// reset sync_cycles
|
||||||
if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2) {
|
if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2) {
|
||||||
|
@ -3876,14 +3729,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
sync_time = GetCountSspClk() & 0xfffffff8;
|
sync_time = GetCountSspClk() & 0xfffffff8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED) {
|
if (g_dbglevel >= DBG_EXTENDED)
|
||||||
Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n"
|
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);
|
||||||
, i
|
|
||||||
, nt_distance
|
|
||||||
, elapsed_prng_sequences
|
|
||||||
, sync_cycles
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3913,9 +3760,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
} else {
|
} else {
|
||||||
sync_cycles += catch_up_cycles;
|
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);
|
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;
|
last_catch_up = 0;
|
||||||
catch_up_cycles = 0;
|
catch_up_cycles = 0;
|
||||||
|
@ -3928,9 +3774,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
if (received_nack) {
|
if (received_nack) {
|
||||||
catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
|
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_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]);
|
par_list[nt_diff] = reflect8(par[0]);
|
||||||
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream
|
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream
|
||||||
|
@ -3949,15 +3794,12 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
} else {
|
} else {
|
||||||
// No NACK.
|
// No NACK.
|
||||||
if (nt_diff == 0 && first_try) {
|
if (nt_diff == 0 && first_try) {
|
||||||
|
|
||||||
par[0]++;
|
par[0]++;
|
||||||
|
|
||||||
if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK.
|
if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK.
|
||||||
isOK = 2;
|
isOK = 2;
|
||||||
return_status = PM3_ESOFT;
|
return_status = PM3_ESOFT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Why this?
|
// Why this?
|
||||||
par[0] = ((par[0] & 0x1F) + 1) | par_low;
|
par[0] = ((par[0] & 0x1F) + 1) | par_low;
|
||||||
|
@ -4008,7 +3850,7 @@ void DetectNACKbug(void) {
|
||||||
uint8_t uid[10] = { 0x00 };
|
uint8_t uid[10] = { 0x00 };
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = { 0x00 };
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = { 0x00 };
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = { 0x00 };
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = { 0x00 };
|
||||||
uint8_t par[2] = {0x00 }; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
uint8_t par[1] = {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;
|
uint32_t nt = 0, previous_nt = 0, nt_attacked = 0, cuid = 0;
|
||||||
int32_t catch_up_cycles = 0, last_catch_up = 0;
|
int32_t catch_up_cycles = 0, last_catch_up = 0;
|
||||||
|
@ -4059,9 +3901,9 @@ void DetectNACKbug(void) {
|
||||||
++checkbtn_cnt;
|
++checkbtn_cnt;
|
||||||
|
|
||||||
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
||||||
if (have_uid == false) { // need a full select cycle to get the uid first
|
if (!have_uid) { // need a full select cycle to get the uid first
|
||||||
iso14a_card_select_t card_info;
|
iso14a_card_select_t card_info;
|
||||||
if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) {
|
if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
|
||||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Mifare: Can't select card (ALL)");
|
if (g_dbglevel >= DBG_INFO) Dbprintf("Mifare: Can't select card (ALL)");
|
||||||
i = 0;
|
i = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -4083,7 +3925,7 @@ void DetectNACKbug(void) {
|
||||||
}
|
}
|
||||||
have_uid = true;
|
have_uid = true;
|
||||||
} else { // no need for anticollision. We can directly select the card
|
} else { // no need for anticollision. We can directly select the card
|
||||||
if (iso14443a_fast_select_card(uid, cascade_levels) == 0) {
|
if (!iso14443a_fast_select_card(uid, cascade_levels)) {
|
||||||
if (g_dbglevel >= DBG_INFO) Dbprintf("Mifare: Can't select card (UID)");
|
if (g_dbglevel >= DBG_INFO) Dbprintf("Mifare: Can't select card (UID)");
|
||||||
i = 0;
|
i = 0;
|
||||||
have_uid = false;
|
have_uid = false;
|
||||||
|
@ -4297,7 +4139,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
||||||
.modulation_n = 0
|
.modulation_n = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, &pages, NULL) == false) {
|
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, &pages) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
return;
|
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 RAMFUNC SniffIso14443a(uint8_t param);
|
||||||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
|
||||||
uint8_t *ats, size_t ats_len, bool ulc_part1, bool ulc_part2);
|
uint8_t *ats, size_t ats_len);
|
||||||
|
|
||||||
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
||||||
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
|
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
|
||||||
|
@ -152,8 +152,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
||||||
|
|
||||||
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||||
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
|
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
|
||||||
uint32_t *cuid, uint8_t *pages,
|
uint32_t *cuid, uint8_t *pages);
|
||||||
uint8_t *ulc_key);
|
|
||||||
|
|
||||||
bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len);
|
bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, uint8_t *par, int *len);
|
||||||
void iso14443a_antifuzz(uint32_t flags);
|
void iso14443a_antifuzz(uint32_t flags);
|
||||||
|
@ -166,11 +165,8 @@ uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_maxlen, uint8_t
|
||||||
void iso14443a_setup(uint8_t fpga_minor_mode);
|
void iso14443a_setup(uint8_t fpga_minor_mode);
|
||||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res);
|
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res);
|
||||||
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
|
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
|
||||||
int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr,
|
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);
|
||||||
bool anticollision, uint8_t num_cascades, bool no_rats,
|
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
|
||||||
const iso14a_polling_parameters_t *polling_parameters, bool force_rats);
|
|
||||||
int iso14443a_select_card_for_magic(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
|
|
||||||
int iso14443a_fast_select_card(const uint8_t *uid_ptr, uint8_t num_cascades);
|
|
||||||
void iso14a_set_trigger(bool enable);
|
void iso14a_set_trigger(bool enable);
|
||||||
|
|
||||||
int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen);
|
int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen);
|
||||||
|
@ -185,9 +181,8 @@ int EmSendPrecompiledCmd(tag_response_info_t *p_response);
|
||||||
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size);
|
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size);
|
||||||
bool prepare_tag_modulation(tag_response_info_t *response_info, size_t max_buffer_size);
|
bool prepare_tag_modulation(tag_response_info_t *response_info, size_t max_buffer_size);
|
||||||
|
|
||||||
bool EmLogTrace(const uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime,
|
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
|
||||||
uint32_t reader_EndTime, const uint8_t *reader_Parity, const uint8_t *tag_data,
|
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
||||||
uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, const uint8_t *tag_Parity);
|
|
||||||
|
|
||||||
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
|
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
|
||||||
void DetectNACKbug(void);
|
void DetectNACKbug(void);
|
||||||
|
|
|
@ -786,14 +786,14 @@ void SimulateIso14443bTag(const uint8_t *pupi) {
|
||||||
|
|
||||||
// prepare "ATQB" tag answer (encoded):
|
// prepare "ATQB" tag answer (encoded):
|
||||||
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
||||||
uint8_t *encodedATQB = BigBuf_calloc(ts->max);
|
uint8_t *encodedATQB = BigBuf_malloc(ts->max);
|
||||||
uint16_t encodedATQBLen = ts->max;
|
uint16_t encodedATQBLen = ts->max;
|
||||||
memcpy(encodedATQB, ts->buf, ts->max);
|
memcpy(encodedATQB, ts->buf, ts->max);
|
||||||
|
|
||||||
|
|
||||||
// prepare "OK" tag answer (encoded):
|
// prepare "OK" tag answer (encoded):
|
||||||
CodeIso14443bAsTag(respOK, sizeof(respOK));
|
CodeIso14443bAsTag(respOK, sizeof(respOK));
|
||||||
uint8_t *encodedOK = BigBuf_calloc(ts->max);
|
uint8_t *encodedOK = BigBuf_malloc(ts->max);
|
||||||
uint16_t encodedOKLen = ts->max;
|
uint16_t encodedOKLen = ts->max;
|
||||||
memcpy(encodedOK, ts->buf, 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();
|
tosend_t *ts = get_tosend();
|
||||||
|
|
||||||
uint8_t *receivedCmd = BigBuf_calloc(MAX_FRAME_SIZE);
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
|
|
||||||
// prepare "ATQB" tag answer (encoded):
|
// prepare "ATQB" tag answer (encoded):
|
||||||
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
CodeIso14443bAsTag(respATQB, sizeof(respATQB));
|
||||||
uint8_t *encodedATQB = BigBuf_calloc(ts->max);
|
uint8_t *encodedATQB = BigBuf_malloc(ts->max);
|
||||||
uint16_t encodedATQBLen = ts->max;
|
uint16_t encodedATQBLen = ts->max;
|
||||||
memcpy(encodedATQB, ts->buf, ts->max);
|
memcpy(encodedATQB, ts->buf, ts->max);
|
||||||
|
|
||||||
|
|
||||||
// prepare "OK" tag answer (encoded):
|
// prepare "OK" tag answer (encoded):
|
||||||
CodeIso14443bAsTag(respOK, sizeof(respOK));
|
CodeIso14443bAsTag(respOK, sizeof(respOK));
|
||||||
uint8_t *encodedOK = BigBuf_calloc(ts->max);
|
uint8_t *encodedOK = BigBuf_malloc(ts->max);
|
||||||
uint16_t encodedOKLen = ts->max;
|
uint16_t encodedOKLen = ts->max;
|
||||||
memcpy(encodedOK, ts->buf, ts->max);
|
memcpy(encodedOK, ts->buf, ts->max);
|
||||||
|
|
||||||
|
@ -2405,8 +2405,8 @@ void SniffIso14443b(void) {
|
||||||
uint8_t ua_buf[MAX_FRAME_SIZE] = {0};
|
uint8_t ua_buf[MAX_FRAME_SIZE] = {0};
|
||||||
Uart14bInit(ua_buf);
|
Uart14bInit(ua_buf);
|
||||||
|
|
||||||
//Demod14bInit(BigBuf_calloc(MAX_FRAME_SIZE));
|
//Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE), MAX_FRAME_SIZE);
|
||||||
//Uart14bInit(BigBuf_calloc(MAX_FRAME_SIZE));
|
//Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||||
|
|
||||||
// Set FPGA in the appropriate mode
|
// Set FPGA in the appropriate mode
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_SNIFF_IQ);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_SNIFF_IQ);
|
||||||
|
|
|
@ -180,7 +180,8 @@ static void CodeIso15693AsReaderEOF(void) {
|
||||||
|
|
||||||
static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) {
|
static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) {
|
||||||
|
|
||||||
uint8_t *answer = BigBuf_calloc(ISO15693_MAX_RESPONSE_LENGTH);
|
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
|
@ -984,11 +985,10 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
||||||
DecodeTagFSK_t dtfm = { 0 };
|
DecodeTagFSK_t dtfm = { 0 };
|
||||||
DecodeTagFSK_t *dtf = &dtfm;
|
DecodeTagFSK_t *dtf = &dtfm;
|
||||||
|
|
||||||
if (fsk) {
|
if (fsk)
|
||||||
DecodeTagFSKInit(dtf, response, max_len);
|
DecodeTagFSKInit(dtf, response, max_len);
|
||||||
} else {
|
else
|
||||||
DecodeTagInit(dt, response, max_len);
|
DecodeTagInit(dt, response, max_len);
|
||||||
}
|
|
||||||
|
|
||||||
// wait for last transfer to complete
|
// wait for last transfer to complete
|
||||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
|
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY));
|
||||||
|
@ -1014,9 +1014,8 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
|
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
|
||||||
if (behindBy == 0) {
|
if (behindBy == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
samples++;
|
samples++;
|
||||||
if (samples == 1) {
|
if (samples == 1) {
|
||||||
|
@ -1483,7 +1482,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
||||||
bool gotFrame = false;
|
bool gotFrame = false;
|
||||||
|
|
||||||
// the decoder data structure
|
// the decoder data structure
|
||||||
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_calloc(sizeof(DecodeReader_t));
|
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_malloc(sizeof(DecodeReader_t));
|
||||||
DecodeReaderInit(dr, received, max_len, 0, NULL);
|
DecodeReaderInit(dr, received, max_len, 0, NULL);
|
||||||
|
|
||||||
// wait for last transfer to complete
|
// wait for last transfer to complete
|
||||||
|
@ -1588,7 +1587,7 @@ void AcquireRawAdcSamplesIso15693(void) {
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
uint8_t *dest = BigBuf_calloc(4096);
|
uint8_t *dest = BigBuf_malloc(4000);
|
||||||
|
|
||||||
// switch field on
|
// switch field on
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
|
||||||
|
@ -2030,7 +2029,7 @@ void ReaderIso15693(iso15_card_select_t *p_card) {
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
uint8_t *answer = BigBuf_calloc(ISO15693_MAX_RESPONSE_LENGTH);
|
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
|
||||||
// FIRST WE RUN AN INVENTORY TO GET THE TAG UID
|
// FIRST WE RUN AN INVENTORY TO GET THE TAG UID
|
||||||
|
|
|
@ -340,7 +340,7 @@ t55xx_configurations_t *getT55xxConfig(void) {
|
||||||
void loadT55xxConfig(void) {
|
void loadT55xxConfig(void) {
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
|
|
||||||
uint8_t *buf = BigBuf_calloc(T55XX_CONFIG_LEN);
|
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
|
||||||
|
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
if (exists_in_spiffs(T55XX_CONFIG_FILE)) {
|
if (exists_in_spiffs(T55XX_CONFIG_FILE)) {
|
||||||
|
@ -2912,7 +2912,7 @@ void Cotag(uint32_t arg0, bool ledcontrol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
uint8_t *dest = BigBuf_calloc(COTAG_BITS);
|
uint8_t *dest = BigBuf_malloc(COTAG_BITS);
|
||||||
uint16_t bits = doCotagAcquisitionManchester(dest, COTAG_BITS);
|
uint16_t bits = doCotagAcquisitionManchester(dest, COTAG_BITS);
|
||||||
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, dest, bits);
|
reply_ng(CMD_LF_COTAG_READ, PM3_SUCCESS, dest, bits);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -149,7 +149,7 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
|
||||||
data.buffer = BigBuf_get_addr();
|
data.buffer = BigBuf_get_addr();
|
||||||
} else {
|
} else {
|
||||||
*sample_size = MIN(*sample_size, BigBuf_max_traceLen());
|
*sample_size = MIN(*sample_size, BigBuf_max_traceLen());
|
||||||
data.buffer = BigBuf_calloc(*sample_size);
|
data.buffer = BigBuf_malloc(*sample_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -669,7 +669,7 @@ void doT55x7Acquisition(size_t sample_size, bool ledcontrol) {
|
||||||
void doCotagAcquisition(void) {
|
void doCotagAcquisition(void) {
|
||||||
|
|
||||||
uint16_t bufsize = BigBuf_max_traceLen();
|
uint16_t bufsize = BigBuf_max_traceLen();
|
||||||
uint8_t *dest = BigBuf_calloc(bufsize);
|
uint8_t *dest = BigBuf_malloc(bufsize);
|
||||||
|
|
||||||
dest[0] = 0;
|
dest[0] = 0;
|
||||||
|
|
||||||
|
|
|
@ -83,14 +83,14 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MF_WAKE_WUPA: {
|
case MF_WAKE_WUPA: {
|
||||||
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &WUPA_POLLING_PARAMETERS, false) == 0) {
|
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &WUPA_POLLING_PARAMETERS) == 0) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MF_WAKE_REQA: {
|
case MF_WAKE_REQA: {
|
||||||
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &REQA_POLLING_PARAMETERS, false) == 0) {
|
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &REQA_POLLING_PARAMETERS) == 0) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -274,7 +274,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mifare_ultra_auth(keybytes) == 0) {
|
if (!mifare_ultra_auth(keybytes)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
|
@ -304,7 +304,7 @@ void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mifare_ultra_aes_auth(keyno, keybytes) == 0) {
|
if (!mifare_ultra_aes_auth(keyno, keybytes)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed");
|
||||||
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
|
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
|
||||||
return;
|
return;
|
||||||
|
@ -344,7 +344,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||||
uint8_t key[16] = {0x00};
|
uint8_t key[16] = {0x00};
|
||||||
memcpy(key, datain, sizeof(key));
|
memcpy(key, datain, sizeof(key));
|
||||||
|
|
||||||
if (mifare_ultra_auth(key) == 0) {
|
if (!mifare_ultra_auth(key)) {
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1947,7 +1947,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
// Now append the SPI flash dictionnary
|
// Now append the SPI flash dictionnary
|
||||||
if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(MF_KEYS_FILE, dictkeys + (keyCount * MF_KEY_LENGTH), (key_mem_available - keyCount) * MF_KEY_LENGTH, RDV40_SPIFFS_SAFETY_SAFE)) {
|
if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(MF_KEYS_FILE, dictkeys + (keyCount * MF_KEY_LENGTH), (key_mem_available - keyCount) * MF_KEY_LENGTH, RDV40_SPIFFS_SAFETY_SAFE)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) {
|
if (g_dbglevel >= DBG_ERROR) {
|
||||||
Dbprintf("loaded " _GREEN_("%u") " keys from spiffs file `" _YELLOW_("%s") "`", key_mem_available - keyCount, MF_KEYS_FILE);
|
Dbprintf("loaded " _GREEN_("%u") " keys from spiffs file `" _YELLOW_("%s") "`", key_mem_available, MF_KEYS_FILE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Spiffs file `" _RED_("%s") "` cannot be read", MF_KEYS_FILE);
|
Dbprintf("Spiffs file `" _RED_("%s") "` cannot be read", MF_KEYS_FILE);
|
||||||
|
@ -2252,7 +2252,7 @@ OUT:
|
||||||
bar |= ((uint16_t)(found[m] & 1) << j++);
|
bar |= ((uint16_t)(found[m] & 1) << j++);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *tmp = BigBuf_calloc(480 + 10);
|
uint8_t *tmp = BigBuf_malloc(480 + 10);
|
||||||
memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t));
|
memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t));
|
||||||
num_to_bytes(foo, 8, tmp + 480);
|
num_to_bytes(foo, 8, tmp + 480);
|
||||||
tmp[488] = bar & 0xFF;
|
tmp[488] = bar & 0xFF;
|
||||||
|
@ -2409,7 +2409,7 @@ void MifareChkKeys_file(uint8_t *fn) {
|
||||||
|
|
||||||
int changed = rdv40_spiffs_lazy_mount();
|
int changed = rdv40_spiffs_lazy_mount();
|
||||||
uint32_t size = size_in_spiffs((char *)fn);
|
uint32_t size = size_in_spiffs((char *)fn);
|
||||||
uint8_t *mem = BigBuf_calloc(size);
|
uint8_t *mem = BigBuf_malloc(size);
|
||||||
|
|
||||||
rdv40_spiffs_read_as_filetype((char *)fn, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_read_as_filetype((char *)fn, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
|
||||||
|
@ -3022,10 +3022,9 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
|
||||||
|
|
||||||
// reset card
|
// reset card
|
||||||
mf_reset_card();
|
mf_reset_card();
|
||||||
// Use special magic detection function that always attempts RATS regardless of SAK
|
|
||||||
res = iso14443a_select_card_for_magic(uid, card, &cuid, true, 0);
|
res = iso14443a_select_card(uid, card, &cuid, true, 0, false);
|
||||||
if (res) {
|
if (res) {
|
||||||
mf_reset_card();
|
|
||||||
if (cuid == 0xAA55C396) {
|
if (cuid == 0xAA55C396) {
|
||||||
flag |= MAGIC_FLAG_GEN_UNFUSED;
|
flag |= MAGIC_FLAG_GEN_UNFUSED;
|
||||||
}
|
}
|
||||||
|
@ -3221,7 +3220,7 @@ void MifareHasStaticNonce(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (counter) {
|
if (counter) {
|
||||||
Dbprintf("Static nonce....... " _YELLOW_("%08x"), nt);
|
Dbprintf("Static nonce......... " _YELLOW_("%08x"), nt);
|
||||||
data[0] = NONCE_STATIC;
|
data[0] = NONCE_STATIC;
|
||||||
} else {
|
} else {
|
||||||
data[0] = NONCE_NORMAL;
|
data[0] = NONCE_NORMAL;
|
||||||
|
@ -3562,7 +3561,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
|
||||||
AddCrc14A(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE);
|
AddCrc14A(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE);
|
||||||
|
|
||||||
if (doReselect) {
|
if (doReselect) {
|
||||||
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
|
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
|
||||||
retval = PM3_ESOFT;
|
retval = PM3_ESOFT;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
@ -3609,13 +3608,13 @@ void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) {
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE);
|
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
retval = PM3_EMALLOC;
|
retval = PM3_EMALLOC;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *par = BigBuf_calloc(MAX_PARITY_SIZE);
|
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
if (par == NULL) {
|
if (par == NULL) {
|
||||||
retval = PM3_EMALLOC;
|
retval = PM3_EMALLOC;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
@ -3685,7 +3684,7 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t work
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE);
|
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
retval = PM3_EMALLOC;
|
retval = PM3_EMALLOC;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
@ -3697,7 +3696,7 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t work
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *par = BigBuf_calloc(MAX_PARITY_SIZE);
|
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
if (par == NULL) {
|
if (par == NULL) {
|
||||||
retval = PM3_EMALLOC;
|
retval = PM3_EMALLOC;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
|
@ -60,7 +60,7 @@ bool InitDesfireCard(void) {
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
if (iso14443a_select_card(NULL, &card, NULL, true, 0, false) == 0) {
|
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) DbpString("Can't select card");
|
if (g_dbglevel >= DBG_ERROR) DbpString("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return false;
|
return false;
|
||||||
|
@ -157,7 +157,7 @@ void MifareDesfireGetInformation(void) {
|
||||||
pcb_blocknum = 0;
|
pcb_blocknum = 0;
|
||||||
|
|
||||||
// card select - information
|
// card select - information
|
||||||
if (iso14443a_select_card(NULL, &card, NULL, true, 0, false) == 0) {
|
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) {
|
if (g_dbglevel >= DBG_ERROR) {
|
||||||
DbpString("Can't select card");
|
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
|
// 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
|
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 571
|
||||||
|
|
||||||
uint8_t *free_buffer = BigBuf_calloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||||
// modulation buffer pointer and current buffer free space size
|
// modulation buffer pointer and current buffer free space size
|
||||||
uint8_t *free_buffer_pointer = free_buffer;
|
uint8_t *free_buffer_pointer = free_buffer;
|
||||||
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
||||||
|
@ -579,6 +579,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// find reader field
|
||||||
|
if (cardSTATE == MFEMUL_NOFIELD) {
|
||||||
|
|
||||||
|
vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
|
||||||
|
|
||||||
|
if (vHf > MF_MINFIELDV) {
|
||||||
|
cardSTATE_TO_IDLE();
|
||||||
|
LED_A_ON();
|
||||||
|
}
|
||||||
|
button_pushed = BUTTON_PRESS();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
FpgaEnableTracing();
|
FpgaEnableTracing();
|
||||||
//Now, get data
|
//Now, get data
|
||||||
int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par);
|
int res = EmGetCmd(receivedCmd, sizeof(receivedCmd), &receivedCmd_len, receivedCmd_par);
|
||||||
|
@ -745,6 +760,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
|
||||||
// WORK
|
// WORK
|
||||||
case MFEMUL_WORK: {
|
case MFEMUL_WORK: {
|
||||||
|
|
||||||
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
|
// Dbprintf("[MFEMUL_WORK] Enter in case");
|
||||||
|
}
|
||||||
|
|
||||||
if (receivedCmd_len == 0) {
|
if (receivedCmd_len == 0) {
|
||||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
||||||
break;
|
break;
|
||||||
|
@ -790,11 +809,10 @@ 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));
|
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
|
// sector out of range - do not respond
|
||||||
if ((cardAUTHSC >= cardMaxSEC) && (flags & FLAG_MF_ALLOW_OOB_AUTH) == 0) {
|
if (cardAUTHSC >= cardMaxSEC) {
|
||||||
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Out of range sector %d(0x%02x) >= %d(0x%02x)", cardAUTHSC, cardAUTHSC, cardMaxSEC, cardMaxSEC);
|
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Out of range sector %d(0x%02x)", cardAUTHSC, cardAUTHSC);
|
||||||
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,8 +229,7 @@ int sam_get_version(bool info) {
|
||||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||||
|
|
||||||
uint8_t payload[] = {
|
uint8_t payload[] = {
|
||||||
0xa0, // <- SAM command
|
0xa0, 0x02, // <- SAM command
|
||||||
0x02, // <- Length
|
|
||||||
0x82, 0x00 // <- get version
|
0x82, 0x00 // <- get version
|
||||||
};
|
};
|
||||||
uint16_t payload_len = sizeof(payload);
|
uint16_t payload_len = sizeof(payload);
|
||||||
|
@ -279,7 +278,7 @@ int sam_get_version(bool info) {
|
||||||
}
|
}
|
||||||
if (g_dbglevel >= DBG_INFO || info) {
|
if (g_dbglevel >= DBG_INFO || info) {
|
||||||
DbpString(_BLUE_("-- SAM Information --"));
|
DbpString(_BLUE_("-- SAM Information --"));
|
||||||
Dbprintf(_YELLOW_("Firmware version: ")"%d.%d", sam_version_an[2], sam_version_an[3]);
|
Dbprintf(_YELLOW_("Firmware version: ")"%X.%X", sam_version_an[2], sam_version_an[3]);
|
||||||
Dbprintf(_YELLOW_("Firmware ID: "));
|
Dbprintf(_YELLOW_("Firmware ID: "));
|
||||||
Dbhexdump(sam_build_an[1], sam_build_an + 2, false);
|
Dbhexdump(sam_build_an[1], sam_build_an + 2, false);
|
||||||
}
|
}
|
||||||
|
@ -310,8 +309,7 @@ int sam_get_serial_number(void) {
|
||||||
uint16_t response_len = ISO7816_MAX_FRAME;
|
uint16_t response_len = ISO7816_MAX_FRAME;
|
||||||
|
|
||||||
uint8_t payload[] = {
|
uint8_t payload[] = {
|
||||||
0xa0, // <- SAM command
|
0xa0, 0x02, // <- SAM command
|
||||||
0x02, // <- Length
|
|
||||||
0x96, 0x00 // <- get serial number
|
0x96, 0x00 // <- get serial number
|
||||||
};
|
};
|
||||||
uint16_t payload_len = sizeof(payload);
|
uint16_t payload_len = sizeof(payload);
|
||||||
|
|
|
@ -103,13 +103,10 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
|
||||||
|
|
||||||
nfc_tx_len = sam_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf);
|
nfc_tx_len = sam_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf);
|
||||||
|
|
||||||
bool is_cmd_check = ((nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_CHECK);
|
bool is_cmd_check = (nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_CHECK;
|
||||||
|
|
||||||
if (is_cmd_check && break_on_nr_mac) {
|
if (is_cmd_check && break_on_nr_mac) {
|
||||||
|
|
||||||
memcpy(response, nfc_tx_buf, nfc_tx_len);
|
memcpy(response, nfc_tx_buf, nfc_tx_len);
|
||||||
*response_len = nfc_tx_len;
|
*response_len = nfc_tx_len;
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_INFO) {
|
if (g_dbglevel >= DBG_INFO) {
|
||||||
DbpString("NR-MAC: ");
|
DbpString("NR-MAC: ");
|
||||||
Dbhexdump((*response_len) - 1, response + 1, false);
|
Dbhexdump((*response_len) - 1, response + 1, false);
|
||||||
|
@ -118,8 +115,7 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_cmd_update = ((nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_UPDATE);
|
bool is_cmd_update = (nfc_tx_buf[0] & 0x0F) == ICLASS_CMD_UPDATE;
|
||||||
|
|
||||||
if (is_cmd_update && prevent_epurse_update && nfc_tx_buf[0] == 0x87 && nfc_tx_buf[1] == 0x02) {
|
if (is_cmd_update && prevent_epurse_update && nfc_tx_buf[0] == 0x87 && nfc_tx_buf[1] == 0x02) {
|
||||||
// block update(2) command and fake the response to prevent update of epurse
|
// block update(2) command and fake the response to prevent update of epurse
|
||||||
|
|
||||||
|
@ -227,27 +223,18 @@ static int sam_send_request_iso15(const uint8_t *const request, const uint8_t re
|
||||||
// 07
|
// 07
|
||||||
// 90 00
|
// 90 00
|
||||||
if (request_len == 0) {
|
if (request_len == 0) {
|
||||||
|
if (
|
||||||
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] == 0x8a && sam_rx_buf[5 + 4] == 0x03)
|
||||||
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)) {
|
&&
|
||||||
|
!(sam_rx_buf[5] == 0xbd && sam_rx_buf[5 + 2] == 0xb3 && sam_rx_buf[5 + 4] == 0xa0)
|
||||||
if (g_dbglevel >= DBG_ERROR) {
|
) {
|
||||||
|
if (g_dbglevel >= DBG_ERROR)
|
||||||
Dbprintf("No PACS data in SAM response");
|
Dbprintf("No PACS data in SAM response");
|
||||||
}
|
|
||||||
res = PM3_ESOFT;
|
res = PM3_ESOFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
*response_len = sam_rx_buf[5 + 1] + 2;
|
||||||
}
|
|
||||||
|
|
||||||
if (sam_rx_buf[5] == 0xBD && sam_rx_buf[4] != 0x00) { //secure channel flag is not 0x00
|
|
||||||
Dbprintf(_YELLOW_("Secure channel flag set to: ")"%02x", sam_rx_buf[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(response, sam_rx_buf + 5, *response_len);
|
memcpy(response, sam_rx_buf + 5, *response_len);
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -374,14 +361,14 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skipDetect == false) {
|
if (!skipDetect) {
|
||||||
// step 2: get card information
|
// step 2: get card information
|
||||||
picopass_hdr_t card_a_info;
|
picopass_hdr_t card_a_info;
|
||||||
uint32_t eof_time = 0;
|
uint32_t eof_time = 0;
|
||||||
|
|
||||||
// implicit StartSspClk() happens here
|
// implicit StartSspClk() happens here
|
||||||
Iso15693InitReader();
|
Iso15693InitReader();
|
||||||
if (select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod) == false) {
|
if (!select_iclass_tag(&card_a_info, false, &eof_time, shallow_mod)) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,10 +383,8 @@ int sam_picopass_get_pacs(PacketCommandNG *c) {
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (g_dbglevel >= DBG_INFO)
|
||||||
if (g_dbglevel >= DBG_INFO) {
|
|
||||||
print_result("Response data", sam_response, sam_response_len);
|
print_result("Response data", sam_response, sam_response_len);
|
||||||
}
|
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ OBJS = $(OBJDIR)/bootrom.s19
|
||||||
# version_pm3.c should be checked on every compilation
|
# version_pm3.c should be checked on every compilation
|
||||||
version_pm3.c: default_version_pm3.c .FORCE
|
version_pm3.c: default_version_pm3.c .FORCE
|
||||||
$(info [=] CHECK $@)
|
$(info [=] CHECK $@)
|
||||||
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
|
$(Q)$(CP) $< $@
|
||||||
|
|
||||||
all: showinfo $(OBJS)
|
all: showinfo $(OBJS)
|
||||||
|
|
||||||
|
|
|
@ -402,7 +402,6 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/cmdlfvisa2000.c
|
${PM3_ROOT}/client/src/cmdlfvisa2000.c
|
||||||
${PM3_ROOT}/client/src/cmdlfzx8211.c
|
${PM3_ROOT}/client/src/cmdlfzx8211.c
|
||||||
${PM3_ROOT}/client/src/cmdmain.c
|
${PM3_ROOT}/client/src/cmdmain.c
|
||||||
${PM3_ROOT}/client/src/cmdmqtt.c
|
|
||||||
${PM3_ROOT}/client/src/cmdnfc.c
|
${PM3_ROOT}/client/src/cmdnfc.c
|
||||||
${PM3_ROOT}/client/src/cmdparser.c
|
${PM3_ROOT}/client/src/cmdparser.c
|
||||||
${PM3_ROOT}/client/src/cmdpiv.c
|
${PM3_ROOT}/client/src/cmdpiv.c
|
||||||
|
@ -435,7 +434,7 @@ set (TARGET_SOURCES
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c
|
OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c
|
||||||
COMMAND 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
|
COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c
|
||||||
DEPENDS ${PM3_ROOT}/common/default_version_pm3.c
|
DEPENDS ${PM3_ROOT}/common/default_version_pm3.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -693,7 +692,7 @@ add_executable(proxmark3
|
||||||
${ADDITIONAL_SRC}
|
${ADDITIONAL_SRC}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
|
target_compile_options(proxmark3 PUBLIC -Wall -O3)
|
||||||
if (EMBED_READLINE)
|
if (EMBED_READLINE)
|
||||||
if (NOT SKIPREADLINE EQUAL 1)
|
if (NOT SKIPREADLINE EQUAL 1)
|
||||||
add_dependencies(proxmark3 ncurses readline)
|
add_dependencies(proxmark3 ncurses readline)
|
||||||
|
@ -773,7 +772,6 @@ target_link_libraries(proxmark3 PRIVATE
|
||||||
pm3rrg_rdv4_reveng
|
pm3rrg_rdv4_reveng
|
||||||
pm3rrg_rdv4_hardnested
|
pm3rrg_rdv4_hardnested
|
||||||
pm3rrg_rdv4_id48
|
pm3rrg_rdv4_id48
|
||||||
pm3rrg_rdv4_mqtt
|
|
||||||
${ADDITIONAL_LNK})
|
${ADDITIONAL_LNK})
|
||||||
|
|
||||||
if (NOT SKIPPTHREAD EQUAL 1)
|
if (NOT SKIPPTHREAD EQUAL 1)
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
ifeq ($(PLTNAME),)
|
ifeq ($(PLTNAME),)
|
||||||
-include ../Makefile.platform
|
-include ../Makefile.platform
|
||||||
-include ../.Makefile.options.cache
|
-include ../.Makefile.options.cache
|
||||||
# Default platform if no platform specified
|
|
||||||
PLATFORM?=PM3RDV4
|
|
||||||
ifneq ($(PLATFORM), $(CACHED_PLATFORM))
|
ifneq ($(PLATFORM), $(CACHED_PLATFORM))
|
||||||
$(error platform definitions have been changed, please "make clean" at the root of the project)
|
$(error platform definitions have been changed, please "make clean" at the root of the project)
|
||||||
endif
|
endif
|
||||||
|
@ -133,12 +131,6 @@ WHEREAMILIBINC = -I$(WHEREAMILIBPATH)
|
||||||
WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a
|
WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a
|
||||||
WHEREAMILIBLD =
|
WHEREAMILIBLD =
|
||||||
|
|
||||||
## MQTT
|
|
||||||
MQTTLIBPATH = ./deps/mqtt
|
|
||||||
MQTTLIBINC = -I$(MQTTLIBPATH)
|
|
||||||
MQTTLIB = $(MQTTLIBPATH)/mqtt.a
|
|
||||||
MQTTLIBLD =
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# common local libraries #
|
# common local libraries #
|
||||||
##########################
|
##########################
|
||||||
|
@ -247,12 +239,6 @@ STATICLIBS += $(WHEREAMILIB)
|
||||||
LDLIBS += $(WHEREAMILIBLD)
|
LDLIBS += $(WHEREAMILIBLD)
|
||||||
PM3INCLUDES += $(WHEREAMILIBINC)
|
PM3INCLUDES += $(WHEREAMILIBINC)
|
||||||
|
|
||||||
## MQTT
|
|
||||||
# not distributed as system library
|
|
||||||
STATICLIBS += $(MQTTLIB)
|
|
||||||
LDLIBS += $(MQTTLIBLD)
|
|
||||||
PM3INCLUDES += $(MQTTLIBINC)
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# system libraries #
|
# system libraries #
|
||||||
####################
|
####################
|
||||||
|
@ -454,14 +440,13 @@ endif
|
||||||
ifeq ($(SWIG_LUA_FOUND),1)
|
ifeq ($(SWIG_LUA_FOUND),1)
|
||||||
PM3CFLAGS += -DHAVE_LUA_SWIG
|
PM3CFLAGS += -DHAVE_LUA_SWIG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SWIG_PYTHON_FOUND),1)
|
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||||
PM3CFLAGS += -DHAVE_PYTHON_SWIG
|
PM3CFLAGS += -DHAVE_PYTHON_SWIG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PM3CFLAGS += -DHAVE_SNPRINTF
|
PM3CFLAGS += -DHAVE_SNPRINTF
|
||||||
|
|
||||||
CXXFLAGS ?= -Wall -Werror
|
CXXFLAGS ?= -Wall
|
||||||
CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES)
|
CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES)
|
||||||
|
|
||||||
PM3CXXFLAGS = $(CXXFLAGS)
|
PM3CXXFLAGS = $(CXXFLAGS)
|
||||||
|
@ -597,7 +582,6 @@ endif
|
||||||
ifeq ($(SWIG_LUA_FOUND),1)
|
ifeq ($(SWIG_LUA_FOUND),1)
|
||||||
$(info Lua SWIG: wrapper found)
|
$(info Lua SWIG: wrapper found)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SWIG_PYTHON_FOUND),1)
|
ifeq ($(SWIG_PYTHON_FOUND),1)
|
||||||
$(info Python SWIG: wrapper found)
|
$(info Python SWIG: wrapper found)
|
||||||
endif
|
endif
|
||||||
|
@ -698,7 +682,6 @@ SRCS = mifare/aiddesfire.c \
|
||||||
cmdlfvisa2000.c \
|
cmdlfvisa2000.c \
|
||||||
cmdlfzx8211.c \
|
cmdlfzx8211.c \
|
||||||
cmdmain.c \
|
cmdmain.c \
|
||||||
cmdmqtt.c \
|
|
||||||
cmdnfc.c \
|
cmdnfc.c \
|
||||||
cmdparser.c \
|
cmdparser.c \
|
||||||
cmdpiv.c \
|
cmdpiv.c \
|
||||||
|
@ -894,7 +877,6 @@ endif
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) 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:
|
@# Just in case someone compiled within these dirs:
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
||||||
|
|
||||||
|
@ -992,10 +974,6 @@ ifneq ($(WHEREAMI_FOUND),1)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(MQTTLIB): .FORCE
|
|
||||||
$(info [*] MAKE $@)
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(MQTTLIBPATH) all
|
|
||||||
|
|
||||||
########
|
########
|
||||||
# SWIG #
|
# SWIG #
|
||||||
########
|
########
|
||||||
|
@ -1017,7 +995,7 @@ src/pm3_pywrap.c: pm3.i
|
||||||
# version_pm3.c should be checked on every compilation
|
# version_pm3.c should be checked on every compilation
|
||||||
src/version_pm3.c: default_version_pm3.c .FORCE
|
src/version_pm3.c: default_version_pm3.c .FORCE
|
||||||
$(info [=] CHECK $@)
|
$(info [=] CHECK $@)
|
||||||
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
|
$(Q)$(CP) $< $@
|
||||||
|
|
||||||
# easy printing of MAKE VARIABLES
|
# easy printing of MAKE VARIABLES
|
||||||
print-%: ; @echo $* = $($*)
|
print-%: ; @echo $* = $($*)
|
||||||
|
|
|
@ -31,6 +31,3 @@ endif()
|
||||||
if (NOT TARGET pm3rrg_rdv4_whereami)
|
if (NOT TARGET pm3rrg_rdv4_whereami)
|
||||||
include(whereami.cmake)
|
include(whereami.cmake)
|
||||||
endif()
|
endif()
|
||||||
if (NOT TARGET pm3rrg_rdv4_mqtt)
|
|
||||||
include(mqtt.cmake)
|
|
||||||
endif()
|
|
|
@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE
|
||||||
m
|
m
|
||||||
pm3rrg_rdv4_mbedtls)
|
pm3rrg_rdv4_mbedtls)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool
|
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool
|
||||||
|
|
|
@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE
|
||||||
../../include
|
../../include
|
||||||
../src)
|
../src)
|
||||||
target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser)
|
target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser)
|
||||||
target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON)
|
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_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE
|
target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE
|
||||||
|
@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3)
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE
|
target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE
|
||||||
-mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f)
|
-mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3)
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE
|
target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE
|
||||||
-mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f)
|
-mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3)
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE
|
target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE
|
||||||
-mmmx -msse2 -mavx -mno-avx2 -mno-avx512f)
|
-mmmx -msse2 -mavx -mno-avx2 -mno-avx512f)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3)
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE
|
target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE
|
||||||
-mmmx -msse2 -mavx -mavx2 -mno-avx512f)
|
-mmmx -msse2 -mavx -mavx2 -mno-avx512f)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3)
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE
|
target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE
|
||||||
-mmmx -msse2 -mavx -mavx2 -mavx512f)
|
-mmmx -msse2 -mavx -mavx2 -mavx512f)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE
|
target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE
|
||||||
|
@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS)
|
||||||
hardnested/hardnested_bf_core.c
|
hardnested/hardnested_bf_core.c
|
||||||
hardnested/hardnested_bitarray_core.c)
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3)
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE
|
target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE
|
||||||
-mfpu=neon)
|
-mfpu=neon)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC
|
||||||
hardnested/hardnested_bruteforce.c
|
hardnested/hardnested_bruteforce.c
|
||||||
$<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd>
|
$<TARGET_OBJECTS:pm3rrg_rdv4_hardnested_nosimd>
|
||||||
${SIMD_TARGETS})
|
${SIMD_TARGETS})
|
||||||
target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
target_include_directories(pm3rrg_rdv4_hardnested PRIVATE
|
target_include_directories(pm3rrg_rdv4_hardnested PRIVATE
|
||||||
../../common
|
../../common
|
||||||
|
|
|
@ -177,15 +177,14 @@ crack_states_thread(void *x) {
|
||||||
|
|
||||||
char progress_text[80];
|
char progress_text[80];
|
||||||
char keystr[19];
|
char keystr[19];
|
||||||
snprintf(keystr, sizeof(keystr), "%012" PRIX64, key);
|
snprintf(keystr, sizeof(keystr), "%012" PRIX64 " ", key);
|
||||||
snprintf(progress_text, sizeof(progress_text), "Brute force phase completed. Key found: " _GREEN_("%s"), keystr);
|
snprintf(progress_text, sizeof(progress_text), "Brute force phase completed. Key found: " _GREEN_("%s"), keystr);
|
||||||
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
|
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
|
||||||
PrintAndLogEx(INFO, "---------+---------+---------------------------------------------------------+-----------------+-------");
|
|
||||||
break;
|
break;
|
||||||
} else if (keys_found) {
|
} else if (keys_found) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (thread_arg->silent == false) {
|
if (!thread_arg->silent) {
|
||||||
char progress_text[80];
|
char progress_text[80];
|
||||||
snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%% ", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states));
|
snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%% ", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states));
|
||||||
float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested / 2;
|
float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested / 2;
|
||||||
|
@ -338,7 +337,7 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
|
||||||
bucket_count = 0;
|
bucket_count = 0;
|
||||||
for (statelist_t *p = candidates; p != NULL; p = p->next) {
|
for (statelist_t *p = candidates; p != NULL; p = p->next) {
|
||||||
if (p->states[ODD_STATE] != NULL && p->states[EVEN_STATE] != NULL) {
|
if (p->states[ODD_STATE] != NULL && p->states[EVEN_STATE] != NULL) {
|
||||||
if (ensure_buckets_alloc(bucket_count + 1) == false) {
|
if (!ensure_buckets_alloc(bucket_count + 1)) {
|
||||||
PrintAndLogEx(ERR, "Can't allocate buckets, abort!");
|
PrintAndLogEx(ERR, "Can't allocate buckets, abort!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +375,6 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
|
||||||
thread_args[i].best_first_bytes = best_first_bytes;
|
thread_args[i].best_first_bytes = best_first_bytes;
|
||||||
pthread_create(&threads[i], NULL, crack_states_thread, (void *)&thread_args[i]);
|
pthread_create(&threads[i], NULL, crack_states_thread, (void *)&thread_args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_brute_force_threads; i++) {
|
for (uint32_t i = 0; i < num_brute_force_threads; i++) {
|
||||||
pthread_join(threads[i], 0);
|
pthread_join(threads[i], 0);
|
||||||
}
|
}
|
||||||
|
@ -387,13 +385,11 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
|
||||||
|
|
||||||
uint64_t elapsed_time = msclock() - start_time;
|
uint64_t elapsed_time = msclock() - start_time;
|
||||||
|
|
||||||
if (bf_rate != NULL) {
|
if (bf_rate != NULL)
|
||||||
*bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0);
|
*bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0);
|
||||||
}
|
|
||||||
|
|
||||||
if (keys_found > 0) {
|
if (keys_found > 0)
|
||||||
*found_key = found_bs_key;
|
*found_key = found_bs_key;
|
||||||
}
|
|
||||||
|
|
||||||
return (keys_found != 0);
|
return (keys_found != 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ add_library(pm3rrg_rdv4_id48 STATIC
|
||||||
id48/id48_generator.c
|
id48/id48_generator.c
|
||||||
id48/id48_recover.c
|
id48/id48_recover.c
|
||||||
)
|
)
|
||||||
target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -Werror -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO)
|
target_compile_options( pm3rrg_rdv4_id48 PRIVATE -Wpedantic -Wall -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function -DID48_NO_STDIO)
|
||||||
target_include_directories(pm3rrg_rdv4_id48 PRIVATE id48)
|
target_include_directories(pm3rrg_rdv4_id48 PRIVATE id48)
|
||||||
target_include_directories(pm3rrg_rdv4_id48 INTERFACE id48)
|
target_include_directories(pm3rrg_rdv4_id48 INTERFACE id48)
|
||||||
set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_id48 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
|
@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC
|
||||||
|
|
||||||
target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H)
|
target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H)
|
||||||
target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson)
|
target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson)
|
||||||
target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3)
|
target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
|
@ -440,32 +440,33 @@ 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 json_dump_file(const json_t *json, const char *path, size_t flags) {
|
||||||
|
int result;
|
||||||
|
|
||||||
FILE *f = fopen(path, "w");
|
FILE *output = fopen(path, "w");
|
||||||
if (f == NULL) {
|
if (!output)
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = json_dumpf(json, f, flags);
|
|
||||||
|
|
||||||
if (fclose(f) != 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return res;
|
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 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 (!(flags & JSON_ENCODE_ANY)) {
|
||||||
if (!json_is_array(json) && !json_is_object(json)) {
|
if (!json_is_array(json) && !json_is_object(json))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hashtable_t parents_set;
|
if (hashtable_init(&parents_set))
|
||||||
if (hashtable_init(&parents_set)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
res = do_dump(json, flags, 0, &parents_set, callback, data);
|
||||||
int res = do_dump(json, flags, 0, &parents_set, callback, data);
|
|
||||||
hashtable_close(&parents_set);
|
hashtable_close(&parents_set);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,5 +52,5 @@ if (NOT MINGW)
|
||||||
endif (NOT MINGW)
|
endif (NOT MINGW)
|
||||||
|
|
||||||
target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua)
|
target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua)
|
||||||
target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON)
|
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 PRIVATE ../../common)
|
||||||
target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls)
|
target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls)
|
||||||
target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
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)
|
|
|
@ -1,21 +0,0 @@
|
||||||
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.
|
|
|
@ -1,14 +0,0 @@
|
||||||
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
|
|
|
@ -1,152 +0,0 @@
|
||||||
#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
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,235 +0,0 @@
|
||||||
/*
|
|
||||||
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 */
|
|
|
@ -1,173 +0,0 @@
|
||||||
#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
|
|
|
@ -1,73 +0,0 @@
|
||||||
#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
|
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
#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
|
../src
|
||||||
../../include)
|
../../include)
|
||||||
target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng)
|
target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng)
|
||||||
target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON)
|
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)
|
target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor)
|
||||||
# Strange errors on Mingw when compiling with -O3
|
# Strange errors on Mingw when compiling with -O3
|
||||||
target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2)
|
target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2)
|
||||||
set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON)
|
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_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED)
|
||||||
target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami)
|
target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami)
|
||||||
target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3)
|
target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3)
|
||||||
set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON)
|
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
|
# R.A.T.T transport card key A/B
|
||||||
AA034F342A55
|
AA034F342A55
|
||||||
456776908C48
|
456776908C48
|
||||||
#
|
|
||||||
# BusFacil - Brazilian public transport card for some cities
|
# BusFacil - Brazilian public transport card for some cities
|
||||||
fae9b14365a9
|
fae9b14365a9
|
||||||
c567dd4a6004
|
c567dd4a6004
|
||||||
|
@ -3108,32 +3108,6 @@ AB921CF0752C
|
||||||
567D734C403C
|
567D734C403C
|
||||||
2426217B3B3B
|
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)
|
# Card keys from Andalusian public transport system (Consorcio de Transportes)
|
||||||
1848A8D1E4C5
|
1848A8D1E4C5
|
||||||
16EE1FE134E4
|
16EE1FE134E4
|
||||||
|
|
|
@ -9,7 +9,6 @@ d3f7d3f7d3f7d3f7
|
||||||
000000000000000000000000000000000000000000000000 #NXP Default 3K3DES
|
000000000000000000000000000000000000000000000000 #NXP Default 3K3DES
|
||||||
00112233445566778899AABBCCDDEEFF0102030405060708
|
00112233445566778899AABBCCDDEEFF0102030405060708
|
||||||
ffffffffffffffffffffffffffffffffffffffffffffffff
|
ffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7
|
|
||||||
425245414B4D454946594F5543414E21 # default UL-C key
|
425245414B4D454946594F5543414E21 # default UL-C key
|
||||||
00112233445566778899AABBCCDDEEFF #TI TRF7970A sloa213
|
00112233445566778899AABBCCDDEEFF #TI TRF7970A sloa213
|
||||||
79702553797025537970255379702553 #TI TRF7970A sloa213
|
79702553797025537970255379702553 #TI TRF7970A sloa213
|
||||||
|
|
|
@ -434,7 +434,7 @@ set (TARGET_SOURCES
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c
|
OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c
|
||||||
COMMAND 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
|
COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c
|
||||||
DEPENDS ${PM3_ROOT}/common/default_version_pm3.c
|
DEPENDS ${PM3_ROOT}/common/default_version_pm3.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ local function perform_check(uid, numsectors)
|
||||||
for sector = 0, #keys do
|
for sector = 0, #keys do
|
||||||
-- Check if user aborted
|
-- Check if user aborted
|
||||||
if core.kbd_enter_pressed() then
|
if core.kbd_enter_pressed() then
|
||||||
print('Aborted via keyboard!')
|
print('Aborted by user')
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,7 @@ local function main(args)
|
||||||
if answer == 'n' then
|
if answer == 'n' then
|
||||||
core.console('clear')
|
core.console('clear')
|
||||||
print( string.rep('--',39) )
|
print( string.rep('--',39) )
|
||||||
print(ac.red..' Aborted via keyboard!'..ac.reset)
|
print(ac.red..' USER ABORTED'..ac.reset)
|
||||||
print( string.rep('--',39) )
|
print( string.rep('--',39) )
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
|
@ -198,7 +198,7 @@ local function main(args)
|
||||||
core.console('lf em 410x reader')
|
core.console('lf em 410x reader')
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print(ac.red..'aborted via keyboard!'..ac.reset)
|
print(ac.red..'User aborted'..ac.reset)
|
||||||
low = i
|
low = i
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ desc = [[
|
||||||
is found, it uses the wipe command to erase the T5577. Then the reanimation
|
is found, it uses the wipe command to erase the T5577. Then the reanimation
|
||||||
procedure is applied. If the password is not found or doesn't exist the script
|
procedure is applied. If the password is not found or doesn't exist the script
|
||||||
only performs the reanimation procedure. The script revives 99% of blocked tags.
|
only performs the reanimation procedure. The script revives 99% of blocked tags.
|
||||||
]]
|
]]
|
||||||
usage = [[
|
usage = [[
|
||||||
script run lf_t55xx_fix
|
script run lf_t55xx_fix
|
||||||
]]
|
]]
|
||||||
|
@ -87,7 +87,7 @@ local function reanimate_t5577(password)
|
||||||
p:console('lf t55 wipe -p ' .. password)
|
p:console('lf t55 wipe -p ' .. password)
|
||||||
print("T5577 wiped using a password: " ..ac.green.. password ..ac.reset)
|
print("T5577 wiped using a password: " ..ac.green.. password ..ac.reset)
|
||||||
else
|
else
|
||||||
print(ac.yellow.." No valid password found, proceeding with reanimation."..ac.reset)
|
print(ac.yellow.."No valid password found, proceeding with reanimation."..ac.reset)
|
||||||
end
|
end
|
||||||
|
|
||||||
p:console('lf t55 write -b 0 -d 000880E8 -p 00000000')
|
p:console('lf t55 write -b 0 -d 000880E8 -p 00000000')
|
||||||
|
|
|
@ -4,16 +4,7 @@ local ac = require('ansicolors')
|
||||||
local os = require('os')
|
local os = require('os')
|
||||||
local dash = string.rep('--', 32)
|
local dash = string.rep('--', 32)
|
||||||
local dir = os.getenv('HOME') .. '/.proxmark3/logs/'
|
local dir = os.getenv('HOME') .. '/.proxmark3/logs/'
|
||||||
local logfilecmd
|
local logfile = (io.popen('dir /a-d /o-d /tw /b/s "' .. dir .. '" 2>nul:'):read("*a"):match("%C+"))
|
||||||
|
|
||||||
--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 log_file_path = dir .. "Paxton_log.txt"
|
||||||
local nam = ""
|
local nam = ""
|
||||||
local pm3 = require('pm3')
|
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:
|
with open(dict_path, 'r', encoding='utf-8') as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
if line[0] != '#' and len(line) >= 12:
|
if line[0] != '#' and len(line) >= 12:
|
||||||
DEFAULT_KEYS.add(line[:12].lower())
|
DEFAULT_KEYS.add(line[:12])
|
||||||
show(f"Loaded {dict_def}")
|
show(f"Loaded {dict_def}")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
show(f"Warning, {dict_def} not found.")
|
show(f"Warning, {dict_def} not found.")
|
||||||
|
@ -226,7 +226,6 @@ def recovery(init_check=False, final_check=False, keep=False, no_oob=False,
|
||||||
dict_dnwd = None
|
dict_dnwd = None
|
||||||
def_nt = ["" for _ in range(NUM_SECTORS)]
|
def_nt = ["" for _ in range(NUM_SECTORS)]
|
||||||
if supply_chain:
|
if supply_chain:
|
||||||
default_nonces = ''
|
|
||||||
try:
|
try:
|
||||||
default_nonces = f'{save_path}hf-mf-{uid:04X}-default_nonces.json'
|
default_nonces = f'{save_path}hf-mf-{uid:04X}-default_nonces.json'
|
||||||
with open(default_nonces, 'r') as file:
|
with open(default_nonces, 'r') as file:
|
||||||
|
@ -585,6 +584,8 @@ def recovery(init_check=False, final_check=False, keep=False, no_oob=False,
|
||||||
if "Found keys have been dumped to" in line:
|
if "Found keys have been dumped to" in line:
|
||||||
keyfile = line[line.index("`"):].strip("`")
|
keyfile = line[line.index("`"):].strip("`")
|
||||||
else:
|
else:
|
||||||
|
show()
|
||||||
|
show(color("found keys:", fg="green"), prompt=plus)
|
||||||
show(prompt=plus)
|
show(prompt=plus)
|
||||||
show("-----+-----+--------------+---+--------------+----", prompt=plus)
|
show("-----+-----+--------------+---+--------------+----", prompt=plus)
|
||||||
show(" Sec | Blk | key A |res| key B |res", prompt=plus)
|
show(" Sec | Blk | key A |res| key B |res", prompt=plus)
|
||||||
|
|
|
@ -305,9 +305,6 @@ FRA_OrganizationalAuthority_Contract_Provider = {
|
||||||
0x021: {
|
0x021: {
|
||||||
1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1),
|
1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1),
|
||||||
},
|
},
|
||||||
0x040: {
|
|
||||||
28: InterticHelper('Colmar', 'Trace / Keolis', Describe_Usage_1_1),
|
|
||||||
},
|
|
||||||
0x057: {
|
0x057: {
|
||||||
1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), # Strange usage ?, kept on generic 1
|
1: InterticHelper('Lyon', 'TCL / Keolis', Describe_Usage_1), # Strange usage ?, kept on generic 1
|
||||||
},
|
},
|
||||||
|
@ -338,7 +335,6 @@ FRA_OrganizationalAuthority_Contract_Provider = {
|
||||||
},
|
},
|
||||||
0x912: {
|
0x912: {
|
||||||
3: InterticHelper('Le Havre', 'Lia / Transdev', Describe_Usage_1_1),
|
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'),
|
35: InterticHelper('Cherbourg-en-Cotentin', 'Cap Cotentin / Transdev'),
|
||||||
},
|
},
|
||||||
0x913: {
|
0x913: {
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Cardax Card Data Application",
|
"Description": "Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Unused Cardax Card Data Application",
|
"Description": "Unused Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Unused Cardax Card Data Application",
|
"Description": "Unused Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -148,7 +148,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Unused Cardax Card Data Application",
|
"Description": "Unused Cardax Card Data Application (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -156,7 +156,7 @@
|
||||||
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
"Vendor": "Gallagher Group Limited via PEC (New Zealand) Limited",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Gallagher Security Credential",
|
"Name": "Gallagher Security Credential",
|
||||||
"Description": "Card Application Directory (CAD)",
|
"Description": "Card Application Directory (CAD) (Alternative Endian)",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -223,6 +223,134 @@
|
||||||
"Description": "Securitron DESFire EV2 Credential",
|
"Description": "Securitron DESFire EV2 Credential",
|
||||||
"Type": "pacs"
|
"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",
|
"AID": "F484D1",
|
||||||
"Vendor": "HID",
|
"Vendor": "HID",
|
||||||
|
@ -767,14 +895,6 @@
|
||||||
"Description": "car2go - Member Card // Multi Functional Badge / Private Application #1",
|
"Description": "car2go - Member Card // Multi Functional Badge / Private Application #1",
|
||||||
"Type": "carsharing"
|
"Type": "carsharing"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"AID": "000001",
|
|
||||||
"Vendor": "Invalid / Reserved",
|
|
||||||
"Country": "",
|
|
||||||
"Name": "Invalid / Reserved",
|
|
||||||
"Description": "Used by ATL Breeze, PHL FREEDOM, and YVR Compass",
|
|
||||||
"Type": "transport"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"AID": "000005",
|
"AID": "000005",
|
||||||
"Vendor": "Transports Metropolitans de Barcelona (TMB)",
|
"Vendor": "Transports Metropolitans de Barcelona (TMB)",
|
||||||
|
@ -783,6 +903,14 @@
|
||||||
"Description": "BCN T-mobilitat",
|
"Description": "BCN T-mobilitat",
|
||||||
"Type": "transport"
|
"Type": "transport"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"AID": "000001",
|
||||||
|
"Vendor": "Invalid / Reserved",
|
||||||
|
"Country": "",
|
||||||
|
"Name": "Invalid / Reserved",
|
||||||
|
"Description": "Used by ATL Breeze, PHL FREEDOM, and YVR Compass",
|
||||||
|
"Type": "transport"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"AID": "0000F0",
|
"AID": "0000F0",
|
||||||
"Vendor": "Metropolitan Transportation Authority (MTA) / Bayerische Motoren Werke (BMW) AG",
|
"Vendor": "Metropolitan Transportation Authority (MTA) / Bayerische Motoren Werke (BMW) AG",
|
||||||
|
@ -793,7 +921,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "002000",
|
"AID": "002000",
|
||||||
"Vendor": "Metrolinx via Accenture",
|
"Vendor": "Metrolinx",
|
||||||
"Country": "CA",
|
"Country": "CA",
|
||||||
"Name": "PRESTO Card (YYZ/YHM/YOW)",
|
"Name": "PRESTO Card (YYZ/YHM/YOW)",
|
||||||
"Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data",
|
"Description": "FIDs 00,0F: Backup Data; 08-0E,10-14: Standard Data",
|
||||||
|
@ -1081,7 +1209,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "415431",
|
"AID": "415431",
|
||||||
"Vendor": "Athens Urban Transport Organisation (OASA)",
|
"Vendor": "Athens Urban Transport Organization (OASA)",
|
||||||
"Country": "GR",
|
"Country": "GR",
|
||||||
"Name": "ATH.ENA CARD (ATH)",
|
"Name": "ATH.ENA CARD (ATH)",
|
||||||
"Description": "ATH ATH.ENA CARD",
|
"Description": "ATH ATH.ENA CARD",
|
||||||
|
@ -1153,7 +1281,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "4F5931",
|
"AID": "4F5931",
|
||||||
"Vendor": "Transport for London (TfL) via Cubic Transportation Systems",
|
"Vendor": "Transport for London (TfL)",
|
||||||
"Country": "UK",
|
"Country": "UK",
|
||||||
"Name": "Oyster Card (LHR)",
|
"Name": "Oyster Card (LHR)",
|
||||||
"Description": "FIDs: 00-07: Standard Data",
|
"Description": "FIDs: 00-07: Standard Data",
|
||||||
|
@ -1169,7 +1297,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "534531",
|
"AID": "534531",
|
||||||
"Vendor": "Transport for New South Wales (TfNSW) via Pearl Consortium",
|
"Vendor": "Transport for New South Wales (TfNSW)",
|
||||||
"Country": "AU",
|
"Country": "AU",
|
||||||
"Name": "Opal Card (SYD)",
|
"Name": "Opal Card (SYD)",
|
||||||
"Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History",
|
"Description": "FIDs 00-06: Standard Data; 07: Card Balance/Number and Trip History",
|
||||||
|
@ -1177,7 +1305,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "554000",
|
"AID": "554000",
|
||||||
"Vendor": "Auckland Transport via Thales Group",
|
"Vendor": "Auckland Transport",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "AT HOP Card (AKL)",
|
"Name": "AT HOP Card (AKL)",
|
||||||
"Description": "FIDs: 00: Backup Data; 08/09/0A",
|
"Description": "FIDs: 00: Backup Data; 08/09/0A",
|
||||||
|
@ -1263,14 +1391,6 @@
|
||||||
"Description": "Umo Mobility Card",
|
"Description": "Umo Mobility Card",
|
||||||
"Type": "transport"
|
"Type": "transport"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"AID": "C1B1A1",
|
|
||||||
"Vendor": "AHORROBUS via MOBILITY ADO",
|
|
||||||
"Country": "MX",
|
|
||||||
"Name": "AHORROBUS Card (MEX)",
|
|
||||||
"Description": "MEX AHORROBUS Card",
|
|
||||||
"Type": "transport"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"AID": "C65B80",
|
"AID": "C65B80",
|
||||||
"Vendor": "Umo Mobility via Cubic Transportation Systems",
|
"Vendor": "Umo Mobility via Cubic Transportation Systems",
|
||||||
|
@ -1345,7 +1465,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "F21050",
|
"AID": "F21050",
|
||||||
"Vendor": "Metro Christchurch via INIT / Arc via Vix Technologies",
|
"Vendor": "Metro Christchurch via INIT / Arc",
|
||||||
"Country": "NZ / CA",
|
"Country": "NZ / CA",
|
||||||
"Name": "Metrocard (CHC) / Arc (YEG)",
|
"Name": "Metrocard (CHC) / Arc (YEG)",
|
||||||
"Description": "CHC FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance",
|
"Description": "CHC FIDs: 00: Backup Data; 01/02: Trip History; 03: Card Balance",
|
||||||
|
@ -1353,7 +1473,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "F210E0",
|
"AID": "F210E0",
|
||||||
"Vendor": "TriMet via INIT",
|
"Vendor": "TriMet",
|
||||||
"Country": "US",
|
"Country": "US",
|
||||||
"Name": "hop fastpass (PDX)",
|
"Name": "hop fastpass (PDX)",
|
||||||
"Description": "PDX hop fastpass Card",
|
"Description": "PDX hop fastpass Card",
|
||||||
|
@ -1401,7 +1521,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "F21201",
|
"AID": "F21201",
|
||||||
"Vendor": "Green Bay Metro Transit via Genfare / Winnipeg Transit via Genfare",
|
"Vendor": "Green Bay Metro Transit via Genfare / Winnipeg Transit",
|
||||||
"Country": "US / CA",
|
"Country": "US / CA",
|
||||||
"Name": "Tap-N-Go Card (GRB) / peggo card (YWG)",
|
"Name": "Tap-N-Go Card (GRB) / peggo card (YWG)",
|
||||||
"Description": "GRB Tap-N-Go Card / YWG peggo card",
|
"Description": "GRB Tap-N-Go Card / YWG peggo card",
|
||||||
|
@ -1417,7 +1537,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "F212A0",
|
"AID": "F212A0",
|
||||||
"Vendor": "CTtransit via Genfare",
|
"Vendor": "CTtransit",
|
||||||
"Country": "US",
|
"Country": "US",
|
||||||
"Name": "Go CT Card (BDL)",
|
"Name": "Go CT Card (BDL)",
|
||||||
"Description": "BDL Go CT Card",
|
"Description": "BDL Go CT Card",
|
||||||
|
@ -1425,7 +1545,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "F21360",
|
"AID": "F21360",
|
||||||
"Vendor": "The City and County of Honolulu via INIT",
|
"Vendor": "INIT",
|
||||||
"Country": "US",
|
"Country": "US",
|
||||||
"Name": "HOLO Card (HNL)",
|
"Name": "HOLO Card (HNL)",
|
||||||
"Description": "HNL HOLO Card",
|
"Description": "HNL HOLO Card",
|
||||||
|
@ -1441,7 +1561,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "F21390",
|
"AID": "F21390",
|
||||||
"Vendor": "Otago Regional Council via INIT",
|
"Vendor": "Multiple NZ Transit Agencies via Otago Regional Council",
|
||||||
"Country": "NZ",
|
"Country": "NZ",
|
||||||
"Name": "Bee Card (DUD)",
|
"Name": "Bee Card (DUD)",
|
||||||
"Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance",
|
"Description": "Multi-Modal Transit #0 // FIDs 00: Backup Data; 01-02: Trip History; 03: Card Balance",
|
||||||
|
@ -1463,14 +1583,6 @@
|
||||||
"Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data",
|
"Description": "One Regional Card for All // FIDs 00: Standard Data; 01: Backup Data",
|
||||||
"Type": "transport"
|
"Type": "transport"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"AID": "F21400",
|
|
||||||
"Vendor": "Spokane Transit Authority (STA) via INIT",
|
|
||||||
"Country": "US",
|
|
||||||
"Name": "Connect Card (GEG)",
|
|
||||||
"Description": "GEG Connect Card",
|
|
||||||
"Type": "transport"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"AID": "F40110",
|
"AID": "F40110",
|
||||||
"Vendor": "ITSO Ltd",
|
"Vendor": "ITSO Ltd",
|
||||||
|
@ -1505,7 +1617,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "FF30FF",
|
"AID": "FF30FF",
|
||||||
"Vendor": "Metrolinx via Accenture",
|
"Vendor": "Metrolinx",
|
||||||
"Country": "CA",
|
"Country": "CA",
|
||||||
"Name": "PRESTO Card (YYZ/YHM/YOW)",
|
"Name": "PRESTO Card (YYZ/YHM/YOW)",
|
||||||
"Description": "FID 08: Standard Data",
|
"Description": "FID 08: Standard Data",
|
||||||
|
|
|
@ -1247,6 +1247,14 @@
|
||||||
"Description": "PIV End Point Applet. Last 2 bytes designate version",
|
"Description": "PIV End Point Applet. Last 2 bytes designate version",
|
||||||
"Type": ""
|
"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",
|
"AID": "A00000031510100528",
|
||||||
"Vendor": "Currence Holding/PIN BV",
|
"Vendor": "Currence Holding/PIN BV",
|
||||||
|
@ -2462,37 +2470,5 @@
|
||||||
"Name": "Navigo",
|
"Name": "Navigo",
|
||||||
"Description": "CALYPSO-based transit card",
|
"Description": "CALYPSO-based transit card",
|
||||||
"Type": "transport"
|
"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"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[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,13 +4130,6 @@
|
||||||
"service_provider": "HID Corporation",
|
"service_provider": "HID Corporation",
|
||||||
"system_integrator": "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",
|
"application": "City transport, prepaid ticket, cardholder, servicespass",
|
||||||
"company": "Ridango AS",
|
"company": "Ridango AS",
|
||||||
|
|
|
@ -3527,8 +3527,8 @@ static int CmdAtrLookup(const char *Cmd) {
|
||||||
static int CmdCryptography(const char *Cmd) {
|
static int CmdCryptography(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "data crypto",
|
CLIParserInit(&ctx, "data crypto",
|
||||||
"This command lets you encrypt or decrypt data using DES/3DES/AES.\n"
|
"Encrypt data, right here, right now. Or decrypt.",
|
||||||
"Supply data, key, IV (needed for des MAC or aes), and cryptography action.\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 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"
|
"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"
|
"data crypto -d 04D6850E06AABB80 -k FFFFFFFFFFFFFFFF --iv 9EA0401A00000000 --des -> Calculate a MAC for FMCOS chip. The result should be ED3A0133\n"
|
||||||
|
@ -3544,97 +3544,76 @@ static int CmdCryptography(const char *Cmd) {
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t dati[250] = {0};
|
uint8_t dati[250] = {0};
|
||||||
uint8_t dato[250] = {0};
|
uint8_t dato[250] = {0};
|
||||||
int datilen = 0;
|
int datilen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, dati, &datilen);
|
CLIGetHexWithReturn(ctx, 1, dati, &datilen);
|
||||||
|
uint8_t key[25] = {0};
|
||||||
uint8_t key[33] = {0};
|
|
||||||
int keylen = 0;
|
int keylen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 2, key, &keylen);
|
CLIGetHexWithReturn(ctx, 2, key, &keylen);
|
||||||
|
int type = 0;
|
||||||
uint8_t type = 0;
|
if (arg_get_lit(ctx, 3)) type ^= 8;
|
||||||
if (arg_get_lit(ctx, 3)) {
|
if (arg_get_lit(ctx, 4)) type ^= 4;
|
||||||
type ^= 0x08;
|
if (arg_get_lit(ctx, 5)) type ^= 2;
|
||||||
}
|
|
||||||
|
|
||||||
if (arg_get_lit(ctx, 4)) {
|
|
||||||
type ^= 0x04;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg_get_lit(ctx, 5)) {
|
|
||||||
type ^= 0x02;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t iv[250] = {0};
|
uint8_t iv[250] = {0};
|
||||||
int ivlen = 0;
|
int ivlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 6, iv, &ivlen);
|
CLIGetHexWithReturn(ctx, 6, iv, &ivlen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// Do data length check
|
// Do data length check
|
||||||
if ((type & 0x04) == 0x04) { // Use AES(0) or DES(1)?
|
if ((type & 0x4) >> 2) { // Use AES(0) or DES(1)?
|
||||||
|
|
||||||
if (datilen % 8 != 0) {
|
if (datilen % 8 != 0) {
|
||||||
PrintAndLogEx(ERR, "<data> length must be a multiple of 8. Got %d", datilen);
|
PrintAndLogEx(ERR, "<data> length must be a multiple of 8. Got %d", datilen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keylen != 8 && keylen != 16 && keylen != 24 && keylen != 32) {
|
if (keylen != 8 && keylen != 16 && keylen != 24) {
|
||||||
PrintAndLogEx(ERR, "<key> must be 8, 16, 24, 32 bytes. Got %d", keylen);
|
PrintAndLogEx(ERR, "<key> must be 8, 16 or 24 bytes. Got %d", keylen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (datilen % 16 != 0 && ((type & 0x02) == 0)) {
|
if (datilen % 16 != 0 && ((type & 0x2) >> 1 == 0)) {
|
||||||
PrintAndLogEx(ERR, "<data> length must be a multiple of 16. Got %d", datilen);
|
PrintAndLogEx(ERR, "<data> length must be a multiple of 16. Got %d", datilen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keylen != 16 && keylen != 32) {
|
if (keylen != 16) {
|
||||||
PrintAndLogEx(ERR, "<key> must be 16 or 32 bytes. Got %d", keylen);
|
PrintAndLogEx(ERR, "<key> must be 16 bytes. Got %d", keylen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt(0) or decrypt(1)?
|
// Encrypt(0) or decrypt(1)?
|
||||||
if ((type & 0x08) == 0x08) {
|
if ((type & 0x8) >> 3) {
|
||||||
|
|
||||||
if ((type & 0x04) == 0x04) { // AES or DES?
|
if ((type & 0x4) >> 2) { // AES or DES?
|
||||||
|
|
||||||
if (keylen > 8) {
|
if (keylen > 8) {
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Called 3DES decrypt");
|
||||||
des3_decrypt(dato, dati, key, keylen / 8);
|
des3_decrypt(dato, dati, key, keylen / 8);
|
||||||
PrintAndLogEx(INFO, "3DES decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Called DES decrypt");
|
||||||
if (ivlen == 0) {
|
if (ivlen == 0) {
|
||||||
// If there's an IV, use CBC
|
// If there's an IV, use CBC
|
||||||
des_decrypt_ecb(dato, dati, datilen, key);
|
des_decrypt_ecb(dato, dati, datilen, key);
|
||||||
PrintAndLogEx(INFO, "DES ECB decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
} else {
|
} else {
|
||||||
des_decrypt_cbc(dato, dati, datilen, key, iv);
|
des_decrypt_cbc(dato, dati, datilen, key, iv);
|
||||||
PrintAndLogEx(INFO, "DES CBC decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
if (keylen == 32) {
|
|
||||||
aes256_decode(iv, key, dati, dato, datilen);
|
|
||||||
PrintAndLogEx(INFO, "AES-256 decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
} else {
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Called AES decrypt");
|
||||||
aes_decode(iv, key, dati, dato, datilen);
|
aes_decode(iv, key, dati, dato, datilen);
|
||||||
PrintAndLogEx(INFO, "AES-128 decrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (type & 0x4) { // AES or DES?
|
||||||
if ((type & 0x04) == 0x04) { // AES or DES?
|
if (type & 0x02) { // If we will calculate a MAC
|
||||||
if ((type & 0x02) == 0x02) { // If we will calculate a MAC
|
|
||||||
/*PrintAndLogEx(INFO, "Called FeliCa 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 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
|
for (int i = 0; i < datilen; i+=8){ // For all 8 byte sequences
|
||||||
|
@ -3658,42 +3637,37 @@ static int CmdCryptography(const char *Cmd) {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (keylen > 8) {
|
if (keylen > 8) {
|
||||||
|
PrintAndLogEx(INFO, "Called 3DES encrypt keysize: %i", keylen / 8);
|
||||||
des3_encrypt(dato, dati, key, 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 {
|
} else {
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Called DES encrypt");
|
||||||
|
|
||||||
if (ivlen == 0) {
|
if (ivlen == 0) {
|
||||||
// If there's an IV, use ECB
|
// If there's an IV, use ECB
|
||||||
des_encrypt_ecb(dato, dati, datilen, key);
|
des_encrypt_ecb(dato, dati, datilen, key);
|
||||||
PrintAndLogEx(INFO, "DES ECB encrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
} else {
|
} else {
|
||||||
des_encrypt_cbc(dato, dati, datilen, key, iv);
|
des_encrypt_cbc(dato, dati, datilen, key, iv);
|
||||||
char pad[250];
|
char pad[250];
|
||||||
memset(pad, ' ', 4 + 8 + (datilen - 8) * 3);
|
memset(pad, ' ', 4 + 8 + (datilen - 8) * 3);
|
||||||
pad[8 + (datilen - 8) * 3] = 0; // Make a padding to insert FMCOS macing algorithm guide
|
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, "%sVV VV VV VV FMCOS MAC", pad);
|
||||||
PrintAndLogEx(INFO, "DES CBC encrypt... " _YELLOW_("%s"), sprint_hex_inrow(dato, datilen));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ((type & 0x02) == 0x02) {
|
if (type & 0x02) {
|
||||||
|
PrintAndLogEx(INFO, "Called AES CMAC");
|
||||||
// If we will calculate a MAC
|
// If we will calculate a MAC
|
||||||
aes_cmac8(iv, key, dati, dato, datilen);
|
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 {
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Called AES encrypt");
|
||||||
aes_encode(iv, key, dati, dato, datilen);
|
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;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ int CmdLtrim(const char *Cmd);
|
||||||
int CmdNorm(const char *Cmd); // used by cmd lf data (!)
|
int CmdNorm(const char *Cmd); // used by cmd lf data (!)
|
||||||
int CmdPlot(const char *Cmd); // used by cmd lf cotag
|
int CmdPlot(const char *Cmd); // used by cmd lf cotag
|
||||||
int CmdSave(const char *Cmd); // used by cmd auto
|
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 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
|
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,24 +192,21 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "mem load",
|
CLIParserInit(&ctx, "mem load",
|
||||||
"Loads binary file into flash memory on device\n"
|
"Loads binary file into flash memory on device\n"
|
||||||
"Warning! - mem area to be written must have been wiped first\n\n"
|
"Warning: mem area to be written must have been wiped first\n"
|
||||||
"OBS! - dictionaries are serviced as files in spiffs so no wipe is needed",
|
"( dictionaries are serviced as files in spiffs so no wipe is needed )",
|
||||||
"mem load -f myfile -> upload file myfile values at default offset 0\n"
|
"mem load -f myfile -> upload file myfile values at default offset 0\n"
|
||||||
"mem load -f myfile -o 1024 -> upload file myfile values at offset 1024\n"
|
"mem load -f myfile -o 1024 -> upload file myfile values at offset 1024\n"
|
||||||
"mem load -f mfc_default_keys -m -> upload MIFARE Classic keys\n"
|
"mem load -f mfc_default_keys -m -> upload MFC keys\n"
|
||||||
"mem load -f t55xx_default_pwds -t -> upload T55XX passwords\n"
|
"mem load -f t55xx_default_pwds -t -> upload T55XX passwords\n"
|
||||||
"mem load -f iclass_default_keys -i -> upload iCLASS keys\n"
|
"mem load -f iclass_default_keys -i -> upload iCLASS keys\n"
|
||||||
"mem load -f mfulc_default_keys --ulc -> upload MIFARE UL-C keys\n"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int0("o", "offset", "<dec>", "offset in memory"),
|
arg_int0("o", "offset", "<dec>", "offset in memory"),
|
||||||
arg_lit0("m", "mfc", "upload 6 bytes keys (MIFARE Classic dictionary)"),
|
arg_lit0("m", "mifare,mfc", "upload 6 bytes keys (mifare key dictionary)"),
|
||||||
arg_lit0("i", "iclass", "upload 8 bytes keys (iClass dictionary)"),
|
arg_lit0("i", "iclass", "upload 8 bytes keys (iClass key dictionary)"),
|
||||||
arg_lit0("t", "t55xx", "upload 4 bytes keys (T55xx dictionary)"),
|
arg_lit0("t", "t55xx", "upload 4 bytes keys (password dictionary)"),
|
||||||
arg_lit0(NULL, "ulc", "upload 16 bytes keys (MIFARE UL-C dictionary)"),
|
|
||||||
arg_lit0(NULL, "aes", "upload 16 bytes keys (MIFARE UL-AES dictionary)"),
|
|
||||||
arg_str1("f", "file", "<fn>", "file name"),
|
arg_str1("f", "file", "<fn>", "file name"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -219,35 +216,28 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
bool is_mfc = arg_get_lit(ctx, 2);
|
bool is_mfc = arg_get_lit(ctx, 2);
|
||||||
bool is_iclass = arg_get_lit(ctx, 3);
|
bool is_iclass = arg_get_lit(ctx, 3);
|
||||||
bool is_t55xx = arg_get_lit(ctx, 4);
|
bool is_t55xx = arg_get_lit(ctx, 4);
|
||||||
bool is_ulc = arg_get_lit(ctx, 5);
|
|
||||||
bool is_ulaes = arg_get_lit(ctx, 6);
|
|
||||||
int fnlen = 0;
|
int fnlen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
char spiffsDest[32] = {0};
|
||||||
|
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
Dictionary_t d = DICTIONARY_NONE;
|
Dictionary_t d = DICTIONARY_NONE;
|
||||||
if (is_mfc) {
|
if (is_mfc) {
|
||||||
d = DICTIONARY_MIFARE;
|
d = DICTIONARY_MIFARE;
|
||||||
PrintAndLogEx(INFO, "Treating file as MIFARE Classic keys");
|
PrintAndLogEx(INFO, "treating file as MIFARE Classic keys");
|
||||||
} else if (is_iclass) {
|
} else if (is_iclass) {
|
||||||
d = DICTIONARY_ICLASS;
|
d = DICTIONARY_ICLASS;
|
||||||
PrintAndLogEx(INFO, "Treating file as iCLASS keys");
|
PrintAndLogEx(INFO, "treating file as iCLASS keys");
|
||||||
} else if (is_t55xx) {
|
} else if (is_t55xx) {
|
||||||
d = DICTIONARY_T55XX;
|
d = DICTIONARY_T55XX;
|
||||||
PrintAndLogEx(INFO, "Treating file as T55xx passwords");
|
PrintAndLogEx(INFO, "treating file as T55xx passwords");
|
||||||
} else if (is_ulc) {
|
|
||||||
d = DICTIONARY_MIFARE_ULC;
|
|
||||||
PrintAndLogEx(INFO, "Treating file as MIFARE Ultralight-C keys");
|
|
||||||
} else if (is_ulaes) {
|
|
||||||
d = DICTIONARY_MIFARE_ULAES;
|
|
||||||
PrintAndLogEx(INFO, "Treating file as MIFARE Ultralight AES keys");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t spi_flash_pages = 0;
|
uint8_t spi_flash_pages = 0;
|
||||||
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
int res = rdv4_get_flash_pages64k(&spi_flash_pages);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(ERR, "Failed to get flash pages count (%x)", res);
|
PrintAndLogEx(ERR, "failed to get flash pages count (%x)", res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,8 +246,6 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
uint8_t keylen = 0;
|
uint8_t keylen = 0;
|
||||||
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE_P(spi_flash_pages), sizeof(uint8_t));
|
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE_P(spi_flash_pages), sizeof(uint8_t));
|
||||||
|
|
||||||
char spiffsDest[32] = {0};
|
|
||||||
|
|
||||||
switch (d) {
|
switch (d) {
|
||||||
case DICTIONARY_MIFARE: {
|
case DICTIONARY_MIFARE: {
|
||||||
keylen = MF_KEY_LENGTH;
|
keylen = MF_KEY_LENGTH;
|
||||||
|
@ -304,36 +292,6 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
strcpy(spiffsDest, ICLASS_KEYS_FILE);
|
strcpy(spiffsDest, ICLASS_KEYS_FILE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DICTIONARY_MIFARE_ULC: {
|
|
||||||
keylen = MFULC_KEY_LENGTH;
|
|
||||||
res = loadFileDICTIONARY(filename, data, &datalen, keylen, &keycount);
|
|
||||||
if (res || !keycount) {
|
|
||||||
free(data);
|
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
|
||||||
if (datalen > FLASH_MEM_MAX_SIZE_P(spi_flash_pages)) {
|
|
||||||
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
|
|
||||||
free(data);
|
|
||||||
return PM3_EOVFLOW;
|
|
||||||
}
|
|
||||||
strcpy(spiffsDest, MFULC_KEYS_FILE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DICTIONARY_MIFARE_ULAES: {
|
|
||||||
keylen = MFULAES_KEY_LENGTH;
|
|
||||||
res = loadFileDICTIONARY(filename, data, &datalen, keylen, &keycount);
|
|
||||||
if (res || !keycount) {
|
|
||||||
free(data);
|
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
|
||||||
if (datalen > FLASH_MEM_MAX_SIZE_P(spi_flash_pages)) {
|
|
||||||
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
|
|
||||||
free(data);
|
|
||||||
return PM3_EOVFLOW;
|
|
||||||
}
|
|
||||||
strcpy(spiffsDest, MFULAES_KEYS_FILE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DICTIONARY_NONE: {
|
case DICTIONARY_NONE: {
|
||||||
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
|
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
|
@ -372,12 +330,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
free(data);
|
free(data);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d == DICTIONARY_T55XX) {
|
|
||||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")" passwords to file "_GREEN_("%s"), keycount, spiffsDest);
|
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")" passwords to file "_GREEN_("%s"), keycount, spiffsDest);
|
||||||
} else {
|
|
||||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%u")" keys to file "_GREEN_("%s"), keycount, spiffsDest);
|
|
||||||
}
|
|
||||||
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
||||||
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -776,7 +729,6 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "{ SPI File system }"},
|
{"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "{ SPI File system }"},
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"-----------", CmdHelp, IfPm3Flash, "------------------- " _CYAN_("Operations") " -------------------"},
|
|
||||||
{"baudrate", CmdFlashmemSpiBaud, IfPm3Flash, "Set Flash memory Spi baudrate"},
|
{"baudrate", CmdFlashmemSpiBaud, IfPm3Flash, "Set Flash memory Spi baudrate"},
|
||||||
{"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"},
|
{"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"},
|
||||||
{"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"},
|
{"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"},
|
||||||
|
|
|
@ -26,9 +26,7 @@ typedef enum {
|
||||||
DICTIONARY_NONE = 0,
|
DICTIONARY_NONE = 0,
|
||||||
DICTIONARY_MIFARE,
|
DICTIONARY_MIFARE,
|
||||||
DICTIONARY_T55XX,
|
DICTIONARY_T55XX,
|
||||||
DICTIONARY_ICLASS,
|
DICTIONARY_ICLASS
|
||||||
DICTIONARY_MIFARE_ULC,
|
|
||||||
DICTIONARY_MIFARE_ULAES,
|
|
||||||
} Dictionary_t;
|
} Dictionary_t;
|
||||||
|
|
||||||
int CmdFlashMem(const char *Cmd);
|
int CmdFlashMem(const char *Cmd);
|
||||||
|
|
|
@ -231,13 +231,11 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DropField();
|
|
||||||
|
|
||||||
PROMPT_CLEARLINE;
|
PROMPT_CLEARLINE;
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(WARNING, _RED_("No known/supported 13.56 MHz tags found"));
|
PrintAndLogEx(WARNING, _RED_("No known/supported 13.56 MHz tags found"));
|
||||||
return res;
|
res = PM3_ESOFT;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// no need to print 14A hints, since it will print itself
|
// no need to print 14A hints, since it will print itself
|
||||||
|
|
||||||
|
@ -284,7 +282,9 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
if (success[PROTO_CRYPTORF]) {
|
if (success[PROTO_CRYPTORF]) {
|
||||||
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropField();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +477,7 @@ int CmdHFSniff(const char *Cmd) {
|
||||||
|
|
||||||
if (kbd_enter_pressed()) {
|
if (kbd_enter_pressed()) {
|
||||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
PrintAndLogEx(WARNING, "\naborted via keyboard!");
|
PrintAndLogEx(INFO, "User aborted");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -880,7 +880,6 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
"hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"
|
"hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"
|
||||||
"hf 14a sim -t 11 -> Javacard (JCOP)\n"
|
"hf 14a sim -t 11 -> Javacard (JCOP)\n"
|
||||||
"hf 14a sim -t 12 -> 4K Seos card\n"
|
"hf 14a sim -t 12 -> 4K Seos card\n"
|
||||||
"hf 14a sim -t 13 -> MIFARE Ultralight C"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -891,8 +890,6 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
arg_lit0("x", NULL, "Performs the 'reader attack', nr/ar attack against a reader"),
|
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(NULL, "sk", "Fill simulator keys from found keys"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -926,12 +923,9 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
bool setEmulatorMem = arg_get_lit(ctx, 5);
|
bool setEmulatorMem = arg_get_lit(ctx, 5);
|
||||||
bool verbose = arg_get_lit(ctx, 6);
|
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);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (tagtype > 13) {
|
if (tagtype > 12) {
|
||||||
PrintAndLogEx(ERR, "Undefined tag %d", tagtype);
|
PrintAndLogEx(ERR, "Undefined tag %d", tagtype);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -945,16 +939,11 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint8_t uid[10];
|
uint8_t uid[10];
|
||||||
uint8_t exitAfter;
|
uint8_t exitAfter;
|
||||||
uint8_t rats[20];
|
|
||||||
bool ulc_p1;
|
|
||||||
bool ulc_p2;
|
|
||||||
} PACKED payload;
|
} PACKED payload;
|
||||||
|
|
||||||
payload.tagtype = tagtype;
|
payload.tagtype = tagtype;
|
||||||
payload.flags = flags;
|
payload.flags = flags;
|
||||||
payload.exitAfter = exitAfterNReads;
|
payload.exitAfter = exitAfterNReads;
|
||||||
payload.ulc_p1 = ulc_p1;
|
|
||||||
payload.ulc_p2 = ulc_p2;
|
|
||||||
memcpy(payload.uid, uid, uid_len);
|
memcpy(payload.uid, uid, uid_len);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -968,17 +957,14 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
bool keypress = kbd_enter_pressed();
|
bool keypress = kbd_enter_pressed();
|
||||||
while (keypress == false) {
|
while (keypress == false) {
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == false) {
|
if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == false)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.status != PM3_SUCCESS) {
|
if (resp.status != PM3_SUCCESS)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) {
|
if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
const nonces_t *data = (nonces_t *)resp.data.asBytes;
|
const nonces_t *data = (nonces_t *)resp.data.asBytes;
|
||||||
readerAttack(k_sector, k_sectors_cnt, data[0], setEmulatorMem, verbose);
|
readerAttack(k_sector, k_sectors_cnt, data[0], setEmulatorMem, verbose);
|
||||||
|
@ -1330,7 +1316,7 @@ static int CmdExchangeAPDU(bool chainingin, const uint8_t *datain, int datainlen
|
||||||
|
|
||||||
// Button pressed / user cancelled
|
// Button pressed / user cancelled
|
||||||
if (iLen == -3) {
|
if (iLen == -3) {
|
||||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
PrintAndLogEx(DEBUG, "ERR: APDU: User aborted");
|
||||||
return PM3_EAPDU_FAIL;
|
return PM3_EAPDU_FAIL;
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -3147,18 +3133,18 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||||
if (isMifareClassic || isMifareMini) {
|
if (isMifareClassic || isMifareMini) {
|
||||||
res = detect_classic_static_nonce();
|
res = detect_classic_static_nonce();
|
||||||
if (res == NONCE_STATIC) {
|
if (res == NONCE_STATIC) {
|
||||||
PrintAndLogEx(SUCCESS, "Static nonce....... " _YELLOW_("yes"));
|
PrintAndLogEx(SUCCESS, "Static nonce......... " _YELLOW_("yes"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == NONCE_NORMAL) {
|
if (res == NONCE_NORMAL) {
|
||||||
// not static
|
// not static
|
||||||
res = detect_classic_prng();
|
res = detect_classic_prng();
|
||||||
if (res == 1) {
|
if (res == 1) {
|
||||||
PrintAndLogEx(SUCCESS, "Prng detection..... " _GREEN_("weak"));
|
PrintAndLogEx(SUCCESS, "Prng detection....... " _GREEN_("weak"));
|
||||||
} else if (res == 0) {
|
} else if (res == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Prng detection..... " _YELLOW_("hard"));
|
PrintAndLogEx(SUCCESS, "Prng detection....... " _YELLOW_("hard"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(FAILED, "Prng detection...... " _RED_("fail"));
|
PrintAndLogEx(FAILED, "Prng detection........ " _RED_("fail"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_nack_test) {
|
if (do_nack_test) {
|
||||||
|
|
|
@ -2708,32 +2708,25 @@ static int CmdHF14BCalypsoRead(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
transport_14b_apdu_t cmds[] = {
|
transport_14b_apdu_t cmds[] = {
|
||||||
{"01.Select ICC ", "\x94\xa4\x08\x00\x04\x3f\x00\x00\x02", 9},
|
{"01.Select ICC file", "\x94\xa4\x08\x00\x04\x3f\x00\x00\x02", 9},
|
||||||
{"02.ICC ", "\x94\xb2\x01\x04\x1d", 5},
|
{"02.ICC", "\x94\xb2\x01\x04\x1d", 5},
|
||||||
{"03.Select EnvHol ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x01", 9},
|
{"03.Select EnvHol file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x01", 9},
|
||||||
{"04.EnvHol1 ", "\x94\xb2\x01\x04\x1d", 5},
|
{"04.EnvHol1", "\x94\xb2\x01\x04\x1d", 5},
|
||||||
{"05.Select EvLog ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x10", 9},
|
{"05.Select EvLog file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x10", 9},
|
||||||
{"06.EvLog1 ", "\x94\xb2\x01\x04\x1d", 5},
|
{"06.EvLog1", "\x94\xb2\x01\x04\x1d", 5},
|
||||||
{"07.EvLog2 ", "\x94\xb2\x02\x04\x1d", 5},
|
{"07.EvLog2", "\x94\xb2\x02\x04\x1d", 5},
|
||||||
{"08.EvLog3 ", "\x94\xb2\x03\x04\x1d", 5},
|
{"08.EvLog3", "\x94\xb2\x03\x04\x1d", 5},
|
||||||
{"09.Select ConList ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x50", 9},
|
{"09.Select ConList file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x50", 9},
|
||||||
{"10.ConList ", "\x94\xb2\x01\x04\x1d", 5},
|
{"10.ConList", "\x94\xb2\x01\x04\x1d", 5},
|
||||||
{"11.Select Contra ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x20", 9},
|
{"11.Select Contra file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x20", 9},
|
||||||
{"12.Contra1 ", "\x94\xb2\x01\x04\x1d", 5},
|
{"12.Contra1", "\x94\xb2\x01\x04\x1d", 5},
|
||||||
{"13.Contra2 ", "\x94\xb2\x02\x04\x1d", 5},
|
{"13.Contra2", "\x94\xb2\x02\x04\x1d", 5},
|
||||||
{"14.Contra3 ", "\x94\xb2\x03\x04\x1d", 5},
|
{"14.Contra3", "\x94\xb2\x03\x04\x1d", 5},
|
||||||
{"15.Contra4 ", "\x94\xb2\x04\x04\x1d", 5},
|
{"15.Contra4", "\x94\xb2\x04\x04\x1d", 5},
|
||||||
{"16.Select Counter ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x69", 9},
|
{"16.Select Counter file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x69", 9},
|
||||||
{"17.Counter ", "\x94\xb2\x01\x04\x1d", 5},
|
{"17.Counter", "\x94\xb2\x01\x04\x1d", 5},
|
||||||
{"18.Select SpecEv ", "\x94\xa4\x08\x00\x04\x20\x00\x20\x40", 9},
|
{"18.Select SpecEv file", "\x94\xa4\x08\x00\x04\x20\x00\x20\x40", 9},
|
||||||
{"19.SpecEv1 ", "\x94\xb2\x01\x04\x1d", 5},
|
{"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},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2787,8 +2780,9 @@ static int CmdHF14BCalypsoRead(const char *Cmd) {
|
||||||
|
|
||||||
uint16_t sw = get_sw(response, resplen);
|
uint16_t sw = get_sw(response, resplen);
|
||||||
if (sw != ISO7816_OK) {
|
if (sw != ISO7816_OK) {
|
||||||
PrintAndLogEx(INFO, "%s - command failed (%04x - %s).", cmds[i].desc, sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
PrintAndLogEx(ERR, "Sending command failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||||
continue;
|
switch_off_field_14b();
|
||||||
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "%s - %s", cmds[i].desc, sprint_hex(response, resplen));
|
PrintAndLogEx(INFO, "%s - %s", cmds[i].desc, sprint_hex(response, resplen));
|
||||||
|
@ -3079,7 +3073,7 @@ plot:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (loop && (kbd_enter_pressed() == false));
|
} while (loop && kbd_enter_pressed() == false);
|
||||||
|
|
||||||
if (verbose && found == false) {
|
if (verbose && found == false) {
|
||||||
PrintAndLogEx(FAILED, "no ISO 14443-B tag found");
|
PrintAndLogEx(FAILED, "no ISO 14443-B tag found");
|
||||||
|
|
|
@ -50,6 +50,22 @@
|
||||||
#define Logic1 Iso15693Logic1
|
#define Logic1 Iso15693Logic1
|
||||||
#define FrameEOF Iso15693FrameEOF
|
#define FrameEOF Iso15693FrameEOF
|
||||||
#define CARD_MEMORY_SIZE 4096
|
#define CARD_MEMORY_SIZE 4096
|
||||||
|
#define HF15_UID_LENGTH 8
|
||||||
|
|
||||||
|
#ifndef Crc15
|
||||||
|
# define Crc15(data, len) Crc16ex(CRC_15693, (data), (len))
|
||||||
|
#endif
|
||||||
|
#ifndef CheckCrc15
|
||||||
|
# define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len))
|
||||||
|
#endif
|
||||||
|
#ifndef AddCrc15
|
||||||
|
#define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ISO15_RAW_LEN
|
||||||
|
#define ISO15_RAW_LEN(x) (sizeof(iso15_raw_cmd_t) + (x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef ISO15_ERROR_HANDLING_RESPONSE
|
#ifndef ISO15_ERROR_HANDLING_RESPONSE
|
||||||
#define ISO15_ERROR_HANDLING_RESPONSE { \
|
#define ISO15_ERROR_HANDLING_RESPONSE { \
|
||||||
|
@ -82,11 +98,6 @@
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t lock;
|
|
||||||
uint8_t block[8];
|
|
||||||
} t15memory_t;
|
|
||||||
|
|
||||||
// structure and database for uid -> tagtype lookups
|
// structure and database for uid -> tagtype lookups
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
|
@ -463,7 +474,7 @@ static int getUID(bool verbose, bool loop, uint8_t *buf) {
|
||||||
|
|
||||||
// used with 'hf search'
|
// used with 'hf search'
|
||||||
bool readHF15Uid(bool loop, bool verbose) {
|
bool readHF15Uid(bool loop, bool verbose) {
|
||||||
uint8_t uid[ISO15693_UID_LENGTH] = {0};
|
uint8_t uid[HF15_UID_LENGTH] = {0};
|
||||||
if (getUID(verbose, loop, uid) != PM3_SUCCESS) {
|
if (getUID(verbose, loop, uid) != PM3_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +665,7 @@ static int NxpTestEAS(const uint8_t *uid) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t approxlen = 3 + ISO15693_UID_LENGTH + 2;
|
uint8_t approxlen = 3 + HF15_UID_LENGTH + 2;
|
||||||
iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen);
|
iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen);
|
||||||
if (packet == NULL) {
|
if (packet == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||||
|
@ -666,8 +677,8 @@ static int NxpTestEAS(const uint8_t *uid) {
|
||||||
packet->raw[packet->rawlen++] = ISO15693_EAS_ALARM;
|
packet->raw[packet->rawlen++] = ISO15693_EAS_ALARM;
|
||||||
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
||||||
|
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH); // add UID
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); // add UID
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
|
|
||||||
AddCrc15(packet->raw, packet->rawlen);
|
AddCrc15(packet->raw, packet->rawlen);
|
||||||
packet->rawlen += 2;
|
packet->rawlen += 2;
|
||||||
|
@ -709,7 +720,7 @@ static int NxpCheckSig(uint8_t *uid) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t approxlen = 3 + ISO15693_UID_LENGTH + 2;
|
uint8_t approxlen = 3 + HF15_UID_LENGTH + 2;
|
||||||
iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen);
|
iso15_raw_cmd_t *packet = (iso15_raw_cmd_t *)calloc(1, sizeof(iso15_raw_cmd_t) + approxlen);
|
||||||
if (packet == NULL) {
|
if (packet == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||||
|
@ -722,8 +733,8 @@ static int NxpCheckSig(uint8_t *uid) {
|
||||||
packet->raw[packet->rawlen++] = ISO15693_READ_SIGNATURE;
|
packet->raw[packet->rawlen++] = ISO15693_READ_SIGNATURE;
|
||||||
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
||||||
|
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH); // add UID
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH); // add UID
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
|
|
||||||
AddCrc15(packet->raw, packet->rawlen);
|
AddCrc15(packet->raw, packet->rawlen);
|
||||||
packet->rawlen += 2;
|
packet->rawlen += 2;
|
||||||
|
@ -776,7 +787,7 @@ static int NxpSysInfo(uint8_t *uid) {
|
||||||
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
packet->raw[packet->rawlen++] = 0x04; // IC manufacturer code
|
||||||
|
|
||||||
memcpy(packet->raw + 3, uid, 8); // add UID
|
memcpy(packet->raw + 3, uid, 8); // add UID
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
|
|
||||||
AddCrc15(packet->raw, packet->rawlen);
|
AddCrc15(packet->raw, packet->rawlen);
|
||||||
packet->rawlen += 2;
|
packet->rawlen += 2;
|
||||||
|
@ -889,11 +900,11 @@ static int StCheckSig(uint8_t *uid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ISO15693 Protocol params
|
// ISO15693 Protocol params
|
||||||
packet->raw[packet->rawlen++] = arg_get_raw_flag(ISO15693_UID_LENGTH, false, false, false);
|
packet->raw[packet->rawlen++] = arg_get_raw_flag(HF15_UID_LENGTH, false, false, false);
|
||||||
packet->raw[packet->rawlen++] = ISO15693_READBLOCK;
|
packet->raw[packet->rawlen++] = ISO15693_READBLOCK;
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
packet->flags = (ISO15_CONNECT | ISO15_READ_RESPONSE | ISO15_NO_DISCONNECT);
|
packet->flags = (ISO15_CONNECT | ISO15_READ_RESPONSE | ISO15_NO_DISCONNECT);
|
||||||
uint16_t blkoff = packet->rawlen;
|
uint16_t blkoff = packet->rawlen;
|
||||||
char signature_hex[65] = {0};
|
char signature_hex[65] = {0};
|
||||||
|
@ -932,9 +943,9 @@ static int StCheckSig(uint8_t *uid) {
|
||||||
uint8_t signature[16];
|
uint8_t signature[16];
|
||||||
size_t signature_len;
|
size_t signature_len;
|
||||||
hexstr_to_byte_array(signature_hex, signature, &signature_len);
|
hexstr_to_byte_array(signature_hex, signature, &signature_len);
|
||||||
uint8_t uid_swap[ISO15693_UID_LENGTH];
|
uint8_t uid_swap[HF15_UID_LENGTH];
|
||||||
reverse_array_copy(uid, ISO15693_UID_LENGTH, uid_swap);
|
reverse_array_copy(uid, HF15_UID_LENGTH, uid_swap);
|
||||||
int index = originality_check_verify_ex(uid_swap, ISO15693_UID_LENGTH, signature, signature_len, PK_ST25TV, false, true);
|
int index = originality_check_verify_ex(uid_swap, HF15_UID_LENGTH, signature, signature_len, PK_ST25TV, false, true);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return originality_check_print(signature, signature_len, index);
|
return originality_check_print(signature, signature_len, index);
|
||||||
}
|
}
|
||||||
|
@ -959,7 +970,7 @@ static int CmdHF15Info(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
|
@ -976,7 +987,7 @@ static int CmdHF15Info(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// default fallback to scan for tag.
|
// default fallback to scan for tag.
|
||||||
if (unaddressed == false && uidlen != ISO15693_UID_LENGTH) {
|
if (unaddressed == false && uidlen != HF15_UID_LENGTH) {
|
||||||
scan = true;
|
scan = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,10 +1014,10 @@ static int CmdHF15Info(const char *Cmd) {
|
||||||
free(packet);
|
free(packet);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uidlen = ISO15693_UID_LENGTH;
|
uidlen = HF15_UID_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uidlen == ISO15693_UID_LENGTH) {
|
if (uidlen == HF15_UID_LENGTH) {
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(packet->raw + packet->rawlen, uid, uidlen);
|
memcpy(packet->raw + packet->rawlen, uid, uidlen);
|
||||||
packet->rawlen += uidlen;
|
packet->rawlen += uidlen;
|
||||||
|
@ -1240,11 +1251,8 @@ static int CmdHF15ELoad(const char *Cmd) {
|
||||||
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
||||||
(tag->pagesCount == 0) ||
|
(tag->pagesCount == 0) ||
|
||||||
(tag->bytesPerPage == 0)) {
|
(tag->bytesPerPage == 0)) {
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
||||||
tag->pagesCount,
|
tag->pagesCount, tag->bytesPerPage);
|
||||||
tag->bytesPerPage
|
|
||||||
);
|
|
||||||
free(tag);
|
free(tag);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1478,7 +1486,7 @@ static int CmdHF15Sim(const char *Cmd) {
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
uint8_t block_size;
|
uint8_t block_size;
|
||||||
} PACKED payload;
|
} PACKED payload;
|
||||||
memset(&payload, 0, sizeof(payload));
|
memset(&payload, 0, sizeof(payload));
|
||||||
|
@ -1489,7 +1497,7 @@ static int CmdHF15Sim(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if (uidlen != 0 && uidlen != ISO15693_UID_LENGTH) {
|
if (uidlen != 0 && uidlen != HF15_UID_LENGTH) {
|
||||||
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got ( " _RED_("%i") " )", uidlen);
|
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got ( " _RED_("%i") " )", uidlen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1616,7 +1624,7 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
||||||
struct {
|
struct {
|
||||||
uint8_t pwd[4];
|
uint8_t pwd[4];
|
||||||
bool use_pwd;
|
bool use_pwd;
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
bool use_uid;
|
bool use_uid;
|
||||||
uint8_t afi;
|
uint8_t afi;
|
||||||
} PACKED payload;
|
} PACKED payload;
|
||||||
|
@ -1637,7 +1645,7 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
payload.use_uid = false;
|
payload.use_uid = false;
|
||||||
if (uidlen == ISO15693_UID_LENGTH) {
|
if (uidlen == HF15_UID_LENGTH) {
|
||||||
payload.use_uid = true;
|
payload.use_uid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1695,7 +1703,7 @@ static int CmdHF15WriteDsfid(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH] = {0};
|
uint8_t uid[HF15_UID_LENGTH] = {0};
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
|
||||||
|
@ -1734,10 +1742,10 @@ static int CmdHF15WriteDsfid(const char *Cmd) {
|
||||||
free(packet);
|
free(packet);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uidlen = ISO15693_UID_LENGTH;
|
uidlen = HF15_UID_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uidlen == ISO15693_UID_LENGTH) {
|
if (uidlen == HF15_UID_LENGTH) {
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(packet->raw + packet->rawlen, uid, uidlen);
|
memcpy(packet->raw + packet->rawlen, uid, uidlen);
|
||||||
packet->rawlen += uidlen;
|
packet->rawlen += uidlen;
|
||||||
|
@ -1799,7 +1807,7 @@ static int CmdHF15Dump(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH] = {0};
|
uint8_t uid[HF15_UID_LENGTH] = {0};
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
|
||||||
|
@ -1830,7 +1838,7 @@ static int CmdHF15Dump(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// default fallback to scan for tag.
|
// default fallback to scan for tag.
|
||||||
if (uidlen != ISO15693_UID_LENGTH && !unaddressed) {
|
if (uidlen != HF15_UID_LENGTH && !unaddressed) {
|
||||||
scan = true;
|
scan = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1866,11 +1874,11 @@ static int CmdHF15Dump(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
used_uid = true;
|
used_uid = true;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||||
|
@ -1907,47 +1915,33 @@ static int CmdHF15Dump(const char *Cmd) {
|
||||||
uint8_t dCpt = 10;
|
uint8_t dCpt = 10;
|
||||||
|
|
||||||
int res = iso15_error_handling_card_response(d, resp.length);
|
int res = iso15_error_handling_card_response(d, resp.length);
|
||||||
if (res == PM3_ECRC) {
|
if (res != PM3_SUCCESS) {
|
||||||
free(tag);
|
free(tag);
|
||||||
free(packet);
|
free(packet);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == PM3_SUCCESS) {
|
memcpy(tag->uid, &d[2], 8);
|
||||||
memcpy(tag->uid, d + 2, 8);
|
|
||||||
|
|
||||||
if (d[1] & 0x01) {
|
if (d[1] & 0x01) {
|
||||||
tag->dsfid = d[dCpt];
|
tag->dsfid = d[dCpt++];
|
||||||
}
|
}
|
||||||
dCpt++;
|
|
||||||
|
|
||||||
if (d[1] & 0x02) {
|
if (d[1] & 0x02) {
|
||||||
tag->afi = d[dCpt];
|
tag->afi = d[dCpt++];
|
||||||
}
|
}
|
||||||
dCpt++;
|
|
||||||
|
|
||||||
if (d[1] & 0x04) {
|
if (d[1] & 0x04) {
|
||||||
tag->pagesCount = d[dCpt] + 1;
|
tag->pagesCount = d[dCpt++] + 1;
|
||||||
tag->bytesPerPage = d[dCpt + 1] + 1;
|
tag->bytesPerPage = d[dCpt++] + 1;
|
||||||
} else {
|
} else {
|
||||||
// Set tag memory layout values (if can't be read in SYSINFO)
|
// Set tag memory layout values (if can't be read in SYSINFO)
|
||||||
tag->bytesPerPage = blocksize;
|
tag->bytesPerPage = blocksize;
|
||||||
tag->pagesCount = 128;
|
tag->pagesCount = 128;
|
||||||
}
|
}
|
||||||
dCpt += 2;
|
|
||||||
|
|
||||||
if (d[1] & 0x08) {
|
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)
|
// add length for blockno (1)
|
||||||
|
@ -2184,10 +2178,10 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH] = {0x00};
|
uint8_t uid[HF15_UID_LENGTH] = {0x00};
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter.
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
|
@ -2245,11 +2239,11 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||||
|
@ -2261,9 +2255,7 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
|
|
||||||
// 0 means 1 page,
|
// 0 means 1 page,
|
||||||
// 1 means 2 pages, ...
|
// 1 means 2 pages, ...
|
||||||
if (blockcnt > 0) {
|
if (blockcnt > 0) blockcnt--;
|
||||||
blockcnt--;
|
|
||||||
}
|
|
||||||
|
|
||||||
packet->raw[packet->rawlen++] = blockno;
|
packet->raw[packet->rawlen++] = blockno;
|
||||||
packet->raw[packet->rawlen++] = blockcnt;
|
packet->raw[packet->rawlen++] = blockcnt;
|
||||||
|
@ -2293,7 +2285,7 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
ISO15_ERROR_HANDLING_CARD_RESPONSE(d, resp.length)
|
ISO15_ERROR_HANDLING_CARD_RESPONSE(d, resp.length)
|
||||||
|
|
||||||
// 1 byte cmd, 1 lock byte, 4 / 8 bytes block size, 2 crc
|
// 1 byte cmd, 1 lock byte, 4 / 8 bytes block size, 2 crc
|
||||||
if (resp.length > (1 + ((blockcnt + 1) * (blocksize + 1)) + 2)) {
|
if (resp.length > (1 + (blockcnt * (blocksize + 1)) + 2)) {
|
||||||
PrintAndLogEx(WARNING, "got longer response. Check block size!");
|
PrintAndLogEx(WARNING, "got longer response. Check block size!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2344,10 +2336,10 @@ static int CmdHF15Readblock(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
|
@ -2401,11 +2393,11 @@ static int CmdHF15Readblock(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||||
|
@ -2498,8 +2490,8 @@ static int hf_15_write_blk(const uint8_t *pm3flags, uint16_t flags, const uint8_
|
||||||
|
|
||||||
// add UID
|
// add UID
|
||||||
if (uid) {
|
if (uid) {
|
||||||
memcpy(packet->raw + packet->rawlen, uid, ISO15693_UID_LENGTH);
|
memcpy(packet->raw + packet->rawlen, uid, HF15_UID_LENGTH);
|
||||||
packet->rawlen += ISO15693_UID_LENGTH;
|
packet->rawlen += HF15_UID_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet->raw[packet->rawlen++] = blockno;
|
packet->raw[packet->rawlen++] = blockno;
|
||||||
|
@ -2558,10 +2550,10 @@ static int CmdHF15Write(const char *Cmd) {
|
||||||
argtable[arglen++] = arg_param_end;
|
argtable[arglen++] = arg_param_end;
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
|
@ -2597,7 +2589,7 @@ static int CmdHF15Write(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||||
|
@ -2632,7 +2624,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
||||||
"hf 15 restore -u E011223344556677 -f hf-15-my-dump.bin"
|
"hf 15 restore -u E011223344556677 -f hf-15-my-dump.bin"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[6 + 4] = {0};
|
void *argtable[6 + 5] = {0};
|
||||||
uint8_t arglen = arg_add_default(argtable);
|
uint8_t arglen = arg_add_default(argtable);
|
||||||
argtable[arglen++] = arg_str0("f", "file", "<fn>", "Specify a filename for dump file");
|
argtable[arglen++] = arg_str0("f", "file", "<fn>", "Specify a filename for dump file");
|
||||||
argtable[arglen++] = arg_int0("r", "retry", "<dec>", "number of retries (def 3)");
|
argtable[arglen++] = arg_int0("r", "retry", "<dec>", "number of retries (def 3)");
|
||||||
|
@ -2640,7 +2632,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
||||||
argtable[arglen++] = arg_param_end;
|
argtable[arglen++] = arg_param_end;
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
|
||||||
|
@ -2670,7 +2662,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
||||||
|
|
||||||
// default fallback to scan for tag.
|
// default fallback to scan for tag.
|
||||||
// overriding unaddress parameter :)
|
// overriding unaddress parameter :)
|
||||||
if (uidlen != ISO15693_UID_LENGTH) {
|
if (uidlen != HF15_UID_LENGTH) {
|
||||||
scan = true;
|
scan = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2682,7 +2674,7 @@ static int CmdHF15Restore(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||||
|
@ -2721,11 +2713,8 @@ static int CmdHF15Restore(const char *Cmd) {
|
||||||
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
||||||
(tag->pagesCount == 0) ||
|
(tag->pagesCount == 0) ||
|
||||||
(tag->bytesPerPage == 0)) {
|
(tag->bytesPerPage == 0)) {
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
||||||
tag->pagesCount,
|
tag->pagesCount, tag->bytesPerPage);
|
||||||
tag->bytesPerPage
|
|
||||||
);
|
|
||||||
free(tag);
|
free(tag);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -2756,8 +2745,8 @@ static int CmdHF15Restore(const char *Cmd) {
|
||||||
|
|
||||||
for (tried = 0; tried < retries; tried++) {
|
for (tried = 0; tried < retries; tried++) {
|
||||||
|
|
||||||
retval = hf_15_write_blk(&pm3flags, flags, uid, fast, i, data, tag->bytesPerPage);
|
retval = hf_15_write_blk(&pm3flags, flags, uid, fast
|
||||||
|
, i, data, tag->bytesPerPage);
|
||||||
if (retval == PM3_SUCCESS) {
|
if (retval == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(INPLACE, "blk %3d", i);
|
PrintAndLogEx(INPLACE, "blk %3d", i);
|
||||||
|
|
||||||
|
@ -2820,7 +2809,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
} PACKED payload;
|
} PACKED payload;
|
||||||
|
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
|
@ -2828,7 +2817,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
bool use_v2 = arg_get_lit(ctx, 2);
|
bool use_v2 = arg_get_lit(ctx, 2);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (uidlen != ISO15693_UID_LENGTH) {
|
if (uidlen != HF15_UID_LENGTH) {
|
||||||
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got " _RED_("%i"), uidlen);
|
PrintAndLogEx(WARNING, "UID must include 8 hex bytes, got " _RED_("%i"), uidlen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -2842,7 +2831,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Get current tag");
|
PrintAndLogEx(INFO, "Get current tag");
|
||||||
|
|
||||||
uint8_t carduid[ISO15693_UID_LENGTH] = {0x00};
|
uint8_t carduid[HF15_UID_LENGTH] = {0x00};
|
||||||
if (getUID(true, false, carduid) != PM3_SUCCESS) {
|
if (getUID(true, false, carduid) != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(FAILED, "no tag found");
|
PrintAndLogEx(FAILED, "no tag found");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -2872,10 +2861,10 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse cardUID to compare
|
// reverse cardUID to compare
|
||||||
uint8_t revuid[ISO15693_UID_LENGTH] = {0};
|
uint8_t revuid[HF15_UID_LENGTH] = {0};
|
||||||
reverse_array_copy(carduid, sizeof(carduid), revuid);
|
reverse_array_copy(carduid, sizeof(carduid), revuid);
|
||||||
|
|
||||||
if (memcmp(revuid, payload.uid, ISO15693_UID_LENGTH) == 0) {
|
if (memcmp(revuid, payload.uid, HF15_UID_LENGTH) == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Setting new UID ( " _GREEN_("ok") " )");
|
PrintAndLogEx(SUCCESS, "Setting new UID ( " _GREEN_("ok") " )");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;;
|
return PM3_SUCCESS;;
|
||||||
|
@ -3489,11 +3478,8 @@ static int CmdHF15View(const char *Cmd) {
|
||||||
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) ||
|
||||||
(tag->pagesCount == 0) ||
|
(tag->pagesCount == 0) ||
|
||||||
(tag->bytesPerPage == 0)) {
|
(tag->bytesPerPage == 0)) {
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d",
|
||||||
tag->pagesCount,
|
tag->pagesCount, tag->bytesPerPage);
|
||||||
tag->bytesPerPage
|
|
||||||
);
|
|
||||||
free(tag);
|
free(tag);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -3512,15 +3498,15 @@ static int CmdHF15Wipe(const char *Cmd) {
|
||||||
);
|
);
|
||||||
void *argtable[6 + 3] = {0};
|
void *argtable[6 + 3] = {0};
|
||||||
uint8_t arglen = arg_add_default(argtable);
|
uint8_t arglen = arg_add_default(argtable);
|
||||||
argtable[arglen++] = arg_int0(NULL, "bs", "<dec>", "block size (def 4)");
|
argtable[arglen++] = arg_int0(NULL, "bs", "<dec>", "block size (def 4)"),
|
||||||
argtable[arglen++] = arg_lit0("v", "verbose", "verbose output");
|
argtable[arglen++] = arg_lit0("v", "verbose", "verbose output");
|
||||||
argtable[arglen++] = arg_param_end;
|
argtable[arglen++] = arg_param_end;
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
uint8_t uid[ISO15693_UID_LENGTH];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
bool uid_set = (uidlen == ISO15693_UID_LENGTH) ? true : false;
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; // Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
|
@ -3552,7 +3538,7 @@ static int CmdHF15Wipe(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reverse_array(uid, ISO15693_UID_LENGTH);
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Using unaddressed mode");
|
PrintAndLogEx(INFO, "Using unaddressed mode");
|
||||||
|
|
|
@ -20,24 +20,9 @@
|
||||||
#define CMDHF15_H__
|
#define CMDHF15_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "crc16.h"
|
|
||||||
#include "iso15.h" // typedef structs / enum
|
|
||||||
|
|
||||||
#ifndef Crc15
|
|
||||||
# define Crc15(data, len) Crc16ex(CRC_15693, (data), (len))
|
|
||||||
#endif
|
|
||||||
#ifndef CheckCrc15
|
|
||||||
# define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len))
|
|
||||||
#endif
|
|
||||||
#ifndef AddCrc15
|
|
||||||
#define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ISO15_RAW_LEN
|
|
||||||
#define ISO15_RAW_LEN(x) (sizeof(iso15_raw_cmd_t) + (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int CmdHF15(const char *Cmd);
|
int CmdHF15(const char *Cmd);
|
||||||
|
|
||||||
bool readHF15Uid(bool loop, bool verbose);
|
bool readHF15Uid(bool loop, bool verbose);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -232,7 +232,8 @@ int readHFCryptoRF(bool loop, bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex_inrow(card.uid, card.uidlen));
|
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex_inrow(card.uid, card.uidlen));
|
||||||
set_last_known_card(card);
|
set_last_known_card(card);
|
||||||
}
|
}
|
||||||
} while (loop && (kbd_enter_pressed() == false));
|
} while (loop && kbd_enter_pressed() == false);
|
||||||
|
|
||||||
DropField();
|
DropField();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,5 @@ int CmdHFFelica(const char *Cmd);
|
||||||
int read_felica_uid(bool loop, bool verbose);
|
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_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_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
|
#endif
|
||||||
|
|
|
@ -199,7 +199,7 @@ int read_fudan_uid(bool loop, bool verbose) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (loop && (kbd_enter_pressed() == false));
|
} while (loop && kbd_enter_pressed() == false);
|
||||||
|
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -1135,7 +1135,7 @@ int read_iclass_csn(bool loop, bool verbose, bool shallow_mod) {
|
||||||
res = PM3_EMALLOC;
|
res = PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (loop && (kbd_enter_pressed() == false));
|
} while (loop && kbd_enter_pressed() == false);
|
||||||
|
|
||||||
DropField();
|
DropField();
|
||||||
return res;
|
return res;
|
||||||
|
@ -2130,10 +2130,9 @@ static int CmdHFiClassDump(const char *Cmd) {
|
||||||
return PM3_EOPABORTED;
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_ICLASS_DUMP, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_HF_ICLASS_DUMP, &resp, 2000))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
if (resp.status != PM3_SUCCESS) {
|
if (resp.status != PM3_SUCCESS) {
|
||||||
|
@ -2329,7 +2328,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0(NULL, "nr", "replay of NR/MAC block write or use privilege escalation if mac is empty"),
|
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -2569,7 +2568,6 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -2620,7 +2618,6 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
||||||
bool rawkey = arg_get_lit(ctx, 8);
|
bool rawkey = arg_get_lit(ctx, 8);
|
||||||
bool verbose = arg_get_lit(ctx, 9);
|
bool verbose = arg_get_lit(ctx, 9);
|
||||||
bool shallow_mod = arg_get_lit(ctx, 10);
|
bool shallow_mod = arg_get_lit(ctx, 10);
|
||||||
bool use_replay = arg_get_lit(ctx, 11);
|
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -2667,7 +2664,7 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
||||||
payload->req.use_raw = rawkey;
|
payload->req.use_raw = rawkey;
|
||||||
payload->req.use_elite = elite;
|
payload->req.use_elite = elite;
|
||||||
payload->req.use_credit_key = use_credit_key;
|
payload->req.use_credit_key = use_credit_key;
|
||||||
payload->req.use_replay = use_replay;
|
payload->req.use_replay = false;
|
||||||
payload->req.blockno = startblock;
|
payload->req.blockno = startblock;
|
||||||
payload->req.send_reply = true;
|
payload->req.send_reply = true;
|
||||||
payload->req.do_auth = true;
|
payload->req.do_auth = true;
|
||||||
|
@ -4611,7 +4608,7 @@ static int iclass_recover(uint8_t key[8], uint32_t index_start, uint32_t loop, u
|
||||||
repeat = false;
|
repeat = false;
|
||||||
} else if (resp.status == PM3_EOPABORTED) {
|
} else if (resp.status == PM3_EOPABORTED) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(WARNING, "iCLASS Key Bits Recovery: " _YELLOW_("aborted via keyboard!"));
|
PrintAndLogEx(WARNING, "iCLASS Key Bits Recovery: " _YELLOW_("user aborted"));
|
||||||
repeat = false;
|
repeat = false;
|
||||||
} else if (resp.status == PM3_ESOFT) {
|
} else if (resp.status == PM3_ESOFT) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -5060,24 +5057,6 @@ static int CmdHFiClassUnhash(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
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, "Diversified key... %s", sprint_hex_inrow(div_key, sizeof(div_key)));
|
||||||
PrintAndLogEx(INFO, "-----------------------------------");
|
PrintAndLogEx(INFO, "-----------------------------------");
|
||||||
invert_hash0(div_key);
|
invert_hash0(div_key);
|
||||||
|
@ -5230,7 +5209,7 @@ static int CmdHFiClassLookUp(const char *Cmd) {
|
||||||
item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32);
|
item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32);
|
||||||
|
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid key " _GREEN_("%s"), sprint_hex_inrow(item->key, 8));
|
PrintAndLogEx(SUCCESS, "Found valid key " _GREEN_("%s"), sprint_hex(item->key, 8));
|
||||||
add_key(item->key);
|
add_key(item->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5906,15 +5885,6 @@ static int CmdHFiClassConfigCard(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
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) {
|
static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf iclass sam",
|
CLIParserInit(&ctx, "hf iclass sam",
|
||||||
|
@ -5934,7 +5904,6 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
arg_lit0("p", "prevent", "fake epurse update"),
|
arg_lit0("p", "prevent", "fake epurse update"),
|
||||||
arg_lit0(NULL, "shallow", "shallow mod"),
|
arg_lit0(NULL, "shallow", "shallow mod"),
|
||||||
arg_strx0("d", "data", "<hex>", "DER encoded command to send to SAM"),
|
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_lit0(NULL, "info", "get SAM infos (version, serial number)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -5947,8 +5916,7 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
bool break_nrmac = arg_get_lit(ctx, 5);
|
bool break_nrmac = arg_get_lit(ctx, 5);
|
||||||
bool prevent = arg_get_lit(ctx, 6);
|
bool prevent = arg_get_lit(ctx, 6);
|
||||||
bool shallow_mod = arg_get_lit(ctx, 7);
|
bool shallow_mod = arg_get_lit(ctx, 7);
|
||||||
bool snmp_data = arg_get_lit(ctx, 9);
|
bool info = arg_get_lit(ctx, 9);
|
||||||
bool info = arg_get_lit(ctx, 10);
|
|
||||||
|
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
if (disconnect_after) {
|
if (disconnect_after) {
|
||||||
|
@ -5990,25 +5958,11 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
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();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_HF_SAM_PICOPASS, data, cmdlen + 1);
|
SendCommandNG(CMD_HF_SAM_PICOPASS, data, cmdlen + 1);
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
WaitForResponse(CMD_HF_SAM_PICOPASS, &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) {
|
switch (resp.status) {
|
||||||
case PM3_SUCCESS:
|
case PM3_SUCCESS:
|
||||||
break;
|
break;
|
||||||
|
@ -6067,24 +6021,11 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
PrintAndLogEx(SUCCESS, " hf iclass dump --nr -k %s", sprint_hex_inrow(d + 1, 8));
|
PrintAndLogEx(SUCCESS, " hf iclass dump --nr -k %s", sprint_hex_inrow(d + 1, 8));
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
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 && is_snmp == false) {
|
if (decodeTLV) {
|
||||||
asn1_print(d, d[1] + 2, " ");
|
asn1_print(d, d[1] + 2, " ");
|
||||||
} else if (decodeTLV && is_snmp) {
|
|
||||||
asn1_print(d + 6, resp.length - 6, " ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -584,7 +584,7 @@ static int CmdHF14AJookiSim(const char *Cmd) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (kbd_enter_pressed()) {
|
if (kbd_enter_pressed()) {
|
||||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
PrintAndLogEx(DEBUG, "\naborted via keyboard!");
|
PrintAndLogEx(DEBUG, "User aborted");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -560,7 +560,7 @@ static int CmdLegicSim(const char *Cmd) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (kbd_enter_pressed()) {
|
if (kbd_enter_pressed()) {
|
||||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
PrintAndLogEx(DEBUG, "Aborted via keyboard!");
|
PrintAndLogEx(DEBUG, "User aborted");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,20 +781,17 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces) {
|
||||||
}
|
}
|
||||||
int legic_get_type(legic_card_select_t *card) {
|
int legic_get_type(legic_card_select_t *card) {
|
||||||
|
|
||||||
if (card == NULL) {
|
if (card == NULL)
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_HF_LEGIC_INFO, NULL, 0);
|
SendCommandNG(CMD_HF_LEGIC_INFO, NULL, 0);
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (WaitForResponseTimeout(CMD_HF_LEGIC_INFO, &resp, 1500) == false) {
|
if (WaitForResponseTimeout(CMD_HF_LEGIC_INFO, &resp, 1500) == false)
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.status != PM3_SUCCESS) {
|
if (resp.status != PM3_SUCCESS)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(card, resp.data.asBytes, sizeof(legic_card_select_t));
|
memcpy(card, resp.data.asBytes, sizeof(legic_card_select_t));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -1530,7 +1527,7 @@ int readLegicUid(bool loop, bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, " MSN: " _GREEN_("%s"), sprint_hex(card.uid + 1, sizeof(card.uid) - 1));
|
PrintAndLogEx(SUCCESS, " MSN: " _GREEN_("%s"), sprint_hex(card.uid + 1, sizeof(card.uid) - 1));
|
||||||
legic_print_type(card.cardsize, 0);
|
legic_print_type(card.cardsize, 0);
|
||||||
|
|
||||||
} while (loop && (kbd_enter_pressed() == false));
|
} while (loop && kbd_enter_pressed() == false);
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
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)));
|
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();
|
lto_switch_off_field();
|
||||||
return ret;
|
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 *getVersionStr(uint8_t type, uint8_t major, uint8_t minor) {
|
||||||
|
|
||||||
static char buf[60] = {0x00};
|
static char buf[40] = {0x00};
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (type == 0x01 && major == 0x00)
|
if (type == 0x01 && major == 0x00)
|
||||||
|
@ -255,8 +255,6 @@ static char *getVersionStr(uint8_t type, uint8_t major, uint8_t minor) {
|
||||||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor);
|
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor);
|
||||||
else if (type == 0x01 && major == 0x33 && minor == 0x00)
|
else if (type == 0x01 && major == 0x33 && minor == 0x00)
|
||||||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV3") " )", major, minor);
|
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)
|
else if (type == 0x01 && major == 0x30 && minor == 0x00)
|
||||||
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire Light") " )", major, minor);
|
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire Light") " )", major, minor);
|
||||||
else if (type == 0x02 && major == 0x11 && minor == 0x00)
|
else if (type == 0x02 && major == 0x11 && minor == 0x00)
|
||||||
|
@ -331,9 +329,6 @@ nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
|
||||||
if (type == 0x01 && major == 0x33 && minor == 0x00)
|
if (type == 0x01 && major == 0x33 && minor == 0x00)
|
||||||
return DESFIRE_EV3;
|
return DESFIRE_EV3;
|
||||||
|
|
||||||
if (type == 0x81 && major == 0x43 && minor == 0x01)
|
|
||||||
return DESFIRE_EV3;
|
|
||||||
|
|
||||||
// Duox
|
// Duox
|
||||||
if (type == 0x01 && major == 0xA0 && minor == 0x00)
|
if (type == 0x01 && major == 0xA0 && minor == 0x00)
|
||||||
return DUOX;
|
return DUOX;
|
||||||
|
@ -463,7 +458,7 @@ static void swap24(uint8_t *data) {
|
||||||
|
|
||||||
// default parameters
|
// default parameters
|
||||||
static uint8_t defaultKeyNum = 0;
|
static uint8_t defaultKeyNum = 0;
|
||||||
static DesfireCryptoAlgorithm defaultAlgoId = T_3DES; // Real DESFire cards seem to use 2TDEA by default
|
static DesfireCryptoAlgorithm defaultAlgoId = T_DES;
|
||||||
static uint8_t defaultKey[DESFIRE_MAX_KEY_SIZE] = {0};
|
static uint8_t defaultKey[DESFIRE_MAX_KEY_SIZE] = {0};
|
||||||
static int defaultKdfAlgo = MFDES_KDF_ALGO_NONE;
|
static int defaultKdfAlgo = MFDES_KDF_ALGO_NONE;
|
||||||
static int defaultKdfInputLen = 0;
|
static int defaultKdfInputLen = 0;
|
||||||
|
@ -479,7 +474,6 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext_t *d
|
||||||
uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid,
|
uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid,
|
||||||
uint8_t appid,
|
uint8_t appid,
|
||||||
uint8_t appisoid,
|
uint8_t appisoid,
|
||||||
uint8_t dfnameid,
|
|
||||||
int *securechannel,
|
int *securechannel,
|
||||||
DesfireCommunicationMode defcommmode,
|
DesfireCommunicationMode defcommmode,
|
||||||
uint32_t *id,
|
uint32_t *id,
|
||||||
|
@ -565,22 +559,6 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext_t *d
|
||||||
return PM3_ESOFT;
|
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) {
|
if (appid && id) {
|
||||||
*id = 0x000000;
|
*id = 0x000000;
|
||||||
if (CLIGetUint32Hex(ctx, appid, 0x000000, id, NULL, 3, "AID must have 3 bytes length"))
|
if (CLIGetUint32Hex(ctx, appid, 0x000000, id, NULL, 3, "AID must have 3 bytes length"))
|
||||||
|
@ -634,7 +612,7 @@ static int CmdHF14ADesDefault(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, &securechann, DCMNone, NULL, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, &securechann, DCMNone, NULL, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -1049,7 +1027,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
||||||
DesfireSetKeyNoClear(dctx, keyno, T_DES, deskeyList[curkey]);
|
DesfireSetKeyNoClear(dctx, keyno, T_DES, deskeyList[curkey]);
|
||||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||||
if (res == PM3_SUCCESS) {
|
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;
|
foundKeys[0][keyno][0] = 0x01;
|
||||||
*result = true;
|
*result = true;
|
||||||
memcpy(&foundKeys[0][keyno][1], deskeyList[curkey], 8);
|
memcpy(&foundKeys[0][keyno][1], deskeyList[curkey], 8);
|
||||||
|
@ -1081,7 +1059,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
||||||
DesfireSetKeyNoClear(dctx, keyno, T_3DES, aeskeyList[curkey]);
|
DesfireSetKeyNoClear(dctx, keyno, T_3DES, aeskeyList[curkey]);
|
||||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 2TDEA Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex_inrow(aeskeyList[curkey], 16));
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 2TDEA Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16));
|
||||||
foundKeys[1][keyno][0] = 0x01;
|
foundKeys[1][keyno][0] = 0x01;
|
||||||
*result = true;
|
*result = true;
|
||||||
memcpy(&foundKeys[1][keyno][1], aeskeyList[curkey], 16);
|
memcpy(&foundKeys[1][keyno][1], aeskeyList[curkey], 16);
|
||||||
|
@ -1113,7 +1091,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
||||||
DesfireSetKeyNoClear(dctx, keyno, T_AES, aeskeyList[curkey]);
|
DesfireSetKeyNoClear(dctx, keyno, T_AES, aeskeyList[curkey]);
|
||||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex_inrow(aeskeyList[curkey], 16));
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16));
|
||||||
foundKeys[2][keyno][0] = 0x01;
|
foundKeys[2][keyno][0] = 0x01;
|
||||||
*result = true;
|
*result = true;
|
||||||
memcpy(&foundKeys[2][keyno][1], aeskeyList[curkey], 16);
|
memcpy(&foundKeys[2][keyno][1], aeskeyList[curkey], 16);
|
||||||
|
@ -1145,7 +1123,7 @@ static int AuthCheckDesfire(DesfireContext_t *dctx,
|
||||||
DesfireSetKeyNoClear(dctx, keyno, T_3K3DES, k3kkeyList[curkey]);
|
DesfireSetKeyNoClear(dctx, keyno, T_3K3DES, k3kkeyList[curkey]);
|
||||||
res = DesfireAuthenticate(dctx, secureChannel, false);
|
res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3TDEA Key %02u... " _GREEN_("%s"), curaid, keyno, sprint_hex_inrow(k3kkeyList[curkey], 24));
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3TDEA Key %02u : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24));
|
||||||
foundKeys[3][keyno][0] = 0x01;
|
foundKeys[3][keyno][0] = 0x01;
|
||||||
*result = true;
|
*result = true;
|
||||||
memcpy(&foundKeys[3][keyno][1], k3kkeyList[curkey], 16);
|
memcpy(&foundKeys[3][keyno][1], k3kkeyList[curkey], 16);
|
||||||
|
@ -1537,7 +1515,6 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_str0("f", "file", "<fn>", "Filename of dictionary"),
|
||||||
arg_lit0(NULL, "save", "Save found key and parameters to defaults"),
|
arg_lit0(NULL, "save", "Save found key and parameters to defaults"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -1551,7 +1528,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -1559,13 +1536,13 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
||||||
|
|
||||||
uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0};
|
uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0};
|
||||||
int dict_filenamelen = 0;
|
int dict_filenamelen = 0;
|
||||||
if (CLIParamStrToBuf(arg_get_str(ctx, 14), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
if (CLIParamStrToBuf(arg_get_str(ctx, 13), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||||
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool save = arg_get_lit(ctx, 15);
|
bool save = arg_get_lit(ctx, 14);
|
||||||
|
|
||||||
SetAPDULogging(APDULogging);
|
SetAPDULogging(APDULogging);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
@ -1866,7 +1843,7 @@ static int CmdHF14aDesMAD(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMPlain, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2042,7 +2019,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMPlain, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2164,7 +2141,7 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 0, 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, &securechann, DCMNone, NULL, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2199,32 +2176,25 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
|
||||||
|
|
||||||
reverse_array(startAid, 3);
|
reverse_array(startAid, 3);
|
||||||
reverse_array(endAid, 3);
|
reverse_array(endAid, 3);
|
||||||
|
|
||||||
uint32_t idStart = DesfireAIDByteToUint(startAid);
|
uint32_t idStart = DesfireAIDByteToUint(startAid);
|
||||||
uint32_t idEnd = DesfireAIDByteToUint(endAid);
|
uint32_t idEnd = DesfireAIDByteToUint(endAid);
|
||||||
|
|
||||||
if (idStart > idEnd) {
|
if (idStart > idEnd) {
|
||||||
PrintAndLogEx(ERR, "Start should be lower than end. start: %06x end: %06x", idStart, idEnd);
|
PrintAndLogEx(ERR, "Start should be lower than end. start: %06x end: %06x", idStart, idEnd);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
PrintAndLogEx(INFO, "Bruteforce from %06x to %06x", idStart, idEnd);
|
||||||
PrintAndLogEx(INFO, "Bruteforce from " _YELLOW_("%06x") " to " _YELLOW_("%06x"), idStart, idEnd);
|
|
||||||
PrintAndLogEx(INFO, "Enumerating through all AIDs manually, this will take a while!");
|
PrintAndLogEx(INFO, "Enumerating through all AIDs manually, this will take a while!");
|
||||||
|
|
||||||
for (uint32_t id = idStart; id <= idEnd && id >= idStart; id += idIncrement) {
|
for (uint32_t id = idStart; id <= idEnd && id >= idStart; id += idIncrement) {
|
||||||
|
if (kbd_enter_pressed()) break;
|
||||||
|
|
||||||
if (kbd_enter_pressed()) {
|
int progress = ((id - idStart) * 100) / ((idEnd - idStart));
|
||||||
break;
|
PrintAndLogEx(INPLACE, "Progress: %d %%, current AID: %06X", progress, id);
|
||||||
}
|
|
||||||
|
|
||||||
float progress = ((id - idStart) / (idEnd - idStart));
|
|
||||||
PrintAndLogEx(INPLACE, "Progress " _YELLOW_("%0.1f") " %% current AID: %06X", progress, id);
|
|
||||||
|
|
||||||
res = DesfireSelectAIDHexNoFieldOn(&dctx, id);
|
res = DesfireSelectAIDHexNoFieldOn(&dctx, id);
|
||||||
|
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
printf("\33[2K\r"); // clear current line before printing
|
printf("\33[2K\r"); // clear current line before printing
|
||||||
PrintAndLogEx(SUCCESS, "Got new APPID " _GREEN_("%06X"), id);
|
PrintAndLogEx(SUCCESS, "Got new APPID %06X", id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2249,8 +2219,7 @@ 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 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 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 -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\n"
|
"hf mfdes auth --aid 123456 -> select application 123456 and authenticate via parameters from `default` command");
|
||||||
"hf mfdes auth --dfname D2760000850100 -n 0 -t aes -k 00000000000000000000000000000000 -> select DF by name and authenticate");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -2266,7 +2235,6 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_lit0(NULL, "save", "saves channels parameters to defaults if authentication succeeds"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -2279,13 +2247,13 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMPlain, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMPlain, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool save = arg_get_lit(ctx, 14);
|
bool save = arg_get_lit(ctx, 13);
|
||||||
|
|
||||||
SetAPDULogging(APDULogging);
|
SetAPDULogging(APDULogging);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
@ -2297,9 +2265,7 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dctx.selectedDFNameLen > 0) {
|
if (DesfireMFSelected(selectway, id))
|
||||||
PrintAndLogEx(SUCCESS, "DF selected and authenticated " _GREEN_("successfully"));
|
|
||||||
} else if (DesfireMFSelected(selectway, id))
|
|
||||||
PrintAndLogEx(SUCCESS, "PICC selected and authenticated " _GREEN_("succesfully"));
|
PrintAndLogEx(SUCCESS, "PICC selected and authenticated " _GREEN_("succesfully"));
|
||||||
else
|
else
|
||||||
PrintAndLogEx(SUCCESS, "Application " _CYAN_("%s") " selected and authenticated " _GREEN_("succesfully"), DesfireWayIDStr(selectway, id));
|
PrintAndLogEx(SUCCESS, "Application " _CYAN_("%s") " selected and authenticated " _GREEN_("succesfully"), DesfireWayIDStr(selectway, id));
|
||||||
|
@ -2377,7 +2343,7 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2492,7 +2458,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2655,7 +2621,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0, &securechann, DCMMACed, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2818,7 +2784,7 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2856,8 +2822,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes getuid",
|
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. ",
|
"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 -> execute with default factory setup\n"
|
||||||
"hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings\n"
|
"hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings");
|
||||||
"hf mfdes getuid --dfname D2760000850100 -> select DF by name and get UID");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -2873,7 +2838,6 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -2885,7 +2849,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMEncrypted, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2963,7 +2927,7 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3010,7 +2974,6 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
|
||||||
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -3022,9 +2985,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
||||||
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) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3033,7 +2994,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
|
||||||
SetAPDULogging(APDULogging);
|
SetAPDULogging(APDULogging);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, noauth, verbose);
|
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, 0x000000, noauth, verbose);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
DropField();
|
DropField();
|
||||||
return res;
|
return res;
|
||||||
|
@ -3086,7 +3047,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMEncrypted, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3133,8 +3094,7 @@ 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"\
|
"--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 --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 -> 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\n"\
|
"hf mfdes getkeyversions --aid 123456 --keynum 0d --no-auth -> get key version without authentication");
|
||||||
"hf mfdes getkeyversions --dfname D2760000850100 --keynum 00 -> select DF by name and get key versions");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3150,38 +3110,36 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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, "keynum", "<hex>", "Key number/count (1 hex byte). (def: 0x00)"),
|
||||||
arg_str0(NULL, "keyset", "<hex>", "Keyset number (1 hex byte)"),
|
arg_str0(NULL, "keyset", "<hex>", "Keyset number (1 hex byte)"),
|
||||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||||
|
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 16);
|
bool noauth = arg_get_lit(ctx, 15);
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t keynum32 = 0x00;
|
uint32_t keynum32 = 0x00;
|
||||||
if (CLIGetUint32Hex(ctx, 14, 0x00, &keynum32, NULL, 1, "Key number must have 1 byte length")) {
|
if (CLIGetUint32Hex(ctx, 13, 0x00, &keynum32, NULL, 1, "Key number must have 1 byte length")) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t keysetnum32 = 0x00;
|
uint32_t keysetnum32 = 0x00;
|
||||||
bool keysetpresent = false;
|
bool keysetpresent = false;
|
||||||
if (CLIGetUint32Hex(ctx, 15, 0x00, &keysetnum32, &keysetpresent, 1, "Keyset number must have 1 byte length")) {
|
if (CLIGetUint32Hex(ctx, 14, 0x00, &keysetnum32, &keysetpresent, 1, "Keyset number must have 1 byte length")) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -3238,8 +3196,7 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes getkeysettings",
|
CLIParserInit(&ctx, "hf mfdes getkeysettings",
|
||||||
"Get key settings for card level or application level.",
|
"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 -> 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\n"\
|
"hf mfdes getkeysettings --aid 123456 -> get app 123456 key settings with default key/channel setup");
|
||||||
"hf mfdes getkeysettings --dfname D2760000850100 -> select DF by name and get key settings");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3254,7 +3211,6 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
|
||||||
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -3265,8 +3221,7 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
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, 12, &securechann, DCMMACed, &appid, &selectway);
|
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3344,7 +3299,7 @@ static int CmdHF14ADesGetAIDs(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3416,7 +3371,7 @@ static int CmdHF14ADesGetAppNames(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMMACed, NULL, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3463,8 +3418,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes getfileids",
|
CLIParserInit(&ctx, "hf mfdes getfileids",
|
||||||
"Get File IDs list from card. Master key needs to be provided or flag --no-auth set.",
|
"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 --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\n"
|
"hf mfdes getfileids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup");
|
||||||
"hf mfdes getfileids --dfname D2760000850100 -> select DF by name and get file IDs");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3480,7 +3434,6 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -3488,13 +3441,13 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 14);
|
bool noauth = arg_get_lit(ctx, 13);
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3510,7 +3463,6 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t buf[APDU_RES_LEN] = {0};
|
uint8_t buf[APDU_RES_LEN] = {0};
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
|
|
||||||
|
@ -3526,7 +3478,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
|
||||||
for (int i = 0; i < buflen; i++)
|
for (int i = 0; i < buflen; i++)
|
||||||
PrintAndLogEx(INFO, "File ID: %02x", buf[i]);
|
PrintAndLogEx(INFO, "File ID: %02x", buf[i]);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "There are no files in the application %06x", id);
|
PrintAndLogEx(INFO, "There is no files in the application %06x", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
DropField();
|
DropField();
|
||||||
|
@ -3540,8 +3492,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
||||||
"hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n"
|
"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 -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 -> 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\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 --dfname D2760000850100 -> select DF by name and get file ISO IDs");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3557,7 +3508,6 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -3565,13 +3515,13 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 14);
|
bool noauth = arg_get_lit(ctx, 13);
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3602,7 +3552,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
||||||
for (int i = 0; i < buflen; i += 2)
|
for (int i = 0; i < buflen; i += 2)
|
||||||
PrintAndLogEx(INFO, "File ID: %04x", MemLeToUint2byte(&buf[i]));
|
PrintAndLogEx(INFO, "File ID: %04x", MemLeToUint2byte(&buf[i]));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "There are no files in the application %06x", id);
|
PrintAndLogEx(INFO, "There is no files in the application %06x", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
DropField();
|
DropField();
|
||||||
|
@ -3615,8 +3565,7 @@ 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).",
|
"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 --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 --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\n"
|
"hf mfdes getfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup");
|
||||||
"hf mfdes getfilesettings --dfname D2760000850100 --fid 01 -> select DF by name and get file settings");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3632,7 +3581,6 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_str0(NULL, "fid", "<hex>", "File ID (1 hex byte). (def: 1)"),
|
||||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -3641,20 +3589,20 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 15);
|
bool noauth = arg_get_lit(ctx, 14);
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fileid = 1;
|
uint32_t fileid = 1;
|
||||||
if (CLIGetUint32Hex(ctx, 14, 1, &fileid, NULL, 1, "File ID must have 1 byte length")) {
|
if (CLIGetUint32Hex(ctx, 13, 1, &fileid, NULL, 1, "File ID must have 1 byte length")) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -3679,9 +3627,8 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
PrintAndLogEx(INFO, "%s file %02x settings[%zu]: %s", DesfireWayIDStr(selectway, id), fileid, buflen, sprint_hex(buf, buflen));
|
PrintAndLogEx(INFO, "%s file %02x settings[%zu]: %s", DesfireWayIDStr(selectway, id), fileid, buflen, sprint_hex(buf, buflen));
|
||||||
}
|
|
||||||
|
|
||||||
DesfirePrintFileSettings(buf, buflen);
|
DesfirePrintFileSettings(buf, buflen);
|
||||||
|
|
||||||
|
@ -3824,7 +3771,7 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -3971,7 +3918,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -4075,7 +4022,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
||||||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||||
arg_lit0("v", "verbose", "Verbose output"),
|
arg_lit0("v", "verbose", "Verbose output"),
|
||||||
arg_int0("n", "keyno", "<dec>", "Key number"),
|
arg_int0("n", "keyno", "<dec>", "Key number"),
|
||||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo (deft: 2TDEA)"),
|
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
||||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
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(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||||
|
@ -4108,7 +4055,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -4235,7 +4182,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t appid = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, &securechann, DCMMACed, &appid, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -4353,7 +4300,7 @@ static int CmdHF14ADesCreateTrMACFile(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMEncrypted, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -4460,7 +4407,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -4515,7 +4462,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
|
||||||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||||
arg_lit0("v", "verbose", "Verbose output"),
|
arg_lit0("v", "verbose", "Verbose output"),
|
||||||
arg_int0("n", "keyno", "<dec>", "Key number"),
|
arg_int0("n", "keyno", "<dec>", "Key number"),
|
||||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo (deft: 2TDEA)"),
|
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
||||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
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(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||||
|
@ -4540,7 +4487,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -4710,7 +4657,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -5120,7 +5067,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 0, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -5295,7 +5242,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 0, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -5595,8 +5542,7 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
||||||
"This commands List files inside application AID / ISOID.\n"
|
"This commands List files inside application AID / ISOID.\n"
|
||||||
"Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
"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 --aid 123456 -> AID 123456, list files using `default` command creds\n"
|
||||||
"hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light\n"
|
"hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light");
|
||||||
"hf mfdes lsfiles --dfname D2760000850100 -> select DF by name and list files");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -5612,7 +5558,6 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -5620,13 +5565,13 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 14);
|
bool noauth = arg_get_lit(ctx, 13);
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -5652,9 +5597,9 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filescount == 0) {
|
if (filescount == 0) {
|
||||||
PrintAndLogEx(INFO, "There are no files in the %s", DesfireWayIDStr(selectway, id));
|
PrintAndLogEx(INFO, "There is no files in the %s", DesfireWayIDStr(selectway, id));
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_SUCCESS;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "------------------------------------------ " _CYAN_("File list") " -----------------------------------------------------");
|
PrintAndLogEx(INFO, "------------------------------------------ " _CYAN_("File list") " -----------------------------------------------------");
|
||||||
|
@ -5670,8 +5615,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes lsapp",
|
CLIParserInit(&ctx, "hf mfdes lsapp",
|
||||||
"Show application list. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
"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 -> show application list with defaults from `default` command\n"
|
||||||
"hf mfdes lsapp --files -> show application list and show each file type/settings/etc\n"
|
"hf mfdes lsapp --files -> show application list and show each file type/settings/etc");
|
||||||
"hf mfdes lsapp --dfname D2760000850100 -> list apps after selecting DF by name");
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -5688,7 +5632,6 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
||||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
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, "no-deep", "not to check authentication commands that avail for any application"),
|
||||||
arg_lit0(NULL, "files", "scan files and print file settings"),
|
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
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -5701,7 +5644,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 14, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -5753,7 +5696,6 @@ static int CmdHF14ADesDump(const char *Cmd) {
|
||||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
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, "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, "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_str0("l", "length", "<hex>", "Maximum length for read data files (3 hex bytes, big endian)"),
|
||||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -5762,20 +5704,20 @@ static int CmdHF14ADesDump(const char *Cmd) {
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 15);
|
bool noauth = arg_get_lit(ctx, 14);
|
||||||
|
|
||||||
DesfireContext_t dctx;
|
DesfireContext_t dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t id = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
DesfireISOSelectWay selectway = ISW6bAID;
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, &securechann, (noauth) ? DCMPlain : DCMMACed, &id, &selectway);
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, (noauth) ? DCMPlain : DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t maxlength = 0;
|
uint32_t maxlength = 0;
|
||||||
if (CLIGetUint32Hex(ctx, 14, 0, &maxlength, NULL, 3, "Length parameter must have 3 byte length")) {
|
if (CLIGetUint32Hex(ctx, 13, 0, &maxlength, NULL, 3, "Length parameter must have 3 byte length")) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -5886,7 +5828,6 @@ static command_t CommandTable[] = {
|
||||||
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("Files") " -----------------------"},
|
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("Files") " -----------------------"},
|
||||||
{"getfileids", CmdHF14ADesGetFileIDs, IfPm3Iso14443a, "Get File IDs list"},
|
{"getfileids", CmdHF14ADesGetFileIDs, IfPm3Iso14443a, "Get File IDs list"},
|
||||||
{"getfileisoids", CmdHF14ADesGetFileISOIDs, IfPm3Iso14443a, "Get File ISO IDs list"},
|
{"getfileisoids", CmdHF14ADesGetFileISOIDs, IfPm3Iso14443a, "Get File ISO IDs list"},
|
||||||
{"lsfile", CmdHF14ADesLsFiles, IfPm3Iso14443a, "Show all files list"},
|
|
||||||
{"lsfiles", CmdHF14ADesLsFiles, IfPm3Iso14443a, "Show all files list"},
|
{"lsfiles", CmdHF14ADesLsFiles, IfPm3Iso14443a, "Show all files list"},
|
||||||
{"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"},
|
{"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"},
|
||||||
{"createfile", CmdHF14ADesCreateFile, IfPm3Iso14443a, "Create Standard/Backup File"},
|
{"createfile", CmdHF14ADesCreateFile, IfPm3Iso14443a, "Create Standard/Backup File"},
|
||||||
|
|
|
@ -127,6 +127,7 @@ static void print_progress_header(void) {
|
||||||
get_SIMD_instruction_set(instr_set);
|
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);
|
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, "---------+---------+---------------------------------------------------------+-----------------+-------");
|
||||||
PrintAndLogEx(INFO, " | | | Expected to brute force");
|
PrintAndLogEx(INFO, " | | | Expected to brute force");
|
||||||
PrintAndLogEx(INFO, " Time | #nonces | Activity | #states | time ");
|
PrintAndLogEx(INFO, " Time | #nonces | Activity | #states | time ");
|
||||||
|
@ -135,16 +136,12 @@ 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) {
|
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;
|
static uint64_t last_print_time = 0;
|
||||||
|
|
||||||
if (msclock() - last_print_time >= min_diff_print_time) {
|
if (msclock() - last_print_time >= min_diff_print_time) {
|
||||||
|
|
||||||
last_print_time = msclock();
|
last_print_time = msclock();
|
||||||
uint64_t total_time = msclock() - start_time;
|
uint64_t total_time = msclock() - start_time;
|
||||||
float brute_force_time = brute_force / brute_force_per_second;
|
float brute_force_time = brute_force / brute_force_per_second;
|
||||||
char brute_force_time_string[20];
|
char brute_force_time_string[20];
|
||||||
|
|
||||||
if (brute_force_time < 90) {
|
if (brute_force_time < 90) {
|
||||||
snprintf(brute_force_time_string, sizeof(brute_force_time_string), "%2.0fs", brute_force_time);
|
snprintf(brute_force_time_string, sizeof(brute_force_time_string), "%2.0fs", brute_force_time);
|
||||||
} else if (brute_force_time < 60 * 90) {
|
} else if (brute_force_time < 60 * 90) {
|
||||||
|
@ -154,24 +151,7 @@ void hardnested_print_progress(uint32_t nonces, const char *activity, float brut
|
||||||
} else {
|
} else {
|
||||||
snprintf(brute_force_time_string, sizeof(brute_force_time_string), "%2.0fd", brute_force_time / (60 * 60 * 24));
|
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,14 +486,8 @@ static void init_bitflip_bitarrays(void) {
|
||||||
effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker
|
effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
char progress_text[100];
|
char progress_text[80];
|
||||||
memset(progress_text, 0, sizeof(progress_text));
|
snprintf(progress_text, sizeof(progress_text), "Loaded %u RAW / %u LZ4 / %u BZ2 in %"PRIu64" ms", nraw, nlz4, nbz2, msclock() - init_bitflip_bitarrays_starttime);
|
||||||
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);
|
hardnested_print_progress(0, progress_text, (float)(1LL << 47), 0);
|
||||||
}
|
}
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
|
@ -2507,10 +2481,8 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
free_candidates_memory(candidates);
|
free_candidates_memory(candidates);
|
||||||
candidates = NULL;
|
candidates = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
pre_XOR_nonces();
|
pre_XOR_nonces();
|
||||||
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
|
||||||
|
|
||||||
for (uint8_t j = 0; j < NUM_SUMS && !key_found; j++) {
|
for (uint8_t j = 0; j < NUM_SUMS && !key_found; j++) {
|
||||||
float expected_brute_force = nonces[best_first_bytes[0]].expected_num_brute_force;
|
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]);
|
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]);
|
||||||
|
@ -2572,9 +2544,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
if (nonce_file_read) { // use pre-acquired data from file nonces.bin
|
if (nonce_file_read) { // use pre-acquired data from file nonces.bin
|
||||||
|
|
||||||
res = read_nonce_file(filename);
|
res = read_nonce_file(filename);
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
free_bitflip_bitarrays();
|
free_bitflip_bitarrays();
|
||||||
free_nonces_memory();
|
free_nonces_memory();
|
||||||
|
@ -2584,16 +2554,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
|
||||||
free_part_sum_bitarrays();
|
free_part_sum_bitarrays();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES;
|
hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES;
|
||||||
update_nonce_data(false);
|
update_nonce_data(false);
|
||||||
float brute_force_depth;
|
float brute_force_depth;
|
||||||
shrink_key_space(&brute_force_depth);
|
shrink_key_space(&brute_force_depth);
|
||||||
|
|
||||||
} else { // acquire nonces.
|
} else { // acquire nonces.
|
||||||
|
|
||||||
res = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow, filename);
|
res = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow, filename);
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
free_bitflip_bitarrays();
|
free_bitflip_bitarrays();
|
||||||
free_nonces_memory();
|
free_nonces_memory();
|
||||||
|
|
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