diff --git a/.gitignore b/.gitignore index 7bbad2e87..fd8fe070c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,12 +31,23 @@ version.c *.old *.swp *.json.bak +*.pyc # new build file for add-ons. Makefile.platform # Cache for detecting platform def changes .Makefile.options.cache +# cmake +client/build/ + +# Coverity +cov-int/ +.coverity.conf + +# profiling +*.gcno + !client/resources/hardnested/*.bin !client/resources/hardnested_tables/*.z client/src/ui/ui_overlays.h diff --git a/.travis.yml b/.travis.yml index 5aee2a918..d136892a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,29 +4,23 @@ language: c #default linux build env is: xenial compiler: gcc +os: + - linux + - osx + +dist: xenial + +osx_image: xcode11 + # move some env variables to homebrew env env: global: - HOMEBREW_TRAVIS_BRANCH=$TRAVIS_BRANCH - HOMEBREW_TRAVIS_COMMIT=$TRAVIS_COMMIT - -# Test on Linux and MacOS -matrix: - include: - - 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' + jobs: + - TO_TEST=MAKEFILE MAKE_PARAMS='PLATFORM_EXTRAS=' + - TO_TEST=MAKEFILE MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON' + - TO_TEST=CMAKE addons: apt: @@ -53,18 +47,17 @@ before_install: fi install: - if ! arm-none-eabi-gcc -v; then + if ! arm-none-eabi-gcc -v; then echo "arm-none-eabi-gcc [ERROR]"; travis_terminate 1; fi - - make clean; - make all V=1 "$MAKE_PARAMS"; script: -## start and run a test script - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - ./pm3test.sh; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - ./pm3test.sh; - fi + - if [ "$TO_TEST" = "MAKEFILE" ]; then + make clean && make V=1 "$MAKE_PARAMS"; + ./pm3test.sh; + 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 diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b865244..786d59d74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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... ## [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 CreateStdFile command to Mifare `hf mfdes` (@bkerler) - Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler) diff --git a/Makefile.host b/Makefile.host index 6d405ee14..9f5688939 100644 --- a/Makefile.host +++ b/Makefile.host @@ -28,7 +28,7 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ BINDIR := . OBJDIR := obj -MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o) +MYOBJS ?= $(MYSRCS:%.c=$(OBJDIR)/%.o) CLEAN = $(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: $(Q)$(RM) $(CLEAN) $(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 ifneq (,$(INSTALLTOOLS)) diff --git a/armsrc/Standalone/hf_legic.c b/armsrc/Standalone/hf_legic.c index 8b00766d5..d72c8148e 100644 --- a/armsrc/Standalone/hf_legic.c +++ b/armsrc/Standalone/hf_legic.c @@ -47,10 +47,10 @@ void DownloadLogInstructions() { Dbprintf(""); Dbprintf("[=] List all dumps from flash:"); - Dbprintf("[=] " _YELLOW_("-") "mem spiffs tree"); + Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree"); Dbprintf(""); 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) { diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index 33d4ed764..c71ff344d 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -57,9 +57,9 @@ void DownloadLogInstructions() { Dbprintf(""); 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_("2.") "exit proxmark3 client"); - Dbprintf("[=] " _YELLOW_("3.") "cat "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_("3.") " cat "LF_HIDCOLLECT_LOGFILE); } bool log_exists; diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b44dbc5c5..b05a143f0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -333,7 +333,7 @@ void printConnSpeed(void) { Dbprintf(" Time elapsed............%dms", delta_time); 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; } case CMD_HF_MFU_OTP_TEAROFF: { - MifareU_Otp_Tearoff(); + MifareU_Otp_Tearoff(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } case CMD_HF_MIFARE_STATIC_NONCE: { diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index fb69dee01..e3a20cacc 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -573,7 +573,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" Mifare.................."_YELLOW_("%d")"keys", num); + Dbprintf(" Mifare.................."_YELLOW_("%d")" keys", num); } Flash_CheckBusy(BUSY_TIMEOUT); @@ -581,7 +581,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" T55x7..................."_YELLOW_("%d")"keys", num); + Dbprintf(" T55x7..................."_YELLOW_("%d")" keys", num); } Flash_CheckBusy(BUSY_TIMEOUT); @@ -589,7 +589,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" iClass.................."_YELLOW_("%d")"keys", num); + Dbprintf(" iClass.................."_YELLOW_("%d")" keys", num); } FlashStop(); diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index bbec86fa5..ee658f4bd 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -465,7 +465,7 @@ void LegicRfSimulate(uint8_t cardtype) { } 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()) { WDT_HIT(); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index aa2f68e2a..c65696d1a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -196,7 +196,7 @@ static uint32_t GetT55xxClockBit(uint32_t clock) { 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")); Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); @@ -211,16 +211,16 @@ void printT55xxConfig(void) { switch (i) { case T55XX_DLMODE_FIXED : - sprintf(s, _YELLOW_("fixed bit length") _GREEN_("(default)") "|"); + sprintf(s, _YELLOW_("fixed bit length") _GREEN_(" (default)") " |"); break; case T55XX_DLMODE_LLR : - sprintf(s, _YELLOW_(" long leading reference") "|"); + sprintf(s, _YELLOW_(" long leading reference") " |"); break; case T55XX_DLMODE_LEADING_ZERO : - sprintf(s, _YELLOW_(" leading zero") "|"); + sprintf(s, _YELLOW_(" leading zero") " |"); break; case T55XX_DLMODE_1OF4 : - sprintf(s, _YELLOW_(" 1 of 4 coding reference") "|"); + sprintf(s, _YELLOW_(" 1 of 4 coding reference") " |"); break; default: break; @@ -1291,7 +1291,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) cardnum = (lo >> 1) & 0x7FFFF; 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, lo, (lo >> 1) & 0xFFFF, diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 3769e3565..2851dc08b 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -307,7 +307,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in } 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 diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index a8f829144..0266af633 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2423,12 +2423,14 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { // // Tear-off attack against MFU. // - Moebius et al -void MifareU_Otp_Tearoff() { - -// should the -// optional time be configurable via client side? +void MifareU_Otp_Tearoff(uint8_t arg0, uint32_t arg1, uint8_t *datain) { + uint8_t blockNo = arg0; + uint32_t tearOffTime = arg1; + 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 data to be written? if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off"); @@ -2439,46 +2441,26 @@ void MifareU_Otp_Tearoff() { StartTicks(); -#define OTP_TEAR_OFF_TIME 1000 -#define OTP_BLK_NO 3 - // write cmd to send, include 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? -// memcpy(block + 2, blockData, 4); + MifareUWriteBlock(blockNo, 0, data_fullwrite); AddCrc14A(cmd, sizeof(cmd) - 2); - if (DBGLEVEL >= DBG_ERROR) DbpString("Transmitting"); - // anticollision / select card if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); OnError(1); 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 ReaderTransmit(cmd, sizeof(cmd), NULL); // Wait before cutting power. aka tear-off LED_D_ON(); - WaitUS(OTP_TEAR_OFF_TIME); + WaitUS(tearOffTime); switch_off(); reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 91adba3b1..a4bf2b30b 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -59,6 +59,6 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); // Tear-off test for MFU -void MifareU_Otp_Tearoff(); +void MifareU_Otp_Tearoff(uint8_t arg0, uint32_t arg1, uint8_t *datain); #endif diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 9fb0d9d5d..ecc0ee505 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -1258,7 +1258,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 FpgaDisableTracing(); // NR AR ATTACK - // mfkey32 + // mfkey32 if (((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) && (DBGLEVEL >= DBG_INFO)) { for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { if (ar_nr_collected[i] == 2) { @@ -1274,7 +1274,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 } } } - + // mfkey32 v2 for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) { if (ar_nr_collected[i] == 2) { diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 81172476f..3db0e3c27 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -545,14 +545,14 @@ void rdv40_spiffs_safe_print_fsinfo() { DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); - Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize); - Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize); + Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize); + Dbprintf(" Logical Page Size.........." _YELLOW_("%d")" bytes", fsinfo.pageSize); Dbprintf(""); - Dbprintf(" Max Open Files............." _YELLOW_("%d")"file descriptors", fsinfo.maxOpenFiles); - Dbprintf(" Max Path Length............" _YELLOW_("%d")"chars", fsinfo.maxPathLength); + Dbprintf(" Max Open Files............." _YELLOW_("%d")" file descriptors", fsinfo.maxOpenFiles); + Dbprintf(" Max Path Length............" _YELLOW_("%d")" chars", fsinfo.maxPathLength); DbpString(""); 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%")" /" , fsinfo.totalBytes , fsinfo.usedBytes , fsinfo.freeBytes diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 000000000..50e0c91f9 --- /dev/null +++ b/client/CMakeLists.txt @@ -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) diff --git a/client/Makefile b/client/Makefile index 0be82d040..9b81653a0 100644 --- a/client/Makefile +++ b/client/Makefile @@ -17,7 +17,7 @@ include ../Makefile.defs INSTALLBIN = proxmark3 INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries -VPATH = ../common src/uart src deps +VPATH = ../common src vpath %.dic dictionaries OBJDIR = obj @@ -42,6 +42,10 @@ REVENGPATH = ./deps/reveng REVENGLIB = $(REVENGPATH)/libreveng.a AMIIBOLIBPATH = ./deps/amiitool AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a +HARDNESTEDPATH = ./deps/hardnested +HARDNESTEDLIB = $(HARDNESTEDPATH)/libhardnested.a +CLIPARSERPATH = ./deps/cliparser +CLIPARSERLIB = $(CLIPARSERPATH)/libcliparser.a # common libraries MBEDTLSLIBPATH = ../common/mbedtls @@ -49,17 +53,19 @@ MBEDTLSLIB = $(OBJDIR)/libmbedtls.a ZLIBPATH = ../common/zlib ZLIB = $(OBJDIR)/libz.a -LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH) -INCLUDES_CLIENT = -I./src -I./deps -I../include -I../common -I./deps/cliparser -I./src/uart $(LIBS) -CFLAGS ?= -Wall -Werror -g -O3 +LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH) -I$(HARDNESTEDPATH) -I$(CLIPARSERPATH) +INCLUDES_CLIENT = -I./src -I../include -I../common -I../common_fpga $(LIBS) +CFLAGS ?= -Wall -Werror -O3 # 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) +# WIP Testing +#PM3CFLAGS = $(CFLAGS) -std=c11 -pedantic $(INCLUDES_CLIENT) PREFIX ?= /usr/local ifneq (,$(findstring MINGW,$(platform))) PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850 endif CXXFLAGS ?= -Wall -Werror -O3 -PM3CXXFLAGS = $(CXXFLAGS) -I../include -I/.deps/cliparser +PM3CXXFLAGS = $(CXXFLAGS) -I../include LUAPLATFORM = generic ifneq (,$(findstring MINGW,$(platform))) @@ -112,6 +118,7 @@ ifneq ($(QTLDLIBS),) QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o PM3CFLAGS += -DHAVE_GUI + PM3CXXFLAGS += -DQT_NO_DEBUG else QTGUISRCS = guidummy.cpp QTGUIOBJS = $(OBJDIR)/guidummy.o @@ -122,8 +129,8 @@ DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td # make temporary to final dependency files after successful compilation POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ -CORESRCS = uart_posix.c \ - uart_win32.c \ +CORESRCS = uart/uart_posix.c \ + uart/uart_win32.c \ ui.c \ commonutil.c \ util.c \ @@ -145,8 +152,6 @@ CMDSRCS = crapto1/crapto1.c \ crypto/asn1dump.c \ crypto/libpcrypto.c\ crypto/asn1utils.c\ - cliparser/argtable3.c\ - cliparser/cliparser.c\ loclass/cipher.c \ loclass/cipherutils.c \ loclass/ikeys.c \ @@ -201,7 +206,6 @@ CMDSRCS = crapto1/crapto1.c \ cmdhfmfu.c \ cmdhfmfp.c \ cmdhfmfhard.c \ - deps/hardnested/hardnested_bruteforce.c \ cmdhfmfdes.c \ cmdhftopaz.c \ cmdhffido.c \ @@ -257,48 +261,16 @@ CMDSRCS = crapto1/crapto1.c \ cardhelper.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) CMDOBJS = $(CMDSRCS:%.c=$(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 -CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua -# transition: make sure old flasher is gone too -CLEAN += flasher +CLEAN = $(BINS) src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua +# transition: cleaning also old path stuff +CLEAN += flasher *.moc.cpp ui/ui_overlays.h # need to assign dependancies to build these first... all: $(BINS) @@ -306,10 +278,10 @@ all: $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) -proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(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: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) $(QTLDLIBS) +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 $@) - $(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 @@ -337,6 +309,8 @@ clean: $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) 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 $(info [@] Installing client to $(DESTDIR)$(PREFIX)...) @@ -381,10 +355,18 @@ $(REVENGLIB): $(info [*] MAKE reveng) $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all +$(HARDNESTEDLIB): + $(info [*] MAKE hardnested) + $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) all + $(AMIIBOLIB): $(info [*] MAKE amiibo) $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all +$(CLIPARSERLIB): + $(info [*] MAKE cliparser) + $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) all + # common libraries: $(MBEDTLSLIB): $(info [*] MAKE mbedtls) @@ -399,42 +381,6 @@ $(ZLIB): # easy printing of MAKE VARIABLES 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 $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(info [-] CC $<) @@ -456,8 +402,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVENGSRCS)) \ - $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ +DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ $(OBJDIR)/proxmark3.d diff --git a/client/cmake/FindSSE.cmake b/client/cmake/FindSSE.cmake new file mode 100644 index 000000000..14021e1c1 --- /dev/null +++ b/client/cmake/FindSSE.cmake @@ -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) diff --git a/client/deps/CMakeLists.txt b/client/deps/CMakeLists.txt new file mode 100644 index 000000000..6b577d438 --- /dev/null +++ b/client/deps/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake new file mode 100644 index 000000000..dd185fc91 --- /dev/null +++ b/client/deps/amiibo.cmake @@ -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) diff --git a/client/deps/amiitool/Makefile b/client/deps/amiitool/Makefile index 6926c12c6..ff2c0da88 100644 --- a/client/deps/amiitool/Makefile +++ b/client/deps/amiitool/Makefile @@ -9,6 +9,9 @@ MYSRCS = \ LIB_A = libamiibo.a +# Transition: remove old directories and objects +MYCLEANOLDPATH = ../../amiitool + include ../../../Makefile.host # just for testing amiitool before complete migration into a lib: diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake new file mode 100644 index 000000000..890fd39c5 --- /dev/null +++ b/client/deps/cliparser.cmake @@ -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) diff --git a/client/deps/cliparser/Makefile b/client/deps/cliparser/Makefile new file mode 100644 index 000000000..e1c5b2356 --- /dev/null +++ b/client/deps/cliparser/Makefile @@ -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 diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake new file mode 100644 index 000000000..6559f4faa --- /dev/null +++ b/client/deps/hardnested.cmake @@ -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 + $ + $ + $ + $ + $) +else () + message(STATUS "Not building optimised targets") + set(SIMD_TARGETS) +endif () + +add_library(hardnested STATIC + hardnested/hardnested_bruteforce.c + $ + ${SIMD_TARGETS}) +target_include_directories(hardnested PRIVATE + ../../common + ../../include + ../src + jansson) +target_include_directories(hardnested INTERFACE hardnested) diff --git a/client/deps/hardnested/Makefile b/client/deps/hardnested/Makefile new file mode 100644 index 000000000..84c4ce842 --- /dev/null +++ b/client/deps/hardnested/Makefile @@ -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) $@ diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake new file mode 100644 index 000000000..b2042c6b4 --- /dev/null +++ b/client/deps/jansson.cmake @@ -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) diff --git a/client/deps/jansson/Makefile b/client/deps/jansson/Makefile index 1ef283bab..111aed087 100644 --- a/client/deps/jansson/Makefile +++ b/client/deps/jansson/Makefile @@ -18,4 +18,7 @@ MYSRCS = \ LIB_A = libjansson.a +# Transition: remove old directories and objects +MYCLEANOLDPATH = ../../jansson + include ../../../Makefile.host diff --git a/client/deps/liblua/Makefile b/client/deps/liblua/Makefile index d4b31be0a..692684186 100644 --- a/client/deps/liblua/Makefile +++ b/client/deps/liblua/Makefile @@ -14,6 +14,9 @@ SYSCFLAGS= LIB_A= liblua.a +# Transition: remove old directories and objects +MYCLEANOLDPATH = ../../liblua + # Your platform. See PLATS for possible values. PLAT= none diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake new file mode 100644 index 000000000..3850863b5 --- /dev/null +++ b/client/deps/lua.cmake @@ -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) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake new file mode 100644 index 000000000..13b08bec0 --- /dev/null +++ b/client/deps/mbedtls.cmake @@ -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) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake new file mode 100644 index 000000000..0bf84d05a --- /dev/null +++ b/client/deps/reveng.cmake @@ -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) diff --git a/client/deps/reveng/Makefile b/client/deps/reveng/Makefile index 17d63a4f9..93c363d70 100644 --- a/client/deps/reveng/Makefile +++ b/client/deps/reveng/Makefile @@ -4,13 +4,12 @@ # Add -DPRESETS to compile with preset models (edit config.h) MYSRCPATHS = -MYINCLUDES = -I. -I.. +MYINCLUDES = -I../cliparser MYCFLAGS = -std=c99 -D_ISOC99_SOURCE MYDEFS = -DPRESETS MYSRCS = \ bmpbit.c \ cli.c \ - getopt.c \ model.c \ poly.c \ preset.c \ @@ -18,6 +17,9 @@ MYSRCS = \ LIB_A = libreveng.a +# Transition: remove old directories and objects +MYCLEANOLDPATH = ../../reveng + include ../../../Makefile.host CLEAN += bmptst diff --git a/client/deps/reveng/cli.c b/client/deps/reveng/cli.c index b8de74961..9d849dfc3 100644 --- a/client/deps/reveng/cli.c +++ b/client/deps/reveng/cli.c @@ -53,7 +53,7 @@ #include #include -#include "cliparser/getopt.h" +#include "getopt.h" #ifdef _WIN32 # include # include diff --git a/client/deps/reveng/getopt.c b/client/deps/reveng/getopt.c deleted file mode 100644 index 2c384e6be..000000000 --- a/client/deps/reveng/getopt.c +++ /dev/null @@ -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 -#include -#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; - } -} diff --git a/client/deps/reveng/getopt.h b/client/deps/reveng/getopt.h deleted file mode 100644 index c4b77d31e..000000000 --- a/client/deps/reveng/getopt.h +++ /dev/null @@ -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 diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake new file mode 100644 index 000000000..14ebb5326 --- /dev/null +++ b/client/deps/tinycbor.cmake @@ -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) diff --git a/client/deps/tinycbor/Makefile b/client/deps/tinycbor/Makefile index 376e2b641..713b6e428 100644 --- a/client/deps/tinycbor/Makefile +++ b/client/deps/tinycbor/Makefile @@ -16,6 +16,9 @@ MYSRCS = \ LIB_A = tinycbor.a +# Transition: remove old directories and objects +MYCLEANOLDPATH = ../../tinycbor + # Strange errors on Mingw when compiling with -O3 CFLAGS ?= -Wall -Werror -O2 diff --git a/client/deps/zlib.cmake b/client/deps/zlib.cmake new file mode 100644 index 000000000..882022ab5 --- /dev/null +++ b/client/deps/zlib.cmake @@ -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) diff --git a/client/dictionaries/mfdes_default_keys.dic b/client/dictionaries/mfdes_default_keys.dic new file mode 100644 index 000000000..dac73fa04 --- /dev/null +++ b/client/dictionaries/mfdes_default_keys.dic @@ -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 diff --git a/client/luascripts/hf_writer.lua b/client/luascripts/hf_writer.lua deleted file mode 100644 index ef7c3969b..000000000 --- a/client/luascripts/hf_writer.lua +++ /dev/null @@ -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) diff --git a/client/luascripts/mfc_gen3_writer.lua b/client/luascripts/mfc_gen3_writer.lua new file mode 100644 index 000000000..5222c0d39 --- /dev/null +++ b/client/luascripts/mfc_gen3_writer.lua @@ -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) diff --git a/client/src/cmdcrc.c b/client/src/cmdcrc.c index d51e18021..8830f5530 100644 --- a/client/src/cmdcrc.c +++ b/client/src/cmdcrc.c @@ -22,7 +22,7 @@ # endif /* STDIN_FILENO */ #endif /* _WIN32 */ -#include "reveng/reveng.h" +#include "reveng.h" #include "ui.h" #include "util.h" diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 86cc91dfd..9a809f603 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -21,11 +21,11 @@ #include "graph.h" // for graph data #include "comms.h" #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 "fileutils.h" // searchFile #include "mifare/ndef.h" -#include "cliparser/cliparser.h" +#include "cliparser.h" uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; size_t DemodBufferLen = 0; @@ -101,13 +101,13 @@ static int usage_data_biphaserawdecode(void) { static int usage_data_rawdemod(void) { PrintAndLogEx(NORMAL, "Usage: data rawdemod [modulation] |"); PrintAndLogEx(NORMAL, " [modulation] as 2 char,"); - PrintAndLogEx(NORMAL, " "_YELLOW_("ab")"- ask/biphase"); - PrintAndLogEx(NORMAL, " "_YELLOW_("am")"- ask/manchester"); - PrintAndLogEx(NORMAL, " "_YELLOW_("ar")"- ask/raw"); - PrintAndLogEx(NORMAL, " "_YELLOW_("fs")"- fsk"); - PrintAndLogEx(NORMAL, " "_YELLOW_("nr")"- nrz/direct"); - PrintAndLogEx(NORMAL, " "_YELLOW_("p1")"- psk1"); - PrintAndLogEx(NORMAL, " "_YELLOW_("p2")"- psk2"); + PrintAndLogEx(NORMAL, " "_YELLOW_("ab")" - ask/biphase"); + PrintAndLogEx(NORMAL, " "_YELLOW_("am")" - ask/manchester"); + PrintAndLogEx(NORMAL, " "_YELLOW_("ar")" - ask/raw"); + PrintAndLogEx(NORMAL, " "_YELLOW_("fs")" - fsk"); + PrintAndLogEx(NORMAL, " "_YELLOW_("nr")" - nrz/direct"); + PrintAndLogEx(NORMAL, " "_YELLOW_("p1")" - psk1"); + PrintAndLogEx(NORMAL, " "_YELLOW_("p2")" - psk2"); PrintAndLogEx(NORMAL, " as 'h', prints the help for the specific modulation"); PrintAndLogEx(NORMAL, " see specific modulation help for optional parameters"); PrintAndLogEx(NORMAL, ""); @@ -843,7 +843,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveG // sanity check 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 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) { 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)) { - PrintAndLogEx(SUCCESS, "possible correlation " _YELLOW_("%4zu") "samples", correlation); + PrintAndLogEx(SUCCESS, "possible correlation " _YELLOW_("%4zu") " samples", correlation); } else { 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)) 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; 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] if (response.oldarg[0] > 0) { 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; } diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index ab104276d..8d19c3888 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -266,7 +266,7 @@ static int CmdFlashMemLoad(const char *Cmd) { conn.block_after_ACK = false; 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; } static int CmdFlashMemDump(const char *Cmd) { @@ -321,7 +321,7 @@ static int CmdFlashMemDump(const char *Cmd) { 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)) { PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory"); free(dump); diff --git a/client/src/cmdflashmemspiffs.c b/client/src/cmdflashmemspiffs.c index 8ec0fe8e1..b994ea56c 100644 --- a/client/src/cmdflashmemspiffs.c +++ b/client/src/cmdflashmemspiffs.c @@ -308,7 +308,7 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { 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)) { PrintAndLogEx(FAILED, "ERROR; downloading from spiffs(flashmemory)"); free(dump); @@ -449,7 +449,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { free(data); 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; } diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 9ea34420a..fbc99dbd5 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -16,7 +16,7 @@ #include // tolower #include "cmdparser.h" // command_t -#include "cliparser/cliparser.h" // parse +#include "cliparser.h" // parse #include "comms.h" // clearCommandBuffer #include "lfdemod.h" // computeSignalProperties #include "cmdhf14a.h" // ISO14443-A @@ -39,7 +39,7 @@ #include "ui.h" #include "cmddata.h" #include "graph.h" -#include "../../common_fpga/fpga.h" +#include "fpga.h" static int CmdHelp(const char *Cmd); @@ -92,7 +92,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); if (IfPm3NfcBarcode()) { if (infoThinFilm(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") "found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); res = PM3_SUCCESS; } } @@ -101,7 +101,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for LTO-CM tag..."); if (IfPm3Iso14443a()) { 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; } } @@ -110,7 +110,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { 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; } } @@ -119,7 +119,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { if (readHF15Uid(false)) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") "found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); res = PM3_SUCCESS; } } @@ -128,7 +128,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for LEGIC tag..."); if (IfPm3Legicrf()) { 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; } } @@ -137,7 +137,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for Topaz tag..."); if (IfPm3Iso14443a()) { if (readTopazUid(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") "found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); res = PM3_SUCCESS; } } @@ -146,7 +146,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for FeliCa tag..."); if (IfPm3Felica()) { 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; } } @@ -156,7 +156,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for CryptoRF tag..."); if (IfPm3Iso14443b()) { if (readHFCryptoRF(false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("CryptoRF tag") "found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("CryptoRF tag") " found\n"); res = PM3_SUCCESS; } } @@ -167,7 +167,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag..."); if (IfPm3Iso14443b()) { 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; } } @@ -176,7 +176,7 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag..."); if (IfPm3Iclass()) { 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; } } @@ -196,7 +196,7 @@ int CmdHFTune(const char *Cmd) { if (cmdp == 'h') return usage_hf_tune(); 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; clearCommandBuffer(); diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 029b354d2..c53bc08b6 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -19,7 +19,7 @@ #include "commonutil.h" // ARRAYLEN #include "comms.h" // clearCommandBuffer #include "cmdtrace.h" -#include "cliparser/cliparser.h" +#include "cliparser.h" #include "cmdhfmf.h" #include "cmdhfmfu.h" #include "emv/emvcore.h" @@ -466,7 +466,7 @@ int CmdHF14ASim(const char *Cmd) { break; } 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; } cmdp += 2; diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 9762ba498..620a75bd7 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -29,7 +29,7 @@ #include "comms.h" // clearCommandBuffer #include "cmdtrace.h" #include "iso15693tools.h" -#include "../crypto/libpcrypto.h" +#include "crypto/libpcrypto.h" #include "graph.h" #include "crc16.h" // iso15 crc #include "cmddata.h" // getsamples @@ -928,7 +928,7 @@ static int CmdHF15Info(const char *Cmd) { memcpy(uid, recv + 2, sizeof(uid)); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------"); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(SUCCESS, " TYPE: " _YELLOW_("%s"), getTagInfo_15(recv + 2)); PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index e6f89790a..e35479db9 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -30,9 +30,9 @@ #include "proxmark3.h" #include "emv/emvcore.h" #include "emv/emvjson.h" -#include "cliparser/cliparser.h" -#include "../crypto/asn1utils.h" -#include "../crypto/libpcrypto.h" +#include "cliparser.h" +#include "crypto/asn1utils.h" +#include "crypto/libpcrypto.h" #include "fido/cbortools.h" #include "fido/fidocore.h" #include "emv/dump.h" diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 73163e1ea..c687e316d 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -19,10 +19,10 @@ #include "util_posix.h" #include "comms.h" #include "mbedtls/des.h" -#include "../loclass/cipherutils.h" -#include "../loclass/cipher.h" -#include "../loclass/ikeys.h" -#include "../loclass/elite_crack.h" +#include "loclass/cipherutils.h" +#include "loclass/cipher.h" +#include "loclass/ikeys.h" +#include "loclass/elite_crack.h" #include "fileutils.h" #include "protocols.h" #include "cardhelper.h" @@ -927,7 +927,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { uint32_t limit = MIN(applimit, decryptedlen / 8); 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); } uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8)); @@ -1415,7 +1415,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // print the dump PrintAndLogEx(NORMAL, ""); 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); if (filename[0] == 0) { @@ -2052,11 +2052,11 @@ static int CmdHFiClassReadTagFile(const char *Cmd) { 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, "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; 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); free(dump); return PM3_SUCCESS; @@ -2223,7 +2223,7 @@ static int loadKeys(char *filename) { memcpy(iClass_Key_Table[i], dump + (i * 8), 8); 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; } @@ -2440,7 +2440,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { if (use_raw) 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, "CSN | %s", sprint_hex(CSN, sizeof(CSN))); 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) { 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; } } diff --git a/client/src/cmdhflegic.c b/client/src/cmdhflegic.c index 04bd692aa..7507e326b 100644 --- a/client/src/cmdhflegic.c +++ b/client/src/cmdhflegic.c @@ -55,7 +55,7 @@ static int usage_legic_rdbl(void) { } static int usage_legic_sim(void) { 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] \n"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : this help"); @@ -217,7 +217,7 @@ static int CmdLegicInfo(const char *Cmd) { 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 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(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], sprint_hex(data + 1, 3), data[4], @@ -394,7 +394,7 @@ static int CmdLegicInfo(const char *Cmd) { (segment_flag & 0x4) >> 2, (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, wrc, ((data[i + 3] ^ crc) & 0x80) >> 7, diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index c5b73c0c6..6434a9e88 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -616,7 +616,7 @@ static int CmdHfLTRestore(const char *Cmd) { is_data_loaded = loadFileEML(filename, (uint8_t *)dump_data, &dump_datalen); } 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) { diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 44e56351b..8c6247614 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -19,8 +19,8 @@ #include "cmdtrace.h" #include "emv/dump.h" #include "mifare/mifaredefault.h" // mifare default key array -#include "cliparser/cliparser.h" // argtable -#include "hardnested/hardnested_bf_core.h" // SetSIMDInstr +#include "cliparser.h" // argtable +#include "hardnested_bf_core.h" // SetSIMDInstr #include "mifare/mad.h" #include "mifare/ndef.h" #include "protocols.h" @@ -249,10 +249,10 @@ static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, " t write keys to emulator memory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk 0 A 1234567890ab")" -- target block 0, Key A using key 1234567890ab"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk 0 A mfc_default_keys.dic")" -- target block 0, Key A using default dictionary file"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk *1 ? t")" -- target all blocks, all keys, 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk *1 ? d")" -- target all blocks, all keys, 1K, write to file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk 0 A 1234567890ab")" -- target block 0, Key A using key 1234567890ab"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk 0 A mfc_default_keys.dic")" -- target block 0, Key A using default dictionary file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk *1 ? t")" -- target all blocks, all keys, 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf chk *1 ? d")" -- target all blocks, all keys, 1K, write to file"); return PM3_SUCCESS; } static int usage_hf14_chk_fast(void) { @@ -270,12 +270,12 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " m use dictionary from flashmemory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 1234567890ab")" -- target 1K using key 1234567890ab"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 mfc_default_keys.dic")" -- target 1K using default dictionary file"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 t")" -- target 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 d")" -- target 1K, write to file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 1234567890ab")" -- target 1K using key 1234567890ab"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 mfc_default_keys.dic")" -- target 1K using default dictionary file"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 t")" -- target 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 d")" -- target 1K, write to file"); if (IfPm3Flash()) - PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 m")" -- target 1K, use dictionary from flashmemory"); + PrintAndLogEx(NORMAL, _YELLOW_(" hf mf fchk 1 m")" -- target 1K, use dictionary from flashmemory"); return PM3_SUCCESS; } /* @@ -1361,7 +1361,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } 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"); // nested sectors @@ -1408,7 +1408,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } 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? @@ -1576,7 +1576,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { } 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"); // nested sectors @@ -1613,7 +1613,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { } 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? @@ -2060,7 +2060,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, _YELLOW_("======================= START KNOWN KEY ATTACK =======================")); } 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, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) @@ -2095,13 +2095,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { know_target_key = true; blockNo = i; 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, j ? 'B' : 'A', sprint_hex(key, sizeof(key)) ); } 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, j ? 'B' : 'A', 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); } 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 @@ -2219,13 +2219,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { know_target_key = true; blockNo = i; 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, j ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) ); } 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, j ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) @@ -2267,7 +2267,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Store the keys e_sector[blockNo].Key[keyType] = key64; 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, keyType ? 'B' : 'A', sprint_hex(key, sizeof(key)) @@ -2307,7 +2307,7 @@ noValidKeyFound: 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].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, j ? 'B' : 'A', 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].Key[current_key_type_i] = key64; 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_key_type_i ? 'B' : 'A', 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 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_key_type_i ? 'B' : 'A', sprint_hex(tmp_key, sizeof(tmp_key)) @@ -2522,7 +2522,7 @@ all_found: // Generate and show statistics 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(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]); 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 , strA, e_sector[i].foundKey[0] , 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) 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 , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] @@ -4520,7 +4520,7 @@ static int CmdHF14AMfice(const char *Cmd) { 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) { PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), filename); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index d02c1ddfa..4b091343b 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -16,21 +16,21 @@ #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" -#include "cmdhw.h" #include "cmdhf14a.h" -#include "mbedtls/des.h" #include "mbedtls/aes.h" -#include "../crypto/libpcrypto.h" +#include "crypto/libpcrypto.h" #include "protocols.h" -#include "mifare.h" // desfire raw command options #include "cmdtrace.h" -#include "cliparser/cliparser.h" +#include "cliparser.h" #include "emv/apduinfo.h" // APDU manipulation / errorcodes #include "emv/emvcore.h" // APDU logging #include "util_posix.h" // msleep -#include "mifare/mifare4.h" // MIFARE Authenticate / MAC #include "mifare/desfire_crypto.h" #include "crapto1/crapto1.h" +#include "fileutils.h" + +#define MAX_KEY_LEN 24 +#define MAX_KEYS_LIST_LEN 1024 struct desfire_key defaultkey = {0}; static desfirekey_t sessionkey = &defaultkey; @@ -175,17 +175,11 @@ static char *cluster_to_text(uint8_t cluster) { case CL_ADMIN: return "card administration"; case CL_MISC1: - return "miscellaneous applications"; case CL_MISC2: - return "miscellaneous applications"; case CL_MISC3: - return "miscellaneous applications"; case CL_MISC4: - return "miscellaneous applications"; case CL_MISC5: - return "miscellaneous applications"; case CL_MISC6: - return "miscellaneous applications"; case CL_MISC7: return "miscellaneous applications"; case CL_AIRLINES: @@ -219,7 +213,6 @@ static char *cluster_to_text(uint8_t cluster) { case CL_CITYCARD: return "city card services"; case CL_ACCESS_CONTROL_1: - return "access control & security"; case CL_ACCESS_CONTROL_2: return "access control & security"; case CL_VIGIK: @@ -289,19 +282,12 @@ static char *cluster_to_text(uint8_t cluster) { case CL_MAIL: return "mail"; case CL_AMISC: - return "miscellaneous applications"; case CL_AMISC1: - return "miscellaneous applications"; case CL_AMISC2: - return "miscellaneous applications"; case CL_AMISC3: - return "miscellaneous applications"; case CL_AMISC4: - return "miscellaneous applications"; case CL_AMISC5: - return "miscellaneous applications"; case CL_AMISC6: - return "miscellaneous applications"; case CL_AMISC7: return "miscellaneous applications"; default: @@ -311,7 +297,7 @@ static char *cluster_to_text(uint8_t cluster) { } typedef enum { - UNKNOWN = 0, + DESFIRE_UNKNOWN = 0, DESFIRE_MF3ICD40, DESFIRE_EV1, DESFIRE_EV2, @@ -344,9 +330,9 @@ static char *getCardSizeStr(uint8_t fsize) { // is LSB set? 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 - sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize); + sprintf(retStr, "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize); return buf; } @@ -356,14 +342,14 @@ static char *getProtocolStr(uint8_t id, bool hw) { char *retStr = buf; 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) { 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 - sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id); + sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-3, 14443-4") ")", id); } else { - sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id); + sprintf(retStr, "0x%02X (" _YELLOW_("Unknown") ")", id); } return buf; } @@ -374,17 +360,17 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { char *retStr = buf; 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) - sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV1") ")", major, minor); + sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor); 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) -// sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV3") ")", major, minor); +// sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor); 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 - sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor); + sprintf(retStr, "%x.%x (" _YELLOW_("Unknown") ")", major, minor); return buf; } @@ -653,7 +639,7 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) { if (major == 0x11 && minor == 0x00) return PLUS_EV1; - return UNKNOWN; + return DESFIRE_UNKNOWN; } 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}; int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false); if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Sending auth command %02X " _RED_("failed"), subcommand); - return PM3_ESOFT; + return 1; } } else if (payload->mode == MFDES_AUTH_PICC) { /*cmd[0] = AUTHENTICATE; @@ -747,13 +732,11 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, } if (!recv_len) { - PrintAndLogEx(ERR, "Authentication failed. Card timeout."); - return PM3_ESOFT; + return 2; } if (sw != status(MFDES_ADDITIONAL_FRAME)) { - PrintAndLogEx(ERR, "Authentication failed. Invalid key number."); - return PM3_ESOFT; + return 3; } int expectedlen = 8; @@ -762,8 +745,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, } if (recv_len != expectedlen) { - PrintAndLogEx(ERR, "Authentication failed. Length of answer %d doesn't match algo length %d.", recv_len, expectedlen); - return PM3_ESOFT; + return 4; } int rndlen = recv_len; @@ -778,8 +760,7 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, // Part 3 if (payload->algo == MFDES_ALGO_AES) { if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed"); - return PM3_ESOFT; + return 5; } mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndB, RndB); } 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 (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { - PrintAndLogEx(ERR, "mbedtls_aes_setkey_enc failed"); - return PM3_ESOFT; + return 6; } mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both); 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}; int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false); if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Sending auth command %02X " _RED_("failed"), subcommand); - return PM3_ESOFT; + return 7; } } else { /*cmd[0] = ADDITIONAL_FRAME; @@ -881,14 +860,12 @@ int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload, } if (!recv_len) { - PrintAndLogEx(ERR, "Authentication failed. Card timeout."); - return PM3_ESOFT; + return 8; } if (payload->mode != MFDES_AUTH_PICC) { if (sw != status(MFDES_S_OPERATION_OK)) { - PrintAndLogEx(ERR, "Authentication failed."); - return PM3_ESOFT; + return 9; } } else { /*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); } else if (payload->mode == MFDES_AUTH_AES) { if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - PrintAndLogEx(ERR, "mbedtls_aes_setkey_dec failed"); - return PM3_ESOFT; + return 10; } 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); for (int x = 0; x < rndlen; x++) { if (RndA[x] != encRndA[x]) { - PrintAndLogEx(ERR, "Authentication failed. Cannot verify Session Key."); if (g_debugMode > 1) { PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, 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; } +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 static int test_desfire_authenticate() { uint8_t data[] = {0x00}; @@ -2839,11 +2853,11 @@ static int CmdHF14ADesInfo(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------"); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); 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, " 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(INFO, "--- " _CYAN_("Hardware Information")); 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; } +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) { (void)Cmd; // Cmd is not used so far DropField(); @@ -3082,7 +3239,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "-- Mifare DESFire Enumerate applications --------------------"); 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) { @@ -3116,7 +3273,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) { // Get File IDs 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--) { 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; - 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, " SESSION : " _GREEN_("%s"), sprint_hex(rpayload.sessionkey, keylength)); PrintAndLogEx(INFO, "-------------------------------------------------------------"); } else { + AuthToError(error); return PM3_ESOFT; } PrintAndLogEx(INFO, "-------------------------------------------------------------"); 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", "", "Use specific AID (3 hex bytes, big endian)"), + arg_str0("kK", "key", "", "Key for checking (HEX 16 bytes)"), + arg_str0("dD", "dict", "", "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", "", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"), + arg_str0("jJ", "json", "", "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) { (void)Cmd; // Cmd is not used so far return CmdTraceList("des"); @@ -3364,6 +4027,8 @@ static command_t CommandTable[] = { {"getvalue", CmdHF14ADesGetValueData, IfPm3Iso14443a, "Get value of file"}, {"changevalue", CmdHF14ADesChangeValue, IfPm3Iso14443a, "Write value of a value file (credit/debit/clear)"}, {"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"}, + {"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"}, + {"chk", CmdHF14aDesChk, IfPm3Iso14443a, "Check keys"}, /* ToDo: diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 85e91ac64..6fc146164 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -32,10 +32,10 @@ #include "util_posix.h" #include "crapto1/crapto1.h" #include "parity.h" -#include "hardnested/hardnested_bruteforce.h" -#include "hardnested/hardnested_bf_core.h" -#include "hardnested/hardnested_bitarray_core.h" -#include "zlib.h" +#include "hardnested_bruteforce.h" +#include "hardnested_bf_core.h" +#include "hardnested_bitarray_core.h" +#include "zlib/zlib.h" #include "fileutils.h" #define NUM_CHECK_BITFLIPS_THREADS (num_CPUs()) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 91418b191..728101ce7 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -19,13 +19,13 @@ #include "mifare/mifare4.h" #include "mifare/mad.h" #include "mifare/ndef.h" -#include "cliparser/cliparser.h" +#include "cliparser.h" #include "emv/dump.h" #include "mifare/mifaredefault.h" #include "util_posix.h" #include "fileutils.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}; 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? 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 - sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize); + sprintf(retStr, "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize); return buf; } @@ -70,14 +70,14 @@ static char *getProtocolStr(uint8_t id, bool hw) { char *retStr = buf; 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) { 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 - sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id); + sprintf(retStr, "0x%02X (" _YELLOW_("ISO 14443-3, 14443-4") ")", id); } else { - sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id); + sprintf(retStr, "0x%02X (" _YELLOW_("Unknown") ")", id); } return buf; } @@ -88,20 +88,20 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { char *retStr = buf; 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) - sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV1") ")", major, minor); + sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor); 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) -// sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV3") ")", major, minor); +// sprintf(retStr, "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor); 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) - sprintf(retStr, "%x.%x ( " _YELLOW_("Plus EV1") ")", major, minor); + sprintf(retStr, "%x.%x (" _YELLOW_("Plus EV1") ")", major, minor); else - sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor); + sprintf(retStr, "%x.%x (" _YELLOW_("Unknown") ")", major, minor); return buf; } @@ -112,16 +112,16 @@ static char *getTypeStr(uint8_t type) { switch (type) { case 1: - sprintf(retStr, "0x%02X ( " _YELLOW_("DESFire") ")", type); + sprintf(retStr, "0x%02X (" _YELLOW_("DESFire") ")", type); break; case 2: - sprintf(retStr, "0x%02X ( " _YELLOW_("Plus") ")", type); + sprintf(retStr, "0x%02X (" _YELLOW_("Plus") ")", type); break; case 3: - sprintf(retStr, "0x%02X ( " _YELLOW_("Ultralight") ")", type); + sprintf(retStr, "0x%02X (" _YELLOW_("Ultralight") ")", type); break; case 4: - sprintf(retStr, "0x%02X ( " _YELLOW_("NTAG") ")", type); + sprintf(retStr, "0x%02X (" _YELLOW_("NTAG") ")", type); break; default: break; @@ -227,7 +227,7 @@ static int get_plus_signature(uint8_t *signature, int *signature_len) { static int plus_print_version(uint8_t *version) { PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(version + 14, 7)); 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(INFO, "--- " _CYAN_("Hardware Information")); 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(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------"); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); bool supportVersion = false; @@ -328,11 +328,11 @@ static int CmdHFMFPInfo(const char *Cmd) { uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8); 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; } 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; } @@ -357,7 +357,7 @@ static int CmdHFMFPInfo(const char *Cmd) { } 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) { @@ -1190,7 +1190,7 @@ static int CmdHFMFPChk(const char *Cmd) { PrintAndLogEx(ERR, "Key list is empty. Nothing to check."); return PM3_EINVARG; } else { - PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") "keys", keyListLen); + PrintAndLogEx(INFO, "Loaded " _YELLOW_("%zu") " keys", keyListLen); } if (!verbose) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index fcac8d137..9bdd9b814 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -11,7 +11,7 @@ #include #include "cmdparser.h" #include "commonutil.h" -#include "../crypto/libpcrypto.h" +#include "crypto/libpcrypto.h" #include "mbedtls/des.h" #include "cmdhfmf.h" #include "cmdhf14a.h" @@ -20,7 +20,7 @@ #include "protocols.h" #include "generator.h" #include "mifare/ndef.h" -#include "cliparser/cliparser.h" +#include "cliparser.h" #define MAX_UL_BLOCKS 0x0F @@ -64,13 +64,13 @@ static int usage_hf_mfu_info(void) { static int usage_hf_mfu_dump(void) { 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, "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, "Usage: hf mfu dump k l f p q <#pages>"); PrintAndLogEx(NORMAL, " Options :"); PrintAndLogEx(NORMAL, " k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); - PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w/o .bin") "to save the dump as"); + PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w/o .bin") " to save the dump as"); PrintAndLogEx(NORMAL, " p : starting Page number to manually set a page to start the dump at"); PrintAndLogEx(NORMAL, " q : number of Pages to manually set how many pages to dump"); PrintAndLogEx(NORMAL, ""); @@ -91,8 +91,8 @@ static int usage_hf_mfu_restore(void) { PrintAndLogEx(NORMAL, " l : (optional) swap entered key's endianness"); 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, " r : (optional) use the password found in dumpfile to configure tag. requires " _YELLOW_("'e'") "parameter to work"); - PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w .bin") "to restore"); + PrintAndLogEx(NORMAL, " r : (optional) use the password found in dumpfile to configure tag. requires " _YELLOW_("'e'") " parameter to work"); + PrintAndLogEx(NORMAL, " f : " _YELLOW_("filename w .bin") " to restore"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); 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) { 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 [numblocks]"); PrintAndLogEx(NORMAL, " Options:"); PrintAndLogEx(NORMAL, " h : this help"); @@ -198,7 +198,7 @@ static int usage_hf_mfu_ucsetuid(void) { PrintAndLogEx(NORMAL, "Usage: hf mfu setuid "); PrintAndLogEx(NORMAL, " [uid] - (14 hex symbols)"); 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, "Examples:"); 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) { - PrintAndLogEx(NORMAL, "Tear-off test against OTP block on MFU tags."); - PrintAndLogEx(NORMAL, "Usage: hf mfu otptear [h]"); + 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 b i l s d t \n"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : this help"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu otptear")); + PrintAndLogEx(NORMAL, " b : (optional) block to run the test - default block: 8 (not OTP for safety)"); + PrintAndLogEx(NORMAL, " i