mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-28 03:06:14 +08:00
commit
1770c1e37c
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -31,12 +31,23 @@ version.c
|
||||||
*.old
|
*.old
|
||||||
*.swp
|
*.swp
|
||||||
*.json.bak
|
*.json.bak
|
||||||
|
*.pyc
|
||||||
|
|
||||||
# new build file for add-ons.
|
# new build file for add-ons.
|
||||||
Makefile.platform
|
Makefile.platform
|
||||||
# Cache for detecting platform def changes
|
# Cache for detecting platform def changes
|
||||||
.Makefile.options.cache
|
.Makefile.options.cache
|
||||||
|
|
||||||
|
# cmake
|
||||||
|
client/build/
|
||||||
|
|
||||||
|
# Coverity
|
||||||
|
cov-int/
|
||||||
|
.coverity.conf
|
||||||
|
|
||||||
|
# profiling
|
||||||
|
*.gcno
|
||||||
|
|
||||||
!client/resources/hardnested/*.bin
|
!client/resources/hardnested/*.bin
|
||||||
!client/resources/hardnested_tables/*.z
|
!client/resources/hardnested_tables/*.z
|
||||||
client/src/ui/ui_overlays.h
|
client/src/ui/ui_overlays.h
|
||||||
|
|
43
.travis.yml
43
.travis.yml
|
@ -4,29 +4,23 @@ language: c
|
||||||
#default linux build env is: xenial
|
#default linux build env is: xenial
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
|
|
||||||
|
dist: xenial
|
||||||
|
|
||||||
|
osx_image: xcode11
|
||||||
|
|
||||||
# move some env variables to homebrew env
|
# move some env variables to homebrew env
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- HOMEBREW_TRAVIS_BRANCH=$TRAVIS_BRANCH
|
- HOMEBREW_TRAVIS_BRANCH=$TRAVIS_BRANCH
|
||||||
- HOMEBREW_TRAVIS_COMMIT=$TRAVIS_COMMIT
|
- HOMEBREW_TRAVIS_COMMIT=$TRAVIS_COMMIT
|
||||||
|
jobs:
|
||||||
# Test on Linux and MacOS
|
- TO_TEST=MAKEFILE MAKE_PARAMS='PLATFORM_EXTRAS='
|
||||||
matrix:
|
- TO_TEST=MAKEFILE MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
|
||||||
include:
|
- TO_TEST=CMAKE
|
||||||
- os: osx
|
|
||||||
osx_image: xcode11
|
|
||||||
env: MAKE_PARAMS='PLATFORM_EXTRAS='
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode11
|
|
||||||
env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
|
|
||||||
- os: linux
|
|
||||||
dist: xenial
|
|
||||||
sudo: required
|
|
||||||
env: MAKE_PARAMS='PLATFORM_EXTRAS='
|
|
||||||
- os: linux
|
|
||||||
dist: xenial
|
|
||||||
sudo: required
|
|
||||||
env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
|
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
@ -58,13 +52,12 @@ install:
|
||||||
travis_terminate 1;
|
travis_terminate 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
make clean;
|
|
||||||
make all V=1 "$MAKE_PARAMS";
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
## start and run a test script
|
- if [ "$TO_TEST" = "MAKEFILE" ]; then
|
||||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
make clean && make V=1 "$MAKE_PARAMS";
|
||||||
./pm3test.sh;
|
|
||||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
|
||||||
./pm3test.sh;
|
./pm3test.sh;
|
||||||
fi
|
fi
|
||||||
|
- if [ "$TO_TEST" = "CMAKE" ]; then
|
||||||
|
mkdir -p client/build && ( cd client/build && cmake .. && make VERBOSE=1 );
|
||||||
|
PM3BIN=./client/build/proxmark3 ./pm3test.sh client;
|
||||||
|
fi
|
||||||
|
|
|
@ -3,6 +3,7 @@ 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]
|
## [unreleased][unreleased]
|
||||||
|
- Added Mifare Ultralight tear off experiment (@cintainfinita and @fukmar)
|
||||||
- Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler)
|
- Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler)
|
||||||
- Added CreateStdFile command to Mifare `hf mfdes` (@bkerler)
|
- Added CreateStdFile command to Mifare `hf mfdes` (@bkerler)
|
||||||
- Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler)
|
- Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler)
|
||||||
|
|
|
@ -28,7 +28,7 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
||||||
BINDIR := .
|
BINDIR := .
|
||||||
OBJDIR := obj
|
OBJDIR := obj
|
||||||
|
|
||||||
MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o)
|
MYOBJS ?= $(MYSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
||||||
|
|
||||||
all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
||||||
|
@ -36,6 +36,11 @@ all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
||||||
clean:
|
clean:
|
||||||
$(Q)$(RM) $(CLEAN)
|
$(Q)$(RM) $(CLEAN)
|
||||||
$(Q)$(RMDIR) $(OBJDIR)
|
$(Q)$(RMDIR) $(OBJDIR)
|
||||||
|
ifneq (,$(MYCLEANOLDPATH))
|
||||||
|
$(Q)$(RM) $(foreach f,$(CLEAN),$(MYCLEANOLDPATH)/$(f))
|
||||||
|
$(Q)$(RMDIR) $(MYCLEANOLDPATH)/$(OBJDIR)
|
||||||
|
$(Q)$(RMDIR_SOFT) $(MYCLEANOLDPATH) 2>/dev/null || true
|
||||||
|
endif
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
ifneq (,$(INSTALLTOOLS))
|
ifneq (,$(INSTALLTOOLS))
|
||||||
|
|
|
@ -47,10 +47,10 @@
|
||||||
void DownloadLogInstructions() {
|
void DownloadLogInstructions() {
|
||||||
Dbprintf("");
|
Dbprintf("");
|
||||||
Dbprintf("[=] List all dumps from flash:");
|
Dbprintf("[=] List all dumps from flash:");
|
||||||
Dbprintf("[=] " _YELLOW_("-") "mem spiffs tree");
|
Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree");
|
||||||
Dbprintf("");
|
Dbprintf("");
|
||||||
Dbprintf("[=] To save a dump file from flash to client:");
|
Dbprintf("[=] To save a dump file from flash to client:");
|
||||||
Dbprintf("[=] " _YELLOW_("-") "mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin");
|
Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin");
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_dump_to_file(legic_card_select_t *p_card) {
|
void save_dump_to_file(legic_card_select_t *p_card) {
|
||||||
|
|
|
@ -57,9 +57,9 @@
|
||||||
void DownloadLogInstructions() {
|
void DownloadLogInstructions() {
|
||||||
Dbprintf("");
|
Dbprintf("");
|
||||||
Dbprintf("[=] To get the logfile from flash and display it:");
|
Dbprintf("[=] To get the logfile from flash and display it:");
|
||||||
Dbprintf("[=] " _YELLOW_("1.") "mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE);
|
Dbprintf("[=] " _YELLOW_("1.") " mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE);
|
||||||
Dbprintf("[=] " _YELLOW_("2.") "exit proxmark3 client");
|
Dbprintf("[=] " _YELLOW_("2.") " exit proxmark3 client");
|
||||||
Dbprintf("[=] " _YELLOW_("3.") "cat "LF_HIDCOLLECT_LOGFILE);
|
Dbprintf("[=] " _YELLOW_("3.") " cat "LF_HIDCOLLECT_LOGFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool log_exists;
|
bool log_exists;
|
||||||
|
|
|
@ -333,7 +333,7 @@ void printConnSpeed(void) {
|
||||||
|
|
||||||
Dbprintf(" Time elapsed............%dms", delta_time);
|
Dbprintf(" Time elapsed............%dms", delta_time);
|
||||||
Dbprintf(" Bytes transferred.......%d", bytes_transferred);
|
Dbprintf(" Bytes transferred.......%d", bytes_transferred);
|
||||||
Dbprintf(" Transfer Speed PM3 -> Client = " _YELLOW_("%d") "bytes/s", 1000 * bytes_transferred / delta_time);
|
Dbprintf(" Transfer Speed PM3 -> Client = " _YELLOW_("%d") " bytes/s", 1000 * bytes_transferred / delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1295,7 +1295,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MFU_OTP_TEAROFF: {
|
case CMD_HF_MFU_OTP_TEAROFF: {
|
||||||
MifareU_Otp_Tearoff();
|
MifareU_Otp_Tearoff(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MIFARE_STATIC_NONCE: {
|
case CMD_HF_MIFARE_STATIC_NONCE: {
|
||||||
|
|
|
@ -573,7 +573,7 @@ void Flashmem_print_info(void) {
|
||||||
if (isok == 2) {
|
if (isok == 2) {
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
if (num != 0xFFFF && num != 0x0)
|
if (num != 0xFFFF && num != 0x0)
|
||||||
Dbprintf(" Mifare.................."_YELLOW_("%d")"keys", num);
|
Dbprintf(" Mifare.................."_YELLOW_("%d")" keys", num);
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
@ -581,7 +581,7 @@ void Flashmem_print_info(void) {
|
||||||
if (isok == 2) {
|
if (isok == 2) {
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
if (num != 0xFFFF && num != 0x0)
|
if (num != 0xFFFF && num != 0x0)
|
||||||
Dbprintf(" T55x7..................."_YELLOW_("%d")"keys", num);
|
Dbprintf(" T55x7..................."_YELLOW_("%d")" keys", num);
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
@ -589,7 +589,7 @@ void Flashmem_print_info(void) {
|
||||||
if (isok == 2) {
|
if (isok == 2) {
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
if (num != 0xFFFF && num != 0x0)
|
if (num != 0xFFFF && num != 0x0)
|
||||||
Dbprintf(" iClass.................."_YELLOW_("%d")"keys", num);
|
Dbprintf(" iClass.................."_YELLOW_("%d")" keys", num);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
|
|
|
@ -465,7 +465,7 @@ void LegicRfSimulate(uint8_t cardtype) {
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
DbpString("[=] Starting Legic emulator, press " _YELLOW_("button") "to end");
|
DbpString("[=] Starting Legic emulator, press " _YELLOW_("button") " to end");
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
while (!BUTTON_PRESS() && !data_available()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ static uint32_t GetT55xxClockBit(uint32_t clock) {
|
||||||
|
|
||||||
void printT55xxConfig(void) {
|
void printT55xxConfig(void) {
|
||||||
|
|
||||||
#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") "| ");
|
#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") " | ");
|
||||||
|
|
||||||
DbpString(_BLUE_("LF T55XX config"));
|
DbpString(_BLUE_("LF T55XX config"));
|
||||||
Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]");
|
Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]");
|
||||||
|
@ -211,16 +211,16 @@ void printT55xxConfig(void) {
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case T55XX_DLMODE_FIXED :
|
case T55XX_DLMODE_FIXED :
|
||||||
sprintf(s, _YELLOW_("fixed bit length") _GREEN_("(default)") "|");
|
sprintf(s, _YELLOW_("fixed bit length") _GREEN_(" (default)") " |");
|
||||||
break;
|
break;
|
||||||
case T55XX_DLMODE_LLR :
|
case T55XX_DLMODE_LLR :
|
||||||
sprintf(s, _YELLOW_(" long leading reference") "|");
|
sprintf(s, _YELLOW_(" long leading reference") " |");
|
||||||
break;
|
break;
|
||||||
case T55XX_DLMODE_LEADING_ZERO :
|
case T55XX_DLMODE_LEADING_ZERO :
|
||||||
sprintf(s, _YELLOW_(" leading zero") "|");
|
sprintf(s, _YELLOW_(" leading zero") " |");
|
||||||
break;
|
break;
|
||||||
case T55XX_DLMODE_1OF4 :
|
case T55XX_DLMODE_1OF4 :
|
||||||
sprintf(s, _YELLOW_(" 1 of 4 coding reference") "|");
|
sprintf(s, _YELLOW_(" 1 of 4 coding reference") " |");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1291,7 +1291,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
cardnum = (lo >> 1) & 0x7FFFF;
|
cardnum = (lo >> 1) & 0x7FFFF;
|
||||||
fac = ((hi & 0xF) << 12) | (lo >> 20);
|
fac = ((hi & 0xF) << 12) | (lo >> 20);
|
||||||
}
|
}
|
||||||
Dbprintf("TAG ID: " _GREEN_("%x%08x (%d)") "- Format Len: " _GREEN_("%d") "bit - FC: " _GREEN_("%d") "- Card: "_GREEN_("%d"),
|
Dbprintf("TAG ID: " _GREEN_("%x%08x (%d)") " - Format Len: " _GREEN_("%d") " bit - FC: " _GREEN_("%d") " - Card: "_GREEN_("%d"),
|
||||||
hi,
|
hi,
|
||||||
lo,
|
lo,
|
||||||
(lo >> 1) & 0xFFFF,
|
(lo >> 1) & 0xFFFF,
|
||||||
|
|
|
@ -307,7 +307,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
Dbprintf("Done, saved " _YELLOW_("%d")"out of " _YELLOW_("%d")"seen samples at " _YELLOW_("%d")"bits/sample", samples.total_saved, samples.counter, bits_per_sample);
|
Dbprintf("Done, saved " _YELLOW_("%d")" out of " _YELLOW_("%d")" seen samples at " _YELLOW_("%d")" bits/sample", samples.total_saved, samples.counter, bits_per_sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
||||||
|
|
|
@ -2423,12 +2423,14 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) {
|
||||||
//
|
//
|
||||||
// Tear-off attack against MFU.
|
// Tear-off attack against MFU.
|
||||||
// - Moebius et al
|
// - Moebius et al
|
||||||
void MifareU_Otp_Tearoff() {
|
void MifareU_Otp_Tearoff(uint8_t arg0, uint32_t arg1, uint8_t *datain) {
|
||||||
|
uint8_t blockNo = arg0;
|
||||||
// should the
|
uint32_t tearOffTime = arg1;
|
||||||
// optional time be configurable via client side?
|
uint8_t data_fullwrite[4] = {0x00};
|
||||||
|
uint8_t data_testwrite[4] = {0x00};
|
||||||
|
memcpy(data_fullwrite, datain, 4);
|
||||||
|
memcpy(data_testwrite, datain + 4, 4);
|
||||||
// optional authentication before?
|
// optional authentication before?
|
||||||
// optional data to be written?
|
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off");
|
if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off");
|
||||||
|
|
||||||
|
@ -2439,46 +2441,26 @@ void MifareU_Otp_Tearoff() {
|
||||||
|
|
||||||
StartTicks();
|
StartTicks();
|
||||||
|
|
||||||
#define OTP_TEAR_OFF_TIME 1000
|
|
||||||
#define OTP_BLK_NO 3
|
|
||||||
|
|
||||||
// write cmd to send, include CRC
|
// write cmd to send, include CRC
|
||||||
// 1b write, 1b block, 4b data, 2 crc
|
// 1b write, 1b block, 4b data, 2 crc
|
||||||
uint8_t cmd[] = {MIFARE_ULC_WRITE, OTP_BLK_NO, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0};
|
uint8_t cmd[] = {MIFARE_ULC_WRITE, blockNo, data_testwrite[0], data_testwrite[1], data_testwrite[2], data_testwrite[3], 0, 0};
|
||||||
|
|
||||||
// User specific data to write?
|
MifareUWriteBlock(blockNo, 0, data_fullwrite);
|
||||||
// memcpy(block + 2, blockData, 4);
|
|
||||||
|
|
||||||
AddCrc14A(cmd, sizeof(cmd) - 2);
|
AddCrc14A(cmd, sizeof(cmd) - 2);
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_ERROR) DbpString("Transmitting");
|
if (DBGLEVEL >= DBG_ERROR) DbpString("Transmitting");
|
||||||
|
|
||||||
// anticollision / select card
|
// anticollision / select card
|
||||||
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
|
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
|
||||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card");
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
// UL-EV1 / NTAG authentication
|
|
||||||
if (usePwd) {
|
|
||||||
uint8_t pwd[4] = {0x00};
|
|
||||||
memcpy(pwd, datain + 4, 4);
|
|
||||||
uint8_t pack[4] = {0, 0, 0, 0};
|
|
||||||
if (!mifare_ul_ev1_auth(pwd, pack)) {
|
|
||||||
OnError(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// send
|
// send
|
||||||
ReaderTransmit(cmd, sizeof(cmd), NULL);
|
ReaderTransmit(cmd, sizeof(cmd), NULL);
|
||||||
|
|
||||||
// Wait before cutting power. aka tear-off
|
// Wait before cutting power. aka tear-off
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
WaitUS(OTP_TEAR_OFF_TIME);
|
WaitUS(tearOffTime);
|
||||||
switch_off();
|
switch_off();
|
||||||
|
|
||||||
reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0);
|
||||||
|
|
|
@ -59,6 +59,6 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain);
|
||||||
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
|
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
|
||||||
|
|
||||||
// Tear-off test for MFU
|
// Tear-off test for MFU
|
||||||
void MifareU_Otp_Tearoff();
|
void MifareU_Otp_Tearoff(uint8_t arg0, uint32_t arg1, uint8_t *datain);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -545,11 +545,11 @@ void rdv40_spiffs_safe_print_fsinfo() {
|
||||||
DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)"));
|
DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)"));
|
||||||
|
|
||||||
|
|
||||||
Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize);
|
Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize);
|
||||||
Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize);
|
Dbprintf(" Logical Page Size.........." _YELLOW_("%d")" bytes", fsinfo.pageSize);
|
||||||
Dbprintf("");
|
Dbprintf("");
|
||||||
Dbprintf(" Max Open Files............." _YELLOW_("%d")"file descriptors", fsinfo.maxOpenFiles);
|
Dbprintf(" Max Open Files............." _YELLOW_("%d")" file descriptors", fsinfo.maxOpenFiles);
|
||||||
Dbprintf(" Max Path Length............" _YELLOW_("%d")"chars", fsinfo.maxPathLength);
|
Dbprintf(" Max Path Length............" _YELLOW_("%d")" chars", fsinfo.maxPathLength);
|
||||||
DbpString("");
|
DbpString("");
|
||||||
Dbprintf(" filesystem size used available use% mounted");
|
Dbprintf(" filesystem size used available use% mounted");
|
||||||
Dbprintf(" spiffs %6d B %6d B %6d B"_YELLOW_("%2d%")" /"
|
Dbprintf(" spiffs %6d B %6d B %6d B"_YELLOW_("%2d%")" /"
|
||||||
|
|
284
client/CMakeLists.txt
Normal file
284
client/CMakeLists.txt
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(proxmark3)
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_LESS "3.7.0")
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
|
if(APPLE AND EXISTS /usr/local/opt/qt5)
|
||||||
|
# Homebrew installs Qt5 (up to at least 5.11.0) in
|
||||||
|
# /usr/local/qt5. Ensure that it can be found by CMake
|
||||||
|
# since it is not in the default /usr/local prefix.
|
||||||
|
# Add it to PATHS so that it doesn't override the
|
||||||
|
# CMAKE_PREFIX_PATH environment variable.
|
||||||
|
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
|
||||||
|
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
|
||||||
|
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
|
||||||
|
endif()
|
||||||
|
set(QT_PACKAGELIST
|
||||||
|
Qt5Core
|
||||||
|
Qt5Widgets
|
||||||
|
Qt5Gui
|
||||||
|
)
|
||||||
|
set(Qt5_FOUND ON)
|
||||||
|
foreach(_qt_package IN LISTS QT_PACKAGELIST)
|
||||||
|
find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS})
|
||||||
|
if(NOT ${_qt_package}_FOUND)
|
||||||
|
set(Qt5_FOUND OFF)
|
||||||
|
endif(NOT ${_qt_package}_FOUND)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
SET (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
INCLUDE(FindSSE)
|
||||||
|
if(NOT SSE2_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSE2 on this machine.")
|
||||||
|
endif(NOT SSE2_FOUND)
|
||||||
|
if(NOT SSE3_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSE3 on this machine.")
|
||||||
|
endif(NOT SSE3_FOUND)
|
||||||
|
if(NOT SSSE3_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSSE3 on this machine.")
|
||||||
|
endif(NOT SSSE3_FOUND)
|
||||||
|
if(NOT SSE4_1_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSE4.1 on this machine.")
|
||||||
|
endif(NOT SSE4_1_FOUND)
|
||||||
|
if(NOT AVX_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for AVX on this machine.")
|
||||||
|
endif(NOT AVX_FOUND)
|
||||||
|
if(NOT AVX2_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for AVX2 on this machine.")
|
||||||
|
endif(NOT AVX2_FOUND)
|
||||||
|
if(NOT AVX512_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for AVX512 on this machine.")
|
||||||
|
endif(NOT AVX512_FOUND)
|
||||||
|
|
||||||
|
add_subdirectory(deps)
|
||||||
|
|
||||||
|
set (TARGET_SOURCES
|
||||||
|
src/proxmark3.c
|
||||||
|
../common/commonutil.c
|
||||||
|
../common/util_posix.c
|
||||||
|
../common/parity.c
|
||||||
|
../common/bucketsort.c
|
||||||
|
../common/crapto1/crapto1.c
|
||||||
|
../common/crapto1/crypto1.c
|
||||||
|
../common/crc.c
|
||||||
|
../common/crc16.c
|
||||||
|
../common/crc32.c
|
||||||
|
../common/crc64.c
|
||||||
|
../common/lfdemod.c
|
||||||
|
../common/legic_prng.c
|
||||||
|
../common/iso15693tools.c
|
||||||
|
../common/cardhelper.c
|
||||||
|
../common/generator.c
|
||||||
|
src/crypto/asn1dump.c
|
||||||
|
src/crypto/asn1utils.c
|
||||||
|
src/crypto/libpcrypto.c
|
||||||
|
src/emv/test/cda_test.c
|
||||||
|
src/emv/test/crypto_test.c
|
||||||
|
src/emv/test/cryptotest.c
|
||||||
|
src/emv/test/dda_test.c
|
||||||
|
src/emv/test/sda_test.c
|
||||||
|
src/emv/apduinfo.c
|
||||||
|
src/emv/cmdemv.c
|
||||||
|
src/emv/crypto.c
|
||||||
|
src/emv/crypto_polarssl.c
|
||||||
|
src/emv/dol.c
|
||||||
|
src/emv/dump.c
|
||||||
|
src/emv/emv_pk.c
|
||||||
|
src/emv/emv_pki.c
|
||||||
|
src/emv/emv_pki_priv.c
|
||||||
|
src/emv/emv_roca.c
|
||||||
|
src/emv/emv_tags.c
|
||||||
|
src/emv/emvcore.c
|
||||||
|
src/emv/emvjson.c
|
||||||
|
src/emv/tlv.c
|
||||||
|
src/fido/additional_ca.c
|
||||||
|
src/fido/cbortools.c
|
||||||
|
src/fido/cose.c
|
||||||
|
src/fido/fidocore.c
|
||||||
|
src/loclass/cipher.c
|
||||||
|
src/loclass/cipherutils.c
|
||||||
|
src/loclass/elite_crack.c
|
||||||
|
src/loclass/hash1_brute.c
|
||||||
|
src/loclass/ikeys.c
|
||||||
|
src/mifare/mad.c
|
||||||
|
src/mifare/mfkey.c
|
||||||
|
src/mifare/mifare4.c
|
||||||
|
src/mifare/mifaredefault.c
|
||||||
|
src/mifare/mifarehost.c
|
||||||
|
src/mifare/ndef.c
|
||||||
|
src/mifare/desfire_crypto.c
|
||||||
|
src/uart/uart_posix.c
|
||||||
|
src/uart/uart_win32.c
|
||||||
|
src/ui/overlays.ui
|
||||||
|
src/aidsearch.c
|
||||||
|
src/cmdanalyse.c
|
||||||
|
src/cmdcrc.c
|
||||||
|
src/cmddata.c
|
||||||
|
src/cmdflashmem.c
|
||||||
|
src/cmdflashmemspiffs.c
|
||||||
|
src/cmdhf.c
|
||||||
|
src/cmdhf14a.c
|
||||||
|
src/cmdhf14b.c
|
||||||
|
src/cmdhf15.c
|
||||||
|
src/cmdhfcryptorf.c
|
||||||
|
src/cmdhfepa.c
|
||||||
|
src/cmdhffelica.c
|
||||||
|
src/cmdhffido.c
|
||||||
|
src/cmdhficlass.c
|
||||||
|
src/cmdhflegic.c
|
||||||
|
src/cmdhflist.c
|
||||||
|
src/cmdhflto.c
|
||||||
|
src/cmdhfmf.c
|
||||||
|
src/cmdhfmfdes.c
|
||||||
|
src/cmdhfmfhard.c
|
||||||
|
src/cmdhfmfp.c
|
||||||
|
src/cmdhfmfu.c
|
||||||
|
src/cmdhfthinfilm.c
|
||||||
|
src/cmdhftopaz.c
|
||||||
|
src/cmdhw.c
|
||||||
|
src/cmdlf.c
|
||||||
|
src/cmdlfawid.c
|
||||||
|
src/cmdlfcotag.c
|
||||||
|
src/cmdlfem4x.c
|
||||||
|
src/cmdlffdx.c
|
||||||
|
src/cmdlfgallagher.c
|
||||||
|
src/cmdlfguard.c
|
||||||
|
src/cmdlfhid.c
|
||||||
|
src/cmdlfhitag.c
|
||||||
|
src/cmdlfindala.c
|
||||||
|
src/cmdlfio.c
|
||||||
|
src/cmdlfjablotron.c
|
||||||
|
src/cmdlfkeri.c
|
||||||
|
src/cmdlfmotorola.c
|
||||||
|
src/cmdlfnedap.c
|
||||||
|
src/cmdlfnexwatch.c
|
||||||
|
src/cmdlfnoralsy.c
|
||||||
|
src/cmdlfpac.c
|
||||||
|
src/cmdlfparadox.c
|
||||||
|
src/cmdlfpcf7931.c
|
||||||
|
src/cmdlfpresco.c
|
||||||
|
src/cmdlfpyramid.c
|
||||||
|
src/cmdlfsecurakey.c
|
||||||
|
src/cmdlft55xx.c
|
||||||
|
src/cmdlfti.c
|
||||||
|
src/cmdlfverichip.c
|
||||||
|
src/cmdlfviking.c
|
||||||
|
src/cmdlfvisa2000.c
|
||||||
|
src/cmdmain.c
|
||||||
|
src/cmdparser.c
|
||||||
|
src/cmdscript.c
|
||||||
|
src/cmdsmartcard.c
|
||||||
|
src/cmdtrace.c
|
||||||
|
src/cmdusart.c
|
||||||
|
src/cmdwiegand.c
|
||||||
|
src/comms.c
|
||||||
|
src/fileutils.c
|
||||||
|
src/flash.c
|
||||||
|
src/graph.c
|
||||||
|
src/preferences.c
|
||||||
|
src/pm3_binlib.c
|
||||||
|
src/pm3_bitlib.c
|
||||||
|
src/prng.c
|
||||||
|
src/scandir.c
|
||||||
|
src/scripting.c
|
||||||
|
src/tea.c
|
||||||
|
src/ui.c
|
||||||
|
src/util.c
|
||||||
|
src/whereami.c
|
||||||
|
src/wiegand_formats.c
|
||||||
|
src/wiegand_formatutils.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(ADDITIONAL_SRC "")
|
||||||
|
set(ADDITIONAL_LNK "")
|
||||||
|
|
||||||
|
set(X86_CPUS x86 x86_64 i686)
|
||||||
|
|
||||||
|
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
message("Apple device detected.")
|
||||||
|
set(ADDITIONAL_SRC src/util_darwin.h src/util_darwin.m ${ADDITIONAL_SRC})
|
||||||
|
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
|
if (MINGW)
|
||||||
|
set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}")
|
||||||
|
endif (MINGW)
|
||||||
|
|
||||||
|
if (Qt5_FOUND)
|
||||||
|
message("Qt5 library found, building gui :)")
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set (TARGET_SOURCES
|
||||||
|
src/proxgui.cpp
|
||||||
|
src/proxguiqt.cpp
|
||||||
|
${TARGET_SOURCES})
|
||||||
|
|
||||||
|
add_definitions("-DHAVE_GUI")
|
||||||
|
set(ADDITIONAL_LNK Qt5::Core Qt5::Widgets Qt5::Gui ${ADDITIONAL_LNK})
|
||||||
|
else (Qt5_FOUND)
|
||||||
|
message("Qt5 library not found, not building gui")
|
||||||
|
set(TARGET_SOURCES
|
||||||
|
src/guidummy.cpp
|
||||||
|
${TARGET_SOURCES})
|
||||||
|
endif (Qt5_FOUND)
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
proxmark3
|
||||||
|
${TARGET_SOURCES}
|
||||||
|
${ADDITIONAL_SRC}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
|
||||||
|
|
||||||
|
target_include_directories(proxmark3 PRIVATE
|
||||||
|
../common
|
||||||
|
../common_fpga
|
||||||
|
../include
|
||||||
|
src
|
||||||
|
)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
set_target_properties(proxmark3 PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks, -L/usr/local/opt/readline/lib")
|
||||||
|
set_target_properties(proxmark3 PROPERTIES COMPILE_FLAGS "-I/usr/local/opt/readline/include")
|
||||||
|
else (APPLE)
|
||||||
|
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
||||||
|
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
|
|
||||||
|
find_library(cliparser REQUIRED)
|
||||||
|
find_library(jansson REQUIRED)
|
||||||
|
find_library(tinycbor REQUIRED)
|
||||||
|
find_library(lua REQUIRED)
|
||||||
|
find_library(mbedtls REQUIRED)
|
||||||
|
find_library(reveng REQUIRED)
|
||||||
|
find_library(z REQUIRED)
|
||||||
|
find_library(hardnested REQUIRED)
|
||||||
|
|
||||||
|
target_link_libraries(proxmark3 PRIVATE readline pthread m mbedtls cliparser jansson lua tinycbor amiibo reveng z hardnested ${ADDITIONAL_LNK})
|
||||||
|
|
||||||
|
install(TARGETS proxmark3 DESTINATION "bin")
|
||||||
|
install(DIRECTORY cmdscripts lualibs luascripts resources dictionaries DESTINATION "share/proxmark3")
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT lualibs/pm3_cmd.lua
|
||||||
|
COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua"
|
||||||
|
COMMENT "Creating lualibs/pm3_cmd.lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT lualibs/mfc_default_keys.lua
|
||||||
|
COMMAND "awk -f default_keys_dic2lua.awk mfc_default_keys.dic > lualibs/mfc_default_keys.lua"
|
||||||
|
COMMENT "Creating lualibs/mfc_default_keys.lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
#"make package" will trigger this
|
||||||
|
SET(CPACK_GENERATOR "DEB")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Iceman")
|
||||||
|
INCLUDE(CPack)
|
117
client/Makefile
117
client/Makefile
|
@ -17,7 +17,7 @@ include ../Makefile.defs
|
||||||
INSTALLBIN = proxmark3
|
INSTALLBIN = proxmark3
|
||||||
INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries
|
INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries
|
||||||
|
|
||||||
VPATH = ../common src/uart src deps
|
VPATH = ../common src
|
||||||
vpath %.dic dictionaries
|
vpath %.dic dictionaries
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
|
||||||
|
@ -42,6 +42,10 @@ REVENGPATH = ./deps/reveng
|
||||||
REVENGLIB = $(REVENGPATH)/libreveng.a
|
REVENGLIB = $(REVENGPATH)/libreveng.a
|
||||||
AMIIBOLIBPATH = ./deps/amiitool
|
AMIIBOLIBPATH = ./deps/amiitool
|
||||||
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
|
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
|
||||||
|
HARDNESTEDPATH = ./deps/hardnested
|
||||||
|
HARDNESTEDLIB = $(HARDNESTEDPATH)/libhardnested.a
|
||||||
|
CLIPARSERPATH = ./deps/cliparser
|
||||||
|
CLIPARSERLIB = $(CLIPARSERPATH)/libcliparser.a
|
||||||
|
|
||||||
# common libraries
|
# common libraries
|
||||||
MBEDTLSLIBPATH = ../common/mbedtls
|
MBEDTLSLIBPATH = ../common/mbedtls
|
||||||
|
@ -49,17 +53,19 @@ MBEDTLSLIB = $(OBJDIR)/libmbedtls.a
|
||||||
ZLIBPATH = ../common/zlib
|
ZLIBPATH = ../common/zlib
|
||||||
ZLIB = $(OBJDIR)/libz.a
|
ZLIB = $(OBJDIR)/libz.a
|
||||||
|
|
||||||
LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH)
|
LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH) -I$(HARDNESTEDPATH) -I$(CLIPARSERPATH)
|
||||||
INCLUDES_CLIENT = -I./src -I./deps -I../include -I../common -I./deps/cliparser -I./src/uart $(LIBS)
|
INCLUDES_CLIENT = -I./src -I../include -I../common -I../common_fpga $(LIBS)
|
||||||
CFLAGS ?= -Wall -Werror -g -O3
|
CFLAGS ?= -Wall -Werror -O3
|
||||||
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
||||||
PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT)
|
PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT)
|
||||||
|
# WIP Testing
|
||||||
|
#PM3CFLAGS = $(CFLAGS) -std=c11 -pedantic $(INCLUDES_CLIENT)
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
||||||
endif
|
endif
|
||||||
CXXFLAGS ?= -Wall -Werror -O3
|
CXXFLAGS ?= -Wall -Werror -O3
|
||||||
PM3CXXFLAGS = $(CXXFLAGS) -I../include -I/.deps/cliparser
|
PM3CXXFLAGS = $(CXXFLAGS) -I../include
|
||||||
|
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
|
@ -112,6 +118,7 @@ ifneq ($(QTLDLIBS),)
|
||||||
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
|
||||||
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
||||||
PM3CFLAGS += -DHAVE_GUI
|
PM3CFLAGS += -DHAVE_GUI
|
||||||
|
PM3CXXFLAGS += -DQT_NO_DEBUG
|
||||||
else
|
else
|
||||||
QTGUISRCS = guidummy.cpp
|
QTGUISRCS = guidummy.cpp
|
||||||
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
||||||
|
@ -122,8 +129,8 @@ DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
# make temporary to final dependency files after successful compilation
|
# make temporary to final dependency files after successful compilation
|
||||||
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
||||||
|
|
||||||
CORESRCS = uart_posix.c \
|
CORESRCS = uart/uart_posix.c \
|
||||||
uart_win32.c \
|
uart/uart_win32.c \
|
||||||
ui.c \
|
ui.c \
|
||||||
commonutil.c \
|
commonutil.c \
|
||||||
util.c \
|
util.c \
|
||||||
|
@ -145,8 +152,6 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
crypto/asn1dump.c \
|
crypto/asn1dump.c \
|
||||||
crypto/libpcrypto.c\
|
crypto/libpcrypto.c\
|
||||||
crypto/asn1utils.c\
|
crypto/asn1utils.c\
|
||||||
cliparser/argtable3.c\
|
|
||||||
cliparser/cliparser.c\
|
|
||||||
loclass/cipher.c \
|
loclass/cipher.c \
|
||||||
loclass/cipherutils.c \
|
loclass/cipherutils.c \
|
||||||
loclass/ikeys.c \
|
loclass/ikeys.c \
|
||||||
|
@ -201,7 +206,6 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
cmdhfmfu.c \
|
cmdhfmfu.c \
|
||||||
cmdhfmfp.c \
|
cmdhfmfp.c \
|
||||||
cmdhfmfhard.c \
|
cmdhfmfhard.c \
|
||||||
deps/hardnested/hardnested_bruteforce.c \
|
|
||||||
cmdhfmfdes.c \
|
cmdhfmfdes.c \
|
||||||
cmdhftopaz.c \
|
cmdhftopaz.c \
|
||||||
cmdhffido.c \
|
cmdhffido.c \
|
||||||
|
@ -257,48 +261,16 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
cardhelper.c \
|
cardhelper.c \
|
||||||
preferences.c
|
preferences.c
|
||||||
|
|
||||||
cpu_arch = $(shell uname -m)
|
|
||||||
ifneq ($(findstring 86, $(cpu_arch)), )
|
|
||||||
MULTIARCHSRCS = deps/hardnested/hardnested_bf_core.c deps/hardnested/hardnested_bitarray_core.c
|
|
||||||
endif
|
|
||||||
ifneq ($(findstring amd64, $(cpu_arch)), )
|
|
||||||
MULTIARCHSRCS = deps/hardnested/hardnested_bf_core.c deps/hardnested/hardnested_bitarray_core.c
|
|
||||||
endif
|
|
||||||
ifeq ($(MULTIARCHSRCS), )
|
|
||||||
CMDSRCS += deps/hardnested/hardnested_bf_core.c deps/hardnested/hardnested_bitarray_core.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
||||||
MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \
|
|
||||||
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \
|
|
||||||
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \
|
|
||||||
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX.o) \
|
|
||||||
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX2.o)
|
|
||||||
|
|
||||||
SUPPORTS_AVX512 := $(shell echo | gcc -E -mavx512f - > /dev/null 2>&1 && echo "True" )
|
|
||||||
|
|
||||||
HARD_SWITCH_NOSIMD = -mno-mmx -mno-sse2 -mno-avx -mno-avx2
|
|
||||||
HARD_SWITCH_MMX = -mmmx -mno-sse2 -mno-avx -mno-avx2
|
|
||||||
HARD_SWITCH_SSE2 = -mmmx -msse2 -mno-avx -mno-avx2
|
|
||||||
HARD_SWITCH_AVX = -mmmx -msse2 -mavx -mno-avx2
|
|
||||||
HARD_SWITCH_AVX2 = -mmmx -msse2 -mavx -mavx2
|
|
||||||
HARD_SWITCH_AVX512 = -mmmx -msse2 -mavx -mavx2 -mavx512f
|
|
||||||
ifeq "$(SUPPORTS_AVX512)" "True"
|
|
||||||
HARD_SWITCH_NOSIMD += -mno-avx512f
|
|
||||||
HARD_SWITCH_MMX += -mno-avx512f
|
|
||||||
HARD_SWITCH_SSE2 += -mno-avx512f
|
|
||||||
HARD_SWITCH_AVX += -mno-avx512f
|
|
||||||
HARD_SWITCH_AVX2 += -mno-avx512f
|
|
||||||
MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o)
|
|
||||||
endif
|
|
||||||
|
|
||||||
BINS = proxmark3
|
BINS = proxmark3
|
||||||
CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
CLEAN = $(BINS) src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
||||||
# transition: make sure old flasher is gone too
|
# transition: cleaning also old path stuff
|
||||||
CLEAN += flasher
|
CLEAN += flasher *.moc.cpp ui/ui_overlays.h
|
||||||
|
|
||||||
# need to assign dependancies to build these first...
|
# need to assign dependancies to build these first...
|
||||||
all: $(BINS)
|
all: $(BINS)
|
||||||
|
@ -306,10 +278,10 @@ all: $(BINS)
|
||||||
all-static: LDLIBS:=-static $(LDLIBS)
|
all-static: LDLIBS:=-static $(LDLIBS)
|
||||||
all-static: $(BINS)
|
all-static: $(BINS)
|
||||||
|
|
||||||
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(QTLDLIBS)
|
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) $(QTLDLIBS)
|
||||||
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
||||||
$(info [=] LD $@)
|
$(info [=] LD $@)
|
||||||
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@
|
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
src/proxgui.cpp: src/ui/ui_overlays.h
|
src/proxgui.cpp: src/ui/ui_overlays.h
|
||||||
|
|
||||||
|
@ -337,6 +309,8 @@ clean:
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) clean
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(info [@] Installing client to $(DESTDIR)$(PREFIX)...)
|
$(info [@] Installing client to $(DESTDIR)$(PREFIX)...)
|
||||||
|
@ -381,10 +355,18 @@ $(REVENGLIB):
|
||||||
$(info [*] MAKE reveng)
|
$(info [*] MAKE reveng)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all
|
||||||
|
|
||||||
|
$(HARDNESTEDLIB):
|
||||||
|
$(info [*] MAKE hardnested)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) all
|
||||||
|
|
||||||
$(AMIIBOLIB):
|
$(AMIIBOLIB):
|
||||||
$(info [*] MAKE amiibo)
|
$(info [*] MAKE amiibo)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all
|
||||||
|
|
||||||
|
$(CLIPARSERLIB):
|
||||||
|
$(info [*] MAKE cliparser)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) all
|
||||||
|
|
||||||
# common libraries:
|
# common libraries:
|
||||||
$(MBEDTLSLIB):
|
$(MBEDTLSLIB):
|
||||||
$(info [*] MAKE mbedtls)
|
$(info [*] MAKE mbedtls)
|
||||||
|
@ -399,42 +381,6 @@ $(ZLIB):
|
||||||
# easy printing of MAKE VARIABLES
|
# easy printing of MAKE VARIABLES
|
||||||
print-%: ; @echo $* = $($*)
|
print-%: ; @echo $* = $($*)
|
||||||
|
|
||||||
$(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d
|
|
||||||
$(info [-] CC(NOSIMD) $<)
|
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(PM3CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $<
|
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d && $(TOUCH) $@
|
|
||||||
|
|
||||||
$(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d
|
|
||||||
$(info [-] CC(MMX) $<)
|
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(PM3CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $<
|
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d && $(TOUCH) $@
|
|
||||||
|
|
||||||
$(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d
|
|
||||||
$(info [-] CC(SSE2) $<)
|
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(PM3CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $<
|
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d && $(TOUCH) $@
|
|
||||||
|
|
||||||
$(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d
|
|
||||||
$(info [-] CC(AVX) $<)
|
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $<
|
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d && $(TOUCH) $@
|
|
||||||
|
|
||||||
$(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d
|
|
||||||
$(info [-] CC(AVX2) $<)
|
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $<
|
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d && $(TOUCH) $@
|
|
||||||
|
|
||||||
$(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d
|
|
||||||
$(info [-] CC(AVX512) $<)
|
|
||||||
$(Q)$(MKDIR) $(dir $@)
|
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $<
|
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d && $(TOUCH) $@
|
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
||||||
$(info [-] CC $<)
|
$(info [-] CC $<)
|
||||||
|
@ -456,8 +402,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
|
||||||
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
|
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVENGSRCS)) \
|
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS)) \
|
||||||
$(patsubst %.o, %.d, $(MULTIARCHOBJS)) \
|
|
||||||
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
|
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
|
||||||
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \
|
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \
|
||||||
$(OBJDIR)/proxmark3.d
|
$(OBJDIR)/proxmark3.d
|
||||||
|
|
168
client/cmake/FindSSE.cmake
Normal file
168
client/cmake/FindSSE.cmake
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
# Check if SSE/AVX instructions are available on the machine where
|
||||||
|
# the project is compiled.
|
||||||
|
|
||||||
|
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
EXEC_PROGRAM(cat ARGS "/proc/cpuinfo" OUTPUT_VARIABLE CPUINFO)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(sse2).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "sse2" "${SSE_THERE}" SSE2_TRUE)
|
||||||
|
IF (SSE2_TRUE)
|
||||||
|
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
|
||||||
|
ELSE (SSE2_TRUE)
|
||||||
|
set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
|
||||||
|
ENDIF (SSE2_TRUE)
|
||||||
|
|
||||||
|
# /proc/cpuinfo apparently omits sse3 :(
|
||||||
|
STRING(REGEX REPLACE "^.*[^s](sse3).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "sse3" "${SSE_THERE}" SSE3_TRUE)
|
||||||
|
IF (NOT SSE3_TRUE)
|
||||||
|
STRING(REGEX REPLACE "^.*(T2300).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "T2300" "${SSE_THERE}" SSE3_TRUE)
|
||||||
|
ENDIF (NOT SSE3_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(ssse3).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "ssse3" "${SSE_THERE}" SSSE3_TRUE)
|
||||||
|
IF (SSE3_TRUE OR SSSE3_TRUE)
|
||||||
|
set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
|
||||||
|
ELSE (SSE3_TRUE OR SSSE3_TRUE)
|
||||||
|
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
|
||||||
|
ENDIF (SSE3_TRUE OR SSSE3_TRUE)
|
||||||
|
IF (SSSE3_TRUE)
|
||||||
|
set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
|
||||||
|
ELSE (SSSE3_TRUE)
|
||||||
|
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
|
||||||
|
ENDIF (SSSE3_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(sse4_1).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "sse4_1" "${SSE_THERE}" SSE41_TRUE)
|
||||||
|
IF (SSE41_TRUE)
|
||||||
|
set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
|
||||||
|
ELSE (SSE41_TRUE)
|
||||||
|
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
|
||||||
|
ENDIF (SSE41_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(avx).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "avx" "${SSE_THERE}" AVX_TRUE)
|
||||||
|
IF (AVX_TRUE)
|
||||||
|
set(AVX_FOUND true CACHE BOOL "AVX available on host")
|
||||||
|
ELSE (AVX_TRUE)
|
||||||
|
set(AVX_FOUND false CACHE BOOL "AVX available on host")
|
||||||
|
ENDIF (AVX_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(avx2).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "avx2" "${SSE_THERE}" AVX2_TRUE)
|
||||||
|
IF (AVX2_TRUE)
|
||||||
|
set(AVX2_FOUND true CACHE BOOL "AVX2 available on host")
|
||||||
|
ELSE (AVX2_TRUE)
|
||||||
|
set(AVX2_FOUND false CACHE BOOL "AVX2 available on host")
|
||||||
|
ENDIF (AVX2_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(avx512).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "avx512" "${SSE_THERE}" AVX2_TRUE)
|
||||||
|
IF (AVX512_TRUE)
|
||||||
|
set(AVX512_FOUND true CACHE BOOL "AVX512 available on host")
|
||||||
|
ELSE (AVX2_TRUE)
|
||||||
|
set(AVX512_FOUND false CACHE BOOL "AVX512 available on host")
|
||||||
|
ENDIF (AVX512_TRUE)
|
||||||
|
|
||||||
|
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
EXEC_PROGRAM("/usr/sbin/sysctl -n machdep.cpu.features" OUTPUT_VARIABLE
|
||||||
|
CPUINFO)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*[^S](SSE2).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "SSE2" "${SSE_THERE}" SSE2_TRUE)
|
||||||
|
IF (SSE2_TRUE)
|
||||||
|
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
|
||||||
|
ELSE (SSE2_TRUE)
|
||||||
|
set(SSE2_FOUND false CACHE BOOL "SSE2 available on host")
|
||||||
|
ENDIF (SSE2_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*[^S](SSE3).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "SSE3" "${SSE_THERE}" SSE3_TRUE)
|
||||||
|
IF (SSE3_TRUE)
|
||||||
|
set(SSE3_FOUND true CACHE BOOL "SSE3 available on host")
|
||||||
|
ELSE (SSE3_TRUE)
|
||||||
|
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
|
||||||
|
ENDIF (SSE3_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(SSSE3).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "SSSE3" "${SSE_THERE}" SSSE3_TRUE)
|
||||||
|
IF (SSSE3_TRUE)
|
||||||
|
set(SSSE3_FOUND true CACHE BOOL "SSSE3 available on host")
|
||||||
|
ELSE (SSSE3_TRUE)
|
||||||
|
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
|
||||||
|
ENDIF (SSSE3_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "SSE4.1" "${SSE_THERE}" SSE41_TRUE)
|
||||||
|
IF (SSE41_TRUE)
|
||||||
|
set(SSE4_1_FOUND true CACHE BOOL "SSE4.1 available on host")
|
||||||
|
ELSE (SSE41_TRUE)
|
||||||
|
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
|
||||||
|
ENDIF (SSE41_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(AVX).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "AVX" "${SSE_THERE}" AVX_TRUE)
|
||||||
|
IF (AVX_TRUE)
|
||||||
|
set(AVX_FOUND true CACHE BOOL "AVX available on host")
|
||||||
|
ELSE (AVX_TRUE)
|
||||||
|
set(AVX_FOUND false CACHE BOOL "AVX available on host")
|
||||||
|
ENDIF (AVX_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(AVX2).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "AVX2" "${SSE_THERE}" AVX2_TRUE)
|
||||||
|
IF (AVX2_TRUE)
|
||||||
|
set(AVX2_FOUND true CACHE BOOL "AVX2 available on host")
|
||||||
|
ELSE (AVX2_TRUE)
|
||||||
|
set(AVX2_FOUND false CACHE BOOL "AVX2 available on host")
|
||||||
|
ENDIF (AVX2_TRUE)
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^.*(AVX512).*$" "\\1" SSE_THERE ${CPUINFO})
|
||||||
|
STRING(COMPARE EQUAL "AVX512" "${SSE_THERE}" AVX2_TRUE)
|
||||||
|
IF (AVX2_TRUE)
|
||||||
|
set(AVX2_FOUND true CACHE BOOL "AVX512 available on host")
|
||||||
|
ELSE (AVX2_TRUE)
|
||||||
|
set(AVX2_FOUND false CACHE BOOL "AVX512 available on host")
|
||||||
|
ENDIF (AVX2_TRUE)
|
||||||
|
|
||||||
|
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
|
# TODO
|
||||||
|
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
|
||||||
|
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
|
||||||
|
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
|
||||||
|
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
|
||||||
|
set(AVX_FOUND false CACHE BOOL "AVX available on host")
|
||||||
|
set(AVX2_FOUND false CACHE BOOL "AVX2 available on host")
|
||||||
|
set(AVX512_FOUND false CACHE BOOL "AVX512 available on host")
|
||||||
|
ELSE(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
set(SSE2_FOUND true CACHE BOOL "SSE2 available on host")
|
||||||
|
set(SSE3_FOUND false CACHE BOOL "SSE3 available on host")
|
||||||
|
set(SSSE3_FOUND false CACHE BOOL "SSSE3 available on host")
|
||||||
|
set(SSE4_1_FOUND false CACHE BOOL "SSE4.1 available on host")
|
||||||
|
set(AVX_FOUND false CACHE BOOL "AVX available on host")
|
||||||
|
set(AVX2_FOUND false CACHE BOOL "AVX2 available on host")
|
||||||
|
set(AVX512_FOUND false CACHE BOOL "AVX512 available on host")
|
||||||
|
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
|
||||||
|
if(NOT SSE2_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSE2 on this machine.")
|
||||||
|
endif(NOT SSE2_FOUND)
|
||||||
|
if(NOT SSE3_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSE3 on this machine.")
|
||||||
|
endif(NOT SSE3_FOUND)
|
||||||
|
if(NOT SSSE3_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSSE3 on this machine.")
|
||||||
|
endif(NOT SSSE3_FOUND)
|
||||||
|
if(NOT SSE4_1_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for SSE4.1 on this machine.")
|
||||||
|
endif(NOT SSE4_1_FOUND)
|
||||||
|
if(NOT AVX_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for AVX on this machine.")
|
||||||
|
endif(NOT AVX_FOUND)
|
||||||
|
if(NOT AVX2_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for AVX2 on this machine.")
|
||||||
|
endif(NOT AVX2_FOUND)
|
||||||
|
if(NOT AVX512_FOUND)
|
||||||
|
MESSAGE(STATUS "Could not find hardware support for AVX512 on this machine.")
|
||||||
|
endif(NOT AVX512_FOUND)
|
||||||
|
mark_as_advanced(SSE2_FOUND SSE3_FOUND SSSE3_FOUND SSE4_1_FOUND, AVX_FOUND, AVX2_FOUND)
|
9
client/deps/CMakeLists.txt
Normal file
9
client/deps/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
include(cliparser.cmake)
|
||||||
|
include(tinycbor.cmake)
|
||||||
|
include(jansson.cmake)
|
||||||
|
include(lua.cmake)
|
||||||
|
include(mbedtls.cmake)
|
||||||
|
include(amiibo.cmake)
|
||||||
|
include(reveng.cmake)
|
||||||
|
include(zlib.cmake)
|
||||||
|
include(hardnested.cmake)
|
18
client/deps/amiibo.cmake
Normal file
18
client/deps/amiibo.cmake
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# just for testing amiitool before complete migration into a lib:
|
||||||
|
|
||||||
|
#amiitool:
|
||||||
|
#gcc $(CFLAGS) \
|
||||||
|
#amiitool.c $(MYSRCS) ../../../../common/../../commonutil.c ../ui.c -lreadline -lm ../../../../common/mbedtls/libmbedtls.a \
|
||||||
|
#-o amiitool
|
||||||
|
|
||||||
|
set_property(SOURCE PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
add_library(amiibo STATIC
|
||||||
|
amiitool/amiibo.c
|
||||||
|
amiitool/drbg.c
|
||||||
|
amiitool/keygen.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(amiibo PRIVATE ../../include ../../common)
|
||||||
|
target_include_directories(amiibo INTERFACE amiitool)
|
||||||
|
target_compile_options(amiibo PRIVATE -Wall -Werror -O3)
|
|
@ -9,6 +9,9 @@ MYSRCS = \
|
||||||
|
|
||||||
LIB_A = libamiibo.a
|
LIB_A = libamiibo.a
|
||||||
|
|
||||||
|
# Transition: remove old directories and objects
|
||||||
|
MYCLEANOLDPATH = ../../amiitool
|
||||||
|
|
||||||
include ../../../Makefile.host
|
include ../../../Makefile.host
|
||||||
|
|
||||||
# just for testing amiitool before complete migration into a lib:
|
# just for testing amiitool before complete migration into a lib:
|
||||||
|
|
11
client/deps/cliparser.cmake
Normal file
11
client/deps/cliparser.cmake
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
add_library(cliparser STATIC
|
||||||
|
cliparser/argtable3.c
|
||||||
|
cliparser/cliparser.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(cliparser PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include
|
||||||
|
../src)
|
||||||
|
target_include_directories(cliparser INTERFACE cliparser)
|
||||||
|
target_compile_options(cliparser PRIVATE -Wall -Werror -O3)
|
11
client/deps/cliparser/Makefile
Normal file
11
client/deps/cliparser/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
MYSRCPATHS =
|
||||||
|
MYINCLUDES = -I../../../common -I../../../include -I../../src
|
||||||
|
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
|
||||||
|
MYDEFS =
|
||||||
|
MYSRCS = \
|
||||||
|
argtable3.c \
|
||||||
|
cliparser.c
|
||||||
|
|
||||||
|
LIB_A = libcliparser.a
|
||||||
|
|
||||||
|
include ../../../Makefile.host
|
108
client/deps/hardnested.cmake
Normal file
108
client/deps/hardnested.cmake
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
set_property(SOURCE PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
## CPU-specific code
|
||||||
|
## These are mostly for x86-based architectures, which is not useful for many Android devices.
|
||||||
|
add_library(hardnested_nosimd OBJECT
|
||||||
|
hardnested/hardnested_bf_core.c
|
||||||
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
|
target_include_directories(hardnested_nosimd PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include)
|
||||||
|
target_compile_options(hardnested_nosimd PRIVATE -Wall -Werror -O3)
|
||||||
|
|
||||||
|
set(X86_CPUS x86 x86_64 i686)
|
||||||
|
|
||||||
|
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
|
||||||
|
if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS)
|
||||||
|
message(STATUS "Building optimised x86/x86_64 binaries")
|
||||||
|
target_compile_options(hardnested_nosimd BEFORE PRIVATE
|
||||||
|
-mno-mmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||||
|
|
||||||
|
## x86 / MMX
|
||||||
|
add_library(hardnested_mmx OBJECT
|
||||||
|
hardnested/hardnested_bf_core.c
|
||||||
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
|
target_compile_options(hardnested_mmx PRIVATE -Wall -Werror -O3)
|
||||||
|
target_compile_options(hardnested_mmx BEFORE PRIVATE
|
||||||
|
-mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||||
|
|
||||||
|
target_include_directories(hardnested_mmx PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include)
|
||||||
|
|
||||||
|
## x86 / SSE2
|
||||||
|
add_library(hardnested_sse2 OBJECT
|
||||||
|
hardnested/hardnested_bf_core.c
|
||||||
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
|
target_compile_options(hardnested_sse2 PRIVATE -Wall -Werror -O3)
|
||||||
|
target_compile_options(hardnested_sse2 BEFORE PRIVATE
|
||||||
|
-mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f)
|
||||||
|
|
||||||
|
target_include_directories(hardnested_sse2 PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include)
|
||||||
|
|
||||||
|
## x86 / AVX
|
||||||
|
add_library(hardnested_avx OBJECT
|
||||||
|
hardnested/hardnested_bf_core.c
|
||||||
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
|
target_compile_options(hardnested_avx PRIVATE -Wall -Werror -O3)
|
||||||
|
target_compile_options(hardnested_avx BEFORE PRIVATE
|
||||||
|
-mmmx -msse2 -mavx -mno-avx2 -mno-avx512f)
|
||||||
|
|
||||||
|
target_include_directories(hardnested_avx PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include)
|
||||||
|
|
||||||
|
## x86 / AVX2
|
||||||
|
add_library(hardnested_avx2 OBJECT
|
||||||
|
hardnested/hardnested_bf_core.c
|
||||||
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
|
target_compile_options(hardnested_avx2 PRIVATE -Wall -Werror -O3)
|
||||||
|
target_compile_options(hardnested_avx2 BEFORE PRIVATE
|
||||||
|
-mmmx -msse2 -mavx -mavx2 -mno-avx512f)
|
||||||
|
|
||||||
|
target_include_directories(hardnested_avx2 PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include)
|
||||||
|
|
||||||
|
## x86 / AVX512
|
||||||
|
add_library(hardnested_avx512 OBJECT
|
||||||
|
hardnested/hardnested_bf_core.c
|
||||||
|
hardnested/hardnested_bitarray_core.c)
|
||||||
|
|
||||||
|
target_compile_options(hardnested_avx512 PRIVATE -Wall -Werror -O3)
|
||||||
|
target_compile_options(hardnested_avx512 BEFORE PRIVATE
|
||||||
|
-mmmx -msse2 -mavx -mavx2 -mavx512f)
|
||||||
|
|
||||||
|
target_include_directories(hardnested_avx512 PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include)
|
||||||
|
|
||||||
|
set(SIMD_TARGETS
|
||||||
|
$<TARGET_OBJECTS:hardnested_mmx>
|
||||||
|
$<TARGET_OBJECTS:hardnested_sse2>
|
||||||
|
$<TARGET_OBJECTS:hardnested_avx>
|
||||||
|
$<TARGET_OBJECTS:hardnested_avx2>
|
||||||
|
$<TARGET_OBJECTS:hardnested_avx512>)
|
||||||
|
else ()
|
||||||
|
message(STATUS "Not building optimised targets")
|
||||||
|
set(SIMD_TARGETS)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_library(hardnested STATIC
|
||||||
|
hardnested/hardnested_bruteforce.c
|
||||||
|
$<TARGET_OBJECTS:hardnested_nosimd>
|
||||||
|
${SIMD_TARGETS})
|
||||||
|
target_include_directories(hardnested PRIVATE
|
||||||
|
../../common
|
||||||
|
../../include
|
||||||
|
../src
|
||||||
|
jansson)
|
||||||
|
target_include_directories(hardnested INTERFACE hardnested)
|
83
client/deps/hardnested/Makefile
Normal file
83
client/deps/hardnested/Makefile
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
MYSRCPATHS =
|
||||||
|
MYINCLUDES = -I../../../common -I../../../include -I../../src -I../jansson
|
||||||
|
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
|
||||||
|
MYDEFS =
|
||||||
|
MYSRCS = hardnested_bruteforce.c
|
||||||
|
|
||||||
|
cpu_arch = $(shell uname -m)
|
||||||
|
ifneq ($(findstring 86, $(cpu_arch)), )
|
||||||
|
MULTIARCHSRCS = hardnested_bf_core.c hardnested_bitarray_core.c
|
||||||
|
endif
|
||||||
|
ifneq ($(findstring amd64, $(cpu_arch)), )
|
||||||
|
MULTIARCHSRCS = hardnested_bf_core.c hardnested_bitarray_core.c
|
||||||
|
endif
|
||||||
|
ifeq ($(MULTIARCHSRCS), )
|
||||||
|
MYSRCS += hardnested_bf_core.c hardnested_bitarray_core.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
LIB_A = libhardnested.a
|
||||||
|
|
||||||
|
MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
|
MYOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \
|
||||||
|
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \
|
||||||
|
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \
|
||||||
|
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX.o) \
|
||||||
|
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX2.o)
|
||||||
|
|
||||||
|
SUPPORTS_AVX512 := $(shell echo | gcc -E -mavx512f - > /dev/null 2>&1 && echo "True" )
|
||||||
|
|
||||||
|
HARD_SWITCH_NOSIMD = -mno-mmx -mno-sse2 -mno-avx -mno-avx2
|
||||||
|
HARD_SWITCH_MMX = -mmmx -mno-sse2 -mno-avx -mno-avx2
|
||||||
|
HARD_SWITCH_SSE2 = -mmmx -msse2 -mno-avx -mno-avx2
|
||||||
|
HARD_SWITCH_AVX = -mmmx -msse2 -mavx -mno-avx2
|
||||||
|
HARD_SWITCH_AVX2 = -mmmx -msse2 -mavx -mavx2
|
||||||
|
HARD_SWITCH_AVX512 = -mmmx -msse2 -mavx -mavx2 -mavx512f
|
||||||
|
ifeq "$(SUPPORTS_AVX512)" "True"
|
||||||
|
HARD_SWITCH_NOSIMD += -mno-avx512f
|
||||||
|
HARD_SWITCH_MMX += -mno-avx512f
|
||||||
|
HARD_SWITCH_SSE2 += -mno-avx512f
|
||||||
|
HARD_SWITCH_AVX += -mno-avx512f
|
||||||
|
HARD_SWITCH_AVX2 += -mno-avx512f
|
||||||
|
MYOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o)
|
||||||
|
endif
|
||||||
|
|
||||||
|
include ../../../Makefile.host
|
||||||
|
|
||||||
|
$(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d
|
||||||
|
$(info DEBUG $<)
|
||||||
|
|
||||||
|
$(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d
|
||||||
|
$(info [-] CC(NOSIMD) $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d && $(TOUCH) $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d
|
||||||
|
$(info [-] CC(MMX) $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d && $(TOUCH) $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d
|
||||||
|
$(info [-] CC(SSE2) $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d && $(TOUCH) $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d
|
||||||
|
$(info [-] CC(AVX) $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d && $(TOUCH) $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d
|
||||||
|
$(info [-] CC(AVX2) $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d && $(TOUCH) $@
|
||||||
|
|
||||||
|
$(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d
|
||||||
|
$(info [-] CC(AVX512) $<)
|
||||||
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d && $(TOUCH) $@
|
20
client/deps/jansson.cmake
Normal file
20
client/deps/jansson.cmake
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
set_property(SOURCE PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
add_library(jansson STATIC
|
||||||
|
jansson/dump.c
|
||||||
|
jansson/error.c
|
||||||
|
jansson/hashtable.c
|
||||||
|
jansson/hashtable_seed.c
|
||||||
|
jansson/load.c
|
||||||
|
jansson/memory.c
|
||||||
|
jansson/pack_unpack.c
|
||||||
|
jansson/strbuffer.c
|
||||||
|
jansson/strconv.c
|
||||||
|
jansson/utf.c
|
||||||
|
jansson/path.c
|
||||||
|
jansson/value.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(jansson PRIVATE HAVE_STDINT_H)
|
||||||
|
target_include_directories(jansson INTERFACE jansson)
|
||||||
|
target_compile_options(jansson PRIVATE -Wall -Werror -Wno-unused-function -O3)
|
|
@ -18,4 +18,7 @@ MYSRCS = \
|
||||||
|
|
||||||
LIB_A = libjansson.a
|
LIB_A = libjansson.a
|
||||||
|
|
||||||
|
# Transition: remove old directories and objects
|
||||||
|
MYCLEANOLDPATH = ../../jansson
|
||||||
|
|
||||||
include ../../../Makefile.host
|
include ../../../Makefile.host
|
||||||
|
|
|
@ -14,6 +14,9 @@ SYSCFLAGS=
|
||||||
|
|
||||||
LIB_A= liblua.a
|
LIB_A= liblua.a
|
||||||
|
|
||||||
|
# Transition: remove old directories and objects
|
||||||
|
MYCLEANOLDPATH = ../../liblua
|
||||||
|
|
||||||
# Your platform. See PLATS for possible values.
|
# Your platform. See PLATS for possible values.
|
||||||
PLAT= none
|
PLAT= none
|
||||||
|
|
||||||
|
|
48
client/deps/lua.cmake
Normal file
48
client/deps/lua.cmake
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
add_library(lua STATIC
|
||||||
|
liblua/lapi.c
|
||||||
|
liblua/lcode.c
|
||||||
|
liblua/lctype.c
|
||||||
|
liblua/ldebug.c
|
||||||
|
liblua/ldo.c
|
||||||
|
liblua/ldump.c
|
||||||
|
liblua/lfunc.c
|
||||||
|
liblua/lgc.c
|
||||||
|
liblua/llex.c
|
||||||
|
liblua/lmem.c
|
||||||
|
liblua/lobject.c
|
||||||
|
liblua/lopcodes.c
|
||||||
|
liblua/lparser.c
|
||||||
|
liblua/lstate.c
|
||||||
|
liblua/lstring.c
|
||||||
|
liblua/ltable.c
|
||||||
|
liblua/ltm.c
|
||||||
|
liblua/lundump.c
|
||||||
|
liblua/lvm.c
|
||||||
|
liblua/lzio.c
|
||||||
|
liblua/lauxlib.c
|
||||||
|
liblua/lbaselib.c
|
||||||
|
liblua/lbitlib.c
|
||||||
|
liblua/lcorolib.c
|
||||||
|
liblua/ldblib.c
|
||||||
|
liblua/liolib.c
|
||||||
|
liblua/lmathlib.c
|
||||||
|
liblua/loslib.c
|
||||||
|
liblua/lstrlib.c
|
||||||
|
liblua/ltablib.c
|
||||||
|
liblua/loadlib.c
|
||||||
|
liblua/linit.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(lua PRIVATE LUA_COMPAT_ALL)
|
||||||
|
|
||||||
|
if (NOT MINGW)
|
||||||
|
if (APPLE)
|
||||||
|
target_compile_definitions(lua PRIVATE LUA_USE_MACOSX)
|
||||||
|
else (APPLE)
|
||||||
|
target_compile_definitions(lua PRIVATE LUA_USE_LINUX)
|
||||||
|
target_link_libraries(lua INTERFACE dl)
|
||||||
|
endif (APPLE)
|
||||||
|
endif (NOT MINGW)
|
||||||
|
|
||||||
|
target_include_directories(lua INTERFACE liblua)
|
||||||
|
target_compile_options(lua PRIVATE -Wall -Werror -O3)
|
50
client/deps/mbedtls.cmake
Normal file
50
client/deps/mbedtls.cmake
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
set_property(SOURCE PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
add_library(mbedtls STATIC
|
||||||
|
../../common/mbedtls/aes.c
|
||||||
|
../../common/mbedtls/asn1parse.c
|
||||||
|
../../common/mbedtls/asn1write.c
|
||||||
|
../../common/mbedtls/base64.c
|
||||||
|
../../common/mbedtls/bignum.c
|
||||||
|
../../common/mbedtls/ctr_drbg.c
|
||||||
|
../../common/mbedtls/entropy_poll.c
|
||||||
|
../../common/mbedtls/entropy.c
|
||||||
|
../../common/mbedtls/error.c
|
||||||
|
../../common/mbedtls/timing.c
|
||||||
|
../../common/mbedtls/ecp.c
|
||||||
|
../../common/mbedtls/ecp_curves.c
|
||||||
|
../../common/mbedtls/certs.c
|
||||||
|
../../common/mbedtls/camellia.c
|
||||||
|
../../common/mbedtls/blowfish.c
|
||||||
|
../../common/mbedtls/cipher_wrap.c
|
||||||
|
../../common/mbedtls/cipher.c
|
||||||
|
../../common/mbedtls/cmac.c
|
||||||
|
../../common/mbedtls/des.c
|
||||||
|
../../common/mbedtls/ecdsa.c
|
||||||
|
../../common/mbedtls/md.c
|
||||||
|
../../common/mbedtls/md_wrap.c
|
||||||
|
../../common/mbedtls/md5.c
|
||||||
|
../../common/mbedtls/oid.c
|
||||||
|
../../common/mbedtls/pem.c
|
||||||
|
../../common/mbedtls/arc4.c
|
||||||
|
../../common/mbedtls/pk.c
|
||||||
|
../../common/mbedtls/pk_wrap.c
|
||||||
|
../../common/mbedtls/pkwrite.c
|
||||||
|
../../common/mbedtls/pkcs5.c
|
||||||
|
../../common/mbedtls/pkcs12.c
|
||||||
|
../../common/mbedtls/pkparse.c
|
||||||
|
../../common/mbedtls/platform.c
|
||||||
|
../../common/mbedtls/platform_util.c
|
||||||
|
../../common/mbedtls/rsa.c
|
||||||
|
../../common/mbedtls/rsa_internal.c
|
||||||
|
../../common/mbedtls/sha1.c
|
||||||
|
../../common/mbedtls/sha256.c
|
||||||
|
../../common/mbedtls/sha512.c
|
||||||
|
../../common/mbedtls/threading.c
|
||||||
|
../../common/mbedtls/x509.c
|
||||||
|
../../common/mbedtls/x509_crl.c
|
||||||
|
../../common/mbedtls/x509_crt.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(mbedtls PRIVATE ../../common)
|
||||||
|
target_compile_options(mbedtls PRIVATE -Wall -Werror -O3)
|
15
client/deps/reveng.cmake
Normal file
15
client/deps/reveng.cmake
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
set_property(SOURCE PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
add_library(reveng STATIC
|
||||||
|
reveng/bmpbit.c
|
||||||
|
reveng/cli.c
|
||||||
|
reveng/model.c
|
||||||
|
reveng/poly.c
|
||||||
|
reveng/preset.c
|
||||||
|
reveng/reveng.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(reveng PRIVATE PRESETS)
|
||||||
|
target_include_directories(reveng PRIVATE ../cliparser)
|
||||||
|
target_include_directories(reveng INTERFACE reveng)
|
||||||
|
target_compile_options(reveng PRIVATE -Wall -Werror -O3)
|
|
@ -4,13 +4,12 @@
|
||||||
# Add -DPRESETS to compile with preset models (edit config.h)
|
# Add -DPRESETS to compile with preset models (edit config.h)
|
||||||
|
|
||||||
MYSRCPATHS =
|
MYSRCPATHS =
|
||||||
MYINCLUDES = -I. -I..
|
MYINCLUDES = -I../cliparser
|
||||||
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
|
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
|
||||||
MYDEFS = -DPRESETS
|
MYDEFS = -DPRESETS
|
||||||
MYSRCS = \
|
MYSRCS = \
|
||||||
bmpbit.c \
|
bmpbit.c \
|
||||||
cli.c \
|
cli.c \
|
||||||
getopt.c \
|
|
||||||
model.c \
|
model.c \
|
||||||
poly.c \
|
poly.c \
|
||||||
preset.c \
|
preset.c \
|
||||||
|
@ -18,6 +17,9 @@ MYSRCS = \
|
||||||
|
|
||||||
LIB_A = libreveng.a
|
LIB_A = libreveng.a
|
||||||
|
|
||||||
|
# Transition: remove old directories and objects
|
||||||
|
MYCLEANOLDPATH = ../../reveng
|
||||||
|
|
||||||
include ../../../Makefile.host
|
include ../../../Makefile.host
|
||||||
|
|
||||||
CLEAN += bmptst
|
CLEAN += bmptst
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "cliparser/getopt.h"
|
#include "getopt.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Replacement for Unix "getopt()", for DOS/Windows/etc.
|
|
||||||
|
|
||||||
getopt.c 1.3 2003/09/17 16:17:59
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2003 by David A. Hinds -- All Rights Reserved
|
|
||||||
|
|
||||||
This file is part of ASPEX.
|
|
||||||
|
|
||||||
ASPEX is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
ASPEX is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with ASPEX; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "getopt.h"
|
|
||||||
|
|
||||||
char *optarg;
|
|
||||||
int optind = 1, opterr, optopt;
|
|
||||||
int pos = 0;
|
|
||||||
int getopt(int argc, char *argv[], const char *optstring) {
|
|
||||||
//static int pos = 0;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
if (pos == 0) {
|
|
||||||
if ((optind >= argc) || (*argv[optind] != '-'))
|
|
||||||
return EOF;
|
|
||||||
pos = 1;
|
|
||||||
if (argv[optind][pos] == '\0')
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = strchr(optstring, argv[optind][pos]);
|
|
||||||
if (str == NULL) {
|
|
||||||
optopt = argv[optind][pos];
|
|
||||||
if (opterr)
|
|
||||||
fprintf(stderr, "%s: illegal option -- %c\n", argv[0],
|
|
||||||
optopt);
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str[1] == ':') {
|
|
||||||
if (argv[optind][pos + 1] != '\0') {
|
|
||||||
optarg = &argv[optind][pos + 1];
|
|
||||||
return *str;
|
|
||||||
}
|
|
||||||
optind++;
|
|
||||||
if (optind >= argc) {
|
|
||||||
optopt = *str;
|
|
||||||
if (opterr)
|
|
||||||
fprintf(stderr, "%s: option requires an argument -- %c\n",
|
|
||||||
argv[0], optopt);
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
optarg = argv[optind];
|
|
||||||
optind++;
|
|
||||||
pos = 0;
|
|
||||||
return *str;
|
|
||||||
} else {
|
|
||||||
pos++;
|
|
||||||
if (argv[optind][pos] == '\0') {
|
|
||||||
optind++;
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
return *str;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
getopt.h 1.2 2003/09/17 16:17:59
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2003 by David A. Hinds -- All Rights Reserved
|
|
||||||
|
|
||||||
This file is part of ASPEX.
|
|
||||||
|
|
||||||
ASPEX is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
ASPEX is distributed in the hope that it will be useful, but
|
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with ASPEX; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GETOPT_H
|
|
||||||
#define __GETOPT_H
|
|
||||||
|
|
||||||
extern char *optarg;
|
|
||||||
extern int optind, opterr, optopt, pos;
|
|
||||||
int getopt(int argc, char *argv[], const char *optstring);
|
|
||||||
|
|
||||||
#endif
|
|
14
client/deps/tinycbor.cmake
Normal file
14
client/deps/tinycbor.cmake
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
add_library(tinycbor STATIC
|
||||||
|
tinycbor/cborencoder.c
|
||||||
|
tinycbor/cborencoder_close_container_checked.c
|
||||||
|
tinycbor/cborerrorstrings.c
|
||||||
|
tinycbor/cborparser.c
|
||||||
|
tinycbor/cborparser_dup_string.c
|
||||||
|
tinycbor/cborpretty.c
|
||||||
|
tinycbor/cbortojson.c
|
||||||
|
tinycbor/cborvalidation.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(tinycbor INTERFACE tinycbor)
|
||||||
|
# Strange errors on Mingw when compiling with -O3
|
||||||
|
target_compile_options(tinycbor PRIVATE -Wall -Werror -O2)
|
|
@ -16,6 +16,9 @@ MYSRCS = \
|
||||||
|
|
||||||
LIB_A = tinycbor.a
|
LIB_A = tinycbor.a
|
||||||
|
|
||||||
|
# Transition: remove old directories and objects
|
||||||
|
MYCLEANOLDPATH = ../../tinycbor
|
||||||
|
|
||||||
# Strange errors on Mingw when compiling with -O3
|
# Strange errors on Mingw when compiling with -O3
|
||||||
CFLAGS ?= -Wall -Werror -O2
|
CFLAGS ?= -Wall -Werror -O2
|
||||||
|
|
||||||
|
|
14
client/deps/zlib.cmake
Normal file
14
client/deps/zlib.cmake
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
set_property(SOURCE PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
|
add_library(z STATIC
|
||||||
|
../../common/zlib/deflate.c
|
||||||
|
../../common/zlib/adler32.c
|
||||||
|
../../common/zlib/trees.c
|
||||||
|
../../common/zlib/zutil.c
|
||||||
|
../../common/zlib/inflate.c
|
||||||
|
../../common/zlib/inffast.c
|
||||||
|
../../common/zlib/inftrees.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(z PRIVATE Z_SOLO NO_GZIP ZLIB_PM3_TUNED)
|
||||||
|
target_compile_options(z PRIVATE -Wall -Werror -O3)
|
44
client/dictionaries/mfdes_default_keys.dic
Normal file
44
client/dictionaries/mfdes_default_keys.dic
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
0000000000000000 #NXP Default DES
|
||||||
|
7544d1652bc9bd43
|
||||||
|
00000000000000000000000000000000 #NXP Default 3DES/AES
|
||||||
|
000000000000000000000000000000000000000000000000 #NXP Default 3K3DES
|
||||||
|
00112233445566778899AABBCCDDEEFF #TI TRF7970A sloa213
|
||||||
|
79702553797025537970255379702553 #TI TRF7970A sloa213
|
||||||
|
4E617468616E2E4C6920546564647920
|
||||||
|
43464F494D48504E4C4359454E528841 #NHIF
|
||||||
|
6AC292FAA1315B4D858AB3A3D7D5933A
|
||||||
|
404142434445464748494a4b4c4d4e4f
|
||||||
|
00112233445566778899aabbccddeeff
|
||||||
|
2b7e151628aed2a6abf7158809cf4f3c
|
||||||
|
fbeed618357133667c85e08f7236a8de
|
||||||
|
f7ddac306ae266ccf90bc11ee46d513b
|
||||||
|
54686973206973206D79206B65792020
|
||||||
|
ffffffffffffffffffffffffffffffff
|
||||||
|
a0a1a2a3a4a5a6a7a0a1a2a3a4a5a6a7
|
||||||
|
b0b1b2b3b4b5b6b7b0b1b2b3b4b5b6b7
|
||||||
|
b0b1b2b3b4b5b6b7b8b9babbbcbdbebf
|
||||||
|
d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7
|
||||||
|
11111111111111111111111111111111
|
||||||
|
22222222222222222222222222222222
|
||||||
|
33333333333333333333333333333333
|
||||||
|
44444444444444444444444444444444
|
||||||
|
55555555555555555555555555555555
|
||||||
|
66666666666666666666666666666666
|
||||||
|
77777777777777777777777777777777
|
||||||
|
88888888888888888888888888888888
|
||||||
|
99999999999999999999999999999999
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
|
cccccccccccccccccccccccccccccccc
|
||||||
|
dddddddddddddddddddddddddddddddd
|
||||||
|
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||||
|
000102030405060708090a0b0c0d0e0f
|
||||||
|
0102030405060708090a0b0c0d0e0f10
|
||||||
|
00010203040506070809101112131415
|
||||||
|
01020304050607080910111213141516
|
||||||
|
16151413121110090807060504030201
|
||||||
|
15141312111009080706050403020100
|
||||||
|
0f0e0d0c0b0a09080706050403020100
|
||||||
|
100f0e0d0c0b0a090807060504030201
|
||||||
|
404142434445464748494a4b4c4d4e4f
|
||||||
|
303132333435363738393a3b3c3d3e3f
|
|
@ -1,231 +0,0 @@
|
||||||
local utils = require('utils')
|
|
||||||
local getopt = require('getopt')
|
|
||||||
local read14a = require('read14a')
|
|
||||||
|
|
||||||
--[[
|
|
||||||
---Suggestions of improvement:
|
|
||||||
--- Add support another types of dumps: BIN, JSON
|
|
||||||
--- Maybe it will be not only as `mfc_gen3_writer`, like a universal dump manager.
|
|
||||||
--- Add undependence from the operation system. At the moment code not working in Linux.
|
|
||||||
--- Add more chinesse backdoors RAW commands for UID changing (find RAW for the 4 byte familiar chinese card, from native it soft: http://bit.ly/39VIDsU)
|
|
||||||
--- Hide system messages when you writing a dumps, replace it to some of like [#####----------] 40%
|
|
||||||
|
|
||||||
-- iceman notes:
|
|
||||||
-- doesn't take consideration filepaths for dump files.
|
|
||||||
-- doesn't allow A keys for authenticating when writing
|
|
||||||
-- doesn't verify that card is magic gen3.
|
|
||||||
-- doesn't take several versions of same dump ( -1, -2, -3 ) styles.
|
|
||||||
--]]
|
|
||||||
|
|
||||||
copyright = ''
|
|
||||||
author = 'Winds'
|
|
||||||
version = 'v1.0.0'
|
|
||||||
desc = [[
|
|
||||||
The script gives you a easy way to write your *.eml dumps onto normal MFC and magic Gen3 cards.
|
|
||||||
|
|
||||||
Works with both 4 and 7 bytes NXP MIFARE Classic 1K cards.
|
|
||||||
The script also has the possibility to change UID and permanent lock uid on magic Gen3 cards.
|
|
||||||
|
|
||||||
It supports the following functionality.
|
|
||||||
|
|
||||||
1. Write it to the same of current card UID.
|
|
||||||
2. Write it to magic Gen3 card.
|
|
||||||
3. Change uid to match dump on magic Gen3 card.
|
|
||||||
4. Permanent lock UID on magic Gen3 card.
|
|
||||||
5. Erase all data at the card and set the FF FF FF FF FF FF keys, and Access Conditions to 78778800.
|
|
||||||
|
|
||||||
Script works in a wizard styled way.
|
|
||||||
]]
|
|
||||||
example = [[
|
|
||||||
1. script run mfc_gen3_writer
|
|
||||||
]]
|
|
||||||
usage = [[
|
|
||||||
Select your *.eml dump from list to write to the card.
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- Some globals
|
|
||||||
local DEBUG = false -- the debug flag
|
|
||||||
|
|
||||||
-------------------------------
|
|
||||||
-- Some utilities
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
---
|
|
||||||
-- A debug printout-function
|
|
||||||
local function dbg(args)
|
|
||||||
if not DEBUG then return end
|
|
||||||
if type(args) == 'table' then
|
|
||||||
local i = 1
|
|
||||||
while args[i] do
|
|
||||||
dbg(args[i])
|
|
||||||
i = i+1
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print('###', args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- This is only meant to be used when errors occur
|
|
||||||
local function oops(err)
|
|
||||||
print('ERROR:', err)
|
|
||||||
core.clearCommandBuffer()
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- Usage help
|
|
||||||
local function help()
|
|
||||||
print(copyright)
|
|
||||||
print(author)
|
|
||||||
print(version)
|
|
||||||
print(desc)
|
|
||||||
print('Example usage')
|
|
||||||
print(example)
|
|
||||||
print(usage)
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- GetUID
|
|
||||||
local function GetUID()
|
|
||||||
return read14a.read(true, true).uid
|
|
||||||
end
|
|
||||||
---
|
|
||||||
--
|
|
||||||
local function dropfield()
|
|
||||||
read14a.disconnect()
|
|
||||||
core.clearCommandBuffer()
|
|
||||||
end
|
|
||||||
---
|
|
||||||
-- Wait for tag (MFC)
|
|
||||||
local function wait()
|
|
||||||
read14a.waitFor14443a()
|
|
||||||
end
|
|
||||||
---
|
|
||||||
--
|
|
||||||
local function main(args)
|
|
||||||
|
|
||||||
-- Arguments for the script
|
|
||||||
for o, a in getopt.getopt(args, 'hd') do
|
|
||||||
if o == 'h' then return help() end
|
|
||||||
if o == 'd' then DEBUG = true end
|
|
||||||
end
|
|
||||||
|
|
||||||
local files = {} -- Array for eml files
|
|
||||||
local b_keys = {} -- Array for B keys
|
|
||||||
local eml = {} -- Array for data in block 32
|
|
||||||
local num_dumps = 0 -- num of found eml dump files
|
|
||||||
|
|
||||||
local tab = string.rep('-', 64)
|
|
||||||
--
|
|
||||||
wait()
|
|
||||||
print(tab)
|
|
||||||
|
|
||||||
local length = 25
|
|
||||||
local e = 16
|
|
||||||
-- Detect 7 byte card
|
|
||||||
if string.len(GetUID()) == 14 then
|
|
||||||
length = 31
|
|
||||||
e = 22
|
|
||||||
end
|
|
||||||
dropfield()
|
|
||||||
|
|
||||||
---List all EML files in /client
|
|
||||||
local dumpEML = "find '.' -iname '*dump.eml' -type f"
|
|
||||||
local p = assert(io.popen(dumpEML))
|
|
||||||
for _ in p:lines() do
|
|
||||||
|
|
||||||
-- The length of eml file
|
|
||||||
if string.len(_) == length then
|
|
||||||
num_dumps = num_dumps + 1
|
|
||||||
-- cut UID from eml file
|
|
||||||
files[num_dumps] = string.sub(_, 9, e)
|
|
||||||
print(' '..num_dumps..' | '..files[num_dumps])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
p.close()
|
|
||||||
|
|
||||||
if num_dumps == 0 then return oops("Didn't find any dump files") end
|
|
||||||
|
|
||||||
print(tab)
|
|
||||||
print(' Your card has UID '..GetUID())
|
|
||||||
print('')
|
|
||||||
print(' Select which dump to write (1 until '..num_dumps..')')
|
|
||||||
print(tab)
|
|
||||||
io.write(' --> ')
|
|
||||||
|
|
||||||
local no = tonumber(io.read())
|
|
||||||
print(tab)
|
|
||||||
print(' You have been selected card dump ' .. no .. ', with UID : '..files[no])
|
|
||||||
|
|
||||||
--- Load eml file
|
|
||||||
local dumpfile = assert(io.open('./hf-mf-' .. files[no] .. '-dump.eml', 'r'))
|
|
||||||
for _ in dumpfile:lines() do table.insert(eml, _); end
|
|
||||||
dumpfile.close()
|
|
||||||
|
|
||||||
--- Extract B key from EML file
|
|
||||||
local b = 0
|
|
||||||
for i = 1, #eml do
|
|
||||||
if (i % 4 == 0) then
|
|
||||||
repeat
|
|
||||||
b = b + 1
|
|
||||||
-- Cut key from block
|
|
||||||
b_keys[b] = string.sub(eml[i], (#eml[i] - 11), #eml[i])
|
|
||||||
until b % 4 == 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print(tab)
|
|
||||||
dbg(b_keys)
|
|
||||||
dbg(eml)
|
|
||||||
|
|
||||||
--- Change UID on certain version of magic Gen3 card.
|
|
||||||
if (utils.confirm(' Change UID ?') == true) then
|
|
||||||
wait()
|
|
||||||
--core.console('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1]))
|
|
||||||
print('hf 14a raw -s -c -t 2000 90f0cccc10'..tostring(eml[1]))
|
|
||||||
print(tab)
|
|
||||||
print(' The new card UID : ' .. GetUID())
|
|
||||||
end
|
|
||||||
print(tab)
|
|
||||||
|
|
||||||
--- Lock UID
|
|
||||||
if (utils.confirm(' Permanent lock UID ? (card can never change uid again) ') == true) then
|
|
||||||
wait()
|
|
||||||
core.console('hf 14a raw -s -c -t 2000 90fd111100')
|
|
||||||
end
|
|
||||||
print(tab)
|
|
||||||
|
|
||||||
--- Writing blocks
|
|
||||||
local default_key = 'FFFFFFFFFFFF'
|
|
||||||
local default_key_blk = 'FFFFFFFFFFFF78778800FFFFFFFFFFFF'
|
|
||||||
local empty = string.rep('0', 32)
|
|
||||||
local cmd_wrbl = 'hf mf wrbl %d B %s %s'
|
|
||||||
|
|
||||||
if (utils.confirm(' Are you using a empty card with default key?') == true) then
|
|
||||||
wait()
|
|
||||||
for i = 1, #eml do
|
|
||||||
core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i]))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print(tab)
|
|
||||||
if (utils.confirm(' Delete ALL data and write all keys to 0x'..default_key..' ?') == true) then
|
|
||||||
wait()
|
|
||||||
for i = 1, #eml do
|
|
||||||
if (i % 4 == 0) then
|
|
||||||
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk))
|
|
||||||
else
|
|
||||||
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print(tab)
|
|
||||||
print('Writing to card')
|
|
||||||
wait()
|
|
||||||
for i = 1, #eml do
|
|
||||||
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i]))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
dropfield()
|
|
||||||
print(tab)
|
|
||||||
print('Done')
|
|
||||||
end
|
|
||||||
|
|
||||||
main(args)
|
|
390
client/luascripts/mfc_gen3_writer.lua
Normal file
390
client/luascripts/mfc_gen3_writer.lua
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
local utils = require('utils')
|
||||||
|
local getopt = require('getopt')
|
||||||
|
local cmds = require('commands')
|
||||||
|
local read14a = require('read14a')
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Notes
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
--[[
|
||||||
|
---Suggestions of improvement:
|
||||||
|
--- Add support another types of dumps: BIN, JSON
|
||||||
|
--- Maybe it will be not only as `mfc_gen3_writer`, like a universal dump manager.
|
||||||
|
--- Add undependence from the operation system. At the moment code not working in Linux.
|
||||||
|
--- Add more chinesse backdoors RAW commands for UID changing (find RAW for the 4 byte familiar chinese card, from native it soft: http://bit.ly/39VIDsU)
|
||||||
|
--- Hide system messages when you writing a dumps, replace it to some of like [#####----------] 40%
|
||||||
|
|
||||||
|
-- iceman notes:
|
||||||
|
-- doesn't take consideration filepaths for dump files.
|
||||||
|
-- doesn't allow A keys for authenticating when writing
|
||||||
|
-- doesn't verify that card is magic gen3.
|
||||||
|
-- doesn't take several versions of same dump ( -1, -2, -3 ) styles.
|
||||||
|
--]]
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Script hat
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
copyright = ''
|
||||||
|
author = 'Winds'
|
||||||
|
version = 'v1.0.0'
|
||||||
|
desc = [[
|
||||||
|
The script gives you a easy way to write your *.eml dumps onto normal MFC and magic Gen3 cards.
|
||||||
|
|
||||||
|
Works with both 4 and 7 bytes NXP MIFARE Classic 1K cards.
|
||||||
|
The script also has the possibility to change UID and permanent lock uid on magic Gen3 cards.
|
||||||
|
|
||||||
|
It supports the following functionality.
|
||||||
|
|
||||||
|
1. Write it to the same of current card UID.
|
||||||
|
2. Write it to magic Gen3 card.
|
||||||
|
3. Change uid to match dump on magic Gen3 card.
|
||||||
|
4. Permanent lock UID on magic Gen3 card.
|
||||||
|
5. Erase all data at the card and set the FF FF FF FF FF FF keys, and Access Conditions to 78778800.
|
||||||
|
|
||||||
|
Script works in a wizard styled way.
|
||||||
|
]]
|
||||||
|
example = [[
|
||||||
|
1. script run mfc_gen3_writer
|
||||||
|
]]
|
||||||
|
usage = [[
|
||||||
|
Select your *.eml dump from list to write to the card.
|
||||||
|
]]
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Global variables
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local DEBUG = false -- the debug flag
|
||||||
|
local files = {} -- Array for eml files
|
||||||
|
local b_keys = {} -- Array for B keys
|
||||||
|
local eml = {} -- Array for data in block 32
|
||||||
|
local num_dumps = 0 -- num of found eml dump files
|
||||||
|
local tab = string.rep('-', 64)
|
||||||
|
local empty = string.rep('0', 32) -- Writing blocks
|
||||||
|
local default_key = 'FFFFFFFFFFFF' -- Writing blocks
|
||||||
|
local default_key_type = '01' --KeyA: 00, KeyB: 01
|
||||||
|
local default_key_blk = 'FFFFFFFFFFFF78778800FFFFFFFFFFFF' -- Writing blocks
|
||||||
|
local piswords_uid_lock = 'hf 14a raw -s -c -t 2000 90fd111100'
|
||||||
|
local piswords_uid_change = 'hf 14a raw -s -c -t 2000 90f0cccc10'
|
||||||
|
local cmd_wrbl = 'hf mf wrbl %d B %s %s' -- Writing blocks
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- A debug printout-function
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function dbg(args)
|
||||||
|
if not DEBUG then return end
|
||||||
|
if type(args) == 'table' then
|
||||||
|
local i = 1
|
||||||
|
while args[i] do
|
||||||
|
dbg(args[i])
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print('###', args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- This is only meant to be used when errors occur
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function oops(err)
|
||||||
|
print('ERROR:', err)
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Usage help
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function help()
|
||||||
|
print(copyright)
|
||||||
|
print(author)
|
||||||
|
print(version)
|
||||||
|
print(desc)
|
||||||
|
print('Example usage')
|
||||||
|
print(example)
|
||||||
|
print(usage)
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- GetUID
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function GetUID()
|
||||||
|
return read14a.read(true, true).uid
|
||||||
|
end
|
||||||
|
--
|
||||||
|
local function dropfield()
|
||||||
|
read14a.disconnect()
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Wait for tag (MFC)
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function wait()
|
||||||
|
read14a.waitFor14443a()
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Return key code 00/01 to string
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function KeyAB()
|
||||||
|
if default_key_type == '00' then
|
||||||
|
return 'KeyA'
|
||||||
|
else
|
||||||
|
return 'KeyB'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Check response from Proxmark
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function getblockdata(response)
|
||||||
|
if response.Status == 0 then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Check 0xFFFFFFFFFFFF key for tag (MFC)
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function checkkey()
|
||||||
|
local status = 0
|
||||||
|
for i = 1, #eml do
|
||||||
|
cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_READBL, data = ('%02x%02x%s'):format((i-1), default_key_type, default_key)}
|
||||||
|
if (getblockdata(cmd:sendNG(false)) == true) then
|
||||||
|
status = status + 1
|
||||||
|
print(('%s %02s %s %s %s'):format(' ', (i-1), KeyAB(), default_key, 'OK'))
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if status == #eml then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Check Pissword backdor
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function checkmagic()
|
||||||
|
--Have no RAW ISO14443A command in appmain.c
|
||||||
|
cmd = Command:newNG{cmd = cmds.CMD_HF_ISO14443A_READER, data = piswords_uid_change .. GetUID()} -- sample check to pull the same UID to card and check response
|
||||||
|
if (getblockdata(cmd:sendNG(false)) == true) then
|
||||||
|
print('Magic')
|
||||||
|
else
|
||||||
|
print('Not magic')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Main function
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local function main(args)
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Arguments for script
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
for o, a in getopt.getopt(args, 'hd') do
|
||||||
|
if o == 'h' then return help() end
|
||||||
|
if o == 'd' then DEBUG = true end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
wait()
|
||||||
|
print(tab)
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Detect 7/4 byte card
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
if string.len(GetUID()) == 14 then
|
||||||
|
eml_file_uid_start = 18 -- For windows with '---------- ' prefix
|
||||||
|
eml_file_uid_end = 31
|
||||||
|
eml_file_lengt = 40
|
||||||
|
else
|
||||||
|
eml_file_uid_start = 18 -- For windows with '---------- ' prefix
|
||||||
|
eml_file_uid_end = 25
|
||||||
|
eml_file_lengt = 34
|
||||||
|
end
|
||||||
|
dropfield()
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- List all EML files in /client
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local dumpEML = 'find "." "*dump.eml"' -- Fixed for windows
|
||||||
|
local p = assert(io.popen(dumpEML))
|
||||||
|
for _ in p:lines() do
|
||||||
|
-- The length of eml file
|
||||||
|
if string.len(_) == eml_file_lengt then
|
||||||
|
num_dumps = num_dumps + 1
|
||||||
|
-- cut UID from eml file
|
||||||
|
files[num_dumps] = string.sub(_, eml_file_uid_start, eml_file_uid_end) -- cut numeretic UID
|
||||||
|
print(' '..num_dumps..' | '..files[num_dumps])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
p.close()
|
||||||
|
--
|
||||||
|
if num_dumps == 0 then return oops("Didn't find any dump files") end
|
||||||
|
--
|
||||||
|
print(tab)
|
||||||
|
print(' Your card has UID '..GetUID())
|
||||||
|
print('')
|
||||||
|
print(' Select which dump to write (1 until '..num_dumps..')')
|
||||||
|
print(tab)
|
||||||
|
io.write(' --> ')
|
||||||
|
--
|
||||||
|
local uid_no = tonumber(io.read())
|
||||||
|
print(tab)
|
||||||
|
print(' You have been selected card dump No ' .. uid_no .. ', with UID: ' .. files[uid_no] .. '. Your card UID: ' .. GetUID())
|
||||||
|
--
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Load eml file
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local dumpfile = assert(io.open('./hf-mf-' .. files[uid_no] .. '-dump.eml', 'r'))
|
||||||
|
for _ in dumpfile:lines() do table.insert(eml, _); end
|
||||||
|
dumpfile.close()
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Extract B key from EML file
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
local b = 0
|
||||||
|
for i = 1, #eml do
|
||||||
|
if (i % 4 == 0) then
|
||||||
|
repeat
|
||||||
|
b = b + 1
|
||||||
|
-- Cut key from block
|
||||||
|
b_keys[b] = string.sub(eml[i], (#eml[i] - 11), #eml[i])
|
||||||
|
until b % 4 == 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print(tab)
|
||||||
|
dbg(b_keys)
|
||||||
|
dbg(eml)
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Change UID on certain version of magic Gen3 card.
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
if (utils.confirm(' Change UID ?') == true) then
|
||||||
|
wait()
|
||||||
|
core.console(piswords_uid_change .. tostring(eml[1]))
|
||||||
|
print(tab)
|
||||||
|
print(' The new card UID : ' .. GetUID())
|
||||||
|
end
|
||||||
|
print(tab)
|
||||||
|
--checkmagic()
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Lock UID
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
if (utils.confirm(' Permanent lock UID ? (card can never change uid again) ') == true) then
|
||||||
|
wait()
|
||||||
|
core.console(piswords_uid_lock)
|
||||||
|
end
|
||||||
|
--
|
||||||
|
print(tab)
|
||||||
|
print(' Going to check the all ' .. KeyAB() .. ' by ' .. default_key)
|
||||||
|
print(tab)
|
||||||
|
--
|
||||||
|
if checkkey() == true then
|
||||||
|
print(tab)
|
||||||
|
if (utils.confirm(' Card is Empty. Write selected dump to card ?') == true) then
|
||||||
|
for i = 1, #eml do
|
||||||
|
core.console(string.format(cmd_wrbl, (i-1), default_key, eml[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print(tab)
|
||||||
|
if (utils.confirm(' Delete ALL data and write all keys to 0x' .. default_key .. ' ?') == true) then
|
||||||
|
wait()
|
||||||
|
for i = 1, #eml do
|
||||||
|
if (i % 4 == 0) then
|
||||||
|
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], default_key_blk))
|
||||||
|
else
|
||||||
|
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], empty))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print(tab)
|
||||||
|
if (utils.confirm(' Write selected dump to card ?') == true) then
|
||||||
|
print(tab)
|
||||||
|
wait()
|
||||||
|
for i = 1, #eml do
|
||||||
|
core.console(string.format(cmd_wrbl, (i-1), b_keys[i], eml[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dropfield()
|
||||||
|
print(tab)
|
||||||
|
print('You are welcome')
|
||||||
|
end
|
||||||
|
--
|
||||||
|
---
|
||||||
|
-------------------------------
|
||||||
|
-- Start Main function
|
||||||
|
-------------------------------
|
||||||
|
---
|
||||||
|
--
|
||||||
|
main(args)
|
|
@ -22,7 +22,7 @@
|
||||||
# endif /* STDIN_FILENO */
|
# endif /* STDIN_FILENO */
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include "reveng/reveng.h"
|
#include "reveng.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
#include "graph.h" // for graph data
|
#include "graph.h" // for graph data
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "lfdemod.h" // for demod code
|
#include "lfdemod.h" // for demod code
|
||||||
#include "../loclass/cipherutils.h" // for decimating samples in getsamples
|
#include "loclass/cipherutils.h" // for decimating samples in getsamples
|
||||||
#include "cmdlfem4x.h" // askem410xdecode
|
#include "cmdlfem4x.h" // askem410xdecode
|
||||||
#include "fileutils.h" // searchFile
|
#include "fileutils.h" // searchFile
|
||||||
#include "mifare/ndef.h"
|
#include "mifare/ndef.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
|
|
||||||
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||||
size_t DemodBufferLen = 0;
|
size_t DemodBufferLen = 0;
|
||||||
|
@ -101,13 +101,13 @@ static int usage_data_biphaserawdecode(void) {
|
||||||
static int usage_data_rawdemod(void) {
|
static int usage_data_rawdemod(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: data rawdemod [modulation] <help>|<options>");
|
PrintAndLogEx(NORMAL, "Usage: data rawdemod [modulation] <help>|<options>");
|
||||||
PrintAndLogEx(NORMAL, " [modulation] as 2 char,");
|
PrintAndLogEx(NORMAL, " [modulation] as 2 char,");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("ab")"- ask/biphase");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("ab")" - ask/biphase");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("am")"- ask/manchester");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("am")" - ask/manchester");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("ar")"- ask/raw");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("ar")" - ask/raw");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("fs")"- fsk");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("fs")" - fsk");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("nr")"- nrz/direct");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("nr")" - nrz/direct");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("p1")"- psk1");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("p1")" - psk1");
|
||||||
PrintAndLogEx(NORMAL, " "_YELLOW_("p2")"- psk2");
|
PrintAndLogEx(NORMAL, " "_YELLOW_("p2")" - psk2");
|
||||||
PrintAndLogEx(NORMAL, " <help> as 'h', prints the help for the specific modulation");
|
PrintAndLogEx(NORMAL, " <help> as 'h', prints the help for the specific modulation");
|
||||||
PrintAndLogEx(NORMAL, " <options> see specific modulation help for optional parameters");
|
PrintAndLogEx(NORMAL, " <options> see specific modulation help for optional parameters");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -843,7 +843,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG
|
||||||
// sanity check
|
// sanity check
|
||||||
if (window > len) window = len;
|
if (window > len) window = len;
|
||||||
|
|
||||||
if (verbose) PrintAndLogEx(INFO, "performing " _YELLOW_("%zu") "correlations", GraphTraceLen - window);
|
if (verbose) PrintAndLogEx(INFO, "performing " _YELLOW_("%zu") " correlations", GraphTraceLen - window);
|
||||||
|
|
||||||
//test
|
//test
|
||||||
double autocv = 0.0; // Autocovariance value
|
double autocv = 0.0; // Autocovariance value
|
||||||
|
@ -899,9 +899,9 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG
|
||||||
|
|
||||||
if (verbose && foo < bar) {
|
if (verbose && foo < bar) {
|
||||||
distance = idx_1 - idx;
|
distance = idx_1 - idx;
|
||||||
PrintAndLogEx(SUCCESS, "possible visible correlation "_YELLOW_("%4d") "samples", distance);
|
PrintAndLogEx(SUCCESS, "possible visible correlation "_YELLOW_("%4d") " samples", distance);
|
||||||
} else if (verbose && (correlation > 1)) {
|
} else if (verbose && (correlation > 1)) {
|
||||||
PrintAndLogEx(SUCCESS, "possible correlation " _YELLOW_("%4zu") "samples", correlation);
|
PrintAndLogEx(SUCCESS, "possible correlation " _YELLOW_("%4zu") " samples", correlation);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(FAILED, "no repeating pattern found, try increasing window size");
|
PrintAndLogEx(FAILED, "no repeating pattern found, try increasing window size");
|
||||||
}
|
}
|
||||||
|
@ -1599,7 +1599,7 @@ int getSamples(uint32_t n, bool verbose) {
|
||||||
if (n == 0 || n > sizeof(got))
|
if (n == 0 || n > sizeof(got))
|
||||||
n = sizeof(got);
|
n = sizeof(got);
|
||||||
|
|
||||||
if (verbose) PrintAndLogEx(INFO, "Reading " _YELLOW_("%u") "bytes from device memory", n);
|
if (verbose) PrintAndLogEx(INFO, "Reading " _YELLOW_("%u") " bytes from device memory", n);
|
||||||
|
|
||||||
PacketResponseNG response;
|
PacketResponseNG response;
|
||||||
if (!GetFromDevice(BIG_BUF, got, n, 0, NULL, 0, &response, 10000, true)) {
|
if (!GetFromDevice(BIG_BUF, got, n, 0, NULL, 0, &response, 10000, true)) {
|
||||||
|
@ -1614,7 +1614,7 @@ int getSamples(uint32_t n, bool verbose) {
|
||||||
//Old devices without this feature would send 0 at arg[0]
|
//Old devices without this feature would send 0 at arg[0]
|
||||||
if (response.oldarg[0] > 0) {
|
if (response.oldarg[0] > 0) {
|
||||||
sample_config *sc = (sample_config *) response.data.asBytes;
|
sample_config *sc = (sample_config *) response.data.asBytes;
|
||||||
if (verbose) PrintAndLogEx(INFO, "Samples @ " _YELLOW_("%d") "bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation);
|
if (verbose) PrintAndLogEx(INFO, "Samples @ " _YELLOW_("%d") " bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation);
|
||||||
bits_per_sample = sc->bits_per_sample;
|
bits_per_sample = sc->bits_per_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,7 +266,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
|
|
||||||
conn.block_after_ACK = false;
|
conn.block_after_ACK = false;
|
||||||
free(data);
|
free(data);
|
||||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")"bytes to offset "_GREEN_("%u"), datalen, start_index);
|
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")" bytes to offset "_GREEN_("%u"), datalen, start_index);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int CmdFlashMemDump(const char *Cmd) {
|
static int CmdFlashMemDump(const char *Cmd) {
|
||||||
|
@ -321,7 +321,7 @@ static int CmdFlashMemDump(const char *Cmd) {
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")"bytes from flashmem", len);
|
PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")" bytes from flashmem", len);
|
||||||
if (!GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, 0, NULL, -1, true)) {
|
if (!GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, 0, NULL, -1, true)) {
|
||||||
PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory");
|
PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory");
|
||||||
free(dump);
|
free(dump);
|
||||||
|
|
|
@ -308,7 +308,7 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) {
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "downloading "_YELLOW_("%u") "bytes from spiffs (flashmem)", len);
|
PrintAndLogEx(INFO, "downloading "_YELLOW_("%u") " bytes from spiffs (flashmem)", len);
|
||||||
if (!GetFromDevice(SPIFFS, dump, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) {
|
if (!GetFromDevice(SPIFFS, dump, len, start_index, (uint8_t *)destfilename, 32, NULL, -1, true)) {
|
||||||
PrintAndLogEx(FAILED, "ERROR; downloading from spiffs(flashmemory)");
|
PrintAndLogEx(FAILED, "ERROR; downloading from spiffs(flashmemory)");
|
||||||
free(dump);
|
free(dump);
|
||||||
|
@ -449,7 +449,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
if (res == PM3_SUCCESS)
|
if (res == PM3_SUCCESS)
|
||||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename);
|
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") " bytes to file "_GREEN_("%s"), datalen, destfilename);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include <ctype.h> // tolower
|
#include <ctype.h> // tolower
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "cliparser/cliparser.h" // parse
|
#include "cliparser.h" // parse
|
||||||
#include "comms.h" // clearCommandBuffer
|
#include "comms.h" // clearCommandBuffer
|
||||||
#include "lfdemod.h" // computeSignalProperties
|
#include "lfdemod.h" // computeSignalProperties
|
||||||
#include "cmdhf14a.h" // ISO14443-A
|
#include "cmdhf14a.h" // ISO14443-A
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "../../common_fpga/fpga.h"
|
#include "fpga.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
|
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
|
||||||
if (IfPm3NfcBarcode()) {
|
if (IfPm3NfcBarcode()) {
|
||||||
if (infoThinFilm(false) == PM3_SUCCESS) {
|
if (infoThinFilm(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for LTO-CM tag...");
|
PrintAndLogEx(INPLACE, "Searching for LTO-CM tag...");
|
||||||
if (IfPm3Iso14443a()) {
|
if (IfPm3Iso14443a()) {
|
||||||
if (infoLTO(false) == PM3_SUCCESS) {
|
if (infoLTO(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LTO-CM tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LTO-CM tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag...");
|
PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag...");
|
||||||
if (IfPm3Iso14443a()) {
|
if (IfPm3Iso14443a()) {
|
||||||
if (infoHF14A(false, false, false) > 0) {
|
if (infoHF14A(false, false, false) > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
|
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
|
||||||
if (IfPm3Iso15693()) {
|
if (IfPm3Iso15693()) {
|
||||||
if (readHF15Uid(false)) {
|
if (readHF15Uid(false)) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for LEGIC tag...");
|
PrintAndLogEx(INPLACE, "Searching for LEGIC tag...");
|
||||||
if (IfPm3Legicrf()) {
|
if (IfPm3Legicrf()) {
|
||||||
if (readLegicUid(false) == PM3_SUCCESS) {
|
if (readLegicUid(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC Prime tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC Prime tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for Topaz tag...");
|
PrintAndLogEx(INPLACE, "Searching for Topaz tag...");
|
||||||
if (IfPm3Iso14443a()) {
|
if (IfPm3Iso14443a()) {
|
||||||
if (readTopazUid(false) == PM3_SUCCESS) {
|
if (readTopazUid(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for FeliCa tag...");
|
PrintAndLogEx(INPLACE, "Searching for FeliCa tag...");
|
||||||
if (IfPm3Felica()) {
|
if (IfPm3Felica()) {
|
||||||
if (readFelicaUid(false) == PM3_SUCCESS) {
|
if (readFelicaUid(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") "found\n");
|
PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for CryptoRF tag...");
|
PrintAndLogEx(INPLACE, "Searching for CryptoRF tag...");
|
||||||
if (IfPm3Iso14443b()) {
|
if (IfPm3Iso14443b()) {
|
||||||
if (readHFCryptoRF(false) == PM3_SUCCESS) {
|
if (readHFCryptoRF(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("CryptoRF tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("CryptoRF tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag...");
|
PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag...");
|
||||||
if (IfPm3Iso14443b()) {
|
if (IfPm3Iso14443b()) {
|
||||||
if (readHF14B(false) == 1) {
|
if (readHF14B(false) == 1) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag...");
|
PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag...");
|
||||||
if (IfPm3Iclass()) {
|
if (IfPm3Iclass()) {
|
||||||
if (readIclass(false, false) == PM3_SUCCESS) {
|
if (readIclass(false, false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") "found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n");
|
||||||
res = PM3_SUCCESS;
|
res = PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ int CmdHFTune(const char *Cmd) {
|
||||||
if (cmdp == 'h') return usage_hf_tune();
|
if (cmdp == 'h') return usage_hf_tune();
|
||||||
int iter = param_get32ex(Cmd, 0, 0, 10);
|
int iter = param_get32ex(Cmd, 0, 0, 10);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Measuring HF antenna, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit");
|
PrintAndLogEx(INFO, "Measuring HF antenna, click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit");
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
#include "comms.h" // clearCommandBuffer
|
#include "comms.h" // clearCommandBuffer
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "cmdhfmf.h"
|
#include "cmdhfmf.h"
|
||||||
#include "cmdhfmfu.h"
|
#include "cmdhfmfu.h"
|
||||||
#include "emv/emvcore.h"
|
#include "emv/emvcore.h"
|
||||||
|
@ -466,7 +466,7 @@ int CmdHF14ASim(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
PrintAndLogEx(SUCCESS, "Emulating " _YELLOW_("ISO/IEC 14443 type A tag")"with " _GREEN_("%d byte UID (%s)"), uidlen, sprint_hex(uid, uidlen));
|
PrintAndLogEx(SUCCESS, "Emulating " _YELLOW_("ISO/IEC 14443 type A tag")" with " _GREEN_("%d byte UID (%s)"), uidlen, sprint_hex(uid, uidlen));
|
||||||
useUIDfromEML = false;
|
useUIDfromEML = false;
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "comms.h" // clearCommandBuffer
|
#include "comms.h" // clearCommandBuffer
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "iso15693tools.h"
|
#include "iso15693tools.h"
|
||||||
#include "../crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "crc16.h" // iso15 crc
|
#include "crc16.h" // iso15 crc
|
||||||
#include "cmddata.h" // getsamples
|
#include "cmddata.h" // getsamples
|
||||||
|
@ -928,7 +928,7 @@ static int CmdHF15Info(const char *Cmd) {
|
||||||
|
|
||||||
memcpy(uid, recv + 2, sizeof(uid));
|
memcpy(uid, recv + 2, sizeof(uid));
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, " TYPE: " _YELLOW_("%s"), getTagInfo_15(recv + 2));
|
PrintAndLogEx(SUCCESS, " TYPE: " _YELLOW_("%s"), getTagInfo_15(recv + 2));
|
||||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "emv/emvcore.h"
|
#include "emv/emvcore.h"
|
||||||
#include "emv/emvjson.h"
|
#include "emv/emvjson.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "../crypto/asn1utils.h"
|
#include "crypto/asn1utils.h"
|
||||||
#include "../crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "fido/cbortools.h"
|
#include "fido/cbortools.h"
|
||||||
#include "fido/fidocore.h"
|
#include "fido/fidocore.h"
|
||||||
#include "emv/dump.h"
|
#include "emv/dump.h"
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "mbedtls/des.h"
|
#include "mbedtls/des.h"
|
||||||
#include "../loclass/cipherutils.h"
|
#include "loclass/cipherutils.h"
|
||||||
#include "../loclass/cipher.h"
|
#include "loclass/cipher.h"
|
||||||
#include "../loclass/ikeys.h"
|
#include "loclass/ikeys.h"
|
||||||
#include "../loclass/elite_crack.h"
|
#include "loclass/elite_crack.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "cardhelper.h"
|
#include "cardhelper.h"
|
||||||
|
@ -927,7 +927,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
uint32_t limit = MIN(applimit, decryptedlen / 8);
|
uint32_t limit = MIN(applimit, decryptedlen / 8);
|
||||||
|
|
||||||
if (decryptedlen / 8 != applimit) {
|
if (decryptedlen / 8 != applimit) {
|
||||||
PrintAndLogEx(WARNING, "Actual file len " _YELLOW_("%zu") "vs HID app-limit len " _YELLOW_("%u"), decryptedlen, applimit * 8);
|
PrintAndLogEx(WARNING, "Actual file len " _YELLOW_("%zu") " vs HID app-limit len " _YELLOW_("%u"), decryptedlen, applimit * 8);
|
||||||
PrintAndLogEx(INFO, "Setting limit to " _GREEN_("%u"), limit * 8);
|
PrintAndLogEx(INFO, "Setting limit to " _GREEN_("%u"), limit * 8);
|
||||||
}
|
}
|
||||||
uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8));
|
uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8));
|
||||||
|
@ -1415,7 +1415,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) {
|
||||||
// print the dump
|
// print the dump
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "------+--+-------------------------+----------");
|
PrintAndLogEx(INFO, "------+--+-------------------------+----------");
|
||||||
PrintAndLogEx(INFO, " CSN |00| " _GREEN_("%s") "|", sprint_hex(tag_data, 8));
|
PrintAndLogEx(INFO, " CSN |00| " _GREEN_("%s") " |", sprint_hex(tag_data, 8));
|
||||||
printIclassDumpContents(tag_data, 1, (gotBytes / 8), gotBytes);
|
printIclassDumpContents(tag_data, 1, (gotBytes / 8), gotBytes);
|
||||||
|
|
||||||
if (filename[0] == 0) {
|
if (filename[0] == 0) {
|
||||||
|
@ -2052,11 +2052,11 @@ static int CmdHFiClassReadTagFile(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename);
|
PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename);
|
||||||
PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, (uint16_t)(bytes_read >> 3), (uint16_t)(bytes_read >> 3));
|
PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, (uint16_t)(bytes_read >> 3), (uint16_t)(bytes_read >> 3));
|
||||||
PrintAndLogEx(INFO, "Printing blocks from");
|
PrintAndLogEx(INFO, "Printing blocks from");
|
||||||
PrintAndLogEx(INFO, "start " _YELLOW_("0x%02x") "end " _YELLOW_("0x%02x"), (startblock == 0) ? 6 : startblock, endblock);
|
PrintAndLogEx(INFO, "start " _YELLOW_("0x%02x") " end " _YELLOW_("0x%02x"), (startblock == 0) ? 6 : startblock, endblock);
|
||||||
}
|
}
|
||||||
uint8_t *csn = dump;
|
uint8_t *csn = dump;
|
||||||
PrintAndLogEx(INFO, "------+--+-------------------------+----------");
|
PrintAndLogEx(INFO, "------+--+-------------------------+----------");
|
||||||
PrintAndLogEx(INFO, " CSN |00| " _GREEN_("%s") "|", sprint_hex(csn, 8));
|
PrintAndLogEx(INFO, " CSN |00| " _GREEN_("%s") " |", sprint_hex(csn, 8));
|
||||||
printIclassDumpContents(dump, startblock, endblock, bytes_read);
|
printIclassDumpContents(dump, startblock, endblock, bytes_read);
|
||||||
free(dump);
|
free(dump);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -2223,7 +2223,7 @@ static int loadKeys(char *filename) {
|
||||||
memcpy(iClass_Key_Table[i], dump + (i * 8), 8);
|
memcpy(iClass_Key_Table[i], dump + (i * 8), 8);
|
||||||
|
|
||||||
free(dump);
|
free(dump);
|
||||||
PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") "keys from %s", i, filename);
|
PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from %s", i, filename);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2440,7 +2440,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
|
||||||
if (use_raw)
|
if (use_raw)
|
||||||
PrintAndLogEx(SUCCESS, "Using " _YELLOW_(" raw mode"));
|
PrintAndLogEx(SUCCESS, "Using " _YELLOW_(" raw mode"));
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Searching for " _YELLOW_("%s") "key", (use_credit_key) ? "CREDIT" : "DEBIT");
|
PrintAndLogEx(SUCCESS, "Searching for " _YELLOW_("%s") " key", (use_credit_key) ? "CREDIT" : "DEBIT");
|
||||||
PrintAndLogEx(SUCCESS, "Tag info");
|
PrintAndLogEx(SUCCESS, "Tag info");
|
||||||
PrintAndLogEx(SUCCESS, "CSN | %s", sprint_hex(CSN, sizeof(CSN)));
|
PrintAndLogEx(SUCCESS, "CSN | %s", sprint_hex(CSN, sizeof(CSN)));
|
||||||
PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR)));
|
PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR)));
|
||||||
|
@ -2714,7 +2714,7 @@ static int CmdHFiClassLookUp(const char *Cmd) {
|
||||||
|
|
||||||
if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) {
|
if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) {
|
||||||
memcpy(iClass_Key_Table[i], item->key, 8);
|
memcpy(iClass_Key_Table[i], item->key, 8);
|
||||||
PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")"to view", i);
|
PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ static int usage_legic_rdbl(void) {
|
||||||
}
|
}
|
||||||
static int usage_legic_sim(void) {
|
static int usage_legic_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, "Simulates a LEGIC Prime tag. MIM22, MIM256, MIM1024 types can be emulated");
|
PrintAndLogEx(NORMAL, "Simulates a LEGIC Prime tag. MIM22, MIM256, MIM1024 types can be emulated");
|
||||||
PrintAndLogEx(NORMAL, "Use " _YELLOW_("`hf legic eload`") "to upload a dump into emulator memory\n");
|
PrintAndLogEx(NORMAL, "Use " _YELLOW_("`hf legic eload`") " to upload a dump into emulator memory\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf legic sim [h] <tagtype>\n");
|
PrintAndLogEx(NORMAL, "Usage: hf legic sim [h] <tagtype>\n");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : this help");
|
PrintAndLogEx(NORMAL, " h : this help");
|
||||||
|
@ -217,7 +217,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Reading full tag memory of " _YELLOW_("%d") "bytes...", card.cardsize);
|
PrintAndLogEx(SUCCESS, "Reading full tag memory of " _YELLOW_("%d") " bytes...", card.cardsize);
|
||||||
|
|
||||||
// allocate receiver buffer
|
// allocate receiver buffer
|
||||||
uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
|
uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
|
||||||
|
@ -239,7 +239,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " " _CYAN_("CDF: System Area"));
|
PrintAndLogEx(SUCCESS, " " _CYAN_("CDF: System Area"));
|
||||||
PrintAndLogEx(NORMAL, "------------------------------------------------------");
|
PrintAndLogEx(NORMAL, "------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, "MCD: " _GREEN_("%02X") " MSN: " _GREEN_("%s") " MCC: " _GREEN_("%02X") " ( %s)",
|
PrintAndLogEx(SUCCESS, "MCD: " _GREEN_("%02X") " MSN: " _GREEN_("%s") " MCC: " _GREEN_("%02X") " (%s)",
|
||||||
data[0],
|
data[0],
|
||||||
sprint_hex(data + 1, 3),
|
sprint_hex(data + 1, 3),
|
||||||
data[4],
|
data[4],
|
||||||
|
@ -394,7 +394,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||||
(segment_flag & 0x4) >> 2,
|
(segment_flag & 0x4) >> 2,
|
||||||
(segment_flag & 0x8) >> 3
|
(segment_flag & 0x8) >> 3
|
||||||
);
|
);
|
||||||
PrintAndLogEx(SUCCESS, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X ( %s)",
|
PrintAndLogEx(SUCCESS, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)",
|
||||||
wrp,
|
wrp,
|
||||||
wrc,
|
wrc,
|
||||||
((data[i + 3] ^ crc) & 0x80) >> 7,
|
((data[i + 3] ^ crc) & 0x80) >> 7,
|
||||||
|
|
|
@ -616,7 +616,7 @@ static int CmdHfLTRestore(const char *Cmd) {
|
||||||
is_data_loaded = loadFileEML(filename, (uint8_t *)dump_data, &dump_datalen);
|
is_data_loaded = loadFileEML(filename, (uint8_t *)dump_data, &dump_datalen);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")"to restore!\n", filename);
|
PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")" to restore!\n", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_data_loaded == PM3_SUCCESS) {
|
if (is_data_loaded == PM3_SUCCESS) {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "emv/dump.h"
|
#include "emv/dump.h"
|
||||||
#include "mifare/mifaredefault.h" // mifare default key array
|
#include "mifare/mifaredefault.h" // mifare default key array
|
||||||
#include "cliparser/cliparser.h" // argtable
|
#include "cliparser.h" // argtable
|
||||||
#include "hardnested/hardnested_bf_core.h" // SetSIMDInstr
|
#include "hardnested_bf_core.h" // SetSIMDInstr
|
||||||
#include "mifare/mad.h"
|
#include "mifare/mad.h"
|
||||||
#include "mifare/ndef.h"
|
#include "mifare/ndef.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
|
@ -1361,7 +1361,7 @@ static int CmdHF14AMfNested(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t t2 = msclock() - t1;
|
uint64_t t2 = msclock() - t1;
|
||||||
PrintAndLogEx(SUCCESS, "Time to check " _YELLOW_("%zu") "known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0);
|
PrintAndLogEx(SUCCESS, "Time to check " _YELLOW_("%zu") " known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0);
|
||||||
PrintAndLogEx(SUCCESS, "enter nested key recovery");
|
PrintAndLogEx(SUCCESS, "enter nested key recovery");
|
||||||
|
|
||||||
// nested sectors
|
// nested sectors
|
||||||
|
@ -1408,7 +1408,7 @@ static int CmdHF14AMfNested(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t1 = msclock() - t1;
|
t1 = msclock() - t1;
|
||||||
PrintAndLogEx(SUCCESS, "time in nested: " _YELLOW_("%.0f") "seconds\n", (float)t1 / 1000.0);
|
PrintAndLogEx(SUCCESS, "time in nested: " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
|
||||||
|
|
||||||
|
|
||||||
// 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
|
// 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
|
||||||
|
@ -1576,7 +1576,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t t2 = msclock() - t1;
|
uint64_t t2 = msclock() - t1;
|
||||||
PrintAndLogEx(SUCCESS, "Time to check "_YELLOW_("%zu") "known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0);
|
PrintAndLogEx(SUCCESS, "Time to check "_YELLOW_("%zu") " known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0);
|
||||||
PrintAndLogEx(SUCCESS, "enter static nested key recovery");
|
PrintAndLogEx(SUCCESS, "enter static nested key recovery");
|
||||||
|
|
||||||
// nested sectors
|
// nested sectors
|
||||||
|
@ -1613,7 +1613,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t1 = msclock() - t1;
|
t1 = msclock() - t1;
|
||||||
PrintAndLogEx(SUCCESS, "time in static nested: " _YELLOW_("%.0f") "seconds\n", (float)t1 / 1000.0);
|
PrintAndLogEx(SUCCESS, "time in static nested: " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
|
||||||
|
|
||||||
|
|
||||||
// 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
|
// 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
|
||||||
|
@ -2060,7 +2060,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, _YELLOW_("======================= START KNOWN KEY ATTACK ======================="));
|
PrintAndLogEx(INFO, _YELLOW_("======================= START KNOWN KEY ATTACK ======================="));
|
||||||
}
|
}
|
||||||
if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) {
|
if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(INFO, "target sector:%3u key type: %c -- using valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
PrintAndLogEx(INFO, "target sector:%3u key type: %c -- using valid key [" _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||||
blockNo,
|
blockNo,
|
||||||
keyType ? 'B' : 'A',
|
keyType ? 'B' : 'A',
|
||||||
sprint_hex(key, sizeof(key))
|
sprint_hex(key, sizeof(key))
|
||||||
|
@ -2095,13 +2095,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
know_target_key = true;
|
know_target_key = true;
|
||||||
blockNo = i;
|
blockNo = i;
|
||||||
keyType = j;
|
keyType = j;
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key ["_YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||||
i,
|
i,
|
||||||
j ? 'B' : 'A',
|
j ? 'B' : 'A',
|
||||||
sprint_hex(key, sizeof(key))
|
sprint_hex(key, sizeof(key))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key ["_YELLOW_("%s") "]",
|
||||||
i,
|
i,
|
||||||
j ? 'B' : 'A',
|
j ? 'B' : 'A',
|
||||||
sprint_hex(key, sizeof(key))
|
sprint_hex(key, sizeof(key))
|
||||||
|
@ -2141,7 +2141,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6);
|
num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6);
|
||||||
}
|
}
|
||||||
key_cnt = ARRAYLEN(g_mifare_default_keys);
|
key_cnt = ARRAYLEN(g_mifare_default_keys);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from hardcoded default array", key_cnt);
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from hardcoded default array", key_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the dictionary to find sector keys on the card
|
// Use the dictionary to find sector keys on the card
|
||||||
|
@ -2219,13 +2219,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
know_target_key = true;
|
know_target_key = true;
|
||||||
blockNo = i;
|
blockNo = i;
|
||||||
keyType = j;
|
keyType = j;
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||||
i,
|
i,
|
||||||
j ? 'B' : 'A',
|
j ? 'B' : 'A',
|
||||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]",
|
||||||
i,
|
i,
|
||||||
j ? 'B' : 'A',
|
j ? 'B' : 'A',
|
||||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||||
|
@ -2267,7 +2267,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
// Store the keys
|
// Store the keys
|
||||||
e_sector[blockNo].Key[keyType] = key64;
|
e_sector[blockNo].Key[keyType] = key64;
|
||||||
e_sector[blockNo].foundKey[keyType] = 'S';
|
e_sector[blockNo].foundKey[keyType] = 'S';
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||||
blockNo,
|
blockNo,
|
||||||
keyType ? 'B' : 'A',
|
keyType ? 'B' : 'A',
|
||||||
sprint_hex(key, sizeof(key))
|
sprint_hex(key, sizeof(key))
|
||||||
|
@ -2307,7 +2307,7 @@ noValidKeyFound:
|
||||||
if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) {
|
if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) {
|
||||||
e_sector[i].Key[j] = bytes_to_num(tmp_key, 6);
|
e_sector[i].Key[j] = bytes_to_num(tmp_key, 6);
|
||||||
e_sector[i].foundKey[j] = 'R';
|
e_sector[i].foundKey[j] = 'R';
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]",
|
||||||
i,
|
i,
|
||||||
j ? 'B' : 'A',
|
j ? 'B' : 'A',
|
||||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||||
|
@ -2349,7 +2349,7 @@ noValidKeyFound:
|
||||||
e_sector[current_sector_i].foundKey[current_key_type_i] = 'A';
|
e_sector[current_sector_i].foundKey[current_key_type_i] = 'A';
|
||||||
e_sector[current_sector_i].Key[current_key_type_i] = key64;
|
e_sector[current_sector_i].Key[current_key_type_i] = key64;
|
||||||
num_to_bytes(key64, 6, tmp_key);
|
num_to_bytes(key64, 6, tmp_key);
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]",
|
||||||
current_sector_i,
|
current_sector_i,
|
||||||
current_key_type_i ? 'B' : 'A',
|
current_key_type_i ? 'B' : 'A',
|
||||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||||
|
@ -2449,7 +2449,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||||
}
|
}
|
||||||
// Check if the key was found
|
// Check if the key was found
|
||||||
if (e_sector[current_sector_i].foundKey[current_key_type_i]) {
|
if (e_sector[current_sector_i].foundKey[current_key_type_i]) {
|
||||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [" _YELLOW_("%s") "]",
|
||||||
current_sector_i,
|
current_sector_i,
|
||||||
current_key_type_i ? 'B' : 'A',
|
current_key_type_i ? 'B' : 'A',
|
||||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||||
|
@ -2522,7 +2522,7 @@ all_found:
|
||||||
|
|
||||||
// Generate and show statistics
|
// Generate and show statistics
|
||||||
t1 = msclock() - t1;
|
t1 = msclock() - t1;
|
||||||
PrintAndLogEx(INFO, "autopwn execution time: " _YELLOW_("%.0f") "seconds", (float)t1 / 1000.0);
|
PrintAndLogEx(INFO, "autopwn execution time: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0);
|
||||||
|
|
||||||
free(dump);
|
free(dump);
|
||||||
free(e_sector);
|
free(e_sector);
|
||||||
|
@ -3565,7 +3565,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto
|
||||||
snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]);
|
snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]);
|
||||||
|
|
||||||
if (e_sector[i].foundKey[0] > 1) {
|
if (e_sector[i].foundKey[0] > 1) {
|
||||||
PrintAndLogEx(SUCCESS, "| "_YELLOW_("%03d")"| " _GREEN_("%s")" | " _YELLOW_("%c")"| " _GREEN_("%s")" | " _YELLOW_("%c")"|"
|
PrintAndLogEx(SUCCESS, "| "_YELLOW_("%03d")" | " _GREEN_("%s")" | " _YELLOW_("%c")" | " _GREEN_("%s")" | " _YELLOW_("%c")" |"
|
||||||
, i
|
, i
|
||||||
, strA, e_sector[i].foundKey[0]
|
, strA, e_sector[i].foundKey[0]
|
||||||
, strB, e_sector[i].foundKey[1]
|
, strB, e_sector[i].foundKey[1]
|
||||||
|
@ -3577,7 +3577,7 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto
|
||||||
if (start_sector == 0)
|
if (start_sector == 0)
|
||||||
s = i;
|
s = i;
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "| "_YELLOW_("%03d")"| " _GREEN_("%s")" | " _YELLOW_("%d")"| " _GREEN_("%s")" | " _YELLOW_("%d")"|"
|
PrintAndLogEx(SUCCESS, "| "_YELLOW_("%03d")" | " _GREEN_("%s")" | " _YELLOW_("%d")" | " _GREEN_("%s")" | " _YELLOW_("%d")" |"
|
||||||
, s
|
, s
|
||||||
, strA, e_sector[i].foundKey[0]
|
, strA, e_sector[i].foundKey[0]
|
||||||
, strB, e_sector[i].foundKey[1]
|
, strB, e_sector[i].foundKey[1]
|
||||||
|
@ -4520,7 +4520,7 @@ static int CmdHF14AMfice(const char *Cmd) {
|
||||||
strcpy(filename, fptr);
|
strcpy(filename, fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "Collecting "_YELLOW_("%u")"nonces \n", limit);
|
PrintAndLogEx(NORMAL, "Collecting "_YELLOW_("%u")" nonces \n", limit);
|
||||||
|
|
||||||
if ((fnonces = fopen(filename, "wb")) == NULL) {
|
if ((fnonces = fopen(filename, "wb")) == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), filename);
|
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), filename);
|
||||||
|
|
|
@ -16,21 +16,21 @@
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdhw.h"
|
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
#include "mbedtls/des.h"
|
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
#include "../crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "mifare.h" // desfire raw command options
|
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "emv/apduinfo.h" // APDU manipulation / errorcodes
|
#include "emv/apduinfo.h" // APDU manipulation / errorcodes
|
||||||
#include "emv/emvcore.h" // APDU logging
|
#include "emv/emvcore.h" // APDU logging
|
||||||
#include "util_posix.h" // msleep
|
#include "util_posix.h" // msleep
|
||||||
#include "mifare/mifare4.h" // MIFARE Authenticate / MAC
|
|
||||||
#include "mifare/desfire_crypto.h"
|
#include "mifare/desfire_crypto.h"
|
||||||
#include "crapto1/crapto1.h"
|
#include "crapto1/crapto1.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
|
||||||
|
#define MAX_KEY_LEN 24
|
||||||
|
#define MAX_KEYS_LIST_LEN 1024
|
||||||
|
|
||||||
struct desfire_key defaultkey = {0};
|
struct desfire_key defaultkey = {0};
|
||||||
static desfirekey_t sessionkey = &defaultkey;
|
static desfirekey_t sessionkey = &defaultkey;
|
||||||
|
@ -175,17 +175,11 @@ static char *cluster_to_text(uint8_t cluster) {
|
||||||
case CL_ADMIN:
|
case CL_ADMIN:
|
||||||
return "card administration";
|
return "card administration";
|
||||||
case CL_MISC1:
|
case CL_MISC1:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_MISC2:
|
case CL_MISC2:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_MISC3:
|
case CL_MISC3:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_MISC4:
|
case CL_MISC4:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_MISC5:
|
case CL_MISC5:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_MISC6:
|
case CL_MISC6:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_MISC7:
|
case CL_MISC7:
|
||||||
return "miscellaneous applications";
|
return "miscellaneous applications";
|
||||||
case CL_AIRLINES:
|
case CL_AIRLINES:
|
||||||
|
@ -219,7 +213,6 @@ static char *cluster_to_text(uint8_t cluster) {
|
||||||
case CL_CITYCARD:
|
case CL_CITYCARD:
|
||||||
return "city card services";
|
return "city card services";
|
||||||
case CL_ACCESS_CONTROL_1:
|
case CL_ACCESS_CONTROL_1:
|
||||||
return "access control & security";
|
|
||||||
case CL_ACCESS_CONTROL_2:
|
case CL_ACCESS_CONTROL_2:
|
||||||
return "access control & security";
|
return "access control & security";
|
||||||
case CL_VIGIK:
|
case CL_VIGIK:
|
||||||
|
@ -289,19 +282,12 @@ static char *cluster_to_text(uint8_t cluster) {
|
||||||
case CL_MAIL:
|
case CL_MAIL:
|
||||||
return "mail";
|
return "mail";
|
||||||
case CL_AMISC:
|
case CL_AMISC:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC1:
|
case CL_AMISC1:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC2:
|
case CL_AMISC2:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC3:
|
case CL_AMISC3:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC4:
|
case CL_AMISC4:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC5:
|
case CL_AMISC5:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC6:
|
case CL_AMISC6:
|
||||||
return "miscellaneous applications";
|
|
||||||
case CL_AMISC7:
|
case CL_AMISC7:
|
||||||
return "miscellaneous applications";
|
return "miscellaneous applications";
|
||||||
default:
|
default:
|
||||||
|
@ -311,7 +297,7 @@ static char *cluster_to_text(uint8_t cluster) {
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UNKNOWN = 0,
|
DESFIRE_UNKNOWN = 0,
|
||||||
DESFIRE_MF3ICD40,
|
DESFIRE_MF3ICD40,
|
||||||
DESFIRE_EV1,
|
DESFIRE_EV1,
|
||||||
DESFIRE_EV2,
|
DESFIRE_EV2,
|
||||||
|
@ -344,9 +330,9 @@ static char *getCardSizeStr(uint8_t fsize) {
|
||||||
|
|
||||||
// is LSB set?
|
// is LSB set?
|
||||||
if (fsize & 1)
|
if (fsize & 1)
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
|
sprintf(retStr, "0x%02X (" _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize);
|
sprintf(retStr, "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,14 +342,14 @@ static char *getProtocolStr(uint8_t id, bool hw) {
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (id == 0x04) {
|
if (id == 0x04) {
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3 MIFARE, 14443-4") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-3 MIFARE, 14443-4") ")", id);
|
||||||
} else if (id == 0x05) {
|
} else if (id == 0x05) {
|
||||||
if (hw)
|
if (hw)
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-2, 14443-3") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-2, 14443-3") ")", id);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-3, 14443-4") ")", id);
|
||||||
} else {
|
} else {
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("Unknown") ")", id);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -374,17 +360,17 @@ static char *getVersionStr(uint8_t major, uint8_t minor) {
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (major == 0x00)
|
if (major == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire MF3ICD40") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire MF3ICD40") ")", major, minor);
|
||||||
else if (major == 0x01 && minor == 0x00)
|
else if (major == 0x01 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV1") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor);
|
||||||
else if (major == 0x12 && minor == 0x00)
|
else if (major == 0x12 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV2") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV2") ")", major, minor);
|
||||||
// else if (major == 0x13 && minor == 0x00)
|
// else if (major == 0x13 && minor == 0x00)
|
||||||
// sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV3") ")", major, minor);
|
// sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor);
|
||||||
else if (major == 0x30 && minor == 0x00)
|
else if (major == 0x30 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire Light") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire Light") ")", major, minor);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("Unknown") ")", major, minor);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,7 +639,7 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) {
|
||||||
if (major == 0x11 && minor == 0x00)
|
if (major == 0x11 && minor == 0x00)
|
||||||
return PLUS_EV1;
|
return PLUS_EV1;
|
||||||
|
|
||||||
return UNKNOWN;
|
return DESFIRE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, bool defaultkey) {
|
int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, bool defaultkey) {
|
||||||
|
@ -736,8 +722,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
sAPDU apdu = {0x90, subcommand, 0x00, 0x00, 0x01, data};
|
sAPDU apdu = {0x90, subcommand, 0x00, 0x00, 0x01, data};
|
||||||
int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false);
|
int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "Sending auth command %02X " _RED_("failed"), subcommand);
|
return 1;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
} else if (payload->mode == MFDES_AUTH_PICC) {
|
} else if (payload->mode == MFDES_AUTH_PICC) {
|
||||||
/*cmd[0] = AUTHENTICATE;
|
/*cmd[0] = AUTHENTICATE;
|
||||||
|
@ -747,13 +732,11 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recv_len) {
|
if (!recv_len) {
|
||||||
PrintAndLogEx(ERR, "Authentication failed. Card timeout.");
|
return 2;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sw != status(MFDES_ADDITIONAL_FRAME)) {
|
if (sw != status(MFDES_ADDITIONAL_FRAME)) {
|
||||||
PrintAndLogEx(ERR, "Authentication failed. Invalid key number.");
|
return 3;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int expectedlen = 8;
|
int expectedlen = 8;
|
||||||
|
@ -762,8 +745,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recv_len != expectedlen) {
|
if (recv_len != expectedlen) {
|
||||||
PrintAndLogEx(ERR, "Authentication failed. Length of answer %d doesn't match algo length %d.", recv_len, expectedlen);
|
return 4;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
int rndlen = recv_len;
|
int rndlen = recv_len;
|
||||||
|
|
||||||
|
@ -778,8 +760,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
// Part 3
|
// Part 3
|
||||||
if (payload->algo == MFDES_ALGO_AES) {
|
if (payload->algo == MFDES_ALGO_AES) {
|
||||||
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
|
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
|
||||||
PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed");
|
return 5;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndB, RndB);
|
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndB, RndB);
|
||||||
} else if (payload->algo == MFDES_ALGO_DES)
|
} else if (payload->algo == MFDES_ALGO_DES)
|
||||||
|
@ -848,8 +829,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
}
|
}
|
||||||
if (payload->algo == MFDES_ALGO_AES) {
|
if (payload->algo == MFDES_ALGO_AES) {
|
||||||
if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) {
|
if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) {
|
||||||
PrintAndLogEx(ERR, "mbedtls_aes_setkey_enc failed");
|
return 6;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both);
|
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both);
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
|
@ -866,8 +846,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
sAPDU apdu = {0x90, MFDES_ADDITIONAL_FRAME, 0x00, 0x00, bothlen, both};
|
sAPDU apdu = {0x90, MFDES_ADDITIONAL_FRAME, 0x00, 0x00, bothlen, both};
|
||||||
int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false);
|
int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "Sending auth command %02X " _RED_("failed"), subcommand);
|
return 7;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*cmd[0] = ADDITIONAL_FRAME;
|
/*cmd[0] = ADDITIONAL_FRAME;
|
||||||
|
@ -881,14 +860,12 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recv_len) {
|
if (!recv_len) {
|
||||||
PrintAndLogEx(ERR, "Authentication failed. Card timeout.");
|
return 8;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload->mode != MFDES_AUTH_PICC) {
|
if (payload->mode != MFDES_AUTH_PICC) {
|
||||||
if (sw != status(MFDES_S_OPERATION_OK)) {
|
if (sw != status(MFDES_S_OPERATION_OK)) {
|
||||||
PrintAndLogEx(ERR, "Authentication failed.");
|
return 9;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*if (resp[1] != 0x00) {
|
/*if (resp[1] != 0x00) {
|
||||||
|
@ -915,8 +892,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 3);
|
tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 3);
|
||||||
} else if (payload->mode == MFDES_AUTH_AES) {
|
} else if (payload->mode == MFDES_AUTH_AES) {
|
||||||
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
|
if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) {
|
||||||
PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed");
|
return 10;
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
}
|
||||||
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndA, encRndA);
|
mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndA, encRndA);
|
||||||
}
|
}
|
||||||
|
@ -924,12 +900,11 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
rol(RndA, rndlen);
|
rol(RndA, rndlen);
|
||||||
for (int x = 0; x < rndlen; x++) {
|
for (int x = 0; x < rndlen; x++) {
|
||||||
if (RndA[x] != encRndA[x]) {
|
if (RndA[x] != encRndA[x]) {
|
||||||
PrintAndLogEx(ERR, "Authentication failed. Cannot verify Session Key.");
|
|
||||||
if (g_debugMode > 1) {
|
if (g_debugMode > 1) {
|
||||||
PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen));
|
PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen));
|
||||||
PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen));
|
PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen));
|
||||||
}
|
}
|
||||||
return PM3_ESOFT;
|
return 11;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,6 +913,45 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload,
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuthToError(int error) {
|
||||||
|
switch (error) {
|
||||||
|
case 1:
|
||||||
|
PrintAndLogEx(SUCCESS, "Sending auth command failed");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PrintAndLogEx(ERR, "Authentication failed. No data received");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PrintAndLogEx(ERR, "Authentication failed. Invalid key number.");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PrintAndLogEx(ERR, "Authentication failed. Length of answer %d doesn't match algo length %d.");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
PrintAndLogEx(ERR, "mbedtls_aes_setkey_enc failed");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
PrintAndLogEx(SUCCESS, "Sending auth command failed");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
PrintAndLogEx(ERR, "Authentication failed. Card timeout.");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
PrintAndLogEx(ERR, "Authentication failed.");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed");
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
PrintAndLogEx(ERR, "Authentication failed. Cannot verify Session Key.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// -- test if card supports 0x0A
|
// -- test if card supports 0x0A
|
||||||
static int test_desfire_authenticate() {
|
static int test_desfire_authenticate() {
|
||||||
uint8_t data[] = {0x00};
|
uint8_t data[] = {0x00};
|
||||||
|
@ -2839,11 +2853,11 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(package->uid, sizeof(package->uid)));
|
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(package->uid, sizeof(package->uid)));
|
||||||
PrintAndLogEx(SUCCESS, " Batch number: " _GREEN_("%s"), sprint_hex(package->details + 7, 5));
|
PrintAndLogEx(SUCCESS, " Batch number: " _GREEN_("%s"), sprint_hex(package->details + 7, 5));
|
||||||
PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") "/ " _GREEN_("20%02x"), package->details[12], package->details[13]);
|
PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") " / " _GREEN_("20%02x"), package->details[12], package->details[13]);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information"));
|
PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information"));
|
||||||
PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(package->versionHW[0]));
|
PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(package->versionHW[0]));
|
||||||
|
@ -3051,6 +3065,149 @@ static int DecodeFileSettings(uint8_t *src, int src_len, int maclen) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF14ADesDump(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
DropField();
|
||||||
|
uint8_t aid[3] = {0};
|
||||||
|
uint8_t app_ids[78] = {0};
|
||||||
|
uint8_t app_ids_len = 0;
|
||||||
|
|
||||||
|
uint8_t file_ids[33] = {0};
|
||||||
|
uint8_t file_ids_len = 0;
|
||||||
|
|
||||||
|
dfname_t dfnames[255];
|
||||||
|
uint8_t dfname_count = 0;
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
if (handler_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "Can't get list of applications on tag");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler_desfire_dfnames(dfnames, &dfname_count) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(WARNING, _RED_("Can't get DF Names"));
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, "-- Mifare DESFire Dump ----------------------");
|
||||||
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
|
|
||||||
|
for (int i = 0; i < app_ids_len; i += 3) {
|
||||||
|
|
||||||
|
aid[0] = app_ids[i];
|
||||||
|
aid[1] = app_ids[i + 1];
|
||||||
|
aid[2] = app_ids[i + 2];
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, " AID : " _GREEN_("%02X%02X%02X"), aid[2], aid[1], aid[0]);
|
||||||
|
PrintAndLogEx(SUCCESS, " AID Function Cluster 0x%02X: " _YELLOW_("%s"), aid[2], cluster_to_text(aid[2]));
|
||||||
|
|
||||||
|
for (int m = 0; m < dfname_count; m++) {
|
||||||
|
if (dfnames[m].aid[0] == aid[0] && dfnames[m].aid[1] == aid[1] && dfnames[m].aid[2] == aid[2]) {
|
||||||
|
PrintAndLogEx(SUCCESS, " - DF " _YELLOW_("%02X%02X") " Name : " _YELLOW_("%s"), dfnames[m].fid[1], dfnames[m].fid[0], dfnames[m].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t num_keys = 0;
|
||||||
|
uint8_t key_setting = 0;
|
||||||
|
res = handler_desfire_keysettings(&key_setting, &num_keys);
|
||||||
|
if (res != PM3_SUCCESS) return res;
|
||||||
|
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
|
||||||
|
if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) {
|
||||||
|
for (int j = file_ids_len - 1; j >= 0; j--) {
|
||||||
|
PrintAndLogEx(SUCCESS, "\n\n Fileid %d (0x%02x)", file_ids[j], file_ids[j]);
|
||||||
|
|
||||||
|
uint8_t filesettings[20] = {0};
|
||||||
|
int fileset_len = 0;
|
||||||
|
int res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len);
|
||||||
|
int maclen = 0; // To be implemented
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
//if (DecodeFileSettings(filesettings, fileset_len, maclen) != PM3_SUCCESS) {
|
||||||
|
if (fileset_len == 1 + 1 + 2 + 3 + maclen) {
|
||||||
|
int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4];
|
||||||
|
mfdes_data_t fdata;
|
||||||
|
fdata.fileno = file_ids[j];
|
||||||
|
memset(fdata.offset, 0, 3);
|
||||||
|
//memcpy(fdata.length,&filesettings[4],3);
|
||||||
|
memset(fdata.length, 0, 3);
|
||||||
|
uint8_t *data = (uint8_t *)malloc(filesize);
|
||||||
|
fdata.data = data;
|
||||||
|
if (data) {
|
||||||
|
res = handler_desfire_readdata(&fdata, MFDES_DATA_FILE);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii");
|
||||||
|
PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------");
|
||||||
|
int len = le24toh(fdata.length);
|
||||||
|
for (int i = 0; i < len; i += 16) {
|
||||||
|
PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", i, i, sprint_hex(&fdata.data[i], len > 16 ? 16 : len), sprint_ascii(&fdata.data[i], len > 16 ? 16 : len));
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(ERR, "Couldn't read value. Error %d", res);
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (fileset_len == 1 + 1 + 2 + 4 + 4 + 4 + 1 + maclen) {
|
||||||
|
PrintAndLogEx(NORMAL, "\n\nValue file: 0x%0x", file_ids[j]);
|
||||||
|
mfdes_value_t value;
|
||||||
|
value.fileno = file_ids[j];
|
||||||
|
int len = 0;
|
||||||
|
res = handler_desfire_getvalue(&value, &len);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(NORMAL, "\nOffset | Value | Ascii");
|
||||||
|
PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------");
|
||||||
|
for (int i = 0; i < len; i += 16) {
|
||||||
|
PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", i, i, sprint_hex(&value.value[i], len > 16 ? 16 : len), sprint_ascii(&value.value[i], len > 16 ? 16 : len));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(ERR, "Couldn't read value. Error %d", res);
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
}
|
||||||
|
} else if (fileset_len == 1 + 1 + 2 + 3 + 3 + 3 + maclen) {
|
||||||
|
int maxrecords = (filesettings[9] << 16) + (filesettings[8] << 8) + filesettings[7];
|
||||||
|
int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4];
|
||||||
|
mfdes_data_t fdata;
|
||||||
|
fdata.fileno = file_ids[j];
|
||||||
|
memset(fdata.length, 0, 3);
|
||||||
|
//memcpy(fdata.length,&filesettings[4],3);
|
||||||
|
uint8_t *data = (uint8_t *)malloc(filesize);
|
||||||
|
fdata.data = data;
|
||||||
|
if (data) {
|
||||||
|
for (int offset = 0; offset < maxrecords; offset++) {
|
||||||
|
PrintAndLogEx(NORMAL, "\n\nRecord offset: %024x", offset);
|
||||||
|
memset(data, 0, filesize);
|
||||||
|
fdata.offset[0] = offset & 0xFF;
|
||||||
|
fdata.offset[1] = (offset >> 8) & 0xFF;
|
||||||
|
fdata.offset[2] = (offset >> 16) & 0xFF;
|
||||||
|
res = handler_desfire_readdata(&fdata, MFDES_RECORD_FILE);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(NORMAL, "\nOffset | Data | Ascii");
|
||||||
|
PrintAndLogEx(NORMAL, "----------------------------------------------------------------------------");
|
||||||
|
int len = le24toh(fdata.length);
|
||||||
|
for (int i = 0; i < len; i += 16) {
|
||||||
|
PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s", i, i, sprint_hex(&fdata.data[i], len > 16 ? 16 : len), sprint_ascii(&fdata.data[i], len > 16 ? 16 : len));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
|
DropField();
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
DropField();
|
DropField();
|
||||||
|
@ -3082,7 +3239,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "-- Mifare DESFire Enumerate applications --------------------");
|
PrintAndLogEx(INFO, "-- Mifare DESFire Enumerate applications --------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") "application%c", app_ids_len / 3, (app_ids_len == 3) ? ' ' : 's');
|
PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") " application%c", app_ids_len / 3, (app_ids_len == 3) ? ' ' : 's');
|
||||||
|
|
||||||
for (int i = 0; i < app_ids_len; i += 3) {
|
for (int i = 0; i < app_ids_len; i += 3) {
|
||||||
|
|
||||||
|
@ -3116,7 +3273,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||||
|
|
||||||
// Get File IDs
|
// Get File IDs
|
||||||
if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) {
|
if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") "file%c", file_ids_len, (file_ids_len == 1) ? ' ' : 's');
|
PrintAndLogEx(SUCCESS, " Tag report " _GREEN_("%d") " file%c", file_ids_len, (file_ids_len == 1) ? ' ' : 's');
|
||||||
for (int j = file_ids_len - 1; j >= 0; j--) {
|
for (int j = file_ids_len - 1; j >= 0; j--) {
|
||||||
PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[j], file_ids[j]);
|
PrintAndLogEx(SUCCESS, " Fileid %d (0x%02x)", file_ids[j], file_ids[j]);
|
||||||
|
|
||||||
|
@ -3305,17 +3462,523 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
mfdes_auth_res_t rpayload;
|
mfdes_auth_res_t rpayload;
|
||||||
if (handler_desfire_auth(&payload, &rpayload, usedefaultkey) == PM3_SUCCESS) {
|
int error = handler_desfire_auth(&payload, &rpayload, usedefaultkey);
|
||||||
|
if (error == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, " Key : " _GREEN_("%s"), sprint_hex(key, keylength));
|
PrintAndLogEx(SUCCESS, " Key : " _GREEN_("%s"), sprint_hex(key, keylength));
|
||||||
PrintAndLogEx(SUCCESS, " SESSION : " _GREEN_("%s"), sprint_hex(rpayload.sessionkey, keylength));
|
PrintAndLogEx(SUCCESS, " SESSION : " _GREEN_("%s"), sprint_hex(rpayload.sessionkey, keylength));
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
} else {
|
} else {
|
||||||
|
AuthToError(error);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DesFill2bPattern(uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t *deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], size_t *aeskeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], size_t *k3kkeyListLen, uint32_t *startPattern) {
|
||||||
|
for (uint32_t pt = *startPattern; pt < 0x10000; pt++) {
|
||||||
|
if (*deskeyListLen != MAX_KEYS_LIST_LEN) {
|
||||||
|
deskeyList[*deskeyListLen][0] = (pt >> 8) & 0xff;
|
||||||
|
deskeyList[*deskeyListLen][1] = pt & 0xff;
|
||||||
|
memcpy(&deskeyList[*deskeyListLen][2], &deskeyList[*deskeyListLen][0], 2);
|
||||||
|
memcpy(&deskeyList[*deskeyListLen][4], &deskeyList[*deskeyListLen][0], 4);
|
||||||
|
(*deskeyListLen)++;
|
||||||
|
}
|
||||||
|
if (*aeskeyListLen != MAX_KEYS_LIST_LEN) {
|
||||||
|
aeskeyList[*aeskeyListLen][0] = (pt >> 8) & 0xff;
|
||||||
|
aeskeyList[*aeskeyListLen][1] = pt & 0xff;
|
||||||
|
memcpy(&aeskeyList[*aeskeyListLen][2], &aeskeyList[*aeskeyListLen][0], 2);
|
||||||
|
memcpy(&aeskeyList[*aeskeyListLen][4], &aeskeyList[*aeskeyListLen][0], 4);
|
||||||
|
memcpy(&aeskeyList[*aeskeyListLen][8], &aeskeyList[*aeskeyListLen][0], 8);
|
||||||
|
(*aeskeyListLen)++;
|
||||||
|
}
|
||||||
|
if (*k3kkeyListLen != MAX_KEYS_LIST_LEN) {
|
||||||
|
k3kkeyList[*k3kkeyListLen][0] = (pt >> 8) & 0xff;
|
||||||
|
k3kkeyList[*k3kkeyListLen][1] = pt & 0xff;
|
||||||
|
memcpy(&k3kkeyList[*k3kkeyListLen][2], &k3kkeyList[*k3kkeyListLen][0], 2);
|
||||||
|
memcpy(&k3kkeyList[*k3kkeyListLen][4], &k3kkeyList[*k3kkeyListLen][0], 4);
|
||||||
|
memcpy(&k3kkeyList[*k3kkeyListLen][8], &k3kkeyList[*k3kkeyListLen][0], 8);
|
||||||
|
memcpy(&k3kkeyList[*k3kkeyListLen][16], &k3kkeyList[*k3kkeyListLen][0], 4);
|
||||||
|
(*k3kkeyListLen)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*startPattern = pt;
|
||||||
|
if ((*deskeyListLen == MAX_KEYS_LIST_LEN) && (*aeskeyListLen == MAX_KEYS_LIST_LEN) && (*k3kkeyListLen == MAX_KEYS_LIST_LEN))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(*startPattern)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int AuthCheckDesfire(uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], size_t deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], size_t aeskeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], size_t k3kkeyListLen, uint8_t foundKeys[4][0xE][24 + 1], bool *result) {
|
||||||
|
int res = handler_desfire_select_application(aid);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "AID %X does not exist.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usedkeys[0xF] = {0};
|
||||||
|
bool des = false;
|
||||||
|
bool tdes = false;
|
||||||
|
bool aes = false;
|
||||||
|
bool k3kdes = false;
|
||||||
|
|
||||||
|
if (memcmp(aid, "\x00\x00\x00", 3) != 0) {
|
||||||
|
uint8_t file_ids[33] = {0};
|
||||||
|
uint8_t file_ids_len = 0;
|
||||||
|
// Get File IDs
|
||||||
|
if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) {
|
||||||
|
for (int j = file_ids_len - 1; j >= 0; j--) {
|
||||||
|
uint8_t filesettings[20] = {0};
|
||||||
|
int fileset_len = 0;
|
||||||
|
res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
uint16_t accrights = (filesettings[3] << 8) + filesettings[2];
|
||||||
|
int change_access_rights = accrights & 0xF;
|
||||||
|
int read_write_access = (accrights >> 4) & 0xF;
|
||||||
|
int write_access = (accrights >> 8) & 0xF;
|
||||||
|
int read_access = (accrights >> 12) & 0xF;
|
||||||
|
if (change_access_rights == 0xE) change_access_rights = 0x0;
|
||||||
|
if (read_write_access == 0xE) read_write_access = 0x0;
|
||||||
|
if (write_access == 0xE) write_access = 0x0;
|
||||||
|
if (read_access == 0xE) read_access = 0x0;
|
||||||
|
usedkeys[change_access_rights] = 1;
|
||||||
|
usedkeys[read_write_access] = 1;
|
||||||
|
usedkeys[write_access] = 1;
|
||||||
|
usedkeys[read_access] = 1;
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
switch (fileset_len >> 6) {
|
||||||
|
case 0:
|
||||||
|
des = true;
|
||||||
|
tdes = true;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
k3kdes = true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
aes = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (file_ids_len == 0) {
|
||||||
|
for (int z = 0; z < 0xE; z++) {
|
||||||
|
usedkeys[z] = 1;
|
||||||
|
des = true;
|
||||||
|
tdes = true;
|
||||||
|
aes = true;
|
||||||
|
k3kdes = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else des = true;
|
||||||
|
int error = PM3_SUCCESS;
|
||||||
|
bool badlen = false;
|
||||||
|
mfdes_authinput_t payload;
|
||||||
|
uint32_t curaid = (aid[0] & 0xFF) + ((aid[1] & 0xFF) << 8) + ((aid[2] & 0xFF) << 16);
|
||||||
|
if (des) {
|
||||||
|
for (int keyno = 0; keyno < 0xE; keyno++)
|
||||||
|
if (usedkeys[keyno] == 1 && foundKeys[0][keyno][0] == 0) {
|
||||||
|
for (int curkey = 0; curkey < deskeyListLen; curkey++) {
|
||||||
|
payload.keylen = 8;
|
||||||
|
memcpy(payload.key, deskeyList[curkey], 8);
|
||||||
|
payload.mode = MFDES_AUTH_DES;
|
||||||
|
payload.algo = MFDES_ALGO_DES;
|
||||||
|
payload.keyno = keyno;
|
||||||
|
mfdes_auth_res_t rpayload;
|
||||||
|
error = handler_desfire_auth(&payload, &rpayload, false);
|
||||||
|
if (error == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found DES Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(deskeyList[curkey], 8));
|
||||||
|
foundKeys[0][keyno][0] = 0x01;
|
||||||
|
*result = true;
|
||||||
|
memcpy(&foundKeys[0][keyno][1], deskeyList[curkey], 8);
|
||||||
|
break;
|
||||||
|
} else if (error < 7) {
|
||||||
|
badlen = true;
|
||||||
|
DropField();
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "AID %X does not exist.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (badlen == true) {
|
||||||
|
badlen = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tdes) {
|
||||||
|
for (int keyno = 0; keyno < 0xE; keyno++)
|
||||||
|
if (usedkeys[keyno] == 1 && foundKeys[1][keyno][0] == 0) {
|
||||||
|
for (int curkey = 0; curkey < aeskeyListLen; curkey++) {
|
||||||
|
payload.keylen = 16;
|
||||||
|
memcpy(payload.key, aeskeyList[curkey], 16);
|
||||||
|
payload.mode = MFDES_AUTH_DES;
|
||||||
|
payload.algo = MFDES_ALGO_3DES;
|
||||||
|
payload.keyno = keyno;
|
||||||
|
mfdes_auth_res_t rpayload;
|
||||||
|
error = handler_desfire_auth(&payload, &rpayload, false);
|
||||||
|
if (error == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3DES Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16));
|
||||||
|
foundKeys[1][keyno][0] = 0x01;
|
||||||
|
*result = true;
|
||||||
|
memcpy(&foundKeys[1][keyno][1], aeskeyList[curkey], 16);
|
||||||
|
break;
|
||||||
|
} else if (error < 7) {
|
||||||
|
badlen = true;
|
||||||
|
DropField();
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "AID %X does not exist.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (badlen == true) {
|
||||||
|
badlen = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aes) {
|
||||||
|
for (int keyno = 0; keyno < 0xE; keyno++)
|
||||||
|
if (usedkeys[keyno] == 1 && foundKeys[2][keyno][0] == 0) {
|
||||||
|
for (int curkey = 0; curkey < aeskeyListLen; curkey++) {
|
||||||
|
payload.keylen = 16;
|
||||||
|
memcpy(payload.key, aeskeyList[curkey], 16);
|
||||||
|
payload.mode = MFDES_AUTH_AES;
|
||||||
|
payload.algo = MFDES_ALGO_AES;
|
||||||
|
payload.keyno = keyno;
|
||||||
|
mfdes_auth_res_t rpayload;
|
||||||
|
error = handler_desfire_auth(&payload, &rpayload, false);
|
||||||
|
if (error == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16));
|
||||||
|
foundKeys[2][keyno][0] = 0x01;
|
||||||
|
*result = true;
|
||||||
|
memcpy(&foundKeys[2][keyno][1], aeskeyList[curkey], 16);
|
||||||
|
break;
|
||||||
|
} else if (error < 7) {
|
||||||
|
badlen = true;
|
||||||
|
DropField();
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "AID %X does not exist.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (badlen == true) {
|
||||||
|
badlen = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k3kdes) {
|
||||||
|
for (int keyno = 0; keyno < 0xE; keyno++)
|
||||||
|
if (usedkeys[keyno] == 1 && foundKeys[3][keyno][0] == 0) {
|
||||||
|
for (int curkey = 0; curkey < k3kkeyListLen; curkey++) {
|
||||||
|
payload.keylen = 24;
|
||||||
|
memcpy(payload.key, k3kkeyList[curkey], 24);
|
||||||
|
payload.mode = MFDES_AUTH_ISO;
|
||||||
|
payload.algo = MFDES_ALGO_3K3DES;
|
||||||
|
payload.keyno = keyno;
|
||||||
|
mfdes_auth_res_t rpayload;
|
||||||
|
error = handler_desfire_auth(&payload, &rpayload, false);
|
||||||
|
if (error == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3K3 Key %d : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24));
|
||||||
|
foundKeys[3][keyno][0] = 0x01;
|
||||||
|
*result = true;
|
||||||
|
memcpy(&foundKeys[3][keyno][1], k3kkeyList[curkey], 16);
|
||||||
|
break;
|
||||||
|
} else if (error < 7) {
|
||||||
|
badlen = true;
|
||||||
|
DropField();
|
||||||
|
res = handler_desfire_select_application(aid);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "AID %X does not exist.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (badlen == true) {
|
||||||
|
badlen = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DropField();
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF14aDesChk(const char *Cmd) {
|
||||||
|
int res;
|
||||||
|
uint8_t deskeyList[MAX_KEYS_LIST_LEN][8] = {{0}};
|
||||||
|
uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16] = {{0}};
|
||||||
|
uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][MAX_KEY_LEN] = {{0}};
|
||||||
|
size_t deskeyListLen = 0;
|
||||||
|
size_t aeskeyListLen = 0;
|
||||||
|
size_t k3kkeyListLen = 0;
|
||||||
|
uint8_t foundKeys[4][0xE][24 + 1] = {{{0}}};
|
||||||
|
|
||||||
|
CLIParserInit("hf mfdes chk",
|
||||||
|
"Checks keys with Mifare Desfire card.",
|
||||||
|
"Usage:\n"
|
||||||
|
" hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n"
|
||||||
|
" hf mfdes chk -d mfdes_default_keys -> check keys from dictionary against all existing aid on card\n"
|
||||||
|
" hf mfdes chk -d mfdes_default_keys -a 123456 -> check keys from dictionary against aid 0x123456\n"
|
||||||
|
" hf mfdes chk -a 123456 --pattern1b -j keys -> check all 1-byte keys pattern on aid 0x123456 and save found keys to json\n"
|
||||||
|
" hf mfdes chk -a 123456 --pattern2b --startp2b FA00 -> check all 2-byte keys pattern on aid 0x123456. Start from key FA00FA00...FA00\n");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_strx0("aA", "aid", "<aid>", "Use specific AID (3 hex bytes, big endian)"),
|
||||||
|
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
|
||||||
|
arg_str0("dD", "dict", "<file>", "File with keys dictionary"),
|
||||||
|
arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
|
||||||
|
arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
|
||||||
|
arg_str0(NULL, "startp2b", "<Pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
|
||||||
|
arg_str0("jJ", "json", "<file>", "Json file to save keys"),
|
||||||
|
arg_lit0("vV", "verbose", "Verbose mode."),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(Cmd, argtable, false);
|
||||||
|
|
||||||
|
int aidlength = 0;
|
||||||
|
uint8_t aid[3] = {0};
|
||||||
|
CLIGetHexWithReturn(1, aid, &aidlength);
|
||||||
|
swap24(aid);
|
||||||
|
uint8_t vkey[16] = {0};
|
||||||
|
int vkeylen = 0;
|
||||||
|
CLIGetHexWithReturn(2, vkey, &vkeylen);
|
||||||
|
|
||||||
|
if (vkeylen > 0) {
|
||||||
|
if (vkeylen == 8) {
|
||||||
|
memcpy(&deskeyList[deskeyListLen], vkey, 8);
|
||||||
|
deskeyListLen++;
|
||||||
|
} else if (vkeylen == 16) {
|
||||||
|
memcpy(&aeskeyList[aeskeyListLen], vkey, 16);
|
||||||
|
aeskeyListLen++;
|
||||||
|
} else if (vkeylen == 24) {
|
||||||
|
memcpy(&k3kkeyList[k3kkeyListLen], vkey, 16);
|
||||||
|
k3kkeyListLen++;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(ERR, "Specified key must have 8, 16 or 24 bytes length.");
|
||||||
|
CLIParserFree();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0};
|
||||||
|
int dict_filenamelen = 0;
|
||||||
|
if (CLIParamStrToBuf(arg_get_str(3), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||||
|
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||||
|
CLIParserFree();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pattern1b = arg_get_lit(4);
|
||||||
|
bool pattern2b = arg_get_lit(5);
|
||||||
|
|
||||||
|
if (pattern1b && pattern2b) {
|
||||||
|
PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only.");
|
||||||
|
CLIParserFree();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dict_filenamelen && (pattern1b || pattern2b)) {
|
||||||
|
PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command.");
|
||||||
|
CLIParserFree();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t startPattern = 0x0000;
|
||||||
|
uint8_t vpattern[2];
|
||||||
|
int vpatternlen = 0;
|
||||||
|
CLIGetHexWithReturn(6, vpattern, &vpatternlen);
|
||||||
|
if (vpatternlen > 0) {
|
||||||
|
if (vpatternlen > 0 && vpatternlen <= 2) {
|
||||||
|
startPattern = (vpattern[0] << 8) + vpattern[1];
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(ERR, "Pattern must be 2-byte length.");
|
||||||
|
CLIParserFree();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if (!pattern2b)
|
||||||
|
PrintAndLogEx(WARNING, "Pattern entered, but search mode not is 2-byte search.");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t jsonname[250] = {0};
|
||||||
|
int jsonnamelen = 0;
|
||||||
|
if (CLIParamStrToBuf(arg_get_str(7), jsonname, sizeof(jsonname), &jsonnamelen)) {
|
||||||
|
PrintAndLogEx(ERR, "Invalid json name.");
|
||||||
|
CLIParserFree();
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
jsonname[jsonnamelen] = 0;
|
||||||
|
|
||||||
|
bool verbose = arg_get_lit(8);
|
||||||
|
|
||||||
|
CLIParserFree();
|
||||||
|
|
||||||
|
// 1-byte pattern search mode
|
||||||
|
if (pattern1b) {
|
||||||
|
for (int i = 0; i < 0x100; i++)
|
||||||
|
memset(aeskeyList[i], i, 16);
|
||||||
|
for (int i = 0; i < 0x100; i++)
|
||||||
|
memset(deskeyList[i], i, 8);
|
||||||
|
for (int i = 0; i < 0x100; i++)
|
||||||
|
memset(k3kkeyList[i], i, 24);
|
||||||
|
aeskeyListLen = 0x100;
|
||||||
|
deskeyListLen = 0x100;
|
||||||
|
k3kkeyListLen = 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-byte pattern search mode
|
||||||
|
if (pattern2b) {
|
||||||
|
DesFill2bPattern(deskeyList, &deskeyListLen, aeskeyList, &aeskeyListLen, k3kkeyList, &k3kkeyListLen, &startPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
// dictionary mode
|
||||||
|
size_t endFilePosition = 0;
|
||||||
|
if (dict_filenamelen) {
|
||||||
|
uint16_t keycnt = 0;
|
||||||
|
res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 8, &keycnt, 0, &endFilePosition, true);
|
||||||
|
deskeyListLen = keycnt;
|
||||||
|
if (endFilePosition)
|
||||||
|
PrintAndLogEx(SUCCESS, "First part of des dictionary successfully loaded.");
|
||||||
|
endFilePosition = 0;
|
||||||
|
res = loadFileDICTIONARYEx((char *)dict_filename, aeskeyList, sizeof(aeskeyList), NULL, 16, &keycnt, 0, &endFilePosition, true);
|
||||||
|
aeskeyListLen = keycnt;
|
||||||
|
if (endFilePosition)
|
||||||
|
PrintAndLogEx(SUCCESS, "First part of aes dictionary successfully loaded.");
|
||||||
|
endFilePosition = 0;
|
||||||
|
res = loadFileDICTIONARYEx((char *)dict_filename, k3kkeyList, sizeof(k3kkeyList), NULL, 24, &keycnt, 0, &endFilePosition, true);
|
||||||
|
k3kkeyListLen = keycnt;
|
||||||
|
if (endFilePosition)
|
||||||
|
PrintAndLogEx(SUCCESS, "First part of k3kdes dictionary successfully loaded.");
|
||||||
|
endFilePosition = 0;
|
||||||
|
|
||||||
|
if (endFilePosition)
|
||||||
|
PrintAndLogEx(SUCCESS, "First part of dictionary successfully loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aeskeyListLen == 0) {
|
||||||
|
PrintAndLogEx(ERR, "Aes key list is empty. Nothing to check.");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " aes keys", aeskeyListLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deskeyListLen == 0) {
|
||||||
|
PrintAndLogEx(ERR, "Des key list is empty. Nothing to check.");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " des keys", deskeyListLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k3kkeyListLen == 0) {
|
||||||
|
PrintAndLogEx(ERR, "K3k key list is empty. Nothing to check.");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " k3kdes keys", k3kkeyListLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!verbose)
|
||||||
|
printf("Search keys:\n");
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
uint8_t app_ids[78] = {0};
|
||||||
|
uint8_t app_ids_len = 0;
|
||||||
|
|
||||||
|
if (handler_desfire_appids(app_ids, &app_ids_len) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "Can't get list of applications on tag");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aidlength != 0) {
|
||||||
|
memcpy(&app_ids[0], aid, 3);
|
||||||
|
app_ids_len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < app_ids_len / 3; x++) {
|
||||||
|
uint32_t curaid = (app_ids[x * 3] & 0xFF) + ((app_ids[(x * 3) + 1] & 0xFF) << 8) + ((app_ids[(x * 3) + 2] & 0xFF) << 16);
|
||||||
|
PrintAndLogEx(ERR, "Checking aid 0x%06X...", curaid);
|
||||||
|
res = AuthCheckDesfire(&app_ids[x * 3], deskeyList, deskeyListLen, aeskeyList, aeskeyListLen, k3kkeyList, k3kkeyListLen, foundKeys, &result);
|
||||||
|
if (res == PM3_EOPABORTED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pattern2b && startPattern < 0x10000) {
|
||||||
|
if (!verbose)
|
||||||
|
printf("p");
|
||||||
|
aeskeyListLen = 0;
|
||||||
|
deskeyListLen = 0;
|
||||||
|
k3kkeyListLen = 0;
|
||||||
|
DesFill2bPattern(deskeyList, &deskeyListLen, aeskeyList, &aeskeyListLen, k3kkeyList, &k3kkeyListLen, &startPattern);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (dict_filenamelen && endFilePosition) {
|
||||||
|
if (!verbose)
|
||||||
|
printf("d");
|
||||||
|
uint16_t keycnt = 0;
|
||||||
|
res = loadFileDICTIONARYEx((char *)dict_filename, deskeyList, sizeof(deskeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false);
|
||||||
|
deskeyListLen = keycnt;
|
||||||
|
keycnt = 0;
|
||||||
|
res = loadFileDICTIONARYEx((char *)dict_filename, aeskeyList, sizeof(aeskeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false);
|
||||||
|
aeskeyListLen = keycnt;
|
||||||
|
keycnt = 0;
|
||||||
|
res = loadFileDICTIONARYEx((char *)dict_filename, k3kkeyList, sizeof(k3kkeyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false);
|
||||||
|
k3kkeyListLen = keycnt;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!verbose)
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// save keys to json
|
||||||
|
if ((jsonnamelen > 0) && result) {
|
||||||
|
// Mifare Desfire info
|
||||||
|
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
WaitForResponse(CMD_ACK, &resp);
|
||||||
|
|
||||||
|
iso14a_card_select_t card;
|
||||||
|
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
|
||||||
|
|
||||||
|
uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||||
|
|
||||||
|
uint8_t data[10 + 1 + 2 + 1 + 256 + (4 * 0xE * (24 + 1))] = {0};
|
||||||
|
uint8_t atslen = 0;
|
||||||
|
if (select_status == 1 || select_status == 2) {
|
||||||
|
memcpy(data, card.uid, card.uidlen);
|
||||||
|
data[10] = card.sak;
|
||||||
|
data[11] = card.atqa[1];
|
||||||
|
data[12] = card.atqa[0];
|
||||||
|
atslen = card.ats_len;
|
||||||
|
data[13] = atslen;
|
||||||
|
memcpy(&data[14], card.ats, atslen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1]
|
||||||
|
memcpy(&data[14 + atslen], foundKeys, 4 * 0xE * (24 + 1));
|
||||||
|
saveFileJSON((char *)jsonname, jsfMfDesfireKeys, data, 0xE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHF14ADesList(const char *Cmd) {
|
static int CmdHF14ADesList(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
return CmdTraceList("des");
|
return CmdTraceList("des");
|
||||||
|
@ -3364,6 +4027,8 @@ static command_t CommandTable[] = {
|
||||||
{"getvalue", CmdHF14ADesGetValueData, IfPm3Iso14443a, "Get value of file"},
|
{"getvalue", CmdHF14ADesGetValueData, IfPm3Iso14443a, "Get value of file"},
|
||||||
{"changevalue", CmdHF14ADesChangeValue, IfPm3Iso14443a, "Write value of a value file (credit/debit/clear)"},
|
{"changevalue", CmdHF14ADesChangeValue, IfPm3Iso14443a, "Write value of a value file (credit/debit/clear)"},
|
||||||
{"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"},
|
{"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"},
|
||||||
|
{"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"},
|
||||||
|
{"chk", CmdHF14aDesChk, IfPm3Iso14443a, "Check keys"},
|
||||||
/*
|
/*
|
||||||
ToDo:
|
ToDo:
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "crapto1/crapto1.h"
|
#include "crapto1/crapto1.h"
|
||||||
#include "parity.h"
|
#include "parity.h"
|
||||||
#include "hardnested/hardnested_bruteforce.h"
|
#include "hardnested_bruteforce.h"
|
||||||
#include "hardnested/hardnested_bf_core.h"
|
#include "hardnested_bf_core.h"
|
||||||
#include "hardnested/hardnested_bitarray_core.h"
|
#include "hardnested_bitarray_core.h"
|
||||||
#include "zlib.h"
|
#include "zlib/zlib.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
|
|
||||||
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
|
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
#include "mifare/mifare4.h"
|
#include "mifare/mifare4.h"
|
||||||
#include "mifare/mad.h"
|
#include "mifare/mad.h"
|
||||||
#include "mifare/ndef.h"
|
#include "mifare/ndef.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "emv/dump.h"
|
#include "emv/dump.h"
|
||||||
#include "mifare/mifaredefault.h"
|
#include "mifare/mifaredefault.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "../crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
|
|
||||||
static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001};
|
uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001};
|
||||||
|
@ -58,9 +58,9 @@ static char *getCardSizeStr(uint8_t fsize) {
|
||||||
|
|
||||||
// is LSB set?
|
// is LSB set?
|
||||||
if (fsize & 1)
|
if (fsize & 1)
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
|
sprintf(retStr, "0x%02X (" _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize);
|
sprintf(retStr, "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,14 +70,14 @@ static char *getProtocolStr(uint8_t id, bool hw) {
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (id == 0x04) {
|
if (id == 0x04) {
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3 MIFARE, 14443-4") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-3 MIFARE, 14443-4") ")", id);
|
||||||
} else if (id == 0x05) {
|
} else if (id == 0x05) {
|
||||||
if (hw)
|
if (hw)
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-2, 14443-3") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-2, 14443-3") ")", id);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-3, 14443-4") ")", id);
|
||||||
} else {
|
} else {
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id);
|
sprintf(retStr, "0x%02X (" _YELLOW_("Unknown") ")", id);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -88,20 +88,20 @@ static char *getVersionStr(uint8_t major, uint8_t minor) {
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (major == 0x00)
|
if (major == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire MF3ICD40") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire MF3ICD40") ")", major, minor);
|
||||||
else if (major == 0x01 && minor == 0x00)
|
else if (major == 0x01 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV1") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor);
|
||||||
else if (major == 0x12 && minor == 0x00)
|
else if (major == 0x12 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV2") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV2") ")", major, minor);
|
||||||
// else if (major == 0x13 && minor == 0x00)
|
// else if (major == 0x13 && minor == 0x00)
|
||||||
// sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV3") ")", major, minor);
|
// sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor);
|
||||||
else if (major == 0x30 && minor == 0x00)
|
else if (major == 0x30 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire Light") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("DESFire Light") ")", major, minor);
|
||||||
|
|
||||||
else if (major == 0x11 && minor == 0x00)
|
else if (major == 0x11 && minor == 0x00)
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("Plus EV1") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("Plus EV1") ")", major, minor);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor);
|
sprintf(retStr, "%x.%x (" _YELLOW_("Unknown") ")", major, minor);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,16 +112,16 @@ static char *getTypeStr(uint8_t type) {
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("DESFire") ")", type);
|
sprintf(retStr, "0x%02X (" _YELLOW_("DESFire") ")", type);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("Plus") ")", type);
|
sprintf(retStr, "0x%02X (" _YELLOW_("Plus") ")", type);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("Ultralight") ")", type);
|
sprintf(retStr, "0x%02X (" _YELLOW_("Ultralight") ")", type);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
sprintf(retStr, "0x%02X ( " _YELLOW_("NTAG") ")", type);
|
sprintf(retStr, "0x%02X (" _YELLOW_("NTAG") ")", type);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -227,7 +227,7 @@ static int get_plus_signature(uint8_t *signature, int *signature_len) {
|
||||||
static int plus_print_version(uint8_t *version) {
|
static int plus_print_version(uint8_t *version) {
|
||||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(version + 14, 7));
|
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(version + 14, 7));
|
||||||
PrintAndLogEx(SUCCESS, " Batch number: " _GREEN_("%s"), sprint_hex(version + 21, 5));
|
PrintAndLogEx(SUCCESS, " Batch number: " _GREEN_("%s"), sprint_hex(version + 21, 5));
|
||||||
PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") "/ " _GREEN_("20%02x"), version[7 + 7 + 7 + 5], version[7 + 7 + 7 + 5 + 1]);
|
PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") " / " _GREEN_("20%02x"), version[7 + 7 + 7 + 5], version[7 + 7 + 7 + 5 + 1]);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information"));
|
PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information"));
|
||||||
PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(version[0]));
|
PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(version[0]));
|
||||||
|
@ -266,7 +266,7 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
||||||
PrintAndLogEx(WARNING, "command don't have any parameters.\n");
|
PrintAndLogEx(WARNING, "command don't have any parameters.\n");
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
|
|
||||||
bool supportVersion = false;
|
bool supportVersion = false;
|
||||||
|
@ -328,11 +328,11 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
||||||
uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8);
|
uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8);
|
||||||
|
|
||||||
if (ATQA & 0x0004) {
|
if (ATQA & 0x0004) {
|
||||||
PrintAndLogEx(INFO, " SIZE: " _GREEN_("2K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4");
|
PrintAndLogEx(INFO, " SIZE: " _GREEN_("2K") " (%s UID)", (ATQA & 0x0040) ? "7" : "4");
|
||||||
isPlus = true;
|
isPlus = true;
|
||||||
}
|
}
|
||||||
if (ATQA & 0x0002) {
|
if (ATQA & 0x0002) {
|
||||||
PrintAndLogEx(INFO, " SIZE: " _GREEN_("4K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4");
|
PrintAndLogEx(INFO, " SIZE: " _GREEN_("4K") " (%s UID)", (ATQA & 0x0040) ? "7" : "4");
|
||||||
isPlus = true;
|
isPlus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card.sak == 0x20) {
|
if (card.sak == 0x20) {
|
||||||
PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") "or " _GREEN_("MIFARE DESFire"));
|
PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire"));
|
||||||
|
|
||||||
if (card.ats_len > 0) {
|
if (card.ats_len > 0) {
|
||||||
|
|
||||||
|
@ -1190,7 +1190,7 @@ static int CmdHFMFPChk(const char *Cmd) {
|
||||||
PrintAndLogEx(ERR, "Key list is empty. Nothing to check.");
|
PrintAndLogEx(ERR, "Key list is empty. Nothing to check.");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") "keys", keyListLen);
|
PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " keys", keyListLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verbose)
|
if (!verbose)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "../crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
#include "mbedtls/des.h"
|
#include "mbedtls/des.h"
|
||||||
#include "cmdhfmf.h"
|
#include "cmdhfmf.h"
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "generator.h"
|
#include "generator.h"
|
||||||
#include "mifare/ndef.h"
|
#include "mifare/ndef.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_UL_BLOCKS 0x0F
|
#define MAX_UL_BLOCKS 0x0F
|
||||||
|
@ -64,13 +64,13 @@ static int usage_hf_mfu_info(void) {
|
||||||
static int usage_hf_mfu_dump(void) {
|
static int usage_hf_mfu_dump(void) {
|
||||||
PrintAndLogEx(NORMAL, "Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
|
PrintAndLogEx(NORMAL, "Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
|
||||||
PrintAndLogEx(NORMAL, "NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
|
PrintAndLogEx(NORMAL, "NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
|
||||||
PrintAndLogEx(NORMAL, "and saves binary dump into the file " _YELLOW_("`filename.bin`") "or " _YELLOW_("`cardUID.bin`"));
|
PrintAndLogEx(NORMAL, "and saves binary dump into the file " _YELLOW_("`filename.bin`") " or " _YELLOW_("`cardUID.bin`"));
|
||||||
PrintAndLogEx(NORMAL, "It autodetects card type.\n");
|
PrintAndLogEx(NORMAL, "It autodetects card type.\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mfu dump k <key> l f <filename w/o .bin> p <page#> q <#pages>");
|
PrintAndLogEx(NORMAL, "Usage: hf mfu dump k <key> l f <filename w/o .bin> p <page#> q <#pages>");
|
||||||
PrintAndLogEx(NORMAL, " Options :");
|
PrintAndLogEx(NORMAL, " Options :");
|
||||||
PrintAndLogEx(NORMAL, " k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
|
PrintAndLogEx(NORMAL, " k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
|
||||||
PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness");
|
PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness");
|
||||||
PrintAndLogEx(NORMAL, " f <fn> : " _YELLOW_("filename w/o .bin") "to save the dump as");
|
PrintAndLogEx(NORMAL, " f <fn> : " _YELLOW_("filename w/o .bin") " to save the dump as");
|
||||||
PrintAndLogEx(NORMAL, " p <pg> : starting Page number to manually set a page to start the dump at");
|
PrintAndLogEx(NORMAL, " p <pg> : starting Page number to manually set a page to start the dump at");
|
||||||
PrintAndLogEx(NORMAL, " q <qty> : number of Pages to manually set how many pages to dump");
|
PrintAndLogEx(NORMAL, " q <qty> : number of Pages to manually set how many pages to dump");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -91,8 +91,8 @@ static int usage_hf_mfu_restore(void) {
|
||||||
PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness");
|
PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness");
|
||||||
PrintAndLogEx(NORMAL, " s : (optional) enable special write UID " _BLUE_("-MAGIC TAG ONLY-"));
|
PrintAndLogEx(NORMAL, " s : (optional) enable special write UID " _BLUE_("-MAGIC TAG ONLY-"));
|
||||||
PrintAndLogEx(NORMAL, " e : (optional) enable special write version/signature " _BLUE_("-MAGIC NTAG 21* ONLY-"));
|
PrintAndLogEx(NORMAL, " e : (optional) enable special write version/signature " _BLUE_("-MAGIC NTAG 21* ONLY-"));
|
||||||
PrintAndLogEx(NORMAL, " r : (optional) use the password found in dumpfile to configure tag. requires " _YELLOW_("'e'") "parameter to work");
|
PrintAndLogEx(NORMAL, " r : (optional) use the password found in dumpfile to configure tag. requires " _YELLOW_("'e'") " parameter to work");
|
||||||
PrintAndLogEx(NORMAL, " f <fn> : " _YELLOW_("filename w .bin") "to restore");
|
PrintAndLogEx(NORMAL, " f <fn> : " _YELLOW_("filename w .bin") " to restore");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu restore s f myfile"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu restore s f myfile"));
|
||||||
|
@ -136,7 +136,7 @@ static int usage_hf_mfu_wrbl(void) {
|
||||||
|
|
||||||
static int usage_hf_mfu_eload(void) {
|
static int usage_hf_mfu_eload(void) {
|
||||||
PrintAndLogEx(NORMAL, "It loads emul dump from the file " _YELLOW_("`filename.eml`"));
|
PrintAndLogEx(NORMAL, "It loads emul dump from the file " _YELLOW_("`filename.eml`"));
|
||||||
PrintAndLogEx(NORMAL, "Hint: See " _YELLOW_("`script run dumptoemul-mfu`") "to convert the .bin to the eml");
|
PrintAndLogEx(NORMAL, "Hint: See " _YELLOW_("`script run dumptoemul-mfu`") " to convert the .bin to the eml");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
|
PrintAndLogEx(NORMAL, "Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
|
||||||
PrintAndLogEx(NORMAL, " Options:");
|
PrintAndLogEx(NORMAL, " Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : this help");
|
PrintAndLogEx(NORMAL, " h : this help");
|
||||||
|
@ -198,7 +198,7 @@ static int usage_hf_mfu_ucsetuid(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mfu setuid <uid (14 hex symbols)>");
|
PrintAndLogEx(NORMAL, "Usage: hf mfu setuid <uid (14 hex symbols)>");
|
||||||
PrintAndLogEx(NORMAL, " [uid] - (14 hex symbols)");
|
PrintAndLogEx(NORMAL, " [uid] - (14 hex symbols)");
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
PrintAndLogEx(NORMAL, "This only works for " _BLUE_("Magic Ultralight") "tags.");
|
PrintAndLogEx(NORMAL, "This only works for " _BLUE_("Magic Ultralight") " tags.");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu setuid 11223344556677"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu setuid 11223344556677"));
|
||||||
|
@ -235,13 +235,21 @@ static int usage_hf_mfu_pwdgen(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usage_hf_mfu_otp_tearoff(void) {
|
static int usage_hf_mfu_otp_tearoff(void) {
|
||||||
PrintAndLogEx(NORMAL, "Tear-off test against OTP block on MFU tags.");
|
PrintAndLogEx(NORMAL, "Tear-off test against OTP block (no 3) on MFU tags - More help sooner or later\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mfu otptear [h]");
|
PrintAndLogEx(NORMAL, "Usage: hf mfu otptear b <block number> i <intervalTime> l <limitTime> s <startTime> d <data before> t <data after>\n");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : this help");
|
PrintAndLogEx(NORMAL, " b <no> : (optional) block to run the test - default block: 8 (not OTP for safety)");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, " i <time> : (optional) time interval to increase in each test - default 500 us");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu otptear"));
|
PrintAndLogEx(NORMAL, " l <time> : (optional) limit time to run the test - default 3000 us");
|
||||||
|
PrintAndLogEx(NORMAL, " s <time> : (optional) start time to run the test - default 0 us");
|
||||||
|
PrintAndLogEx(NORMAL, " d <data> : (optional) data to full-write before trying the OTP test - default 0x00");
|
||||||
|
PrintAndLogEx(NORMAL, " t <data> : (optional) data to write while running the OTP test - default 0x00");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " hf mfu otptear b 3");
|
||||||
|
PrintAndLogEx(NORMAL, " hf mfu otptear b 8 i 100 l 3000 s 1000");
|
||||||
|
PrintAndLogEx(NORMAL, " hf mfu otptear b 3 i 1 l 200");
|
||||||
|
PrintAndLogEx(NORMAL, " hf mfu otptear b 3 i 100 l 2500 s 200 d FFFFFFFF t EEEEEEEE");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,17 +524,17 @@ static int ul_print_default(uint8_t *data) {
|
||||||
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
|
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
|
||||||
int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
||||||
if (data[3] == crc0)
|
if (data[3] == crc0)
|
||||||
PrintAndLogEx(SUCCESS, " BCC0: %02X ( " _GREEN_("ok") ")", data[3]);
|
PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0);
|
PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0);
|
||||||
|
|
||||||
int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
|
int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
|
||||||
if (data[8] == crc1)
|
if (data[8] == crc1)
|
||||||
PrintAndLogEx(SUCCESS, " BCC1: %02X ( " _GREEN_("ok") ")", data[8]);
|
PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1);
|
PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " Internal: %02X ( %s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default"));
|
PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default"));
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " Lock: %s - %s",
|
PrintAndLogEx(SUCCESS, " Lock: %s - %s",
|
||||||
sprint_hex(data + 10, 2),
|
sprint_hex(data + 10, 2),
|
||||||
|
@ -635,10 +643,10 @@ static int ndef_print_CC(uint8_t *data) {
|
||||||
PrintAndLogEx(SUCCESS, " Additional feature information");
|
PrintAndLogEx(SUCCESS, " Additional feature information");
|
||||||
PrintAndLogEx(SUCCESS, " %02X", data[3]);
|
PrintAndLogEx(SUCCESS, " %02X", data[3]);
|
||||||
PrintAndLogEx(SUCCESS, " 00000000");
|
PrintAndLogEx(SUCCESS, " 00000000");
|
||||||
PrintAndLogEx(SUCCESS, " xxx - %02X: RFU ( %s)", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail"));
|
PrintAndLogEx(SUCCESS, " xxx - %02X: RFU (%s)", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(SUCCESS, " x - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support");
|
PrintAndLogEx(SUCCESS, " x - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support");
|
||||||
PrintAndLogEx(SUCCESS, " x - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support");
|
PrintAndLogEx(SUCCESS, " x - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support");
|
||||||
PrintAndLogEx(SUCCESS, " xx - %02X: RFU ( %s)", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail"));
|
PrintAndLogEx(SUCCESS, " xx - %02X: RFU (%s)", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(SUCCESS, " x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support");
|
PrintAndLogEx(SUCCESS, " x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1187,7 +1195,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
if (tagtype == UL_ERROR) return PM3_ESOFT;
|
if (tagtype == UL_ERROR) return PM3_ESOFT;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " --------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
ul_print_type(tagtype, 6);
|
ul_print_type(tagtype, 6);
|
||||||
|
|
||||||
|
@ -1353,7 +1361,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1363,7 +1371,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,7 +1391,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
key = default_pwd_pack[i];
|
key = default_pwd_pack[i];
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") "|| Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password: " _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
|
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
|
||||||
|
@ -2683,29 +2691,133 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
// Moebius et al
|
// Moebius et al
|
||||||
//
|
//
|
||||||
static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
||||||
|
uint8_t blockNoUint = 8;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = 0;
|
bool errors = 0;
|
||||||
uint32_t len = strtol(Cmd, NULL, 0);
|
uint8_t teardata[8] = {0x00};
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0};
|
uint32_t interval = 500; // time in us
|
||||||
|
uint32_t timeLimit = 3000; // time in us
|
||||||
|
uint32_t startTime = 0; // time in us
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'h':
|
case 'h':
|
||||||
return usage_hf_mfu_otp_tearoff();
|
return usage_hf_mfu_otp_tearoff();
|
||||||
|
case 'b':
|
||||||
|
blockNoUint = param_get8(Cmd, cmdp + 1);
|
||||||
|
if (blockNoUint < 0) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong block number");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
interval = param_get32ex(Cmd, cmdp + 1, interval, 10);
|
||||||
|
if (interval <= 0) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong interval number");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
timeLimit = param_get32ex(Cmd, cmdp + 1, timeLimit, 10);
|
||||||
|
if (timeLimit < interval) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong time limit number");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
startTime = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||||
|
if (startTime > (timeLimit - interval)) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong start time number");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (param_gethex(Cmd, cmdp + 1, teardata, 8)) {
|
||||||
|
PrintAndLogEx(WARNING, "Block data must include 8 HEX symbols");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if (param_gethex(Cmd, cmdp + 1, teardata + 4, 8)) {
|
||||||
|
PrintAndLogEx(WARNING, "Block data must include 8 HEX symbols");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors) return usage_hf_mfu_otp_tearoff();
|
if (errors) return usage_hf_mfu_otp_tearoff();
|
||||||
|
|
||||||
|
uint32_t actualTime = startTime;
|
||||||
|
printf("\nStarting TearOff test - Selected Block no: %d ...\n", blockNoUint);
|
||||||
|
|
||||||
|
while (actualTime <= (timeLimit - interval)) {
|
||||||
|
printf("\nTrying attack at: %d us\n", actualTime);
|
||||||
|
printf("\n.....\n");
|
||||||
|
printf("\nReading block before attack: \n");
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_HF_MFU_OTP_TEAROFF, data, len);
|
SendCommandOLD(CMD_HF_MIFAREU_READBL, blockNoUint, 0, 0, NULL, 0);
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
|
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||||
|
if (isOK) {
|
||||||
|
uint8_t *d = resp.data.asBytes;
|
||||||
|
PrintAndLogEx(NORMAL, "\nBlock# | Data | Ascii");
|
||||||
|
PrintAndLogEx(NORMAL, "-----------------------------");
|
||||||
|
PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s\n", blockNoUint, blockNoUint, sprint_hex(d, 4), sprint_ascii(d, 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n.....\n");
|
||||||
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
SendCommandOLD(CMD_HF_MFU_OTP_TEAROFF, blockNoUint, actualTime, 0, teardata, 8);
|
||||||
if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) {
|
if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) {
|
||||||
PrintAndLogEx(WARNING, "Failed");
|
PrintAndLogEx(WARNING, "Failed");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("\nReading block after attack: \n");
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandOLD(CMD_HF_MIFAREU_READBL, blockNoUint, 0, 0, NULL, 0);
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
|
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||||
|
if (isOK) {
|
||||||
|
uint8_t *d = resp.data.asBytes;
|
||||||
|
PrintAndLogEx(NORMAL, "\nBlock# | Data | Ascii");
|
||||||
|
PrintAndLogEx(NORMAL, "-----------------------------");
|
||||||
|
PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s\n", blockNoUint, blockNoUint, sprint_hex(d, 4), sprint_ascii(d, 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TEMPORALLY DISABLED
|
||||||
|
uint8_t d0, d1, d2, d3;
|
||||||
|
d0 = *resp.data.asBytes;
|
||||||
|
d1 = *(resp.data.asBytes + 1);
|
||||||
|
d2 = *(resp.data.asBytes + 2);
|
||||||
|
d3 = *(resp.data.asBytes + 3);
|
||||||
|
if ((d0 != 0xFF) || (d1 != 0xFF) || (d2 != 0xFF) || (d3 = ! 0xFF)) {
|
||||||
|
PrintAndLogEx(NORMAL, "---------------------------------");
|
||||||
|
PrintAndLogEx(NORMAL, " EFFECT AT: %d us", actualTime);
|
||||||
|
PrintAndLogEx(NORMAL, "---------------------------------\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
actualTime += interval;
|
||||||
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,11 +61,11 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos
|
||||||
compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2);
|
compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2);
|
||||||
bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2);
|
bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
|
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")" - %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail"));
|
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")" - " _RED_("fail"));
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%zu")"- %s", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("OK") : _YELLOW_("warning"));
|
PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%zu")" - %s", barcode_len * 8, (barcode_len == 16 || barcode_len == 32) ? _GREEN_("OK") : _YELLOW_("warning"));
|
||||||
PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len));
|
PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len));
|
||||||
if (barcode_len < 4) // too few to go to next decoding stages
|
if (barcode_len < 4) // too few to go to next decoding stages
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
|
@ -414,7 +414,7 @@ static int CmdHFTopazInfo(const char *Cmd) {
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(SUCCESS, "Static Data blocks " _YELLOW_("0x00") "to " _YELLOW_("0x0C")":");
|
PrintAndLogEx(SUCCESS, "Static Data blocks " _YELLOW_("0x00") " to " _YELLOW_("0x0C")":");
|
||||||
PrintAndLogEx(NORMAL, "block# | offset | Data | Locked");
|
PrintAndLogEx(NORMAL, "block# | offset | Data | Locked");
|
||||||
PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------");
|
PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------");
|
||||||
char line[80];
|
char line[80];
|
||||||
|
@ -547,7 +547,7 @@ int readTopazUid(bool verbose) {
|
||||||
|
|
||||||
// printing
|
// printing
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, " UID: %02x %02x %02x %02x %02x %02x %02x",
|
PrintAndLogEx(SUCCESS, " UID: %02x %02x %02x %02x %02x %02x %02x",
|
||||||
topaz_tag.uid[6],
|
topaz_tag.uid[6],
|
||||||
|
|
|
@ -68,7 +68,7 @@ static int usage_hw_setmux(void) {
|
||||||
|
|
||||||
static int usage_hw_connect(void) {
|
static int usage_hw_connect(void) {
|
||||||
PrintAndLogEx(NORMAL, "Connects to a Proxmark3 device via specified serial port");
|
PrintAndLogEx(NORMAL, "Connects to a Proxmark3 device via specified serial port");
|
||||||
PrintAndLogEx(NORMAL, "Baudrate here is only for physical UART or UART-BT, " _YELLOW_("not")"for USB-CDC or blue shark add-on");
|
PrintAndLogEx(NORMAL, "Baudrate here is only for physical UART or UART-BT, " _YELLOW_("not")" for USB-CDC or blue shark add-on");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hw connect [h] [p <port>] [b <baudrate>]");
|
PrintAndLogEx(NORMAL, "Usage: hw connect [h] [p <port>] [b <baudrate>]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
@ -541,7 +541,7 @@ static int CmdPing(const char *Cmd) {
|
||||||
if (WaitForResponseTimeout(CMD_PING, &resp, 1000)) {
|
if (WaitForResponseTimeout(CMD_PING, &resp, 1000)) {
|
||||||
if (len) {
|
if (len) {
|
||||||
bool error = (memcmp(data, resp.data.asBytes, len) != 0);
|
bool error = (memcmp(data, resp.data.asBytes, len) != 0);
|
||||||
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("OK"));
|
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") " and content is %s", error ? _RED_("NOT ok") : _GREEN_("OK"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received"));
|
PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received"));
|
||||||
}
|
}
|
||||||
|
@ -593,7 +593,7 @@ static int CmdConnect(const char *Cmd) {
|
||||||
OpenProxmark(port, false, 10, false, baudrate);
|
OpenProxmark(port, false, 10, false, baudrate);
|
||||||
|
|
||||||
if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) {
|
if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) {
|
||||||
PrintAndLogEx(ERR, _RED_("ERROR:") "cannot communicate with the Proxmark3\n");
|
PrintAndLogEx(ERR, _RED_("ERROR:") " cannot communicate with the Proxmark3\n");
|
||||||
CloseProxmark();
|
CloseProxmark();
|
||||||
return PM3_ENOTTY;
|
return PM3_ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ static int usage_lf_cmdread(void) {
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000");
|
PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000");
|
||||||
PrintAndLogEx(NORMAL, "Extras:");
|
PrintAndLogEx(NORMAL, "Extras:");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_lf_read(void) {
|
static int usage_lf_read(void) {
|
||||||
|
@ -85,7 +85,7 @@ static int usage_lf_read(void) {
|
||||||
PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000 samples silent");
|
PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000 samples silent");
|
||||||
PrintAndLogEx(NORMAL, " lf read");
|
PrintAndLogEx(NORMAL, " lf read");
|
||||||
PrintAndLogEx(NORMAL, "Extras:");
|
PrintAndLogEx(NORMAL, "Extras:");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_lf_sim(void) {
|
static int usage_lf_sim(void) {
|
||||||
|
@ -98,7 +98,7 @@ static int usage_lf_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, " lf sim 240 - start simulating with 240ms gap");
|
PrintAndLogEx(NORMAL, " lf sim 240 - start simulating with 240ms gap");
|
||||||
PrintAndLogEx(NORMAL, " lf sim");
|
PrintAndLogEx(NORMAL, " lf sim");
|
||||||
PrintAndLogEx(NORMAL, "Extras:");
|
PrintAndLogEx(NORMAL, "Extras:");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_lf_sniff(void) {
|
static int usage_lf_sniff(void) {
|
||||||
|
@ -107,9 +107,9 @@ static int usage_lf_sniff(void) {
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h This help");
|
PrintAndLogEx(NORMAL, " h This help");
|
||||||
PrintAndLogEx(NORMAL, "Extras:");
|
PrintAndLogEx(NORMAL, "Extras:");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data samples'")"command to download from device");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data samples'")" command to download from device");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data plot'")"to look at it");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data plot'")" to look at it");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_lf_config(void) {
|
static int usage_lf_config(void) {
|
||||||
|
@ -253,7 +253,7 @@ static int CmdLFTune(const char *Cmd) {
|
||||||
//Validations
|
//Validations
|
||||||
if (errors) return usage_lf_tune();
|
if (errors) return usage_lf_tune();
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Measuring LF antenna at " _YELLOW_("%.2f") "kHz, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit", LF_DIV2FREQ(divisor));
|
PrintAndLogEx(INFO, "Measuring LF antenna at " _YELLOW_("%.2f") " kHz, click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit", LF_DIV2FREQ(divisor));
|
||||||
|
|
||||||
uint8_t params[] = {1, 0};
|
uint8_t params[] = {1, 0};
|
||||||
params[1] = divisor;
|
params[1] = divisor;
|
||||||
|
@ -1189,7 +1189,7 @@ static bool CheckChipType(bool getDeviceData) {
|
||||||
uint32_t word = 0;
|
uint32_t word = 0;
|
||||||
if (EM4x05IsBlock0(&word)) {
|
if (EM4x05IsBlock0(&word)) {
|
||||||
PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05/EM4x69"));
|
PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05/EM4x69"));
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05`") "commands");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05`") " commands");
|
||||||
retval = true;
|
retval = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1197,7 +1197,7 @@ static bool CheckChipType(bool getDeviceData) {
|
||||||
//check for t55xx chip...
|
//check for t55xx chip...
|
||||||
if (tryDetectP1(true)) {
|
if (tryDetectP1(true)) {
|
||||||
PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("T55xx"));
|
PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("T55xx"));
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf t55xx`") "commands");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf t55xx`") " commands");
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1230,7 +1230,7 @@ int CmdLFfind(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "NOTE: some demods output possible binary");
|
PrintAndLogEx(INFO, "NOTE: some demods output possible binary");
|
||||||
PrintAndLogEx(INFO, "if it finds something that looks like a tag");
|
PrintAndLogEx(INFO, "if it finds something that looks like a tag");
|
||||||
PrintAndLogEx(INFO, "False Positives " _YELLOW_("ARE") "possible");
|
PrintAndLogEx(INFO, "False Positives " _YELLOW_("ARE") " possible");
|
||||||
PrintAndLogEx(INFO, "");
|
PrintAndLogEx(INFO, "");
|
||||||
PrintAndLogEx(INFO, "Checking for known tags...");
|
PrintAndLogEx(INFO, "Checking for known tags...");
|
||||||
PrintAndLogEx(INFO, "");
|
PrintAndLogEx(INFO, "");
|
||||||
|
@ -1240,7 +1240,7 @@ int CmdLFfind(const char *Cmd) {
|
||||||
|
|
||||||
if (IfPm3Hitag()) {
|
if (IfPm3Hitag()) {
|
||||||
if (readHitagUid()) {
|
if (readHitagUid()) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,12 +1250,12 @@ int CmdLFfind(const char *Cmd) {
|
||||||
if (getSignalProperties()->isnoise) {
|
if (getSignalProperties()->isnoise) {
|
||||||
|
|
||||||
if (readMotorolaUid()) {
|
if (readMotorolaUid()) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") " found!");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readCOTAGUid()) {
|
if (readCOTAGUid()) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,33 +1265,33 @@ int CmdLFfind(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EM4x50Read("", false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM4x50 ID") "found!"); return PM3_SUCCESS;}
|
if (EM4x50Read("", false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM4x50 ID") " found!"); return PM3_SUCCESS;}
|
||||||
|
|
||||||
if (demodHID() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") "found!"); goto out;}
|
if (demodHID() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
|
||||||
if (demodAWID() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") "found!"); goto out;}
|
if (demodAWID() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
|
||||||
if (demodParadox() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") "found!"); goto out;}
|
if (demodParadox() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;}
|
||||||
|
|
||||||
if (demodEM410x() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") "found!"); goto out;}
|
if (demodEM410x() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
|
||||||
if (demodFDX() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") "found!"); goto out;}
|
if (demodFDX() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
|
||||||
if (demodGuard() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") "found!"); goto out; }
|
if (demodGuard() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
|
||||||
if (demodIdteck() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") "found!"); goto out;}
|
if (demodIdteck() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
|
||||||
if (demodIndala() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") "found!"); goto out;}
|
if (demodIndala() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
|
||||||
if (demodIOProx() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") "found!"); goto out;}
|
if (demodIOProx() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
|
||||||
if (demodJablotron() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") "found!"); goto out;}
|
if (demodJablotron() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;}
|
||||||
if (demodNedap() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") "found!"); goto out;}
|
if (demodNedap() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") " found!"); goto out;}
|
||||||
if (demodNexWatch() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") "found!"); goto out;}
|
if (demodNexWatch() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;}
|
||||||
if (demodNoralsy() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Noralsy ID") "found!"); goto out;}
|
if (demodNoralsy() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Noralsy ID") " found!"); goto out;}
|
||||||
if (demodKeri() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("KERI ID") "found!"); goto out;}
|
if (demodKeri() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("KERI ID") " found!"); goto out;}
|
||||||
if (demodPac() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("PAC/Stanley ID") "found!"); goto out;}
|
if (demodPac() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("PAC/Stanley ID") " found!"); goto out;}
|
||||||
|
|
||||||
if (demodPresco() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Presco ID") "found!"); goto out;}
|
if (demodPresco() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Presco ID") " found!"); goto out;}
|
||||||
if (demodPyramid() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Pyramid ID") "found!"); goto out;}
|
if (demodPyramid() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Pyramid ID") " found!"); goto out;}
|
||||||
if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") "found!"); goto out;}
|
if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") " found!"); goto out;}
|
||||||
if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") "found!"); goto out;}
|
if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") " found!"); goto out;}
|
||||||
if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") "found!"); goto out;}
|
if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") " found!"); goto out;}
|
||||||
if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") "found!"); goto out;}
|
if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") " found!"); goto out;}
|
||||||
// if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;}
|
// if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") " found!"); goto out;}
|
||||||
//if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;}
|
//if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") " found!"); goto out;}
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, _RED_("No known 125/134 kHz tags found!"));
|
PrintAndLogEx(FAILED, _RED_("No known 125/134 kHz tags found!"));
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,7 @@ static int CmdAWIDClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -489,7 +489,7 @@ static int CmdEM410xSim(const char *Cmd) {
|
||||||
|
|
||||||
param_getdec(Cmd, 1, &clk);
|
param_getdec(Cmd, 1, &clk);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Starting simulating UID "_YELLOW_("%02X%02X%02X%02X%02X")"clock: "_YELLOW_("%d"), uid[0], uid[1], uid[2], uid[3], uid[4], clk);
|
PrintAndLogEx(SUCCESS, "Starting simulating UID "_YELLOW_("%02X%02X%02X%02X%02X")" clock: "_YELLOW_("%d"), uid[0], uid[1], uid[2], uid[3], uid[4], clk);
|
||||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation");
|
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation");
|
||||||
|
|
||||||
ConstructEM410xEmulGraph(Cmd, clk);
|
ConstructEM410xEmulGraph(Cmd, clk);
|
||||||
|
@ -580,7 +580,7 @@ static int CmdEM410xBrute(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Loaded "_YELLOW_("%d")" UIDs from "_YELLOW_("%s")", pause delay:"_YELLOW_("%d")"ms", uidcnt, filename, delay);
|
PrintAndLogEx(SUCCESS, "Loaded "_YELLOW_("%d")" UIDs from "_YELLOW_("%s")", pause delay:"_YELLOW_("%d")" ms", uidcnt, filename, delay);
|
||||||
|
|
||||||
// loop
|
// loop
|
||||||
for (uint32_t c = 0; c < uidcnt; ++c) {
|
for (uint32_t c = 0; c < uidcnt; ++c) {
|
||||||
|
@ -701,7 +701,7 @@ static int CmdEM410xWrite(const char *Cmd) {
|
||||||
|
|
||||||
SendCommandMIX(CMD_LF_EM410X_WRITE, card, (uint32_t)(id >> 32), (uint32_t)id, NULL, 0);
|
SendCommandMIX(CMD_LF_EM410X_WRITE, card, (uint32_t)(id >> 32), (uint32_t)id, NULL, 0);
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 410x_read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 410x_read`") " to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,7 +1041,7 @@ static int CmdEM4x50Write(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "no implemented yet");
|
PrintAndLogEx(NORMAL, "no implemented yet");
|
||||||
//
|
//
|
||||||
// PrintAndLogEx(SUCCESS, "Done");
|
// PrintAndLogEx(SUCCESS, "Done");
|
||||||
// PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x50_read`") "to verify");
|
// PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x50_read`") " to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1442,7 +1442,7 @@ static int CmdEM4x05Write(const char *Cmd) {
|
||||||
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05_read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05_read`") " to verify");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
static int CmdEM4x05Wipe(const char *Cmd) {
|
static int CmdEM4x05Wipe(const char *Cmd) {
|
||||||
|
|
|
@ -243,7 +243,7 @@ static int CmdFdxDemod(const char *Cmd) {
|
||||||
|
|
||||||
uint8_t c[] = {0, 0};
|
uint8_t c[] = {0, 0};
|
||||||
compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]);
|
compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]);
|
||||||
PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [ %s] ", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("OK") : _RED_("Fail"));
|
PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [%s] ", crc, (crc == (c[1] << 8 | c[0])) ? _GREEN_("OK") : _RED_("Fail"));
|
||||||
|
|
||||||
if (g_debugMode) {
|
if (g_debugMode) {
|
||||||
PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size);
|
PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size);
|
||||||
|
@ -303,7 +303,7 @@ static int CmdFdxClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdx read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdx read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ static int CmdGallagherClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ static int CmdGuardClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gprox read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gprox read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ static int usage_lf_hid_brute(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w <format> [<field> (decimal)>] [up|down] {...}");
|
PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w <format> [<field> (decimal)>] [up|down] {...}");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : This help");
|
PrintAndLogEx(NORMAL, " h : This help");
|
||||||
PrintAndLogEx(NORMAL, " w <format> : see " _YELLOW_("`wiegand list`") "for available formats");
|
PrintAndLogEx(NORMAL, " w <format> : see " _YELLOW_("`wiegand list`") " for available formats");
|
||||||
PrintAndLogEx(NORMAL, " f <facility-code> : facility code");
|
PrintAndLogEx(NORMAL, " f <facility-code> : facility code");
|
||||||
PrintAndLogEx(NORMAL, " c <cardnumber> : card number to start with");
|
PrintAndLogEx(NORMAL, " c <cardnumber> : card number to start with");
|
||||||
PrintAndLogEx(NORMAL, " i <issuelevel> : issue level");
|
PrintAndLogEx(NORMAL, " i <issuelevel> : issue level");
|
||||||
|
@ -241,9 +241,9 @@ static int CmdHIDDemod(const char *Cmd) {
|
||||||
fc = ((hi & 0xF) << 12) | (lo >> 20);
|
fc = ((hi & 0xF) << 12) | (lo >> 20);
|
||||||
}
|
}
|
||||||
if (fmtLen == 32 && (lo & 0x40000000)) { //if 32 bit and Kastle bit set
|
if (fmtLen == 32 && (lo & 0x40000000)) { //if 32 bit and Kastle bit set
|
||||||
PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: " _GREEN_("%x%08x (%u)")"- Format Len: 32bit - CC: %u - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum);
|
PrintAndLogEx(SUCCESS, "HID Prox TAG (Kastle format) ID: " _GREEN_("%x%08x (%u)")" - Format Len: 32bit - CC: %u - FC: %u - Card: %u", hi, lo, (lo >> 1) & 0xFFFF, cc, fc, cardnum);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "HID Prox TAG ID: " _GREEN_("%x%08x (%u)")"- Format Len: " _GREEN_("%u bit")"- OEM: %03u - FC: " _GREEN_("%u")"- Card: " _GREEN_("%u"),
|
PrintAndLogEx(SUCCESS, "HID Prox TAG ID: " _GREEN_("%x%08x (%u)")" - Format Len: " _GREEN_("%u bit")" - OEM: %03u - FC: " _GREEN_("%u")" - Card: " _GREEN_("%u"),
|
||||||
hi, lo, cardnum, fmtLen, oem, fc, cardnum);
|
hi, lo, cardnum, fmtLen, oem, fc, cardnum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid));
|
SendCommandMIX(CMD_LF_HID_CLONE, hi2, hi, lo, longid, sizeof(longid));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf hid read`") " to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format_idx == -1) {
|
if (format_idx == -1) {
|
||||||
PrintAndLogEx(ERR, "You must select a wiegand format. See " _YELLOW_("`wiegand list`") "for available formats\n");
|
PrintAndLogEx(ERR, "You must select a wiegand format. See " _YELLOW_("`wiegand list`") " for available formats\n");
|
||||||
errors = true;
|
errors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static char* getHitagTypeStr(uint32_t uid) {
|
static char *getHitagTypeStr(uint32_t uid) {
|
||||||
//uid s/n ********
|
//uid s/n ********
|
||||||
uint8_t type = (uid >> 4) & 0xF;
|
uint8_t type = (uid >> 4) & 0xF;
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
return "PCF 7936";
|
return "PCF 7936";
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -111,9 +111,9 @@ static int usage_hitag_reader(void) {
|
||||||
PrintAndLogEx(NORMAL, " Hitag1 (1*)");
|
PrintAndLogEx(NORMAL, " Hitag1 (1*)");
|
||||||
PrintAndLogEx(NORMAL, " Not implemented");
|
PrintAndLogEx(NORMAL, " Not implemented");
|
||||||
PrintAndLogEx(NORMAL, " Hitag2 (2*)");
|
PrintAndLogEx(NORMAL, " Hitag2 (2*)");
|
||||||
PrintAndLogEx(NORMAL, " 21 <password> Read all pages, password mode. Default: " _YELLOW_("4D494B52") "(\"MIKR\")");
|
PrintAndLogEx(NORMAL, " 21 <password> Read all pages, password mode. Default: " _YELLOW_("4D494B52") " (\"MIKR\")");
|
||||||
PrintAndLogEx(NORMAL, " 22 <nr> <ar> Read all pages, challenge mode");
|
PrintAndLogEx(NORMAL, " 22 <nr> <ar> Read all pages, challenge mode");
|
||||||
PrintAndLogEx(NORMAL, " 23 <key> Read all pages, crypto mode. Key format: ISK high + ISK low. Default: " _YELLOW_("4F4E4D494B52") "(\"ONMIKR\")");
|
PrintAndLogEx(NORMAL, " 23 <key> Read all pages, crypto mode. Key format: ISK high + ISK low. Default: " _YELLOW_("4F4E4D494B52") " (\"ONMIKR\")");
|
||||||
PrintAndLogEx(NORMAL, " 25 Test recorded authentications");
|
PrintAndLogEx(NORMAL, " 25 Test recorded authentications");
|
||||||
PrintAndLogEx(NORMAL, " 26 Just read UID");
|
PrintAndLogEx(NORMAL, " 26 Just read UID");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -512,7 +512,7 @@ static int CmdLFHitagInfo(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%08X"), uid);
|
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%08X"), uid);
|
||||||
PrintAndLogEx(SUCCESS, " TYPE: " _GREEN_("%s"), getHitagTypeStr(uid));
|
PrintAndLogEx(SUCCESS, " TYPE: " _GREEN_("%s"), getHitagTypeStr(uid));
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "ui.h" // PrintAndLog
|
#include "ui.h" // PrintAndLog
|
||||||
#include "lfdemod.h" // parityTest, bitbytes_to_byte
|
#include "lfdemod.h" // parityTest, bitbytes_to_byte
|
||||||
|
@ -671,7 +671,7 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
print_blocks(blocks, max);
|
print_blocks(blocks, max);
|
||||||
int res = clone_t55xx_tag(blocks, max);
|
int res = clone_t55xx_tag(blocks, max);
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ static int CmdIOProxClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ static int CmdJablotronDemod(const char *Cmd) {
|
||||||
bool isok = (chksum == jablontron_chksum(DemodBuffer));
|
bool isok = (chksum == jablontron_chksum(DemodBuffer));
|
||||||
|
|
||||||
PrintAndLogEx(isok ? SUCCESS : INFO,
|
PrintAndLogEx(isok ? SUCCESS : INFO,
|
||||||
"Checksum: %02X [ %s]",
|
"Checksum: %02X [%s]",
|
||||||
chksum,
|
chksum,
|
||||||
isok ? _GREEN_("OK") : _RED_("Fail")
|
isok ? _GREEN_("OK") : _RED_("Fail")
|
||||||
);
|
);
|
||||||
|
|
|
@ -305,7 +305,7 @@ static int CmdKeriClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf keri read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf keri read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "protocols.h" // t55xx defines
|
#include "protocols.h" // t55xx defines
|
||||||
#include "cmdlft55xx.h" // clone..
|
#include "cmdlft55xx.h" // clone..
|
||||||
#include "cmdlf.h" // cmdlfconfig
|
#include "cmdlf.h" // cmdlfconfig
|
||||||
#include "cliparser/cliparser.h" // cli parse input
|
#include "cliparser.h" // cli parse input
|
||||||
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
@ -179,7 +179,7 @@ static int CmdMotorolaClone(const char *Cmd) {
|
||||||
print_blocks(blocks, ARRAYLEN(blocks));
|
print_blocks(blocks, ARRAYLEN(blocks));
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf motorola read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf motorola read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -476,7 +476,7 @@ static int CmdLFNedapClone(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nedap read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nedap read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ static int CmdNexWatchClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nexwatch read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nexwatch read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ static int CmdNoralsyClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf noralsy read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf noralsy read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ static int CmdPacClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pac read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pac read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ static int CmdParadoxClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf paradox read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf paradox read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ static int CmdLFPCF7931Write(const char *Cmd) {
|
||||||
SendCommandMIX(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf));
|
SendCommandMIX(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf));
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 read`") " to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ static int CmdPrescoClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf presco read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf presco read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ static int CmdPyramidClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pyramid read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pyramid read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ static int CmdSecurakeyClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf securakey read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf securakey read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,7 +482,7 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass
|
||||||
|
|
||||||
int res = T55xxReadBlockEx(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, override, password, downlink_mode, false);
|
int res = T55xxReadBlockEx(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, override, password, downlink_mode, false);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(WARNING, "Failed to read block0, use " _YELLOW_("`p`") "password parameter?");
|
PrintAndLogEx(WARNING, "Failed to read block0, use " _YELLOW_("`p`") " password parameter?");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass
|
||||||
PrintAndLogEx(WARNING, "Failed to validate pwd bit set on configuration block. aborting.");
|
PrintAndLogEx(WARNING, "Failed to validate pwd bit set on configuration block. aborting.");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "New configuration block " _YELLOW_("%08X")"password " _YELLOW_("%08X"), block0, new_password);
|
PrintAndLogEx(SUCCESS, "New configuration block " _YELLOW_("%08X")" password " _YELLOW_("%08X"), block0, new_password);
|
||||||
PrintAndLogEx(SUCCESS, "Success, tag is locked");
|
PrintAndLogEx(SUCCESS, "Success, tag is locked");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2398,7 +2398,7 @@ static int CmdT55xxRestore(const char *Cmd) {
|
||||||
success = loadFileEML(preferredName, (uint8_t *)data, &datalen);
|
success = loadFileEML(preferredName, (uint8_t *)data, &datalen);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")"to restore!\n", preferredName);
|
PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")" to restore!\n", preferredName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success == PM3_SUCCESS) { // Got data, so write to cards
|
if (success == PM3_SUCCESS) { // Got data, so write to cards
|
||||||
|
@ -3039,7 +3039,7 @@ static int CmdT55xxChkPwds(const char *Cmd) {
|
||||||
if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) {
|
if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, resp.oldarg[1], downlink_mode)) {
|
||||||
found = tryDetectModulation(downlink_mode, T55XX_PrintConfig);
|
found = tryDetectModulation(downlink_mode, T55XX_PrintConfig);
|
||||||
if (found) {
|
if (found) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", resp.oldarg[1]);
|
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", resp.oldarg[1]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Check pwd failed");
|
PrintAndLogEx(WARNING, "Check pwd failed");
|
||||||
|
@ -3089,7 +3089,7 @@ static int CmdT55xxChkPwds(const char *Cmd) {
|
||||||
|
|
||||||
found = tryDetectModulation(dl_mode, T55XX_PrintConfig);
|
found = tryDetectModulation(dl_mode, T55XX_PrintConfig);
|
||||||
if (found) {
|
if (found) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) "]", curr_password);
|
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08"PRIX64) " ]", curr_password);
|
||||||
dl_mode = 4; // Exit other downlink mode checks
|
dl_mode = 4; // Exit other downlink mode checks
|
||||||
c = keycount; // Exit loop
|
c = keycount; // Exit loop
|
||||||
}
|
}
|
||||||
|
@ -3177,10 +3177,10 @@ static int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr - 1);
|
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr - 1);
|
||||||
T55xx_Print_DownlinkMode((found >> 1) & 3);
|
T55xx_Print_DownlinkMode((found >> 1) & 3);
|
||||||
} else
|
} else
|
||||||
PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") "]", curr);
|
PrintAndLogEx(WARNING, "Bruteforce failed, last tried: [ " _YELLOW_("%08X") " ]", curr);
|
||||||
|
|
||||||
t1 = msclock() - t1;
|
t1 = msclock() - t1;
|
||||||
PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1 / 1000.0);
|
PrintAndLogEx(SUCCESS, "\nTime in bruteforce: %.0f seconds\n", (float)t1 / 1000.0);
|
||||||
|
@ -3316,7 +3316,7 @@ out:
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
if (found > 0) {
|
if (found > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") "]", curr_password);
|
PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password);
|
||||||
T55xx_Print_DownlinkMode((found >> 1) & 3);
|
T55xx_Print_DownlinkMode((found >> 1) & 3);
|
||||||
} else
|
} else
|
||||||
PrintAndLogEx(WARNING, "Recover pwd failed");
|
PrintAndLogEx(WARNING, "Recover pwd failed");
|
||||||
|
@ -3683,7 +3683,7 @@ static int CmdT55xxProtect(const char *Cmd) {
|
||||||
|
|
||||||
// lock
|
// lock
|
||||||
if (t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false) {
|
if (t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false) {
|
||||||
PrintAndLogEx(WARNING, "Command failed. Did you run " _YELLOW_("`lf t55xx detect`") "before?");
|
PrintAndLogEx(WARNING, "Command failed. Did you run " _YELLOW_("`lf t55xx detect`") " before?");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -297,7 +297,7 @@ static int CmdTIWrite(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0);
|
SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0);
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf ti read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf ti read`") " to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ static int CmdVerichipClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf verichip read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf verichip read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ static int CmdVikingClone(const char *Cmd) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf viking read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf viking read`") " to verify");
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ static int CmdVisa2kClone(const char *Cmd) {
|
||||||
|
|
||||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
PrintAndLogEx(SUCCESS, "Done");
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf visa2000 read`") "to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf visa2000 read`") " to verify");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ static int lf_search_plus(const char *Cmd) {
|
||||||
// Try to change config!
|
// Try to change config!
|
||||||
uint32_t d;
|
uint32_t d;
|
||||||
d = config.divisor = default_divisor[i];
|
d = config.divisor = default_divisor[i];
|
||||||
PrintAndLogEx(INFO, "--> trying ( " _GREEN_("%d.%02d kHz")")", 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
|
PrintAndLogEx(INFO, "--> trying (" _GREEN_("%d.%02d kHz")")", 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
|
||||||
|
|
||||||
retval = lf_config(&config);
|
retval = lf_config(&config);
|
||||||
if (retval != PM3_SUCCESS)
|
if (retval != PM3_SUCCESS)
|
||||||
|
@ -174,7 +174,7 @@ static int CmdAuto(const char *Cmd) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,");
|
PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,");
|
||||||
PrintAndLogEx(INFO, "Trying " _YELLOW_("`lf read`") "and save a trace for you");
|
PrintAndLogEx(INFO, "Trying " _YELLOW_("`lf read`") " and save a trace for you");
|
||||||
|
|
||||||
CmdPlot("");
|
CmdPlot("");
|
||||||
lf_read(false, 40000);
|
lf_read(false, 40000);
|
||||||
|
|
|
@ -201,7 +201,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) {
|
||||||
if (Commands[i].IsAvailable()) {
|
if (Commands[i].IsAvailable()) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "This command is " _YELLOW_("not available") "in this mode");
|
PrintAndLogEx(WARNING, "This command is " _YELLOW_("not available") " in this mode");
|
||||||
return PM3_ENOTIMPL;
|
return PM3_ENOTIMPL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "comms.h" // getfromdevice
|
#include "comms.h" // getfromdevice
|
||||||
#include "emv/emvcore.h" // decodeTVL
|
#include "emv/emvcore.h" // decodeTVL
|
||||||
#include "../crypto/libpcrypto.h" // sha512hash
|
#include "crypto/libpcrypto.h" // sha512hash
|
||||||
#include "emv/dump.h"
|
#include "emv/dump.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
|
|
|
@ -662,7 +662,7 @@ int CmdTraceList(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Recorded activity (trace len = " _YELLOW_("%lu") "bytes)", traceLen);
|
PrintAndLogEx(SUCCESS, "Recorded activity (trace len = " _YELLOW_("%lu") " bytes)", traceLen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (protocol == FELICA) {
|
if (protocol == FELICA) {
|
||||||
|
@ -674,7 +674,7 @@ int CmdTraceList(const char *Cmd) {
|
||||||
tracepos = printHexLine(tracepos, traceLen, trace, protocol);
|
tracepos = printHexLine(tracepos, traceLen, trace, protocol);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, _YELLOW_("Start") "= Start of Start Bit, " _YELLOW_("End") "= End of last modulation. " _YELLOW_("Src") "= Source of Transfer");
|
PrintAndLogEx(INFO, _YELLOW_("Start") " = Start of Start Bit, " _YELLOW_("End") " = End of last modulation. " _YELLOW_("Src") " = Source of Transfer");
|
||||||
if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO)
|
if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO)
|
||||||
PrintAndLogEx(INFO, "ISO14443A - All times are in carrier periods (1/13.56MHz)");
|
PrintAndLogEx(INFO, "ISO14443A - All times are in carrier periods (1/13.56MHz)");
|
||||||
if (protocol == THINFILM)
|
if (protocol == THINFILM)
|
||||||
|
|
|
@ -316,7 +316,7 @@ static int CmdUsartBtFactory(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USART_BAUD_RATE != atoi(BTADDON_BAUD_NUM)) {
|
if (USART_BAUD_RATE != atoi(BTADDON_BAUD_NUM)) {
|
||||||
PrintAndLogEx(WARNING, _RED_("WARNING:") "current Proxmark3 firmware has default USART baudrate = %i", USART_BAUD_RATE);
|
PrintAndLogEx(WARNING, _RED_("WARNING:") " current Proxmark3 firmware has default USART baudrate = %i", USART_BAUD_RATE);
|
||||||
PrintAndLogEx(WARNING, "Current btfactory implementation is hardcoded to " BTADDON_BAUD_NUM " bauds");
|
PrintAndLogEx(WARNING, "Current btfactory implementation is hardcoded to " BTADDON_BAUD_NUM " bauds");
|
||||||
return PM3_ENOTIMPL;
|
return PM3_ENOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "uart.h"
|
#include "uart/uart.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
#include "util_posix.h" // msclock
|
#include "util_posix.h" // msclock
|
||||||
|
@ -558,11 +558,11 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode,
|
||||||
|
|
||||||
// check result of uart opening
|
// check result of uart opening
|
||||||
if (sp == INVALID_SERIAL_PORT) {
|
if (sp == INVALID_SERIAL_PORT) {
|
||||||
PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") "invalid serial port " _YELLOW_("%s"), portname);
|
PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " invalid serial port " _YELLOW_("%s"), portname);
|
||||||
sp = NULL;
|
sp = NULL;
|
||||||
return false;
|
return false;
|
||||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||||
PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") "serial port " _YELLOW_("%s") " is claimed by another process", portname);
|
PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") " serial port " _YELLOW_("%s") " is claimed by another process", portname);
|
||||||
sp = NULL;
|
sp = NULL;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -641,7 +641,7 @@ int TestProxmark(void) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Communicating with PM3 over %s%s",
|
PrintAndLogEx(INFO, "Communicating with PM3 over %s%s",
|
||||||
conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"),
|
conn.send_via_fpc_usart ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"),
|
||||||
memcmp(conn.serial_port_name, "tcp:", 4) == 0 ? "over " _YELLOW_("TCP") : "");
|
memcmp(conn.serial_port_name, "tcp:", 4) == 0 ? " over " _YELLOW_("TCP") : "");
|
||||||
|
|
||||||
if (conn.send_via_fpc_usart) {
|
if (conn.send_via_fpc_usart) {
|
||||||
PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", conn.uart_speed);
|
PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", conn.uart_speed);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "emvjson.h"
|
#include "emvjson.h"
|
||||||
#include "test/cryptotest.h"
|
#include "test/cryptotest.h"
|
||||||
#include "cliparser/cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "emv_roca.h"
|
#include "emv_roca.h"
|
||||||
|
|
|
@ -92,7 +92,7 @@ int JsonSaveInt(json_t *root, const char *path, int value) {
|
||||||
|
|
||||||
int JsonSaveStr(json_t *root, const char *path, const char *value) {
|
int JsonSaveStr(json_t *root, const char *path, const char *value) {
|
||||||
return JsonSaveJsonObject(root, path, json_string(value));
|
return JsonSaveJsonObject(root, path, json_string(value));
|
||||||
};
|
}
|
||||||
|
|
||||||
int JsonSaveBoolean(json_t *root, const char *path, bool value) {
|
int JsonSaveBoolean(json_t *root, const char *path, bool value) {
|
||||||
return JsonSaveJsonObject(root, path, json_boolean(value));
|
return JsonSaveJsonObject(root, path, json_boolean(value));
|
||||||
|
@ -298,7 +298,7 @@ int JsonLoadBufAsHex(json_t *elm, const char *path, uint8_t *data, size_t maxbuf
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool ParamLoadFromJson(struct tlvdb *tlv) {
|
bool ParamLoadFromJson(struct tlvdb *tlv) {
|
||||||
json_t *root;
|
json_t *root;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <jansson.h>
|
#include "jansson.h"
|
||||||
#include "tlv.h"
|
#include "tlv.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -387,7 +387,7 @@ CborError CborGetArrayBinStringValueEx(CborValue *elm, uint8_t *data, size_t max
|
||||||
*datalen = totallen;
|
*datalen = totallen;
|
||||||
|
|
||||||
return CborNoError;
|
return CborNoError;
|
||||||
};
|
}
|
||||||
|
|
||||||
CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen) {
|
CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen, size_t *datalen) {
|
||||||
if (datalen)
|
if (datalen)
|
||||||
|
@ -402,7 +402,7 @@ CborError CborGetBinStringValue(CborValue *elm, uint8_t *data, size_t maxdatalen
|
||||||
*datalen = slen;
|
*datalen = slen;
|
||||||
|
|
||||||
return CborNoError;
|
return CborNoError;
|
||||||
};
|
}
|
||||||
|
|
||||||
CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimiter) {
|
CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen, char *delimiter) {
|
||||||
CborValue array;
|
CborValue array;
|
||||||
|
@ -435,7 +435,7 @@ CborError CborGetArrayStringValue(CborValue *elm, char *data, size_t maxdatalen,
|
||||||
*datalen = totallen;
|
*datalen = totallen;
|
||||||
|
|
||||||
return CborNoError;
|
return CborNoError;
|
||||||
};
|
}
|
||||||
|
|
||||||
CborError CborGetStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen) {
|
CborError CborGetStringValue(CborValue *elm, char *data, size_t maxdatalen, size_t *datalen) {
|
||||||
if (datalen)
|
if (datalen)
|
||||||
|
@ -450,14 +450,14 @@ CborError CborGetStringValue(CborValue *elm, char *data, size_t maxdatalen, size
|
||||||
*datalen = slen;
|
*datalen = slen;
|
||||||
|
|
||||||
return CborNoError;
|
return CborNoError;
|
||||||
};
|
}
|
||||||
|
|
||||||
CborError CborGetStringValueBuf(CborValue *elm) {
|
CborError CborGetStringValueBuf(CborValue *elm) {
|
||||||
static char stringBuf[2048];
|
static char stringBuf[2048];
|
||||||
memset(stringBuf, 0x00, sizeof(stringBuf));
|
memset(stringBuf, 0x00, sizeof(stringBuf));
|
||||||
|
|
||||||
return CborGetStringValue(elm, stringBuf, sizeof(stringBuf), NULL);
|
return CborGetStringValue(elm, stringBuf, sizeof(stringBuf), NULL);
|
||||||
};
|
}
|
||||||
|
|
||||||
int CBOREncodeElm(json_t *root, const char *rootElmId, CborEncoder *encoder) {
|
int CBOREncodeElm(json_t *root, const char *rootElmId, CborEncoder *encoder) {
|
||||||
json_t *elm = NULL;
|
json_t *elm = NULL;
|
||||||
|
|
|
@ -181,7 +181,7 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si
|
||||||
fwrite(data, 1, datalen, f);
|
fwrite(data, 1, datalen, f);
|
||||||
fflush(f);
|
fflush(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") "bytes to binary file " _YELLOW_("%s"), datalen, fileName);
|
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to binary file " _YELLOW_("%s"), datalen, fileName);
|
||||||
free(fileName);
|
free(fileName);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
|
||||||
}
|
}
|
||||||
fflush(f);
|
fflush(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRId32) "blocks to text file " _YELLOW_("%s"), blocks, fileName);
|
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%" PRId32) " blocks to text file " _YELLOW_("%s"), blocks, fileName);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(fileName);
|
free(fileName);
|
||||||
|
@ -426,6 +426,44 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case jsfMfDesfireKeys:
|
||||||
|
JsonSaveStr(root, "FileType", "mfdes");
|
||||||
|
JsonSaveBufAsHexCompact(root, "$.Card.UID", &data[0], 7);
|
||||||
|
JsonSaveBufAsHexCompact(root, "$.Card.SAK", &data[10], 1);
|
||||||
|
JsonSaveBufAsHexCompact(root, "$.Card.ATQA", &data[11], 2);
|
||||||
|
uint8_t datslen = data[13];
|
||||||
|
if (datslen > 0)
|
||||||
|
JsonSaveBufAsHexCompact(root, "$.Card.ATS", &data[14], datslen);
|
||||||
|
|
||||||
|
uint8_t dvdata[4][0xE][24 + 1] = {{{0}}};
|
||||||
|
memcpy(dvdata, &data[14 + datslen], 4 * 0xE * (24 + 1));
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)datalen; i++) {
|
||||||
|
char path[PATH_MAX_LENGTH] = {0};
|
||||||
|
|
||||||
|
if (dvdata[0][i][0]) {
|
||||||
|
memset(path, 0x00, sizeof(path));
|
||||||
|
sprintf(path, "$.DES.%d.Key", i);
|
||||||
|
JsonSaveBufAsHexCompact(root, path, &dvdata[0][i][1], 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvdata[1][i][0]) {
|
||||||
|
memset(path, 0x00, sizeof(path));
|
||||||
|
sprintf(path, "$.3DES.%d.Key", i);
|
||||||
|
JsonSaveBufAsHexCompact(root, path, &dvdata[1][i][1], 16);
|
||||||
|
}
|
||||||
|
if (dvdata[2][i][0]) {
|
||||||
|
memset(path, 0x00, sizeof(path));
|
||||||
|
sprintf(path, "$.AES.%d.Key", i);
|
||||||
|
JsonSaveBufAsHexCompact(root, path, &dvdata[2][i][1], 16);
|
||||||
|
}
|
||||||
|
if (dvdata[3][i][0]) {
|
||||||
|
memset(path, 0x00, sizeof(path));
|
||||||
|
sprintf(path, "$.K3KDES.%d.Key", i);
|
||||||
|
JsonSaveBufAsHexCompact(root, path, &dvdata[3][i][1], 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case jsfSettings:
|
case jsfSettings:
|
||||||
preferences_save_callback(root);
|
preferences_save_callback(root);
|
||||||
break;
|
break;
|
||||||
|
@ -484,7 +522,7 @@ int saveFileWAVE(const char *preferredName, int *data, size_t datalen) {
|
||||||
}
|
}
|
||||||
fclose(wave_file);
|
fclose(wave_file);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") "bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName);
|
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(fileName);
|
free(fileName);
|
||||||
|
@ -511,7 +549,7 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen) {
|
||||||
|
|
||||||
fflush(f);
|
fflush(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") "bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName);
|
PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to PM3 file " _YELLOW_("'%s'"), datalen, fileName);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(fileName);
|
free(fileName);
|
||||||
|
@ -610,7 +648,7 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
|
||||||
memcpy((data), dump, bytes_read);
|
memcpy((data), dump, bytes_read);
|
||||||
free(dump);
|
free(dump);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") "bytes from binary file " _YELLOW_("%s"), bytes_read, fileName);
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, fileName);
|
||||||
|
|
||||||
*datalen = bytes_read;
|
*datalen = bytes_read;
|
||||||
|
|
||||||
|
@ -666,7 +704,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s
|
||||||
|
|
||||||
*datalen = bytes_read;
|
*datalen = bytes_read;
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") "bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName);
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,7 +755,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") "bytes from text file " _YELLOW_("%s"), counter, fileName);
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file " _YELLOW_("%s"), counter, fileName);
|
||||||
|
|
||||||
if (datalen)
|
if (datalen)
|
||||||
*datalen = counter;
|
*datalen = counter;
|
||||||
|
@ -967,7 +1005,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), vkeycnt, path);
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file " _YELLOW_("%s"), vkeycnt, path);
|
||||||
|
|
||||||
if (datalen)
|
if (datalen)
|
||||||
*datalen = counter;
|
*datalen = counter;
|
||||||
|
@ -1059,7 +1097,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key
|
||||||
memset(line, 0, sizeof(line));
|
memset(line, 0, sizeof(line));
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(path);
|
free(path);
|
||||||
|
|
|
@ -63,6 +63,7 @@ typedef enum {
|
||||||
jsfT5555,
|
jsfT5555,
|
||||||
jsfMfPlusKeys,
|
jsfMfPlusKeys,
|
||||||
jsfSettings,
|
jsfSettings,
|
||||||
|
jsfMfDesfireKeys,
|
||||||
} JSONFileType;
|
} JSONFileType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -235,12 +235,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
|
|
||||||
fd = fopen(name, "rb");
|
fd = fopen(name, "rb");
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name);
|
PrintAndLogEx(ERR, _RED_("Could not open file") " %s >>> ", name);
|
||||||
res = PM3_EFILE;
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, _BLUE_("Loading ELF file") _YELLOW_("%s"), name);
|
PrintAndLogEx(SUCCESS, _BLUE_("Loading ELF file") _YELLOW_(" %s"), name);
|
||||||
|
|
||||||
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
||||||
PrintAndLogEx(ERR, "Error while reading ELF file header");
|
PrintAndLogEx(ERR, "Error while reading ELF file header");
|
||||||
|
@ -336,7 +336,7 @@ static int get_proxmark_state(uint32_t *state) {
|
||||||
*state = resp.oldarg[0];
|
*state = resp.oldarg[0];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd);
|
PrintAndLogEx(ERR, _RED_("Error:") " Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd);
|
||||||
return PM3_EFATAL;
|
return PM3_EFATAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -378,12 +378,12 @@ static int enter_bootloader(char *serial_port_name) {
|
||||||
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
|
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found.");
|
PrintAndLogEx(ERR, _RED_("Error:") " Proxmark3 not found.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode");
|
PrintAndLogEx(ERR, _RED_("Error:") " Unknown Proxmark3 mode");
|
||||||
return PM3_EFATAL;
|
return PM3_EFATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ static int wait_for_ack(PacketResponseNG *ack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flash_suggest_update_bootloader(void) {
|
static void flash_suggest_update_bootloader(void) {
|
||||||
PrintAndLogEx(ERR, _RED_("It is recommended that you first " _YELLOW_("update your bootloader") _RED_("alone,")));
|
PrintAndLogEx(ERR, _RED_("It is recommended that you first" _YELLOW_(" update your bootloader") _RED_(" alone,")));
|
||||||
PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n");
|
PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, _RED_("====================== OBS ! ==========================================="));
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ==========================================="));
|
||||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("CMD_BL_VERSION") _RED_("command")));
|
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_(" CMD_BL_VERSION") _RED_(" command")));
|
||||||
flash_suggest_update_bootloader();
|
flash_suggest_update_bootloader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
||||||
|
|
||||||
int mem_avail = chipid_to_mem_avail(chipinfo);
|
int mem_avail = chipid_to_mem_avail(chipinfo);
|
||||||
if (mem_avail != 0) {
|
if (mem_avail != 0) {
|
||||||
PrintAndLogEx(INFO, "Available memory on this board: "_YELLOW_("%uK") "bytes\n", mem_avail);
|
PrintAndLogEx(INFO, "Available memory on this board: "_YELLOW_("%uK") " bytes\n", mem_avail);
|
||||||
if (mem_avail > 256) {
|
if (mem_avail > 256) {
|
||||||
if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) {
|
if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) {
|
||||||
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================"));
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================"));
|
||||||
|
@ -477,7 +477,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "Available memory on this board: "_RED_("UNKNOWN")"\n");
|
PrintAndLogEx(INFO, "Available memory on this board: "_RED_("UNKNOWN")"\n");
|
||||||
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================================"));
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================================"));
|
||||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("CHIP_INFO") _RED_("command")));
|
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_(" CHIP_INFO") _RED_(" command")));
|
||||||
flash_suggest_update_bootloader();
|
flash_suggest_update_bootloader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,7 +497,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
||||||
return wait_for_ack(&resp);
|
return wait_for_ack(&resp);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, _RED_("====================== OBS ! ========================================"));
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ========================================"));
|
||||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command")));
|
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_(" START_FLASH") _RED_(" command")));
|
||||||
flash_suggest_update_bootloader();
|
flash_suggest_update_bootloader();
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -475,7 +475,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) {
|
||||||
memcpy(master_key, key64, 8);
|
memcpy(master_key, key64, 8);
|
||||||
|
|
||||||
if (memcmp(z_0, result, 4) != 0) {
|
if (memcmp(z_0, result, 4) != 0) {
|
||||||
PrintAndLogEx(WARNING, _RED_("Failed to verify") "calculated master key (k_cus)! Something is wrong.");
|
PrintAndLogEx(WARNING, _RED_("Failed to verify") " calculated master key (k_cus)! Something is wrong.");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
|
@ -511,7 +511,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||||
|
|
||||||
|
|
||||||
if (errors) {
|
if (errors) {
|
||||||
PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data");
|
PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") " again and collect new data");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue