diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..2f13a259a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: iceman1001 +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.gitignore b/.gitignore index f61e85eb9..348195eba 100644 --- a/.gitignore +++ b/.gitignore @@ -35,9 +35,11 @@ Makefile.platform !client/hardnested/*.bin !client/hardnested/tables/*.z client/ui/ui_overlays.h +client/reveng/bmptst hardnested_stats.txt proxmark3 +proxmark3-flasher flasher !flasher/ lua @@ -71,8 +73,9 @@ tools/jtag_openocd/openocd_configuration ppls patches/* *- Copy.* -client/lualibs/mf_default_keys.lua +client/lualibs/mfc_default_keys.lua client/lualibs/pm3_cmd.lua # recompiled fpga_version_info.c +.proxmark3/* diff --git a/.travis.yml b/.travis.yml index 3c12e6d3c..c75bffe9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,18 @@ 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' addons: apt: @@ -27,27 +36,23 @@ addons: homebrew: packages: - readline - - p7zip - - libusb-compat - - perl - qt5 - - wget - RfidResearchGroup/proxmark3/arm-none-eabi-gcc taps: RfidResearchGroup/proxmark3 - -install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew info proxmark3; - brew options proxmark3; - brew install --HEAD proxmark3; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - make all; - fi -script: +install: + 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 - proxmark3 -h ; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - ./client/proxmark3 -h ; - fi \ No newline at end of file + if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + ./pm3test.sh; + elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + ./pm3test.sh; + fi diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ca3660980..20b68be0e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -14,13 +14,13 @@ { "label": "flash fullimage", "type": "shell", - "command": "./flash-fullimage.sh", + "command": "sudo ./pm3-flash-fullimage", "problemMatcher": [] }, { "label": "FLASH BOOTROM", "type": "shell", - "command": "./flash-bootrom.sh", + "command": "sudo ./pm3-flash-bootrom", "problemMatcher": [] } ] diff --git a/CHANGELOG.md b/CHANGELOG.md index b5f7d8d76..2099db5fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,38 @@ 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] + - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) + - Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001) + - Fix `hf iclass clone` - last block always fails (@iceman1001) + - Chg `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001) + - Chg `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001) + - Rename `hf iclass writeblk` -> `hf iclass wrbl` to match hf mf wrbl (@iceman1001) + - Rename `hf iclass readblk` -> `hf iclass rdbl` to match hf mf rdbl (@iceman1001) + - Add cmdscript example and show usage with shebang (@doegox) + - Add instructions for Fedora (@doegox) + - Chg reduce the list of requirements to the minimum and move to QT5 (@doegox) + - Add `make install` and reorganize/rename stuffs accordingly (@doegox) + - Add searchFile for several types of files (@doegox / @iceman1001) + - Chg posix sh version of mkversion (@doegox) + - Chg remove entirely ncurses, not needed nowadays (@doegox) + - Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-) + - Chg `hf iclass encrypt` - now takes transport key as param. (@iceman1001) + - Chg `hf iclass decrypt` - now takes transport key as param. (@iceman1001) + - Chg `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001) + - Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox) + - Chg optimization of iclass mac calculations on deviceside (@pwpiwi) + - Add `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath) + - Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox) + - Change Lua directory scripts/ to luascript/ (@doegox) + - Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox) - Fix reveng integration for all platforms else than WIN32 (@doegox) - Add cheat sheet for easy operations of the Proxmark3 (scund00r) - Chg commands are now in green in the helptext list (@iceman1001) - - Fix 'script run ndefdump' - better exit messages when failing (@iceman1001) - - Fix 'hf iclass dump' - now also saves in EML format (@iceman1001) - - Fix 'hf iclass sim 3' - now works on legacy readers and legacy SE readers (@iceman1001) + - Fix `script run ndefdump` - better exit messages when failing (@iceman1001) + - Fix `hf iclass dump` - now also saves in EML format (@iceman1001) + - Fix `hf iclass sim 3` - now works on legacy readers and legacy SE readers (@iceman1001) - Rework hitag2 read/write help (@ViRb3) - - Add 'lf nedap' - encoding / decoding (anon) + - Add `lf nedap` - encoding / decoding (anon) - Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox) - Add VSCode tasks (@ViRb3) - Better warn user of hardcoded hitag info (@ViRb3) @@ -18,10 +42,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fix hitag password write offset by 1 (@ViRb3) - Fix momentarily flash read/write of dicts (@doegox/@cjbrigato) - Add some more default keys (@anon) - - Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox) - - Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox) - - Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001) - - Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) + - Add `hf thinfilm sim` simulating Thinfilm NFC barcode tags (@doegox) + - Add `hf thinfilm list` specific trace decoding (Thinfilm NFC barcode tags) (@doegox) + - Fix `hf topaz reader` - don't crash when trying to read a Thinfilm tag (@iceman1001) + - Add `hf thinfilm info` - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001) - Add FPGA LF adc path (@anon) - Add ECC support / check for NID_secp128r1 (@pwpiwi) - Add some more default keys (ollibolli) diff --git a/COMPILING.txt b/COMPILING.txt index 04ff1d8bf..58ee40c08 100644 --- a/COMPILING.txt +++ b/COMPILING.txt @@ -1,131 +1,2 @@ -The project compiles on Linux, Mac OS X and Windows (MinGW/MSYS). - -it requires: -- gcc >= 4.8 -- libpthread -- libreadline -- libusb -- perl -- an ARM cross-compiler to compile the firmware -- libncurses5-dev - -and optionally QT for the GUI - - -To compile, just run "make". - -=========== -= Windows = -=========== - -Rather than download and install every one of these packages, a new ProxSpace -environment archive file will be made available for download on the project -page at @Gator96100's repo - -Afterwards just clone the iceman repo or download someone elses. Read instructions on @Gator96100 repo page. (https://github.com/Gator96100/ProxSpace/) - -Download the ProxSpace environment archive and extract it to C:\ - -Links - https://github.com/Gator96100/ProxSpace/archive/master.zip - - -============ -= Mac OS X = -============ - -Installing from HomeBrew tap ---------------------------- -This method is recommended and tested on macOS Sierra 10.12.3 - -1. Install homebrew if you haven't yet already done so: http://brew.sh/ - -2. Tap proxmark repo: - brew tap iceman1001/proxmark3 - -3. Install Proxmark3: - -Stable release - brew install proxmark3 - -Latest non-stable from GitHub (use this if previous command fails) - brew install --HEAD proxmark3 - -For more information go to https://github.com/iceman1001/homebrew-proxmark3 - -Upgrading HomeBrew tap formula ------------------------------ -*This method is useful for those looking to run bleeding-edge versions of iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.* - -Tested on macOS Sierra 10.12.6 - -*Note: This assumes you have already installed iceman's fork from HomeBrew as mentioned above* - -1. Force HomeBrew to pull the latest source from github -`brew upgrade --fetch-HEAD iceman1001/proxmark3/proxmark3` - -2. Flash the bootloader - * With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark 3 as you plug it into a USB port. After about 5 seconds let go of the button and run this command - `$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf` - * After the bootloader finishes flashing, unplug your Proxmark3 from your machine - -3. Flash fullimage.elf - * Press and hold the button on your Proxmark 3 and keep it held as you plug the Proxmark 3 back into the USB port; continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!"* - -`$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf` - -4. Enjoy the update - -Compilling from source manually (Legacy) ---------------------------- - -Tested on OSX 10.10 Yosemite - -1 - Install Xcode and Xcode Command Line Tools - -2 - Install Homebrew and dependencies - brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig - -3 - Download DevKitARM for OSX - http://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r44/ - Unpack devkitARM_r44-osx.tar.bz2 to proxmark3 directory. - -4 - Edit proxmark3/client/Makefile adding path to readline and qt5 - - LDLIBS = -L/usr/local/opt/readline/lib -L/usr/local/opt/qt5/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm - CFLAGS = -std=c99 -I/usr/local/opt/qt5/include -I/usr/local/opt/readline/include -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4 - - If your old brew intallation use /usr/local/Cellar/ path replace /usr/local/opt/readline/lib with your actuall readline and qt5 path. See homebrew manuals. - -5 - Set Environment - - export DEVKITPRO=$HOME/proxmark3/ - export DEVKITARM=$DEVKITPRO/devkitARM - export PATH=${PATH}:${DEVKITARM}/bin - - -============ -= Linux = -============ - -1 - Download - -A precompiled DevKitARM cross compiler tool chain package can be found at -http://sourceforge.net/projects/devkitpro/files/devkitARM -Select the one you need (32bit or 64bit) and unpack to a convinient place, eg -$HOME/proxmark3/. It will create a devkitARM/ subdirectory. - -You will also need a general compiling environment on your computer for -the client and the libusb headers. In most distributions you will get all you -need with the lsb-package (Linux Standard Base). In debian/ubuntu you simply -call `aptitude install lsb libusb-dev libreadline-dev libreadline6`. - -For the graphical plot view, you might need the qtlibs (debian/ubuntu: -libqt4-dev), too. - -2 - Set Environment - -export DEVKITPRO=$HOME/proxmark3/ -export DEVKITARM=$DEVKITPRO/devkitARM -export PATH=${PATH}:${DEVKITARM}/bin +Refer to doc/md/Installation_Instructions/ for up-to-date intructions for various platforms. diff --git a/Makefile b/Makefile index 9be67311b..ebb4dacb8 100644 --- a/Makefile +++ b/Makefile @@ -1,86 +1,131 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -GZIP=gzip -# Windows' echo echos its input verbatim, on Posix there is some -# amount of shell command line parsing going on. echo "" on -# Windows yields literal "", on Linux yields an empty line -ifeq ($(shell echo ""),) - # This is probably a proper system, so we can use uname - DELETE=rm -rf - FLASH_TOOL=client/flasher - platform=$(shell uname) - ifneq (,$(findstring MINGW,$(platform))) - FLASH_PORT=com3 - PATHSEP=\\# - else - FLASH_PORT=/dev/ttyACM0 - PATHSEP=/ - endif -else - # Assume that we are running on native Windows - DELETE=del /q - FLASH_TOOL=client/flasher.exe - platform=Windows - FLASH_PORT=com3 - PATHSEP=\\# -endif +include Makefile.defs -include Makefile.platform -include .Makefile.options.cache include common_arm/Makefile.hal -all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% +# preserve relative DESTDIR path for subdir makes +ifneq (,$(DESTDIR)) + # realpath needs the directory to exist + $(shell $(MKDIR) $(DESTDIR)) + MYDESTDIR:=$(realpath $(DESTDIR)) + ifeq (,$(MYDESTDIR)) + $(error Can't create $(DESTDIR)) + endif +endif + +all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% + +INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py +INSTALLSIMFW=sim011.bin sim011.sha512.txt +INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage +INSTALLSHARES=tools/jtag_openocd traces +INSTALLDOCS=doc/*.md doc/md + +install: all common/install + +common/install: + $(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLSCRIPTS)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) + $(Q)$(CP) $(INSTALLSCRIPTS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) +endif +ifneq (,$(INSTALLSHARES)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)$(CP) $(INSTALLSHARES) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) +endif +ifneq (,$(INSTALLDOCS)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) + $(Q)$(CP) $(INSTALLDOCS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) +endif +ifneq (,$(INSTALLTOOLS)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) + $(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) +endif +ifneq (,$(INSTALLSIMFW)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) +endif +ifeq ($(platform),Linux) + $(Q)$(MKDIR) $(DESTDIR)$(UDEV_PREFIX) + $(Q)$(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif + +uninstall: common/uninstall + +common/uninstall: + $(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLSCRIPTS)) + $(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script))) +endif +ifneq (,$(INSTALLSHARES)) + $(Q)$(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share))) +endif +ifneq (,$(INSTALLDOCS)) + $(Q)$(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc))) + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) +endif +ifneq (,$(INSTALLTOOLS)) + $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool))) +endif + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) +ifneq (,$(INSTALLSIMFW)) + $(Q)$(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) +endif + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) +ifeq ($(platform),Linux) + $(Q)$(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif + $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) mfkey/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR) nonce2key/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR) fpga_compress/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR) bootrom/%: FORCE cleanifplatformchanged $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) DESTDIR=$(MYDESTDIR) armsrc/%: FORCE cleanifplatformchanged fpga_compress/% $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) DESTDIR=$(MYDESTDIR) client/%: FORCE $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) -recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/% + $(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) DESTDIR=$(MYDESTDIR) +recovery/all: bootrom/all armsrc/all +recovery/install: bootrom/all armsrc/all +recovery/%: FORCE cleanifplatformchanged $(info [*] MAKE $@) - $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) + $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) -.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged +.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged help: @echo "Multi-OS Makefile" @echo @echo "Possible targets:" - @echo "+ all - Make all targets: bootrom, armsrc and OS-specific host tools" - @echo "+ clean - Clean in all targets" + @echo "+ all - Make all targets: bootrom, fullimage and OS-specific host tools" + @echo "+ clean - Clean in all targets" + @echo "+ .../clean - Clean in specified target and its deps, e.g. bootrom/clean" + @echo "+ (un)install - Install/uninstall Proxmark files in the system, default to /usr/local/share, + @echo " else provide a PREFIX. See Maintainers.md for more options" @echo - @echo "+ bootrom - Make bootrom" - @echo "+ os - Make armsrc (includes fpga)" - @echo "+ flash-bootrom - Make bootrom and flash it" - @echo "+ flash-os - Make armsrc and flash os image (includes fpga)" - @echo "+ flash-all - Make bootrom and armsrc and flash bootrom and os image" - @echo "+ recovery - Make bootrom and armsrc images for JTAG flashing" + @echo "+ bootrom - Make bootrom" + @echo "+ fullimage - Make armsrc fullimage (includes fpga)" + @echo "+ recovery - Make bootrom and fullimage files for JTAG flashing" @echo - @echo "+ client - Make only the OS-specific host client" - @echo "+ mfkey - Make tools/mfkey" - @echo "+ nonce2key - Make tools/nonce2key" - @echo "+ fpga_compress - Make tools/fpga_compress" + @echo "+ client - Make only the OS-specific host client" + @echo "+ mfkey - Make tools/mfkey" + @echo "+ nonce2key - Make tools/nonce2key" + @echo "+ fpga_compress - Make tools/fpga_compress" @echo - @echo "+ style - Apply some automated source code formatting rules" - @echo "+ checks - Detect various encoding issues in source code" + @echo "+ style - Apply some automated source code formatting rules" + @echo "+ checks - Detect various encoding issues in source code" @echo @echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4" @echo "To activate verbose mode, use make V=1" @@ -89,7 +134,17 @@ client: client/all bootrom: bootrom/all -os: armsrc/all +# aliases fullimage = armsrc + +fullimage: armsrc/all + +fullimage/all: armsrc/all + +fullimage/clean: armsrc/clean + +fullimage/install: armsrc/install + +fullimage/uninstall: armsrc/uninstall recovery: recovery/all @@ -99,17 +154,8 @@ nonce2key: nonce2key/all fpga_compress: fpga_compress/all -flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<) - -flash-os: armsrc/obj/fullimage.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<) - -flash-all: bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf $(FLASH_TOOL) - $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^)) - newtarbin: - $(DELETE) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz + $(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz @touch proxmark3-$(platform)-bin.tar tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin diff --git a/Makefile.defs b/Makefile.defs new file mode 100644 index 000000000..4068d7516 --- /dev/null +++ b/Makefile.defs @@ -0,0 +1,46 @@ +# Hide full compilation line: +ifneq ($(V),1) + Q?=@ +endif +# To see full command lines, use make V=1 + +# been here +DEFSBEENHERE = true + +CP = cp -a +GZIP = gzip +MKDIR = mkdir -p +RM = rm -f +RMDIR = rm -rf +# rmdir only if dir is empty, tolerate failure +RMDIR_SOFT = -rmdir +MV = mv +TOUCH = touch +FALSE = false +TAR = tar +TARFLAGS ?= -v --ignore-failed-read -r +TARFLAGS += -C .. -f +CROSS ?= arm-none-eabi- +CC = gcc +CXX = g++ +LD = g++ + +PATHSEP=/ +PREFIX ?= /usr/local +UDEV_PREFIX ?= /etc/udev/rules.d +INSTALLBINRELPATH ?= bin +INSTALLSHARERELPATH ?= share/proxmark3 +INSTALLFWRELPATH ?= share/proxmark3/firmware +INSTALLTOOLSRELPATH ?= share/proxmark3/tools +INSTALLDOCSRELPATH ?= share/doc/proxmark3 + +platform = $(shell uname) +DETECTED_OS=$(platform) + +ifeq ($(platform),Darwin) + AR= /usr/bin/ar rcs + RANLIB= /usr/bin/ranlib +else + AR= ar rcs + RANLIB= ranlib +endif diff --git a/Makefile.host b/Makefile.host new file mode 100644 index 000000000..bfadd82b7 --- /dev/null +++ b/Makefile.host @@ -0,0 +1,76 @@ +# This Makefile might have been called from various subdirs, trying to find our Makefile.defs +ifeq ($(DEFSBEENHERE),) + -include Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + $(error Can't find Makefile.defs) +endif + +CFLAGS ?= -Wall -Werror -O3 +CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) + +vpath %.c $(MYSRCPATHS) + +# Flags to generate temporary dependency files +DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td +# make temporary to final dependency files after successful compilation +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ + +BINDIR := . +OBJDIR := obj + +MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o) +CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin)) + +all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin)) + +clean: + $(Q)$(RM) $(CLEAN) + $(Q)$(RMDIR) $(OBJDIR) + +install: all +ifneq (,$(INSTALLTOOLS)) + $(info [@] Installing $(BINS) to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) + $(Q)$(CP) $(INSTALLTOOLS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) +endif + @true + +uninstall: +ifneq (,$(INSTALLTOOLS)) + $(info [@] Uninstalling $(BINS) from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool))) +endif + @true + +.PHONY: all clean install uninstall + +$(BINDIR)/$(LIB_A): $(MYOBJS) + $(info [=] AR $(notdir $@)) + $(Q)$(AR) $@ $(MYOBJS) + $(Q)$(RANLIB) $@ + +$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS) + $(info [=] LD $(notdir $@)) + $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) + +$(OBJDIR)/%.o : %.c | $(OBJDIR) + $(info [-] CC $<) + $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< + $(Q)$(POSTCOMPILE) + +$(OBJDIR): + $(Q)$(MKDIR) $(OBJDIR) + +DEPENDENCY_FILES = $(MYOBJS:%.o=%.d) $(BINS:%=$(OBJDIR)/%.d) + +$(DEPENDENCY_FILES): ; +.PRECIOUS: $(DEPENDENCY_FILES) + +-include $(DEPENDENCY_FILES) diff --git a/README.md b/README.md index 81c676b8d..22221abe6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# RRG / Iceman repo, dedicated to Proxmark3 RDV4.0 +# RRG / Iceman repo - Proxmark3 -This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. +This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well. -_Note that it also supports other Proxmark3 platforms as well!_ +It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design. | Releases | Linux & OSX CI | Windows CI | @@ -17,16 +17,23 @@ _Note that it also supports other Proxmark3 platforms as well!_ | ------------------- |:-------------------:| -------------------:| |[What has changed?](#what-has-changed) | [Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)| |[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) | -|[Why didn't you base it on official PM3 Master?](#why-didnt-you-base-it-on-official-pm3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| -|[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| +|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)| +|[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)| -|[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)| -|[Notes on Frame format](/doc/new_frame_format.md)||| -|[Notes on external flash](/doc/ext_flash_notes.md)||| -|[Notes on Termux / Android](/doc/termux_notes.md)||| +|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| +|[Notes on frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| +|[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)| +|[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)| +|[Notes on wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)| +|[Notes on loclass](/doc/loclass_notes.md)||| +|[Notes on paths](/doc/path_notes.md)||| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) || |[Donations](#Donations)||| +## Support on other Proxmark3 platforms + +In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md) + ## What has changed? On the hardware side: @@ -38,11 +45,13 @@ On the hardware side: On the software side: quite a lot, see the [Changelog file](CHANGELOG.md). ## Development -This fork now compiles just fine on + +This repo now compiles just fine on + - Proxspace v3.2 - Windows/mingw environment with Qt5.6.1 & GCC 4.8 - Ubuntu 1404, 1510, 1604, 1804, 1904 - Mac OS X / Homebrew - - ParrotOS, Gentoo, Pentoo + - ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora - WSL, WSL2 (Windows subsystem linux) on Windows 10 - Docker container @@ -54,15 +63,26 @@ If you intend to contribute to the code, please read the [coding style notes](HA - Internal notes on [external flash](/doc/ext_flash_notes.md) - Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) - Internal notes on [Termux / Android](/doc/termux_notes.md) +- Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md) +- Internal notes on [loclass](/doc/loclass_notes.md) +- Internal notes on [EMV](/doc/emv_notes.md) +- Internal notes on [Paths](/doc/path_notes.md) ## Cheat sheet + Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) +## Maintainers ( package, distro ) + +To all distro, package maintainers, we tried to make your life easier. `make install` is now available and if you want to know more. +- [Maintainers](/doc/md/Development/Maintainers.md) + ## Why didn't you base it on official Proxmark3 Master? The separation from official Proxmark3 repo gives us a lot of freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the official Proxmark3 repo with RDV40 specific code. ## Proxmark3 GUI + The official PM3-GUI from Gaucho will not work. The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) Almost, change needed in order to show helptext when client isn't connected to a device. @@ -78,6 +98,7 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st - updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish) # Donations + Nothing says thank you as much as a donation. So if you feel the love, do feel free to become a iceman patron. For some tiers it comes with rewards. https://www.patreon.com/iceman1001 diff --git a/appveyor.yml b/appveyor.yml index 3b937c197..af725ef93 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -73,14 +73,77 @@ clone_script: Write-Host "[ OK ]" -ForegroundColor Green - Write-Host "Update msys2 packages..." -NoNewLine + Write-Host "Update msys2 packages..." $env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path" + + Function ExecUpdate($Name, $Cmd, $ErrorLine) { - C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1 + Write-Host "Exec [$Name]... " -NoNewLine + #--- begin Job + + $Job = Start-Job -Name "$Name" -ScriptBlock { + $env:Path = "C:\ProxSpace\msys\bin;$env:Path" + Set-Location $using:PWD - C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1 + $sb=[scriptblock]::Create("$using:Cmd") + #execute scriptblock + $Cond=&$sb + return $Cond + } + + #--- end Job + + $JobTime=[System.Environment]::TickCount + while($true) { + Try { + $Res = Receive-Job -Job $Job -Keep 2>&1 6>&1 + } + Catch { + $Res = "" + Write-host "error in Receive-Job" + } + + if ($Res -is "String" -and $Res -like "*$ErrorLine*"){ + Write-host "Exit by stop phrase" -ForegroundColor Green + break + } + + if ($Res -is [Object]){ + [bool]$needexit = $false + ForEach($line in $Res){ + if ($line -like "*$ErrorLine*"){ + Write-host "Exit by stop phrase [obj]" -ForegroundColor Green + $needexit = $true + break + } + } + if ($needexit) { + break + } + } + + if(Wait-Job $Job -Timeout 5){ + Write-host "Exit by end job" -ForegroundColor Green + break + } + + if ([System.Environment]::TickCount-$JobTime -gt 1000000) { + Write-host "Exit by timeout" -ForegroundColor Yellow + break + } + } + + Remove-Job -Force $Job + } + + ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" + + ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2" + + Write-Host "Update " -NoNewLine + Write-Host "[ OK ]" -ForegroundColor Green install: - ps: >- @@ -130,54 +193,38 @@ build_script: } - if(!(Test-Path C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z)){ + if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){ - throw "Files in hardnested\tables not exists." + throw "Files in client\resources\hardnested_tables is not exists." } - #copy + #install - Write-Host "Copy release files..." -NoNewLine -ForegroundColor Yellow + Write-Host "Installing..." -NoNewLine -ForegroundColor Yellow - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release + New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\pm3\client\*.exe C:\ProxSpace\Release + bash -c -i 'make install DESTDIR=Release PREFIX=' - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\arm - - Copy-Item C:\ProxSpace\pm3\armsrc\obj\*.elf C:\ProxSpace\Release\arm - - Copy-Item C:\ProxSpace\pm3\bootrom\obj\*.elf C:\ProxSpace\Release\arm - - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\scripts - - Copy-Item C:\ProxSpace\pm3\client\scripts\*.lua C:\ProxSpace\Release\scripts - - New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\hardnested\tables - - Copy-Item C:\ProxSpace\pm3\client\hardnested\*.bin C:\ProxSpace\Release\hardnested - - Copy-Item C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z C:\ProxSpace\Release\hardnested\tables - # dll files - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\pm3\Release\bin - Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\Release + Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\pm3\Release\bin Write-Host "[ OK ]" -ForegroundColor Green @@ -199,7 +246,7 @@ build_script: cd C:\ProxSpace - 7z a release.zip C:\ProxSpace\Release + 7z a release.zip C:\ProxSpace\pm3\Release Push-AppveyorArtifact release.zip -DeploymentName "$releasename" @@ -218,7 +265,7 @@ test_script: Function ExecTest($Name, $File, $Cmd, $CheckResult) { - + #--- begin Job $Job = Start-Job -ScriptBlock { @@ -256,6 +303,13 @@ test_script: if ($Cond -is "String" -and $Cond -like "*true*"){ $res= $true } + ForEach($line in $Cond){ + if ($line -like "*passed*"){ + $res = $true + $Cond = $line + break + } + } } Else { $res=$Cond } @@ -287,6 +341,7 @@ test_script: Remove-Job -Force $Job if(!$res){ + Write-host "--------------------- tests fail" -ForegroundColor Red $global:TestsPassed=$false } } @@ -297,30 +352,34 @@ test_script: #file test - ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\Release\proxmark3.exe} + ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\pm3\Release\bin\proxmark3.exe} - ExecTest "arm image exists" "\arm\fullimage1.elf" {Test-Path C:\ProxSpace\Release\arm\fullimage.elf} + ExecTest "arm bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\bootrom.elf} - ExecTest "bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\Release\arm\bootrom.elf} + ExecTest "arm image exists" "fullimage.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\fullimage.elf} - ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\Release\hardnested\tables\*.z} + ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin} + + ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z} ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip} #proxmark logic tests - ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q wait && echo Passed || echo Failed'} + ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h 2>&1 | grep -q wait && echo passed || echo failed'} - ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo Passed || echo Failed'} + ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo passed || echo failed'} - ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo Passed || echo Failed'} + ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo passed || echo failed'} ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc" ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" + ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok" + #proxmark crypto tests diff --git a/armsrc/Makefile b/armsrc/Makefile index 665c91005..f94868b6e 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -134,6 +134,13 @@ include ../common_arm/Makefile.common COMMON_FLAGS = -Os +INSTALLFW = $(OBJDIR)/fullimage.elf +ifneq (,$(FWTAG)) + INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf)) +else + INSTALLFWTAG = $(notdir $(INSTALLFW)) +endif + OBJS = $(OBJDIR)/fullimage.s19 FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress @@ -144,7 +151,7 @@ all: $(OBJS) # version.c should be remade on every time fullimage.stage1.elf should be remade version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [-] GEN $@) - $(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ + $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) $(info [-] GEN $@) @@ -203,17 +210,26 @@ tarbin: $(OBJS) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf) clean: - $(Q)$(DELETE) $(DEPENDENCY_FILES) - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19 - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.z - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.bin - $(Q)$(DELETE) version.c + $(Q)$(RM) $(DEPENDENCY_FILES) + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19 + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.z + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.bin + $(Q)$(RM) version.c -.PHONY: all clean help +install: all + $(info [@] Installing fullimage to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) + +uninstall: + $(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) + +.PHONY: all clean help install uninstall help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 5d3904794..f082dd117 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -1,6 +1,6 @@ # Default standalone if no standalone specified DEFAULT_STANDALONE=LF_SAMYRUN -HELP_EXAMPLE_STANDALONE=HF_COLIN +HELP_EXAMPLE_STANDALONE=HF_YOUNG # (you can set explicitly STANDALONE= to disable standalone modes) STANDALONE?=$(DEFAULT_STANDALONE) STANDALONE_REQ_DEFS= diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 6580af7fd..dc5c2e071 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -229,7 +229,7 @@ void RAMFUNC SniffAndStore(uint8_t param) { if (DBGLEVEL > 1) Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts); - SpinErr(0, 200, 5); // blink led A + SpinErr(LED_A, 200, 5); SpinDelay(100); } diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 265b7e3c9..6a0d9a19d 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -518,7 +518,7 @@ failtag: if (cjcuid == 0) { cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "%s>>%s BUG: 0000_CJCUID! Retrying...", _XRED_, _XWHITE_); - SpinErr(0, 100, 8); + SpinErr(LED_A, 100, 8); goto failtag; } @@ -636,7 +636,7 @@ failtag: cjTabulize(); DbprintfEx(FLAG_NEWLINE, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _XRED_, _XWHITE_); cjSetCursLeft(); - SpinErr(1, 100, 8); + SpinErr(LED_B, 100, 8); SpinOff(100); return; } @@ -672,7 +672,7 @@ failtag: cjSetCursLeft(); DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B"); - SpinErr(2, 100, 8); + SpinErr(LED_C, 100, 8); SpinOff(100); return; } @@ -778,7 +778,7 @@ readysim: DbprintfEx(FLAG_NEWLINE, "- [ LA FIN ] -\r\n%s`-> You can take shell back :) ...", _XWHITE_); cjSetCursLeft(); vtsend_set_attribute(NULL, 0); - SpinErr(3, 100, 16); + SpinErr(LED_D, 100, 16); SpinDown(75); SpinOff(100); return; diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 8228db512..f71fef393 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -24,131 +24,112 @@ void ModInfo(void) { } // samy's sniff and repeat routine for LF + +// LEDS. +// A , B == which bank (recording) +// FLASHING A, B = clone bank +// C = playing bank A +// D = playing bank B + void RunMod() { StandAloneMode(); - Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); uint32_t high[OPTS], low[OPTS]; int selected = 0; - int playing = 0; - int cardRead = 0; - bool gotCard; - // Turn on selected LED - LED(selected + 1, 0); + +#define STATE_READ 0 +#define STATE_SIM 1 +#define STATE_CLONE 2 + + uint8_t state = STATE_READ; for (;;) { + WDT_HIT(); // exit from SamyRun, send a usbcommand. if (data_available()) break; // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(1000); + int button_pressed = BUTTON_HELD(280); + if ( button_pressed != BUTTON_HOLD ) + continue; +/* +#define BUTTON_NO_CLICK 0 +#define BUTTON_SINGLE_CLICK -1 +#define BUTTON_DOUBLE_CLICK -2 +*/ - Dbprintf("button %d", button_pressed); - SpinDelay(300); + if ( state == STATE_READ ) { - // Button was held for a second, begin recording - if (button_pressed > 0 && cardRead == 0) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_D, 0); + if (selected == 0) { + LED_A_ON(); + LED_B_OFF(); + } else { + LED_B_ON(); + LED_A_OFF(); + } + + LED_C_OFF(); + LED_D_OFF(); + + WAIT_BUTTON_RELEASED(); // record DbpString("[=] starting recording"); - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); + // findone, high, low, no ledcontrol (A) + uint32_t hi = 0, lo = 0; + CmdHIDdemodFSK(1, &hi, &lo, 0); + high[selected] = hi; + low[selected] = lo; - /* need this delay to prevent catching some weird data */ - SpinDelay(500); + Dbprintf("[=] recorded bank %x | %x%08x", selected, high[selected], low[selected]); - CmdHIDdemodFSK(1, &high[selected], &low[selected], 0); - Dbprintf("[=] recorded bank %x | %x %08x", selected, high[selected], low[selected]); - - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - cardRead = 1; - - gotCard = true; - } else if (button_pressed > 0 && cardRead == 1) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_A, 0); - - // record - Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]); - - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - /* need this delay to prevent catching some weird data */ - SpinDelay(500); - - CopyHIDtoT55x7(0, high[selected], low[selected], 0); - Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]); - - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - cardRead = 0; - } - - // Change where to record (or begin playing) - else if (button_pressed && gotCard) { - // Next option if we were previously playing - if (playing) - selected = (selected + 1) % OPTS; - - playing = !playing; - - LEDsoff(); - LED(selected + 1, 0); - - // Begin transmitting - if (playing) { - - LED(LED_B, 0); - DbpString("[=] playing"); - - // wait for button to be released - while (BUTTON_PRESS()) - WDT_HIT(); - - Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]); - CmdHIDsimTAG(high[selected], low[selected], false); - DbpString("[=] done playing"); - - if (BUTTON_HELD(1000) > 0) - goto out; - - /* We pressed a button so ignore it here with a delay */ - SpinDelay(300); - - // when done, we're done playing, move to next option - selected = (selected + 1) % OPTS; - playing = !playing; - LEDsoff(); - LED(selected + 1, 0); - } else { - while (BUTTON_PRESS()) - WDT_HIT(); + // got nothing. blink and loop. + if ( hi == 0 && lo == 0 ) { + SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12); + Dbprintf("[=] recorded nothing, looping"); + continue; } + + SpinErr( (select==0) ? LED_A : LED_B, 250, 2); + state = STATE_SIM; + continue; + + } else if ( state == STATE_SIM ) { + + LED_C_ON(); // Simulate + LED_D_OFF(); + WAIT_BUTTON_RELEASED(); + + Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]); + + // high, low, no led control(A) no time limit + CmdHIDsimTAGEx(high[selected], low[selected], false, -1); + SpinErr( LED_C, 250, 2); + state = STATE_CLONE; + continue; + + } else if ( state == STATE_CLONE ) { + + LED_C_OFF(); + LED_D_ON(); // clone + WAIT_BUTTON_RELEASED(); + + Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]); + + // high2, high, low, no longFMT + CopyHIDtoT55x7(0, high[selected], low[selected], 0); + state = STATE_READ; + SpinErr( LED_D, 250, 2); + selected = (selected + 1) % OPTS; + LEDsoff(); } } -out: - DbpString("[=] exiting"); + DbpString("[=] exiting samyrun"); LEDsoff(); } diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b593c826b..6194cfe39 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -447,15 +447,12 @@ void SendCapabilities(void) { // Show some leds in a pattern to identify StandAlone mod is running void StandAloneMode(void) { - - DbpString("Stand-alone mode! No PC necessary."); - + DbpString("Stand-alone mode, no computer necessary"); SpinDown(50); - SpinOff(50); + SpinDelay(50); SpinUp(50); - SpinOff(50); + SpinDelay(50); SpinDown(50); - SpinDelay(500); } /* @@ -800,7 +797,12 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_LF_T55XX_WAKEUP: { - T55xxWakeUp(packet->oldarg[0], packet->oldarg[1]); + struct p { + uint32_t password; + uint8_t flags; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + T55xxWakeUp(payload->password, payload->flags); break; } case CMD_LF_T55XX_RESET_READ: { @@ -1134,7 +1136,8 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_EML_LOAD: { - MifareECardLoad(packet->oldarg[0], packet->oldarg[1]); + mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes; + MifareECardLoadExt(payload->sectorcnt, payload->keytype); break; } // Work with "magic Chinese" card @@ -1228,18 +1231,36 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_WRITEBL: { - iClass_WriteBlock(packet->oldarg[0], packet->data.asBytes); + struct p { + uint8_t blockno; + uint8_t data[12]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + iClass_WriteBlock(payload->blockno, payload->data); break; } + // iceman2019, unused? case CMD_HF_ICLASS_READCHECK: { // auth step 1 iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]); break; } case CMD_HF_ICLASS_READBL: { - iClass_ReadBlk(packet->oldarg[0]); +/* + struct p { + uint8_t blockno; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + */ + iClass_ReadBlk( packet->data.asBytes[0] ); break; } case CMD_HF_ICLASS_AUTH: { //check +/* + struct p { + uint8_t mac[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; +*/ iClass_Authentication(packet->data.asBytes); break; } @@ -1252,7 +1273,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_CLONE: { - iClass_Clone(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); + struct p { + uint8_t startblock; + uint8_t endblock; + uint8_t data[]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + iClass_Clone(payload->startblock, payload->endblock, payload->data); break; } #endif diff --git a/armsrc/frozen.c b/armsrc/frozen.c index 220f51d6c..a43300319 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -44,7 +44,7 @@ int cs_win_snprintf(char *str, size_t size, const char *format, ...); int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap); #if _MSC_VER >= 1700 -#include +#include "stdint.h" #else typedef _int64 int64_t; typedef unsigned _int64 uint64_t; diff --git a/armsrc/iclass.c b/armsrc/iclass.c index c8504e5ed..5bbcc1b4b 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -55,7 +55,11 @@ #include "protocols.h" #include "ticks.h" -static int timeout = 4096; +static int g_wait = 290; +static int timeout = 5000; +static uint32_t time_rdr = 0; +static uint32_t time_response = 0; + static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay); int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf); @@ -151,7 +155,7 @@ typedef struct { static tUartIc Uart; static void OnError(uint8_t reason) { - reply_old(CMD_ACK, 0, reason, 0, 0, 0); + reply_mix(CMD_ACK, 0, reason, 0, 0, 0); switch_off(); } @@ -160,10 +164,12 @@ static void uart_reset(void) { Uart.synced = false; Uart.frame = false; } + static void uart_init(uint8_t *data) { Uart.buf = data; uart_reset(); } + static void uart_bit(uint8_t bit) { static uint8_t buf = 0xff; static uint8_t n_buf; @@ -889,9 +895,7 @@ void RAMFUNC SniffIClass(void) { // time ZERO, the point from which it all is calculated. time_0 = GetCountSspClk(); - - int divi = 0; - uint8_t tag_byte = 0, foo = 0; + // loop and listen // every sample (1byte in data), // contains HIGH nibble = reader data @@ -902,12 +906,11 @@ void RAMFUNC SniffIClass(void) { for (;;) { WDT_HIT(); - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) break; checked = 0; - } else { - checked++; } + checked++; previous_data <<= 8; previous_data |= *data; @@ -921,14 +924,6 @@ void RAMFUNC SniffIClass(void) { AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE; } - if (*data & 0xF) { - //tag_byte <<= 1; - tag_byte ^= (1 << 4); - foo ^= (1 << (3 - divi)); - Dbprintf(" %d|%x == %d|%x", tag_byte, tag_byte, foo, foo); - } - divi++; - // every odd sample if (sniffCounter & 0x01) { // no need to try decoding reader data if the tag is sending @@ -958,8 +953,6 @@ void RAMFUNC SniffIClass(void) { LED_C_INV(); // LOW nibble is always tag data. /* - - uint32_t tag_byte = ((previous_data & 0x0F000000) >> 8 ) | ((previous_data & 0x000F0000) >> 4 ) | @@ -969,8 +962,8 @@ void RAMFUNC SniffIClass(void) { */ - //uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); - if (ManchesterDecoding_iclass(foo)) { + uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); + if (ManchesterDecoding_iclass(tag_byte)) { time_stop = GetCountSspClk() - time_0; LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); DemodIcReset(); @@ -980,17 +973,15 @@ void RAMFUNC SniffIClass(void) { } TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD); } - tag_byte = 0; - foo = 0; - divi = 0; } } // end main loop +/* if (DBGLEVEL >= 1) { DbpString("[+] Sniff statistics:"); Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false); } - +*/ switch_off(); } @@ -1023,12 +1014,11 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) WDT_HIT(); - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; - } else { - checked++; } + checked++; // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) @@ -1048,6 +1038,7 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) return false; } +/* static uint8_t encode4Bits(const uint8_t b) { // OTA, the least significant bits first // Manchester encoding added @@ -1094,6 +1085,9 @@ static uint8_t encode4Bits(const uint8_t b) { return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa } } +*/ + +static uint8_t lut_enc[] = { 0xAA, 0x6A, 0x9A, 0x5A, 0xA6, 0x66, 0x96, 0x56, 0xA9, 0x69, 0x99, 0x59, 0xA5, 0x65, 0x95, 0x55 }; //----------------------------------------------------------------------------- // Prepare tag messages @@ -1140,8 +1134,8 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { int i; for (i = 0; i < len; i++) { uint8_t b = cmd[i]; - ToSend[++ToSendMax] = encode4Bits(b & 0xF); // least significant half - ToSend[++ToSendMax] = encode4Bits((b >> 4) & 0xF); // most significant half + ToSend[++ToSendMax] = lut_enc[b & 0xF]; // least significant half + ToSend[++ToSendMax] = lut_enc[(b >> 4) & 0xF]; // most significant half } // Send EOF @@ -1427,9 +1421,9 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { uint32_t time_0 = GetCountSspClk(); uint32_t t2r_stime = 0, t2r_etime = 0; uint32_t r2t_stime, r2t_etime = 0; - LED_A_ON(); bool buttonPressed = false; + uint8_t cmd, options, block; while (!exitLoop) { WDT_HIT(); @@ -1450,7 +1444,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { LED_C_ON(); //Signal tracer - if (receivedCmd[0] == ICLASS_CMD_ACTALL) { // 0x0A + cmd = receivedCmd[0] & 0xF; + options = (receivedCmd[0] >> 4) & 0xFF; + block = receivedCmd[1]; + + if (cmd == ICLASS_CMD_ACTALL) { // 0x0A // Reader in anticollission phase modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1; @@ -1458,7 +1456,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data_size = sizeof(sof_data); // adjusted for 330 + (160*num of slot) goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C + } else if (cmd == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C if (len == 1) { // Reader asks for anticollission CSN modulated_response = resp_anticoll; @@ -1470,7 +1468,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { if (len == 4) { // block0,1,2,5 is always readable. - switch (receivedCmd[1]) { + switch (block) { case 0: // csn (0c 00) modulated_response = resp_csn; modulated_response_size = resp_csn_len; @@ -1503,7 +1501,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { if (simulationMode == MODE_FULLSIM) { // 0x0C //Read block //Take the data... - memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8); + memcpy(data_generic_trace, emulator + (block << 3), 8); AddCrc(data_generic_trace, 8); trace_data = data_generic_trace; trace_data_size = 10; @@ -1516,7 +1514,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { } }//swith }// if 4 - } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 + } else if (cmd == ICLASS_CMD_SELECT) { // 0x81 // Reader selects anticollission CSN. // Tag sends the corresponding real CSN modulated_response = resp_csn; @@ -1524,23 +1522,15 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { trace_data = csn_data; trace_data_size = sizeof(csn_data); goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88 - // Read e-purse (88 02) + } else if (cmd == ICLASS_CMD_READCHECK ) { // 0x88 + // Read e-purse KD (88 02) KC (18 02) modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; trace_data = card_challenge_data; trace_data_size = sizeof(card_challenge_data); LED_B_ON(); goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18 - // Read e-purse (18 02) - modulated_response = resp_cc; - modulated_response_size = resp_cc_len; //order = 4; - trace_data = card_challenge_data; - trace_data_size = sizeof(card_challenge_data); - LED_B_ON(); - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_CHECK) { // 0x05 + } else if (cmd == ICLASS_CMD_CHECK) { // 0x05 // Reader random and reader MAC!!! if (simulationMode == MODE_FULLSIM) { // NR, from reader, is in receivedCmd +1 @@ -1578,17 +1568,17 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { } } goto send; - } else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { + } else if (cmd == ICLASS_CMD_HALT && options == 0 && len == 1) { // Reader ends the session modulated_response = resp_sof; modulated_response_size = 0; //order = 0; trace_data = NULL; trace_data_size = 0; goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06 + } else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06 //Read block //Take the data... - memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4); + memcpy(data_generic_trace, emulator + (block << 3), 8 * 4); AddCrc(data_generic_trace, 8 * 4); trace_data = data_generic_trace; trace_data_size = 34; @@ -1596,7 +1586,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { memcpy(modulated_response, ToSend, ToSendMax); modulated_response_size = ToSendMax; goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { + } else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_UPDATE) { //Probably the reader wants to update the nonce. Let's just ignore that for now. // OBS! If this is implemented, don't forget to regenerate the cipher_state @@ -1640,7 +1630,7 @@ send: A legit tag has about 330us delay between reader EOT and tag SOF. **/ if (modulated_response_size > 0) { - t2r_stime = (GetCountSspClk() - time_0) << 4; + t2r_stime = GetCountSspClkDelta(time_0) << 4; SendIClassAnswer(modulated_response, modulated_response_size, 0); t2r_etime = ((GetCountSspClk() - time_0) << 4) - t2r_stime; } @@ -1676,12 +1666,12 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { uint16_t checked = 0; for (;;) { - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) return 0; checked = 0; - } else { - checked++; } + checked++; + // Prevent rx holding register from overflowing if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) { b = AT91C_BASE_SSC->SSC_RHR; @@ -1710,14 +1700,16 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { //----------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. //----------------------------------------------------------------------------- -static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) { +static void TransmitIClassCommand(const uint8_t *cmd, int len, int *wait) { int c = 0; - volatile uint32_t b; bool firstpart = true; uint8_t sendbyte; + time_rdr = 0; + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + AT91C_BASE_SSC->SSC_THR = 0x00; // make sure we timeout previous comms. @@ -1747,20 +1739,9 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int if (c >= len) break; } - - // Prevent rx holding register from overflowing - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = AT91C_BASE_SSC->SSC_RHR; - (void)b; - } } - if (samples) { - if (wait) - *samples = (c + *wait) << 3; - else - *samples = c << 3; - } + time_rdr = GetCountSspClk(); } //----------------------------------------------------------------------------- @@ -1804,17 +1785,12 @@ void CodeIClassCommand(const uint8_t *cmd, int len) { void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { - int samples = 0; - // This is tied to other size changes CodeIClassCommand(frame, len); // Select the card - TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); - if (trigger) - LED_A_ON(); - - rsamples += samples; + TransmitIClassCommand(ToSend, ToSendMax, &wait); + LED_A_ON(); LogTrace(frame, len, rsamples, rsamples, NULL, true); } @@ -1827,22 +1803,20 @@ void ReaderTransmitIClass(uint8_t *frame, int len) { // If a response is captured return TRUE // If it takes too long return FALSE //----------------------------------------------------------------------------- -static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed) { +static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) { // buffer needs to be 512 bytes // maxLen is not used... - - int c = 0; bool skip = false; + LED_D_ON(); + // Set FPGA mode to "reader listen mode", no modulation (listen + // only, since we are receiving, not transmitting). + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); + // Setup UART/DEMOD to receive DemodIcInit(receivedResponse); - if (elapsed) *elapsed = 0; - - // Set FPGA mode to "reader listen mode", no modulation (listen - // only, since we are receiving, not transmitting). - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); - SpinDelayUs(320); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. + SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -1850,38 +1824,28 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, uint16_t checked = 0; + uint32_t card_start = GetCountSspClk(); for (;;) { WDT_HIT(); - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || data_available()) return false; checked = 0; - } else { - checked++; - } - - // keep tx buffer in a defined state anyway. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; - // To make use of exact timing of next command from reader!! - if (elapsed)(*elapsed)++; } + checked++; // Wait for byte be become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - if (c >= timeout) return false; - - c++; b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - skip = !skip; if (skip) continue; if (ManchesterDecoding_iclass(b & 0x0f)) { - if (samples) - *samples = c << 3; + time_response = GetCountSspClk() - card_start; return true; + } else if (GetCountSspClkDelta(card_start) > timeout && Demod.state == DEMOD_IC_UNSYNCD) { + return false; } } } @@ -1889,18 +1853,11 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, } int ReaderReceiveIClass(uint8_t *receivedAnswer) { - int samples = 0; - if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL)) - return false; - - rsamples += samples; + if (GetIClassAnswer(receivedAnswer, 0, NULL) == false) + return 0; LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); - - if (samples == 0) - return false; - return Demod.len; } @@ -1924,25 +1881,34 @@ void setupIclassReader() { // Now give it time to spin up. // Signal field is on with the appropriate LED FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - SpinDelay(300); + SpinDelay(500); StartCountSspClk(); LED_A_ON(); } -bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, uint8_t retries) { +bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) { while (retries-- > 0) { ReaderTransmitIClass(command, cmdsize); //iceman - if received size is bigger than expected, we smash the stack here // since its called with fixed sized arrays + + // update/write command takes 4ms to 15ms before responding + int old_wait = g_wait; + if ( (command[0] & 0xF) == ICLASS_CMD_UPDATE) + g_wait = 3900; + uint8_t got_n = ReaderReceiveIClass(resp); + g_wait = old_wait; + // 0xBB is the internal debug separator byte.. if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { //try again +// SpinDelayUs(360); continue; } @@ -1964,26 +1930,30 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { // act_all... static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 }; - static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; + static uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; + // Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) willbe used + // bit 7: parity. + if (use_credit_key) - readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; + readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK; uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; - uint8_t read_status = 0; - // Send act_all - ReaderTransmitIClass_ext(act_all, 1, 330 + 160); + // Send act_all ( 330 timeout + 160 timeslot); + ReaderTransmitIClass_ext(act_all, 1, 330 + 180); + // Card present? - if (!ReaderReceiveIClass(resp)) return read_status;//Fail + if (ReaderReceiveIClass(resp) == 0) + return 0; //Send Identify ReaderTransmitIClass(identify, 1); //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC - uint8_t len = ReaderReceiveIClass(resp); - if (len != 10) return read_status;//Fail + if ( ReaderReceiveIClass(resp) != 10 ) + return 0; //Copy the Anti-collision CSN to our select-packet memcpy(&select[1], resp, 8); @@ -1992,31 +1962,33 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { ReaderTransmitIClass(select, sizeof(select)); //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC - len = ReaderReceiveIClass(resp); - if (len != 10) return read_status;//Fail + if ( ReaderReceiveIClass(resp) != 10) + return 0; - //Success - level 1, we got CSN - //Save CSN in response data - memcpy(card_data, resp, 8); - - //Flag that we got to at least stage 1, read CSN - read_status = 1; - - // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) + // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) // ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); // if (ReaderReceiveIClass(resp) == 8) { // //Save CC (e-purse) in response data // memcpy(card_data+8, resp, 8); // read_status++; // } + + //Success - level 1, we got CSN + //Save CSN in response data + memcpy(card_data, resp, 8); + + bool isBlk_2 = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); - bool isOK = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); - if (!isOK) return read_status; - + //Flag that we got to at least stage 1, read CSN + if ( isBlk_2 == false) { + return 1; + } + //Save CC (e-purse) in response data memcpy(card_data + 8, resp, 8); - read_status++; - return read_status; + + // we got all data; + return 2; } uint8_t handshakeIclassTag(uint8_t *card_data) { return handshakeIclassTag_ext(card_data, false); @@ -2057,7 +2029,7 @@ void ReaderIClass(uint8_t arg0) { WDT_HIT(); // if only looking for one card try 2 times if we missed it the first time - if (try_once && tryCnt > 2) { + if (try_once && tryCnt > 10) { if (DBGLEVEL > 1) DbpString("Failed to find a tag"); break; } @@ -2140,7 +2112,7 @@ void ReaderIClass(uint8_t arg0) { if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SEND %c", send ? 'y' : 'n'); if (send) { - reply_old(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data)); + reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data)); if (abort_after_read) { LED_B_OFF(); return; @@ -2151,19 +2123,18 @@ void ReaderIClass(uint8_t arg0) { } LED_B_OFF(); - if (checked == 1000) { + if (checked == 2000) { userCancelled = BUTTON_PRESS() || data_available(); checked = 0; - } else { - checked++; } + checked++; } if (userCancelled) { - reply_old(CMD_ACK, 0xFF, 0, 0, card_data, 0); + reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0); switch_off(); } else { - reply_old(CMD_ACK, 0, 0, 0, card_data, 0); + reply_mix(CMD_ACK, 0, 0, 0, card_data, 0); } } @@ -2311,8 +2282,8 @@ void iClass_Authentication(uint8_t *mac) { //memcpy(check+5, mac, 4); // 6 retries - bool isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); - reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); + uint8_t isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); + reply_ng(CMD_HF_ICLASS_AUTH, PM3_SUCCESS, (uint8_t*)&isOK ,sizeof(uint8_t)); } typedef struct iclass_premac { @@ -2333,10 +2304,10 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t keyCount = arg1 & 0xFF; uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t resp[ICLASS_BUFFER_SIZE]; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; + uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; if (use_credit_key) - readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; + readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK; // select card / e-purse uint8_t card_data[6 * 8] = {0}; @@ -2355,12 +2326,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { uint8_t startup_limit = 10; while (read_status != 2) { - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; - } else { - checked++; } + checked++; read_status = handshakeIclassTag_ext(card_data, use_credit_key); if (startup_limit-- == 0) { @@ -2371,16 +2341,17 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { }; // since handshakeIclassTag_ext call sends s readcheck, we start with sending first response. + checked = 0; + // Keychunk loop for (i = 0; i < keyCount; i++) { // Allow button press / usb cmd to interrupt device - if (checked == 1000) { + if (checked == 2000) { if (BUTTON_PRESS() || !data_available()) goto out; checked = 0; - } else { - checked++; } + checked++; WDT_HIT(); LED_B_ON(); @@ -2396,8 +2367,6 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { if (isOK) goto out; - SpinDelayUs(400); //iClass (iso15693-2) should timeout after 330us. - // Auth Sequence MUST begin with reading e-purse. (block2) // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); @@ -2433,10 +2402,14 @@ bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len) { // turn off afterwards // readblock 8 + 2. only want 8. void iClass_ReadBlk(uint8_t blockno) { - uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - bool isOK = iClass_ReadBlock(blockno, data, sizeof(data)); - reply_mix(CMD_ACK, isOK, 0, 0, data, sizeof(data)); + struct p { + bool isOK; + uint8_t blockdata[8]; + } PACKED result; + + result.isOK = iClass_ReadBlock(blockno, result.blockdata, sizeof(result.blockdata)); switch_off(); + reply_ng(CMD_HF_ICLASS_READBL, PM3_SUCCESS, (uint8_t *)&result, sizeof(result)); } // turn off afterwards @@ -2448,7 +2421,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { BigBuf_free(); uint8_t *dataout = BigBuf_malloc(255 * 8); if (dataout == NULL) { - DbpString("[!] out of memory"); + DbpString("[!] fail to allocate memory"); OnError(1); return; } @@ -2468,39 +2441,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { } memcpy(dataout + (blkCnt * 8), blockdata, 8); } + + switch_off(); //return pointer to dump memory in arg3 reply_mix(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0); - switch_off(); BigBuf_free(); } bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { - uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t write[] = { ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t write[] = { 0x80 | ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(write + 2, data, 12); // data + mac AddCrc(write + 1, 13); - - bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); - if (isOK) { //if reader responded correctly - - //if response is not equal to write values - if (memcmp(write + 2, resp, 8)) { - - //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data) - if (blockno != 3 && blockno != 4) { - isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); - } - } - } - return isOK; + return sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); } // turn off afterwards void iClass_WriteBlock(uint8_t blockno, uint8_t *data) { - bool isOK = iClass_WriteBlock_ext(blockno, data); - reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); + uint8_t isOK = iClass_WriteBlock_ext(blockno, data); switch_off(); + reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t*)&isOK, sizeof(uint8_t)); } // turn off afterwards @@ -2509,23 +2469,19 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) { int total_block = (endblock - startblock) + 1; for (i = 0; i < total_block; i++) { // block number - if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) { - Dbprintf("Write block [%02x] successful", i + startblock); + if (iClass_WriteBlock_ext(startblock + i, data + (i * 12))) { + Dbprintf("Write block [%02x] successful", startblock + i); written++; } else { - if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) { - Dbprintf("Write block [%02x] successful", i + startblock); - written++; - } else { - Dbprintf("Write block [%02x] failed", i + startblock); - } + Dbprintf("Write block [%02x] failed", startblock + i); } } - if (written == total_block) - DbpString("Clone complete"); - else - DbpString("Clone incomplete"); - reply_mix(CMD_ACK, 1, 0, 0, 0, 0); switch_off(); + + uint8_t isOK = 0; + if (written == total_block) + isOK = 1; + + reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t)); } diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 786db50dc..794ead3c5 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1672,26 +1672,11 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing // clear TXRDY AT91C_BASE_SSC->SSC_THR = SEC_Y; - volatile uint8_t b; uint16_t c = 0; - uint32_t sendtimer = GetTickCount(); - uint32_t cntr = 0; while (c < len) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = cmd[c++]; - cntr = 0; - } else { - if (cntr++ > 1000) { - cntr = 0; - if (GetTickCount() - sendtimer > 100) - break; - } - } - - //iceman test - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); - (void)b; + AT91C_BASE_SSC->SSC_THR = cmd[c]; + c++; } } diff --git a/armsrc/lfops.c b/armsrc/lfops.c index bee1413fc..e5204a5a5 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -941,7 +941,7 @@ static void fcSTT(int *n) { } // compose fc/X fc/Y waveform (FSKx) -static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { +static uint8_t fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { uint8_t *dest = BigBuf_get_addr(); uint8_t halfFC = fc >> 1; uint8_t wavesPerClock = clock / fc; @@ -966,12 +966,15 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { *n += fc; } } +/* This code interfers with FSK2 and I don't see any example of FSK1 simulation in the code... if (!modAdjOk) { //fsk1 memset(dest + (*n), 0, mod - (mod >> 1)); memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1); *n += mod; } +*/ } + return mod; } // prepare a waveform pattern in the buffer based on the ID given then @@ -1059,17 +1062,17 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, int n = 0, i = 0; uint16_t modCnt = 0; + uint8_t mod = 0; if (separator) { //int fsktype = ( fchigh == 8 && fclow == 5) ? 1 : 2; //fcSTT(&n); } - for (i = 0; i < bitslen; i++) { if (bits[i]) - fcAll(fclow, &n, clk, &modCnt); + mod = fcAll(fchigh, &n, clk+mod, &modCnt); else - fcAll(fchigh, &n, clk, &modCnt); + mod = fcAll(fclow, &n, clk+mod, &modCnt); } WDT_HIT(); @@ -1306,7 +1309,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) hi2 = hi = lo = idx = 0; } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); + DbpString("HID fsk demod stopped"); if (ledcontrol) LED_A_OFF(); } @@ -2060,6 +2063,7 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) { //-- Turn and leave field on to let the begin repeating transmission TurnReadLFOn(20 * 1000); + reply_ng(CMD_LF_T55XX_WAKEUP, PM3_SUCCESS, NULL, 0); } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 5e9de52dd..e8cce812f 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1342,8 +1342,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da for (uint16_t i = s_point; i < keyCount; ++i) { - //if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point); - // Allow button press / usb cmd to interrupt device if (BUTTON_PRESS() && !data_available()) { goto OUT; @@ -1525,6 +1523,33 @@ OUT: FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); BigBuf_free(); BigBuf_Clear_ext(false); + + // special trick ecfill + if (use_flashmem && foundkeys == allkeys) { + + uint8_t block[16] = {0}; + for (int i = 0; i < sectorcnt; i++) { + + uint8_t blockno; + if (i < 32) { + blockno = (i * 4) ^ 0x3; + } else { + blockno = (32 * 4 + (i - 32) * 16) ^ 0xF; + } + // get ST + emlGetMem(block, blockno, 1); + + memcpy(block, k_sector[i].keyA, 6); + memcpy(block + 10, k_sector[i].keyB, 6); + + emlSetMem_xt(block, blockno, 1, sizeof(block)); + } + int oldbg = DBGLEVEL; + DBGLEVEL = DBG_NONE; + MifareECardLoad(sectorcnt, 0); + MifareECardLoad(sectorcnt, 1); + DBGLEVEL = oldbg; + } } else { // partial/none keys found reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0); @@ -1669,10 +1694,15 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) { // Load a card into the emulator memory // //----------------------------------------------------------------------------- -int MifareECardLoad(uint32_t arg0, uint32_t arg1) { +int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType) { + int retval = MifareECardLoad(numSectors, keyType); + reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0); + return retval; +} + +int MifareECardLoad(uint8_t numSectors, uint8_t keyType) { + uint32_t cuid = 0; - uint8_t numSectors = arg0; - uint8_t keyType = arg1; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; @@ -1683,68 +1713,63 @@ int MifareECardLoad(uint32_t arg0, uint32_t arg1) { uint8_t uid[10] = {0x00}; LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); clear_trace(); set_tracing(true); - bool isOK = true; + int retval; if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - isOK = false; - if (DBGLEVEL >= 1) Dbprintf("Can't select card"); + retval = PM3_ESOFT; + if (DBGLEVEL > DBG_ERROR) Dbprintf("Can't select card"); + goto out; } - for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { + for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) { uint64_t ui64Key = emlGetKey(sectorNo, keyType); if (sectorNo == 0) { - if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { - if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo); + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { + if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); break; } } else { - if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) { - isOK = false; - if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); - break; + if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) { + retval = PM3_ESOFT; + if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo); + goto out; } } - for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { - if (isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { - isOK = false; - if (DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); + for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { + if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) { + retval = PM3_ESOFT; + if (DBGLEVEL > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo); break; } - if (isOK) { - if (blockNo < NumBlocksPerSector(sectorNo) - 1) { - emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); - } else { // sector trailer, keep the keys, set only the AC - emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); - memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); - emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); - } + if (blockNo < NumBlocksPerSector(sectorNo) - 1) { + emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); + } else { // sector trailer, keep the keys, set only the AC + emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); + memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); + emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); } } - } - if (mifare_classic_halt(pcs, cuid)) - if (DBGLEVEL >= 1) + if (mifare_classic_halt(pcs, cuid)) { + if (DBGLEVEL > DBG_ERROR) Dbprintf("Halt error"); + } - // ----------------------------- crypto1 destroy + if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); + +out: crypto1_destroy(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - - if (DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED"); - set_tracing(false); - return (isOK) ? PM3_SUCCESS : PM3_EUNDEF; + return retval; } @@ -1955,6 +1980,8 @@ void MifareCIdent() { #define GEN_1A 1 #define GEN_1B 2 #define GEN_2 4 +#define GEN_UNFUSED 5 + // variables uint8_t isGen = 0; uint8_t rec[1] = {0x00}; @@ -1970,19 +1997,19 @@ void MifareCIdent() { // Generation 1 test ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - goto TEST2; - }; + + if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - isGen = GEN_1B; - goto OUT; - }; - isGen = GEN_1A; - goto OUT; + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + + if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { + isGen = GEN_1B; + goto OUT; + }; + isGen = GEN_1A; + goto OUT; + } -TEST2: // reset card FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(100); @@ -1990,6 +2017,12 @@ TEST2: int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { + Dbprintf("cident AA55C396 == %08X", cuid); + if (cuid == 0xAA55C396) { + isGen = GEN_UNFUSED; + goto OUT; + } + ReaderTransmit(rats, sizeof(rats), NULL); res = ReaderReceive(buf, par); if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) { diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 445b04130..d563e37a8 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -31,7 +31,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da void MifareEMemClr(void); void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain); void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); -int MifareECardLoad(uint32_t arg0, uint32_t arg1); +int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype); +int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType); void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index 4894bf6bc..0f762a8d6 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -60,11 +60,59 @@ -- MHS 2015 **/ +/** + + The runtime of opt_doTagMAC_2() with the MHS optimized version was 403 microseconds on Proxmark3. + This was still to slow for some newer readers which didn't want to wait that long. + + Further optimizations to speedup the MAC calculations: + * Optimized opt_Tt logic + * Look up table for opt_select + * Removing many unnecessary bit maskings (& 0x1) + * updating state in place instead of alternating use of a second state structure + * remove the necessity to reverse bits of input and output bytes + + opt_doTagMAC_2() now completes in 270 microseconds. + + -- piwi 2019 +**/ + #include "optimized_cipher.h" -#define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14)^ (s->t >> 10)^ (s->t >> 8)^ (s->t >> 5)^ (s->t >> 4)^ (s->t >> 1)^ s->t)) +static const uint8_t opt_select_LUT[256] = { + 00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04, + 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, + 06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06, + 07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06, + 06, 05, 04, 07, 04, 05, 06, 07, 02, 01, 01, 02, 00, 01, 03, 02, + 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, + 00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00, + 05, 06, 07, 04, 06, 07, 04, 05, 05, 06, 06, 05, 06, 07, 05, 04, + 02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06, + 03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06, + 02, 01, 00, 03, 00, 01, 02, 03, 02, 01, 01, 02, 00, 01, 03, 02, + 03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02, + 04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00, + 01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04, + 04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04, + 01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00 +}; -#define opt_B(s) (((s->b >> 6) ^ (s->b >> 5) ^ (s->b >> 4) ^ (s->b)) & 0x1) +/********************** the table above has been generated with this code: ******** +#include "util.h" +static void init_opt_select_LUT(void) { + for (int r = 0; r < 256; r++) { + uint8_t r_ls2 = r << 2; + uint8_t r_and_ls2 = r & r_ls2; + uint8_t r_or_ls2 = r | r_ls2; + uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); + uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r; + uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r; + opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1); + } + print_result("", opt_select_LUT, 256); +} +***********************************************************************************/ #define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\ |(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\ @@ -74,9 +122,6 @@ * Some background on the expression above can be found here... uint8_t xopt__select(bool x, bool y, uint8_t r) { - uint8_t r_ls2 = r << 2; - uint8_t r_and_ls2 = r & r_ls2; - uint8_t r_or_ls2 = r | r_ls2; //r: r0 r1 r2 r3 r4 r5 r6 r7 //r_ls2: r2 r3 r4 r5 r6 r7 0 0 @@ -96,82 +141,95 @@ uint8_t xopt__select(bool x, bool y, uint8_t r) } */ -void opt_successor(const uint8_t *k, State *s, bool y, State *successor) { - uint8_t Tt = 1 & opt_T(s); +static void opt_successor(const uint8_t *k, State *s, uint8_t y) { +// #define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14) ^ (s->t >> 10) ^ (s->t >> 8) ^ (s->t >> 5) ^ (s->t >> 4)^ (s->t >> 1) ^ s->t)) + // uint8_t Tt = opt_T(s); + uint16_t Tt = s->t & 0xc533; + Tt = Tt ^ (Tt >> 1); + Tt = Tt ^ (Tt >> 4); + Tt = Tt ^ (Tt >> 10); + Tt = Tt ^ (Tt >> 8); - successor->t = (s->t >> 1); - successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15; + s->t = (s->t >> 1); + s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15; - successor->b = s->b >> 1; - successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7; + uint8_t opt_B = s->b; + opt_B ^= s->b >> 6; + opt_B ^= s->b >> 5; + opt_B ^= s->b >> 4; - successor->r = (k[opt__select(Tt, y, s->r)] ^ successor->b) + s->l ; - successor->l = successor->r + s->r; + s->b = s->b >> 1; + s->b |= (opt_B ^ s->r) << 7; + + uint8_t opt_select = opt_select_LUT[s->r] & 0x04; + opt_select |= (opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02; + opt_select |= (opt_select_LUT[s->r] ^ Tt) & 0x01; + + uint8_t r = s->r; + s->r = (k[opt_select] ^ s->b) + s->l ; + s->l = s->r + r; } -void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) { - State x2; +static void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) { for (int i = 0; i < length; i++) { uint8_t head; - head = 1 & (in[i] >> 7); - opt_successor(k, s, head, &x2); + head = in[i]; + opt_successor(k, s, head); - head = 1 & (in[i] >> 6); - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 5); - opt_successor(k, s, head, &x2); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 4); - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 3); - opt_successor(k, s, head, &x2); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 2); - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); - head = 1 & (in[i] >> 1); - opt_successor(k, s, head, &x2); + head >>= 1; + opt_successor(k, s, head); - head = 1 & in[i]; - opt_successor(k, &x2, head, s); + head >>= 1; + opt_successor(k, s, head); } - //For tag MAC, an additional 32 zeroes if (add32Zeroes) { for (int i = 0; i < 16; i++) { - opt_successor(k, s, 0, &x2); - opt_successor(k, &x2, 0, s); + opt_successor(k, s, 0); + opt_successor(k, s, 0); } } } -void opt_output(const uint8_t *k, State *s, uint8_t *buffer) { - State temp = {0, 0, 0, 0}; +static void opt_output(const uint8_t *k, State *s, uint8_t *buffer) { for (uint8_t times = 0; times < 4; times++) { uint8_t bout = 0; - bout |= (s->r & 0x4) << 5; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) << 4; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) << 3; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) << 2; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) << 1; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) ; - opt_successor(k, &temp, 0, s); + bout |= (s->r & 0x4) >> 2; + opt_successor(k, s, 0); bout |= (s->r & 0x4) >> 1; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) >> 2; - opt_successor(k, &temp, 0, s); + opt_successor(k, s, 0); + bout |= (s->r & 0x4); + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 1; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 2; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 3; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 4; + opt_successor(k, s, 0); + bout |= (s->r & 0x4) << 5; + opt_successor(k, s, 0); buffer[times] = bout; } } -void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { +static void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { State _init = { ((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((k[0] ^ 0x4c) + 0x21) & 0xFF,// r @@ -183,45 +241,25 @@ void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) { opt_output(k, &_init, out); } -uint8_t rev_byte(uint8_t b) { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - return b; -} - -void opt_reverse_arraybytecpy(uint8_t *dest, uint8_t *src, size_t len) { - uint8_t i; - for (i = 0; i < len ; i++) - dest[i] = rev_byte(src[i]); -} - void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { - static uint8_t cc_nr[12]; - opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12); uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0}; - opt_MAC(div_key_p, cc_nr, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); + opt_MAC(div_key_p, cc_nr_p, dest); + memcpy(mac, dest, 4); return; } + void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { - static uint8_t cc_nr[8 + 4 + 4]; - opt_reverse_arraybytecpy(cc_nr, cc_p, 12); State _init = { ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r 0x4c, // b 0xE012 // t }; - opt_suc(div_key_p, &_init, cc_nr, 12, true); - uint8_t dest [] = {0, 0, 0, 0}; - opt_output(div_key_p, &_init, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); + opt_suc(div_key_p, &_init, cc_p, 12, true); + opt_output(div_key_p, &_init, mac); return; - } + /** * The tag MAC can be divided (both can, but no point in dividing the reader mac) into * two functions, since the first 8 bytes are known, we can pre-calculate the state @@ -231,17 +269,16 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { * @return the cipher state */ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { - static uint8_t cc_nr[8]; - opt_reverse_arraybytecpy(cc_nr, cc_p, 8); State _init = { ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r 0x4c, // b 0xE012 // t }; - opt_suc(div_key_p, &_init, cc_nr, 8, false); + opt_suc(div_key_p, &_init, cc_p, 8, false); return _init; } + /** * The second part of the tag MAC calculation, since the CC is already calculated into the state, * this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag @@ -252,13 +289,7 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { * @param div_key_p - the key to use */ void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p) { - static uint8_t _nr[4]; - opt_reverse_arraybytecpy(_nr, nr, 4); - opt_suc(div_key_p, &_init, _nr, 4, true); - - uint8_t dest [] = {0, 0, 0, 0}; - opt_output(div_key_p, &_init, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); + opt_suc(div_key_p, &_init, nr, 4, true); + opt_output(div_key_p, &_init, mac); return; } diff --git a/armsrc/optimized_cipher.h b/armsrc/optimized_cipher.h index 893297ddd..c6df25ab8 100644 --- a/armsrc/optimized_cipher.h +++ b/armsrc/optimized_cipher.h @@ -2,7 +2,7 @@ #define OPTIMIZED_CIPHER_H #include "common.h" - +#include "string.h" /** * Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2 * consisting of the following four components: diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 2c679b31f..1690c6ad3 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -94,7 +94,10 @@ size_t DemodPCF7931(uint8_t **outBlocks) { } else { // Error if (++warnings > 10) { - Dbprintf("Error: too many detection errors, aborting."); + + if ( DBGLEVEL >= DBG_EXTENDED ) + Dbprintf("Error: too many detection errors, aborting."); + return 0; } } @@ -135,27 +138,38 @@ bool IsBlock0PCF7931(uint8_t *block) { // assuming all RFU bits are set to 0 // if PAC is enabled password is set to 0 if (block[7] == 0x01) { - if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) + && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { return true; + } } else if (block[7] == 0x00) { - if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) { return true; + } } return false; } bool IsBlock1PCF7931(uint8_t *block) { // assuming all RFU bits are set to 0 - if (block[10] == 0 - && block[11] == 0 - && block[12] == 0 - && block[13] == 0) { - if ((block[14] & 0x7f) <= 9 - && block[15] <= 9) { + uint8_t rb1 = block[14] & 0x80; + uint8_t rfb = block[14] & 0x7f; + uint8_t rlb = block[15]; + + if (block[10] == 0 + && block[11] == 0 + && block[12] == 0 + && block[13] == 0) { + // block 1 is sent only if (RLB >= 1 && RFB <= 1) or RB1 enabled + if (rfb <= rlb + && rfb <= 9 + && rlb <= 9 + && ((rfb <= 1 && rlb >= 1) || rb1)) { return true; } } + return false; } @@ -188,21 +202,28 @@ void ReadPCF7931() { // exit if no block is received if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { - Dbprintf("Error, no tag or bad tag"); + + if ( DBGLEVEL >= DBG_INFO ) + Dbprintf("[!!] Error, no tag or bad tag"); + return; } // exit if too many errors during reading if (tries > 50 && (2 * errors > tries)) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); + + if ( DBGLEVEL >= DBG_INFO ) + Dbprintf("[!!] Error reading the tag, only partial content"); + goto end; } // our logic breaks if we don't get at least two blocks if (n < 2) { + // skip if all 0s block or no blocks if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) continue; + // add block to single blocks list if (single_blocks_cnt < max_blocks) { for (i = 0; i < single_blocks_cnt; ++i) { if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) { @@ -212,6 +233,7 @@ void ReadPCF7931() { } if (j != 1) { memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16); + print_result("got single block", single_blocks[single_blocks_cnt], 16); single_blocks_cnt++; } j = 0; @@ -220,7 +242,12 @@ void ReadPCF7931() { continue; } - Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + if ( DBGLEVEL >= DBG_EXTENDED ) + Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + + for (i = 0; i < n; ++i) { + print_result("got consecutive blocks", tmp_blocks[i], 16); + } i = 0; if (!found_0_1) { @@ -279,10 +306,12 @@ void ReadPCF7931() { } ++tries; if (BUTTON_PRESS()) { - Dbprintf("Button pressed, stopping."); + if ( DBGLEVEL >= DBG_EXTENDED) + Dbprintf("Button pressed, stopping."); + goto end; } - } while (found_blocks != max_blocks); + } while (found_blocks < max_blocks); end: Dbprintf("-----------------------------------------"); @@ -305,7 +334,7 @@ end: Dbprintf("-----------------------------------------"); } - reply_old(CMD_ACK, 0, 0, 0, 0, 0); + reply_mix(CMD_ACK, 0, 0, 0, 0, 0); } static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { @@ -391,8 +420,12 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 @param data : data to write */ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { - Dbprintf("Initialization delay : %d us", init_delay); - Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + + if ( DBGLEVEL >= DBG_INFO ) { + Dbprintf("Initialization delay : %d us", init_delay); + Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + } + Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); Dbprintf("Block address : %02x", address); Dbprintf("Byte address : %02x", byte); @@ -411,8 +444,10 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui void SendCmdPCF7931(uint32_t *tab) { uint16_t u = 0, tempo = 0; - Dbprintf("Sending data frame..."); - + if ( DBGLEVEL >= DBG_INFO ) { + Dbprintf("Sending data frame..."); + } + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); @@ -454,7 +489,6 @@ void SendCmdPCF7931(uint32_t *tab) { SpinDelay(200); AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - LED(0xFFFF, 1000); } @@ -468,13 +502,13 @@ bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) { uint32_t u; for (u = 0; u < 8; ++u) { if (byte & (1 << u)) { //bit is 1 - if (AddBitPCF7931(1, tab, l, p) == 1) return 1; + if (AddBitPCF7931(1, tab, l, p) == 1) return true; } else { //bit is 0 - if (AddBitPCF7931(0, tab, l, p) == 1) return 1; + if (AddBitPCF7931(0, tab, l, p) == 1) return true; } } - return 0; + return false; } /* Add a bits for building the data frame of PCF7931 tags @@ -487,7 +521,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { uint8_t u = 0; //we put the cursor at the last value of the array - for (u = 0; tab[u] != 0; u += 3) { } + for (u = 0; tab[u] != 0; u += 3) { }; if (b == 1) { //add a bit 1 if (u == 0) @@ -497,7 +531,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { tab[u + 1] = 6 * T0_PCF + tab[u] + l; tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p; - return 0; + return false; } else { //add a bit 0 if (u == 0) @@ -507,9 +541,9 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) { tab[u + 1] = 6 * T0_PCF + tab[u] + l; tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p; - return 0; + return false; } - return 1; + return true; } /* Add a custom pattern in the data frame @@ -526,5 +560,5 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) { tab[u + 1] = b + tab[u]; tab[u + 2] = c + tab[u + 1]; - return 0; + return true; } diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index cb4412264..0296b7620 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -96,9 +96,9 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { //////////////////////////////////////////////////////////////////////////////// ////// SPIFFS LOW LEVEL OPERATIONS ///////////////////////////////////////////// -static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ]; -static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ]; -static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ]; +static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ] __attribute__((aligned)); +static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ] __attribute__((aligned)); +static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ] __attribute__((aligned)); static spiffs fs; diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 43555b21b..1510de490 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -185,6 +185,13 @@ uint32_t RAMFUNC GetCountSspClk(void) { return tmp_count; } +uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) { + uint32_t stop = GetCountSspClk(); + if ( stop >= start ) + return stop - start; + return (UINT32_MAX - start) + stop; +} + // ------------------------------------------------------------------------- // Timer for bitbanging, or LF stuff when you need a very precis timer // 1us = 1.5ticks diff --git a/armsrc/ticks.h b/armsrc/ticks.h index 089501c87..e036e018c 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -33,6 +33,7 @@ void SpinDelayCountUs(uint32_t us); void StartCountSspClk(); void ResetSspClk(void); uint32_t RAMFUNC GetCountSspClk(); +uint32_t RAMFUNC GetCountSspClkDelta(); void StartTicks(void); uint32_t GetTicks(void); diff --git a/armsrc/util.c b/armsrc/util.c index b855ab949..888c64b9d 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -90,6 +90,7 @@ void LEDsoff() { LED_D_OFF(); } +//ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8 void LED(int led, int ms) { if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE LED_A_ON(); @@ -123,26 +124,27 @@ void SpinOff(uint32_t pause) { SpinDelay(pause); } -// 0=A, 1=B, 2=C, 3=D +// Blinks.. +// A = 1, B = 2, C = 4, D = 8 void SpinErr(uint8_t led, uint32_t speed, uint8_t times) { SpinOff(speed); NTIME(times) { - switch (led) { - case 0: - LED_A_INV(); - break; - case 1: - LED_B_INV(); - break; - case 2: - LED_C_INV(); - break; - case 3: - LED_D_INV(); - break; - } + + if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE + LED_A_INV(); + if (led & LED_B) // Proxmark3 historical mapping: LED_GREEN + LED_B_INV(); + if (led & LED_C) // Proxmark3 historical mapping: LED_RED + LED_C_INV(); + if (led & LED_D) // Proxmark3 historical mapping: LED_RED2 + LED_D_INV(); + SpinDelay(speed); } + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + LED_D_OFF(); } void SpinDown(uint32_t speed) { diff --git a/bootrom/Makefile b/bootrom/Makefile index c4103b522..d666f3acd 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -31,12 +31,14 @@ APP_CFLAGS += -fno-stack-protector -fno-pie # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common_arm/Makefile.common +INSTALLFW = $(OBJDIR)/bootrom.elf + OBJS = $(OBJDIR)/bootrom.s19 # version.c should be remade on every compilation version.c: default_version.c $(info [=] GEN $@) - $(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ + $(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ all: $(OBJS) @@ -49,14 +51,23 @@ $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ) $(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) clean: - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19 - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map - $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d - $(Q)$(DELETE) version.c + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19 + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map + $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d + $(Q)$(RM) version.c -.PHONY: all clean help +install: all + $(info [@] Installing bootrom to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + +uninstall: + $(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) + +.PHONY: all clean help install help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: diff --git a/client/Makefile b/client/Makefile index 89f8cfb44..6fee6eae8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -9,35 +9,20 @@ # Add -DNOFORCE to disable the -F switch # Add -DPRESETS to compile with preset models (edit config.h) -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +# Must be called before any Makefile include +ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) -CC = gcc -CXX = g++ -LD = g++ -TAR = tar -TARFLAGS = -C .. --ignore-failed-read -rvf -RM = rm -f -MV = mv -TOUCH = touch -FALSE = false +include ../Makefile.defs -ENV_LDFLAGS := $(LDFLAGS) -ENV_CFLAGS := $(CFLAGS) +INSTALLBIN = proxmark3 +INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries -platform = $(shell uname) - -VPATH = ../common ../common/zlib uart +VPATH = ../common uart +vpath %.dic dictionaries OBJDIR = obj -LDLIBS = -ifneq ($(platform),Darwin) - LDLIBS += -L/opt/local/lib -endif -LDLIBS += -L/usr/local/lib -lreadline -lpthread -lm +LDLIBS ?= -L/usr/local/lib +LDLIBS += -lreadline -lpthread -lm # RPi Zero gcc requires -latomic # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld @@ -46,23 +31,35 @@ ifneq ($(platform),Darwin) LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed endif +# local libraries LUALIBPATH = ./liblua LUALIB = $(LUALIBPATH)/liblua.a JANSSONLIBPATH = ./jansson JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a -MBEDTLSLIBPATH = ../common/mbedtls -MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a CBORLIBPATH = ./tinycbor CBORLIB = $(CBORLIBPATH)/tinycbor.a -REVENGFLAGS = -DPRESETS -LIBS = -I../common/zlib -Iuart -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -INCLUDES_CLIENT = -I. -I../include -I../common -I/opt/local/include $(LIBS) -LDFLAGS = $(ENV_LDFLAGS) -CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) -Wall -Werror -g -O3 +REVENGPATH = ./reveng +REVENGLIB = $(REVENGPATH)/libreveng.a +AMIIBOLIBPATH = ./amiitool +AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a + +# common libraries +MBEDTLSLIBPATH = ../common/mbedtls +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. -I../include -I../common -Iuart $(LIBS) +CFLAGS ?= -Wall -Werror -g -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) +PREFIX ?= /usr/local ifneq (,$(findstring MINGW,$(platform))) - CFLAGS += -mno-ms-bitfields + PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850 endif -CXXFLAGS = -I../include -Wall -O3 +CXXFLAGS ?= -Wall -Werror -O3 +PM3CXXFLAGS = $(CXXFLAGS) -I../include LUAPLATFORM = generic ifneq (,$(findstring MINGW,$(platform))) @@ -76,7 +73,6 @@ else LIBS := -I/usr/local/opt/readline/include $(LIBS) else LUALIB += -ldl - LDLIBS += -ltermcap -lncurses LUAPLATFORM = linux endif endif @@ -93,7 +89,7 @@ ifeq ($(QTINCLUDES), ) MOC = $(shell pkg-config --variable=moc_location QtCore) UIC = $(shell pkg-config --variable=uic_location QtCore) else - CXXFLAGS += -std=c++11 -fPIC + PM3CXXFLAGS += -std=c++11 -fPIC endif ifeq ($(QTINCLUDES), ) # if both pkg-config commands failed, search in common places @@ -103,7 +99,7 @@ ifeq ($(QTINCLUDES), ) ifneq ($(wildcard $(QTDIR)/include/QtWidgets),) QTINCLUDES += -I$(QTDIR)/include/QtWidgets QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core - CXXFLAGS += -std=c++11 -fPIC + PM3CXXFLAGS += -std=c++11 -fPIC endif MOC = $(QTDIR)/bin/moc UIC = $(QTDIR)/bin/uic @@ -113,7 +109,7 @@ endif ifneq ($(QTLDLIBS),) QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o - CFLAGS += -DHAVE_GUI + PM3CFLAGS += -DHAVE_GUI else QTGUIOBJS = $(OBJDIR)/guidummy.o endif @@ -121,7 +117,7 @@ endif # Flags to generate temporary dependency files DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td # make temporary to final dependency files after successful compilation -POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d +POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ CORESRCS = uart_posix.c \ uart_win32.c \ @@ -150,7 +146,7 @@ CMDSRCS = crapto1/crapto1.c \ loclass/cipherutils.c \ loclass/ikeys.c \ loclass/elite_crack.c \ - loclass/fileutils.c \ + fileutils.c \ whereami.c \ mifare/mifarehost.c \ parity.c \ @@ -241,7 +237,8 @@ CMDSRCS = crapto1/crapto1.c \ cmdscript.c \ pm3_bitlib.c \ cmdcrc.c \ - bucketsort.c + bucketsort.c \ + flash.c cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) @@ -254,24 +251,11 @@ ifeq ($(MULTIARCHSRCS), ) CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c endif -ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c -ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED -#-DDEBUG -Dverbose=1 - -REVENGSRCS = reveng/preset.c \ - reveng/reveng.c \ - reveng/cli.c \ - reveng/bmpbit.c \ - reveng/model.c \ - reveng/poly.c - QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) -ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) -REVENGOBJS = $(REVENGSRCS:%.c=$(OBJDIR)/%.o) MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \ $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \ @@ -295,23 +279,21 @@ ifeq "$(SUPPORTS_AVX512)" "True" MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o) endif -BINS = proxmark3 flasher -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst +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 # need to assign dependancies to build these first... -all: lua_build jansson_build mbedtls_build cbor_build $(BINS) +all: $(BINS) all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) -proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS) -proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua +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 $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(LDLIBS) -o $@ - -flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS) - $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ + $(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@ proxgui.cpp: ui/ui_overlays.h @@ -327,115 +309,144 @@ lualibs/pm3_cmd.lua: ../include/pm3_cmd.h $(info [=] GEN $@) $(Q)awk -f pm3_cmd_h2lua.awk $^ > $@ -lualibs/mf_default_keys.lua : default_keys.dic +lualibs/mfc_default_keys.lua : mfc_default_keys.dic $(info [=] GEN $@) $(Q)awk -f default_keys_dic2lua.awk $^ > $@ clean: $(Q)$(RM) $(CLEAN) + $(Q)$(RMDIR) $(OBJDIR) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean - $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) 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 + +install: all + $(info [@] Installing client to $(DESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLBIN)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) + $(Q)$(CP) $(INSTALLBIN) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH) +endif +ifneq (,$(INSTALLSHARE)) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) +endif + @true + +uninstall: + $(info [@] Uninstalling client from $(DESTDIR)$(PREFIX)...) +ifneq (,$(INSTALLBIN)) + $(Q)$(RM) $(foreach tool,$(INSTALLBIN),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(tool))) +endif +ifneq (,$(INSTALLSHARE)) + $(Q)$(RMDIR) $(foreach tool,$(INSTALLSHARE),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(tool))) +endif + @true tarbin: $(BINS) $(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) -lua_build: +# local libraries: +$(LUALIB): $(info [*] MAKE liblua for $(LUAPLATFORM)) $(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM) -jansson_build: +$(JANSSONLIB): $(info [*] MAKE jansson) $(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all -mbedtls_build: - $(info [*] MAKE mbedtls) - $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) all - -cbor_build: +$(CBORLIB): $(info [*] MAKE tinycbor) $(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all +$(REVENGLIB): + $(info [*] MAKE reveng) + $(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all -reveng/bmptst: reveng/bmpbit.c reveng/config.h reveng/reveng.h - $(CC) $(CFLAGS) $(REVENGFLAGS) -DBMPTST -o $@ $< - ( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) ) +$(AMIIBOLIB): + $(info [*] MAKE amiibo) + $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all -.PHONY: all clean +# common libraries: +$(MBEDTLSLIB): + $(info [*] MAKE mbedtls) + $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all + +$(ZLIB): + $(info [*] MAKE zlib) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all + +.PHONY: all clean install uninstall # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) $(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d $(info [-] CC(NOSIMD) $<) - $(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d + $(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)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d + $(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)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d + $(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)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d + $(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)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d + $(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)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $< - $(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d + $(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 $<) - $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< + $(Q)$(MKDIR) $(dir $@) + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.cpp $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d $(info [-] CXX $<) - $(Q)$(CXX) $(DEPFLAGS) $(CXXFLAGS) $(QTINCLUDES) -c -o $@ $< + $(Q)$(MKDIR) $(dir $@) + $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $< $(Q)$(POSTCOMPILE) %.o: %.m $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(info [-] CC $<) - $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< + $(Q)$(MKDIR) $(dir $@) + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) -#$(CMDOBJS) $(COREOBJS): $(notdir $(%.c)) %.d -# $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< -# $(POSTCOMPILE) - -#$(ZLIBOBJS): $(notdir $(%.c)) %.d -# $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< -# $(POSTCOMPILE) - -#$(QTGUIOBJS): $(notdir $(%.cpp)) %.d -# $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $< -# $(POSTCOMPILE) - -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(REVENGSRCS)) \ +DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVENGSRCS)) \ $(patsubst %.o, %.d, $(MULTIARCHOBJS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ - $(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d + $(OBJDIR)/proxmark3.d $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) -include $(DEPENDENCY_FILES) - diff --git a/client/amiitool/Makefile b/client/amiitool/Makefile new file mode 100644 index 000000000..c473f58ee --- /dev/null +++ b/client/amiitool/Makefile @@ -0,0 +1,19 @@ +MYSRCPATHS = +MYINCLUDES = -I. -I.. -I../jansson -I../../common/ -I../../include/ +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = +MYSRCS = \ + amiibo.c \ + drbg.c \ + keygen.c + +LIB_A = libamiibo.a + +include ../../Makefile.host + +# 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 diff --git a/client/amiitool/amiibo.c b/client/amiitool/amiibo.c index a8596e30a..d8fe837b1 100644 --- a/client/amiitool/amiibo.c +++ b/client/amiitool/amiibo.c @@ -8,6 +8,7 @@ #include "amiibo.h" #include "mbedtls/md.h" #include "mbedtls/aes.h" +#include "commonutil.h" #define HMAC_POS_DATA 0x008 #define HMAC_POS_TAG 0x1B4 diff --git a/client/amiitool/amiibo.h b/client/amiitool/amiibo.h index 7b56a2c0a..47d544875 100644 --- a/client/amiitool/amiibo.h +++ b/client/amiitool/amiibo.h @@ -13,7 +13,6 @@ #include #include #include "keygen.h" -#include "util.h" #define NFC3D_AMIIBO_SIZE 520 diff --git a/client/amiitool/amiitool.c b/client/amiitool/amiitool.c index 78c8f4d1e..ca34a5c6a 100644 --- a/client/amiitool/amiitool.c +++ b/client/amiitool/amiitool.c @@ -5,10 +5,11 @@ * SPDX-License-Identifier: MIT */ -#include #include #include -#include "../loclass/fileutils.h" +#include "fileutils.h" +#include "amiibo.h" +#include "getopt.h" #define NTAG215_SIZE 540 @@ -16,7 +17,7 @@ static char *self; void amiitool_usage() { fprintf(stderr, - "amiitool build %i (commit %s-%08x)\n" + /*"amiitool build %i (commit %s-%08x)\n"*/ "by Marcos Del Sol Vives \n" "\n" "Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n" @@ -28,7 +29,7 @@ void amiitool_usage() { " -s input save file, save from this file will replace input file ones.\n" " -o output file. If not specified, stdout will be used.\n" " -l decrypt files with invalid signatures.\n", - , self + self ); } @@ -62,6 +63,9 @@ int main(int argc, char **argv) { case 'i': infile = optarg; break; + case 'k': + keyfile = optarg; + break; case 's': savefile = optarg; break; @@ -83,7 +87,8 @@ int main(int argc, char **argv) { } nfc3d_amiibo_keys amiiboKeys; - + if (! LoadAmiikey(amiiboKeys, keyfile)) + return 5; uint8_t original[NTAG215_SIZE]; uint8_t modified[NFC3D_AMIIBO_SIZE]; diff --git a/client/amiitool/drbg.c b/client/amiitool/drbg.c index 623a29776..c1297920f 100644 --- a/client/amiitool/drbg.c +++ b/client/amiitool/drbg.c @@ -8,7 +8,7 @@ #include "drbg.h" #include #include -#include +#include "mbedtls/md.h" void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) { assert(ctx != NULL); diff --git a/client/amiitool/keygen.c b/client/amiitool/keygen.c index 4b74a0232..f148c0dc8 100644 --- a/client/amiitool/keygen.c +++ b/client/amiitool/keygen.c @@ -19,7 +19,7 @@ void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const ui uint8_t *start = output; // 1: Copy whole type string - output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString)); + output = (uint8_t *)strcpy((char *)output, baseKeys->typeString); // 2: Append (16 - magicBytesSize) from the input seed size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize; diff --git a/client/cmddata.c b/client/cmddata.c index 81060cd59..9465c63ac 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -23,6 +23,7 @@ #include "lfdemod.h" // for demod code #include "loclass/cipherutils.h" // for decimating samples in getsamples #include "cmdlfem4x.h" // askem410xdecode +#include "fileutils.h" // searchFile uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; size_t DemodBufferLen = 0; @@ -38,6 +39,7 @@ static int usage_data_printdemodbuf(void) { PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)"); PrintAndLogEx(NORMAL, " o enter offset in # of bits"); PrintAndLogEx(NORMAL, " l enter length to print in # of bits or hex characters respectively"); + PrintAndLogEx(NORMAL, " s strip leading zeroes, i.e. set offset to first bit equal to one"); return PM3_SUCCESS; } static int usage_data_manrawdecode(void) { @@ -401,6 +403,7 @@ void printDemodBuff(void) { int CmdPrintDemodBuff(const char *Cmd) { bool hexMode = false; bool errors = false; + bool lstrip = false; uint32_t offset = 0; uint32_t length = 512; char cmdp = 0; @@ -422,6 +425,10 @@ int CmdPrintDemodBuff(const char *Cmd) { if (!length) errors = true; cmdp += 2; break; + case 's': + lstrip = true; + cmdp ++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -435,6 +442,15 @@ int CmdPrintDemodBuff(const char *Cmd) { PrintAndLogEx(NORMAL, "Demodbuffer is empty"); return PM3_ESOFT; } + if (lstrip) { + char *buf = (char *)(DemodBuffer + offset); + length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length; + uint32_t i; + for (i = 0; i < length; i++) { + if (buf[i] == 1) break; + } + offset += i; + } length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length; if (hexMode) { @@ -1646,11 +1662,20 @@ static int CmdLoad(const char *Cmd) { if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; memcpy(filename, Cmd, len); - FILE *f = fopen(filename, "r"); + char *path; + if (searchFile(&path, TRACES_SUBDIR, filename, ".pm3", true) != PM3_SUCCESS) { + if (searchFile(&path, TRACES_SUBDIR, filename, "", false) != PM3_SUCCESS) { + return PM3_EFILE; + } + } + + FILE *f = fopen(path, "r"); if (!f) { - PrintAndLogEx(WARNING, "couldn't open '%s'", filename); + PrintAndLogEx(WARNING, "couldn't open '%s'", path); + free(path); return PM3_EFILE; } + free(path); GraphTraceLen = 0; char line[80]; diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index 6bb6fbc3c..ce5b37f44 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -14,7 +14,7 @@ #include "cmdparser.h" // command_t #include "pmflash.h" -#include "loclass/fileutils.h" //saveFile +#include "fileutils.h" //saveFile #include "comms.h" //getfromdevice #include "cmdflashmemspiffs.h" // spiffs commands @@ -59,9 +59,9 @@ static int usage_flashmem_load(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0 PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024 - PrintAndLogEx(NORMAL, " mem load f default_keys m"); - PrintAndLogEx(NORMAL, " mem load f default_pwd t"); - PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i"); + PrintAndLogEx(NORMAL, " mem load f mfc_default_keys m"); + PrintAndLogEx(NORMAL, " mem load f t55xx_default_pwds t"); + PrintAndLogEx(NORMAL, " mem load f iclass_default_keys i"); return PM3_SUCCESS; } static int usage_flashmem_dump(void) { @@ -209,9 +209,8 @@ static int CmdFlashMemLoad(const char *Cmd) { datalen += 2; break; case DICTIONARY_NONE: - res = loadFile(filename, ".bin", data, FLASH_MEM_MAX_SIZE, &datalen); - //int res = loadFileEML( filename, data, &datalen); - if (res) { + res = loadFile_safe(filename, ".bin", (void **)&data, &datalen); + if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; } @@ -223,7 +222,7 @@ static int CmdFlashMemLoad(const char *Cmd) { } break; } - +// not needed when we transite to loadxxxx_safe methods.(iceman) uint8_t *newdata = realloc(data, datalen); if (newdata == NULL) { free(data); diff --git a/client/cmdflashmemspiffs.c b/client/cmdflashmemspiffs.c index f53e17915..109f51ae1 100644 --- a/client/cmdflashmemspiffs.c +++ b/client/cmdflashmemspiffs.c @@ -13,7 +13,7 @@ #include "cmdparser.h" // command_t #include "pmflash.h" -#include "loclass/fileutils.h" //saveFile +#include "fileutils.h" //saveFile #include "comms.h" //getfromdevice static int CmdHelp(const char *Cmd); @@ -330,12 +330,15 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); errors = true; - break; } cmdp += 2; break; case 'o': param_getstr(Cmd, cmdp + 1, destfilename, 32); + if (strlen(destfilename) == 0) { + PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); + errors = true; + } cmdp += 2; break; default: @@ -345,42 +348,20 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { } } - if (destfilename[0] == '\0') { - PrintAndLogEx(FAILED, "Destination Filename missing or invalid"); - errors = true; - } - // Validations - if (errors || cmdp == 0) { - usage_flashmemspiffs_load(); - return PM3_EINVARG; - } + if (errors || cmdp == 0) + return usage_flashmemspiffs_load(); size_t datalen = 0; - int res = 0; - uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); + uint8_t *data = NULL; - res = loadFile(filename, "", data, FLASH_MEM_MAX_SIZE, &datalen); + int res = loadFile_safe(filename, "", (void **)&data, &datalen); // int res = loadFileEML( filename, data, &datalen); - if (res) { + if (res != PM3_SUCCESS) { free(data); return PM3_EFILE; } - if (datalen > FLASH_MEM_MAX_SIZE) { - PrintAndLogEx(ERR, "error, filesize is larger than available memory"); - free(data); - return PM3_EOVFLOW; - } - - uint8_t *newdata = realloc(data, datalen); - if (newdata == NULL) { - free(data); - return PM3_EMALLOC; - } else { - data = newdata; - } - // We want to mount before multiple operation so the lazy writes/append will not // trigger a mount + umount each loop iteration (lazy ops device side) SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); @@ -425,6 +406,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { if (!isok) { conn.block_after_ACK = false; PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); + free(data); return PM3_EFLASH; } } diff --git a/client/cmdhf.c b/client/cmdhf.c index a6c5ea11e..8326d988f 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -76,18 +76,23 @@ int CmdHFSearch(const char *Cmd) { PrintAndLogEx(INFO, "Checking for known tags...\n"); + PrintAndLogEx(INPLACE, "Searching for ThinFilm tag..."); if (IfPm3NfcBarcode()) { if (infoThinFilm(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag..."); if (IfPm3Iso14443a()) { if (infoHF14A(false, false) > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for ISO15693 tag..."); if (IfPm3Iso15693()) { if (readHF15Uid(false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n"); @@ -97,25 +102,33 @@ int CmdHFSearch(const char *Cmd) { // until refactoring of ISO15693 cmds, this is needed. DropField(); } + + PrintAndLogEx(INPLACE, "Searching for LEGIC tag..."); if (IfPm3Legicrf()) { if (readLegicUid(false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for Topaz tag..."); if (IfPm3Iso14443a()) { if (readTopazUid() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); return PM3_SUCCESS; } } + // 14b and iclass is the longest test (put last) + PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag..."); if (IfPm3Iso14443a()) { if (readHF14B(false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n"); return PM3_SUCCESS; } } + + PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag..."); if (IfPm3Iclass()) { if (readIclass(false, false) == 1) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n"); @@ -133,7 +146,7 @@ int CmdHFSearch(const char *Cmd) { //} - PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n"); + PrintAndLogEx(FAILED, "\nNo known/supported 13.56 MHz tags found\n"); return PM3_ESOFT; } @@ -208,7 +221,7 @@ static command_t CommandTable[] = { {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"}, {"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"}, - {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags [preliminary]"}, + {"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags"}, {"sniff", CmdHFSniff, IfPm3Hfsniff, " Generic HF Sniff"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 8aea8db6c..b21e8dbd7 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -133,7 +133,7 @@ static const manufactureName manufactureMapping[] = { { 0x61, "Wearlinks Technology Inc. China" }, { 0x62, "Userstar Information Systems Co., Ltd Taiwan" }, { 0x63, "Pragmatic Printing Ltd. UK" }, - { 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico – LSI-TEC Brazil" }, + { 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico - LSI-TEC Brazil" }, { 0x65, "Tendyron Corporation China" }, { 0x66, "MUTO Smart Co., Ltd. Korea" }, { 0x67, "ON Semiconductor USA" }, diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index c5a628835..57f275a31 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -12,7 +12,7 @@ #include "cmdhf14b.h" #include -#include "loclass/fileutils.h" +#include "fileutils.h" #include "cmdparser.h" // command_t #include "comms.h" // clearCommandBuffer diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 2c788087e..eb8cb6f87 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -35,7 +35,7 @@ #include "graph.h" #include "crc16.h" // iso15 crc #include "cmddata.h" // getsamples -#include "loclass/fileutils.h" // savefileEML +#include "fileutils.h" // savefileEML #define FrameSOF Iso15693FrameSOF #define Logic0 Iso15693Logic0 diff --git a/client/cmdhffido.c b/client/cmdhffido.c index e9b3376a9..fbc91e814 100644 --- a/client/cmdhffido.c +++ b/client/cmdhffido.c @@ -44,7 +44,7 @@ static int CmdHelp(const char *Cmd); static int CmdHFFidoInfo(const char *cmd) { if (cmd && strlen(cmd) > 0) - PrintAndLogEx(WARNING, "WARNING: command don't have any parameters.\n"); + PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n"); // info about 14a part infoHF14A(false, false); @@ -75,14 +75,14 @@ static int CmdHFFidoInfo(const char *cmd) { if (!strncmp((char *)buf, "U2F_V2", 7)) { if (!strncmp((char *)buf, "FIDO_2_0", 8)) { - PrintAndLogEx(INFO, "FIDO2 authenricator detected. Version: %.*s", len, buf); + PrintAndLogEx(INFO, "FIDO2 authenticator detected. Version: %.*s", len, buf); } else { - PrintAndLogEx(INFO, "FIDO authenricator detected (not standard U2F)."); + PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F)."); PrintAndLogEx(INFO, "Non U2F authenticator version:"); dump_buffer((const unsigned char *)buf, len, NULL, 0); } } else { - PrintAndLogEx(INFO, "FIDO U2F authenricator detected. Version: %.*s", len, buf); + PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", len, buf); } res = FIDO2GetInfo(buf, sizeof(buf), &len, &sw); @@ -91,13 +91,13 @@ static int CmdHFFidoInfo(const char *cmd) { return res; } if (sw != 0x9000) { - PrintAndLogEx(ERR, "FIDO2 version not exists (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + PrintAndLogEx(ERR, "FIDO2 version doesn't exist (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); return 0; } if (buf[0]) { - PrintAndLogEx(ERR, "FIDO2 ger version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); + PrintAndLogEx(ERR, "FIDO2 get version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0])); return 0; } @@ -163,14 +163,14 @@ static int CmdHFFidoRegister(const char *cmd) { json_t *root = NULL; CLIParserInit("hf fido reg", - "Initiate a U2F token registration. Needs two 32-byte hash number. \nchallenge parameter (32b) and application parameter (32b).", + "Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n" "\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters" "\thf fido reg -p s0 s1 -> execute command with plain parameters"); void *argtable[] = { arg_param_begin, - arg_lit0("aA", "apdu", "show APDU reqests and responses"), + arg_lit0("aA", "apdu", "show APDU requests and responses"), arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"), arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"), arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"), @@ -393,7 +393,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { json_t *root = NULL; CLIParserInit("hf fido auth", - "Initiate a U2F token authentication. Needs key handle and two 32-byte hash number. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).", + "Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n" "\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f " "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"); @@ -640,8 +640,8 @@ static int CmdHFFido2MakeCredential(const char *cmd) { char fname[300] = {0}; CLIParserInit("hf fido make", - "Execute a FIDO2 Make Credentional command. Needs json file with parameters. Sample file `fido2.json`. File can be placed in proxmark directory or in `proxmark/fido` directory.", - "Usage:\n\thf fido make -> execute command default parameters file `fido2.json`\n" + "Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", + "Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n" "\thf fido make test.json -> execute command with parameters file `text.json`"); void *argtable[] = { @@ -713,7 +713,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { return res; if (showCBOR) { - PrintAndLogEx(INFO, "CBOR make credentional request:"); + PrintAndLogEx(INFO, "CBOR make credential request:"); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); TinyCborPrintFIDOPackage(fido2CmdMakeCredential, false, data, datalen); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); @@ -738,7 +738,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { PrintAndLogEx(SUCCESS, "MakeCredential result (%d b) OK.", len); if (showCBOR) { - PrintAndLogEx(SUCCESS, "CBOR make credentional response:"); + PrintAndLogEx(SUCCESS, "CBOR make credential response:"); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); TinyCborPrintFIDOPackage(fido2CmdMakeCredential, true, &buf[1], len - 1); PrintAndLogEx(NORMAL, "---------------- CBOR ------------------"); @@ -766,8 +766,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) { char fname[300] = {0}; CLIParserInit("hf fido assert", - "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") ". File can be placed in proxmark directory or in `proxmark/fido` directory.", - "Usage:\n\thf fido assert -> execute command default parameters file `fido2.json`\n" + "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", + "Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n" "\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId"); void *argtable[] = { @@ -775,7 +775,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"), arg_lit0("cC", "cbor", "show CBOR decoded data"), - arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator don't store credential to its memory)"), + arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator doesn't store credential to its memory)"), arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; @@ -801,7 +801,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { SetAPDULogging(APDULogging); - int res = GetExistsFileNameJson("fido", "fido2", fname); + int res = GetExistsFileNameJson("fido", cjsonname, fname); if (res) { PrintAndLogEx(ERR, "ERROR: Can't found the json file."); return res; diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 7badc7c86..f45151a7b 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -26,20 +26,21 @@ #include "loclass/cipher.h" #include "loclass/ikeys.h" #include "loclass/elite_crack.h" -#include "loclass/fileutils.h" +#include "fileutils.h" #include "protocols.h" #define NUM_CSNS 9 #define ICLASS_KEYS_MAX 8 +#define ICLASS_AUTH_RETRY 10 static int CmdHelp(const char *Cmd); static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 }, + { 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00 }, + { 0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xc1, 0x1b, 0x39 }, + { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -60,38 +61,46 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, " hf iclass eload 'tagdump.bin'"); PrintAndLogEx(NORMAL, " hf iclass sim 3"); PrintAndLogEx(NORMAL, " hf iclass sim 4"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_eload(void) { PrintAndLogEx(NORMAL, "Loads iclass tag-dump into emulator memory on device"); PrintAndLogEx(NORMAL, "Usage: hf iclass eload f "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_decrypt(void) { PrintAndLogEx(NORMAL, "This is simple implementation, it tries to decrypt every block after block 6."); PrintAndLogEx(NORMAL, "Correct behaviour would be to decrypt only the application areas where the key is valid,"); PrintAndLogEx(NORMAL, "which is defined by the configuration block."); PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); - PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); + PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt f "); + PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt d f k "); + PrintAndLogEx(NORMAL, " options"); + PrintAndLogEx(NORMAL, " d 16 bytes hex"); + PrintAndLogEx(NORMAL, " f filename of dump"); + PrintAndLogEx(NORMAL, " k 16 bytes hex"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_12312342343.bin"); - return 0; + PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_1.bin k 000102030405060708090a0b0c0d0e0f"); + PrintAndLogEx(NORMAL, "S hf iclass decrypt d 1122334455667788 k 000102030405060708090a0b0c0d0e0f"); + + return PM3_SUCCESS; } static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); - PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); + PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt "); + PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt d k "); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass encrypt 0102030405060708"); + PrintAndLogEx(NORMAL, " hf iclass encrypt d 0102030405060708"); + PrintAndLogEx(NORMAL, " hf iclass encrypt d 0102030405060708 k 00112233445566778899AABBCCDDEEFF"); PrintAndLogEx(NORMAL, ""); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_dump(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass dump f k c [e|r|v]\n"); @@ -107,23 +116,23 @@ static int usage_hf_iclass_dump(void) { PrintAndLogEx(NORMAL, " hf iclass dump k 001122334455667B"); PrintAndLogEx(NORMAL, " hf iclass dump k AAAAAAAAAAAAAAAA c 001122334455667B"); PrintAndLogEx(NORMAL, " hf iclass dump k AAAAAAAAAAAAAAAA e"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_clone(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass clone f b l k c e|r"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " f : specify a filename to clone from"); - PrintAndLogEx(NORMAL, " b : The first block to clone as 2 hex symbols"); - PrintAndLogEx(NORMAL, " l : Set the Data to write as 16 hex symbols"); - PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); - PrintAndLogEx(NORMAL, " c : If 'c' is specified, the key set is assumed to be the credit key\n"); - PrintAndLogEx(NORMAL, " e : If 'e' is specified, elite computations applied to key"); - PrintAndLogEx(NORMAL, " r : If 'r' is specified, no computations applied to key"); + PrintAndLogEx(NORMAL, " f : specify a filename to clone from"); + PrintAndLogEx(NORMAL, " b : The first block to clone as 2 hex symbols"); + PrintAndLogEx(NORMAL, " l : Set the Data to write as 16 hex symbols"); + PrintAndLogEx(NORMAL, " k : Access Key as 16 hex symbols or 1 hex to select key from memory"); + PrintAndLogEx(NORMAL, " c : If 'c' is specified, the key set is assumed to be the credit key\n"); + PrintAndLogEx(NORMAL, " e : If 'e' is specified, elite computations applied to key"); + PrintAndLogEx(NORMAL, " r : If 'r' is specified, no computations applied to key"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 06 l 19 k 0 e"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_writeblock(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass writeblk b d k [c|e|r|v]\n"); @@ -138,7 +147,7 @@ static int usage_hf_iclass_writeblock(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B"); PrintAndLogEx(NORMAL, " hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass readblk b k [c|e|r|v]\n"); @@ -153,11 +162,11 @@ static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, " hf iclass readblk b 06 k 0011223344556677"); PrintAndLogEx(NORMAL, " hf iclass readblk b 1B k 0011223344556677 c"); PrintAndLogEx(NORMAL, " hf iclass readblk b 0A k 0"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_readtagfile() { PrintAndLogEx(NORMAL, "Usage: hf iclass readtagfile [startblock] [endblock]"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_calc_newkey(void) { PrintAndLogEx(NORMAL, "Calculate new key for updating\n"); @@ -173,24 +182,24 @@ static int usage_hf_iclass_calc_newkey(void) { PrintAndLogEx(NORMAL, " std key to e key read csn : hf iclass calcnewkey o 1122334455667788 n 2233445566778899 e"); PrintAndLogEx(NORMAL, " std to std read csn : hf iclass calcnewkey o 1122334455667788 n 2233445566778899"); PrintAndLogEx(NORMAL, "\nNOTE: * = required\n"); - return 0; + return PM3_SUCCESS;; } static int usage_hf_iclass_managekeys(void) { PrintAndLogEx(NORMAL, "HELP : Manage iClass Keys in client memory:\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass managekeys n [keynbr] k [key] f [filename] s l p\n"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " n : specify the keyNbr to set in memory"); - PrintAndLogEx(NORMAL, " k : set a key in memory"); - PrintAndLogEx(NORMAL, " f : specify a filename to use with load or save operations"); - PrintAndLogEx(NORMAL, " s : save keys in memory to file specified by filename"); - PrintAndLogEx(NORMAL, " l : load keys to memory from file specified by filename"); - PrintAndLogEx(NORMAL, " p : print keys loaded into memory\n"); + PrintAndLogEx(NORMAL, " n : specify the keyNbr to set in memory"); + PrintAndLogEx(NORMAL, " k : set a key in memory"); + PrintAndLogEx(NORMAL, " f : specify a filename to use with load or save operations"); + PrintAndLogEx(NORMAL, " s : save keys in memory to file specified by filename"); + PrintAndLogEx(NORMAL, " l : load keys to memory from file specified by filename"); + PrintAndLogEx(NORMAL, " p : print keys loaded into memory\n"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " set key : hf iclass managekeys n 0 k 1122334455667788"); - PrintAndLogEx(NORMAL, " save key file: hf iclass managekeys f mykeys.bin s"); - PrintAndLogEx(NORMAL, " load key file: hf iclass managekeys f mykeys.bin l"); - PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n"); - return 0; + PrintAndLogEx(NORMAL, " set key : hf iclass managekeys n 0 k 1122334455667788"); + PrintAndLogEx(NORMAL, " save key file : hf iclass managekeys f mykeys.bin s"); + PrintAndLogEx(NORMAL, " load key file : hf iclass managekeys f mykeys.bin l"); + PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n"); + return PM3_SUCCESS; } static int usage_hf_iclass_reader(void) { PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until Enter or the pm3 button is pressed\n"); @@ -200,7 +209,7 @@ static int usage_hf_iclass_reader(void) { PrintAndLogEx(NORMAL, " 1 read only 1 tag"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass reader 1"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_replay(void) { PrintAndLogEx(NORMAL, "Replay a collected mac message"); @@ -210,29 +219,29 @@ static int usage_hf_iclass_replay(void) { PrintAndLogEx(NORMAL, " Mac bytes to replay (8 hexsymbols)"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass replay 00112233"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_sniff(void) { PrintAndLogEx(NORMAL, "Sniff the communication between reader and tag"); PrintAndLogEx(NORMAL, "Usage: hf iclass sniff [h]"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass sniff"); - return 0; + return PM3_SUCCESS; } static int usage_hf_iclass_loclass(void) { PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, "h Show this help"); - PrintAndLogEx(NORMAL, "t Perform self-test"); - PrintAndLogEx(NORMAL, "f Bruteforce iclass dumpfile"); - PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of"); - PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses"); - PrintAndLogEx(NORMAL, " The binary format of the file is expected to be as follows: "); - PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); - PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); - PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); - PrintAndLogEx(NORMAL, " ... totalling N*24 bytes"); - return 0; + PrintAndLogEx(NORMAL, " h Show this help"); + PrintAndLogEx(NORMAL, " t Perform self-test"); + PrintAndLogEx(NORMAL, " f Bruteforce iclass dumpfile"); + PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of"); + PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses"); + PrintAndLogEx(NORMAL, " The binary format of the file is expected to be as follows: "); + PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLogEx(NORMAL, " <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>"); + PrintAndLogEx(NORMAL, " ... totalling N*24 bytes"); + return PM3_SUCCESS; } static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag"); @@ -244,9 +253,9 @@ static int usage_hf_iclass_chk(void) { PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, " c credit key (if not use, default is debit)"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic"); - PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic e"); - return 0; + PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic"); + PrintAndLogEx(NORMAL, " hf iclass chk f dictionaries/iclass_default_keys.dic e"); + return PM3_SUCCESS;; } static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, "Lookup keys takes some sniffed trace data and tries to verify what key was used against a dictionary file"); @@ -260,9 +269,9 @@ static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, " r raw"); PrintAndLogEx(NORMAL, " e elite"); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic"); - PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic e"); - return 0; + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic"); + PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f dictionaries/iclass_default_keys.dic e"); + return PM3_SUCCESS; } static int usage_hf_iclass_permutekey(void) { PrintAndLogEx(NORMAL, "Permute function from 'heart of darkness' paper."); @@ -276,7 +285,7 @@ static int usage_hf_iclass_permutekey(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf iclass permute r 0123456789abcdef"); - return 0; + return PM3_SUCCESS; } /* @@ -541,11 +550,11 @@ static int CmdHFiClassSim(const char *Cmd) { tries++; if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); - return 0; + return PM3_EOPABORTED; } if (tries > 20) { PrintAndLogEx(WARNING, "\ntimeout while waiting for reply."); - return 0; + return PM3_ETIMEOUT; } } uint8_t num_mac = resp.oldarg[1]; @@ -559,7 +568,7 @@ static int CmdHFiClassSim(const char *Cmd) { uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return 2; + return PM3_EMALLOC; } memset(dump, 0, datalen);//<-- Need zeroes for the EPURSE - field (offical) @@ -590,11 +599,11 @@ static int CmdHFiClassSim(const char *Cmd) { tries++; if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard."); - return 0; + return PM3_EOPABORTED; } if (tries > 20) { PrintAndLogEx(WARNING, "\ntimeout while waiting for reply."); - return 0; + return PM3_ETIMEOUT; } } uint8_t num_mac = resp.oldarg[1]; @@ -608,7 +617,7 @@ static int CmdHFiClassSim(const char *Cmd) { uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); - return 2; + return PM3_EMALLOC; } #define MAC_ITEM_SIZE 24 @@ -654,6 +663,10 @@ static int CmdHFiClassSim(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHFiClassInfo(const char *Cmd) { + return PM3_SUCCESS; +} + static int CmdHFiClassReader(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_hf_iclass_reader(); @@ -681,54 +694,85 @@ static int CmdHFiClassReader_Replay(const char *Cmd) { static int CmdHFiClassELoad(const char *Cmd) { - char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload(); - - if (ctmp != 'f') return usage_hf_iclass_eload(); - - //File handling and reading - char filename[FILE_PATH_SIZE]; - - if (param_getstr(Cmd, 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); - return 1; + DumpFileType_t dftype = BIN; + char filename[FILE_PATH_SIZE] = {0}; + bool errors = false; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_eload(); + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + break; + } + cmdp += 2; + break; + case 'j': + dftype = JSON; + cmdp++; + break; + case 'e': + dftype = EML; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); + //Validations + if (errors || cmdp == 0) { + usage_hf_iclass_eload(); + return PM3_EINVARG; + } + + + uint8_t *dump = calloc(2048, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(ERR, "error, cannot allocate memory "); + return PM3_EMALLOC; + } + + size_t bytes_read = 2048; + int res = 0; + + switch (dftype) { + case BIN: { + res = loadFile_safe(filename, ".bin", (void **)&dump, &bytes_read); + break; + } + case EML: { + res = loadFileEML(filename, dump, &bytes_read); + break; + } + case JSON: { + res = loadFileJSON(filename, dump, 2048, &bytes_read); + break; + } + default: + PrintAndLogEx(ERR, "No dictionary loaded"); + return PM3_ESOFT; + } + + if (res != PM3_SUCCESS) { + free(dump); return PM3_EFILE; } - // get filesize in order to malloc memory - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "error, when getting filesize"); - fclose(f); - return 1; + uint8_t *newdump = realloc(dump, bytes_read); + if (newdump == NULL) { + free(dump); + return PM3_EMALLOC; + } else { + dump = newdump; } - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(ERR, "error, cannot allocate memory "); - fclose(f); - return 1; - } - - size_t bytes_read = fread(dump, 1, fsize, f); - fclose(f); - printIclassDumpInfo(dump); - //Validate - - if (bytes_read < fsize) { - PrintAndLogEx(ERR, "error, could only read %d bytes (should be %d)", bytes_read, fsize); - free(dump); - return 1; - } // fast push mode conn.block_after_ACK = true; @@ -754,147 +798,189 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_SUCCESS; } -static int readKeyfile(const char *filename, size_t len, uint8_t *buffer) { - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return PM3_EFILE; - } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - size_t bytes_read = fread(buffer, 1, len, f); - fclose(f); - - if (fsize != len) { - PrintAndLogEx(WARNING, "Warning, file size is %d, expected %d", fsize, len); - return 1; - } - - if (bytes_read != len) { - PrintAndLogEx(WARNING, "Warning, could only read %d bytes, expected %d", bytes_read, len); - return 1; - } - return PM3_SUCCESS; -} +#define ICLASS_DECRYPTION_BIN "iclass_decryptionkey.bin" static int CmdHFiClassDecrypt(const char *Cmd) { - char opt = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt(); + bool errors = false; + bool have_key = false; + bool have_data = false; + bool have_file = false; + uint8_t cmdp = 0; - uint8_t key[16] = { 0 }; - if (readKeyfile("iclass_decryptionkey.bin", 16, key)) return usage_hf_iclass_decrypt(); + uint8_t enc_data[8] = {0}; + + size_t keylen = 0; + uint8_t key[32] = {0}; + uint8_t *keyptr = NULL; - PrintAndLogEx(SUCCESS, "decryption key loaded from file"); - - //Open the tagdump-file - FILE *f; + size_t decryptedlen = 0; + uint8_t *decrypted = NULL; char filename[FILE_PATH_SIZE]; - if (opt == 'f' && param_getstr(Cmd, 1, filename, sizeof(filename)) > 0) { - f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return PM3_EFILE; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_decrypt(); + case 'd': + if (param_gethex(Cmd, cmdp + 1, enc_data, 16)) { + PrintAndLogEx(ERR, "data must be 16 HEX symbols"); + errors = true; + break; + } + have_data = true; + cmdp += 2; + break; + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { + PrintAndLogEx(WARNING, "no filename found after f"); + errors = true; + break; + } + + if (loadFile_safe(filename, "", (void **)&decrypted, &decryptedlen) != PM3_SUCCESS) { + errors = true; + break; + } + have_file = true; + cmdp += 2; + break; + case 'k': + if (param_gethex(Cmd, cmdp + 1, key, 32)) { + PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); + errors = true; + } + have_key = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); + errors = true; + break; } - } else { - return usage_hf_iclass_decrypt(); } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); + if (errors || cmdp < 1) return usage_hf_iclass_decrypt(); - if (fsize <= 0) { - PrintAndLogEx(ERR, "error, when getting filesize"); - fclose(f); - return 2; + if (have_key == false) { + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr, &keylen); + if (res != PM3_SUCCESS) + return PM3_EINVARG; + + memcpy(key, keyptr, sizeof(key)); } - uint8_t *decrypted = calloc(fsize, sizeof(uint8_t)); - if (!decrypted) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return 1; - } - - size_t bytes_read = fread(decrypted, 1, fsize, f); - fclose(f); - if (bytes_read == 0) { - PrintAndLogEx(ERR, "file reading error"); - free(decrypted); - return 3; - } - - picopass_hdr *hdr = (picopass_hdr *)decrypted; - - uint8_t mem = hdr->conf.mem_config; - uint8_t chip = hdr->conf.chip_config; - uint8_t applimit = hdr->conf.app_limit; - uint8_t kb = 2; - uint8_t app_areas = 2; - uint8_t max_blk = 31; - getMemConfig(mem, chip, &max_blk, &app_areas, &kb); - - //Use the first block (CSN) for filename - char outfilename[FILE_PATH_SIZE] = {0}; - snprintf(outfilename, FILE_PATH_SIZE, "iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted", - hdr->csn[0], hdr->csn[1], hdr->csn[2], hdr->csn[3], - hdr->csn[4], hdr->csn[5], hdr->csn[6], hdr->csn[7]); - // tripledes mbedtls_des3_context ctx; mbedtls_des3_set2key_dec(&ctx, key); - uint8_t enc_dump[8] = {0}; - uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { + uint8_t dec_data[8] = {0}; - uint8_t idx = blocknum * 8; - memcpy(enc_dump, decrypted + idx, 8); - - // block 7 or higher, and not empty 0xFF - if (blocknum > 6 && memcmp(enc_dump, empty, 8) != 0) { - mbedtls_des3_crypt_ecb(&ctx, enc_dump, decrypted + idx); - } + if ( have_data ) { + mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); + PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(dec_data, sizeof(dec_data))); } - saveFile(outfilename, ".bin", decrypted, fsize); - printIclassDumpContents(decrypted, 1, (fsize / 8), fsize); - free(decrypted); + if ( have_file ) { + picopass_hdr *hdr = (picopass_hdr *)decrypted; + + uint8_t mem = hdr->conf.mem_config; + uint8_t chip = hdr->conf.chip_config; + uint8_t applimit = hdr->conf.app_limit; + uint8_t kb = 2; + uint8_t app_areas = 2; + uint8_t max_blk = 31; + getMemConfig(mem, chip, &max_blk, &app_areas, &kb); + + uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + for (uint16_t blocknum = 0; blocknum < applimit; ++blocknum) { + + uint8_t idx = blocknum * 8; + memcpy(enc_data, decrypted + idx, 8); + + // block 7 or higher, and not empty 0xFF + if (blocknum > 6 && memcmp(enc_data, empty, 8) != 0) { + mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx); + } + } + + //Use the first block (CSN) for filename + char *fptr = calloc(42, sizeof(uint8_t)); + strcat(fptr, "hf-iclass-"); + FillFileNameByUID(fptr, hdr->csn, "-data-decrypted", sizeof(hdr->csn)); + + saveFile(fptr, ".bin", decrypted, decryptedlen); + saveFileEML(fptr, decrypted, decryptedlen, 8); + saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen); + + printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); + free(decrypted); + free(fptr); + } + + mbedtls_des3_free(&ctx); return PM3_SUCCESS; } -static int iClassEncryptBlkData(uint8_t *blkData) { - uint8_t key[16] = { 0 }; - if (readKeyfile("iclass_decryptionkey.bin", 16, key)) { - usage_hf_iclass_encrypt(); - return 1; - } - PrintAndLogEx(SUCCESS, "decryption file found"); - uint8_t encryptedData[16]; - uint8_t *encrypted = encryptedData; +static void iClassEncryptBlkData(uint8_t *blk_data, uint8_t *key) { + uint8_t encrypted_data[16]; + uint8_t *encrypted = encrypted_data; mbedtls_des3_context ctx; mbedtls_des3_set2key_enc(&ctx, key); - - mbedtls_des3_crypt_ecb(&ctx, blkData, encrypted); - memcpy(blkData, encrypted, 8); - return 1; + mbedtls_des3_crypt_ecb(&ctx, blk_data, encrypted); + memcpy(blk_data, encrypted, 8); + mbedtls_des3_free(&ctx); } static int CmdHFiClassEncryptBlk(const char *Cmd) { - uint8_t blkData[8] = {0}; - char opt = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt(); + bool errors = false; + bool have_key = false; + uint8_t blk_data[8] = {0}; + uint8_t key[16] = {0}; + uint8_t *keyptr = NULL; + uint8_t cmdp = 0; - //get the bytes to encrypt - if (param_gethex(Cmd, 0, blkData, 16)) { - PrintAndLogEx(NORMAL, "BlockData must include 16 HEX symbols"); - return 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_iclass_encrypt(); + case 'd': + if (param_gethex(Cmd, cmdp + 1, blk_data, 16)) { + PrintAndLogEx(ERR, "Block data must include 16 HEX symbols"); + errors = true; + } + cmdp += 2; + break; + case 'k': + if (param_gethex(Cmd, cmdp + 1, key, 32)) { + PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); + errors = true; + } + have_key = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - if (!iClassEncryptBlkData(blkData)) return 0; - printvar("encrypted block", blkData, 8); + if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); + + if (have_key == false) { + size_t keylen = 0; + int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr, &keylen); + if (res != PM3_SUCCESS) + return PM3_EINVARG; + + memcpy(key, keyptr, sizeof(key)); + } + + iClassEncryptBlkData(blk_data, key); + + printvar("encrypted block", blk_data, 8); return PM3_SUCCESS; } @@ -914,7 +1000,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v clearCommandBuffer(); SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "command execute timeout"); return false; } @@ -933,7 +1019,9 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v } if (isOK <= 1) { - PrintAndLogEx(FAILED, "failed to obtain CC! Tag-select is aborting... (%d)", isOK); + if ( verbose ) + PrintAndLogEx(FAILED, "failed to obtain CC! Tag-select is aborting... (%d)", isOK); + return false; } return true; @@ -945,6 +1033,8 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u if (!select_only(CSN, CCNR, use_credit_key, verbose)) { if (verbose) PrintAndLogEx(FAILED, "selecting tag failed"); + +// DropField(); return false; } //get div_key @@ -956,18 +1046,27 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u if (verbose) PrintAndLogEx(SUCCESS, "authing with %s: %s", rawkey ? "raw key" : "diversified key", sprint_hex(div_key, 8)); doMAC(CCNR, div_key, MAC); + PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_AUTH, 0, 0, 0, MAC, 4); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) { - if (verbose) PrintAndLogEx(FAILED, "auth command execute timeout"); + + SendCommandNG(CMD_HF_ICLASS_AUTH, MAC, 4); + if (WaitForResponseTimeout(CMD_HF_ICLASS_AUTH, &resp, 2000) == 0) { + if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); return false; } - uint8_t isOK = resp.oldarg[0] & 0xFF; - if (!isOK) { + + if ( resp.status != PM3_SUCCESS ) { + if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); + return false; + } + + uint8_t isOK = resp.data.asBytes[0]; + if (isOK == 0) { if (verbose) PrintAndLogEx(FAILED, "authentication error"); return false; } + return true; } @@ -1021,6 +1120,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { cmdp += 2; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1052,6 +1152,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1083,7 +1184,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout"); DropField(); - return 0; + return PM3_ESOFT; } DropField(); @@ -1092,7 +1193,8 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (readStatus == 0) { PrintAndLogEx(FAILED, "no tag found"); - return 0; + DropField(); + return PM3_ESOFT; } if (readStatus & (FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_CC)) { @@ -1105,14 +1207,16 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { } // authenticate debit key and get div_key - later store in dump block 3 - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { - //try twice - for some reason it sometimes fails the first time... - PrintAndLogEx(SUCCESS, "retry to select card"); - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { - PrintAndLogEx(WARNING, "failed authenticating with debit key"); - DropField(); - return 0; - } + int numberAuthRetries = ICLASS_AUTH_RETRY; + do { + if (select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) + break; + } while (numberAuthRetries--); + + if ( numberAuthRetries <= 0) { + PrintAndLogEx(WARNING, "failed authenticating with debit key"); + DropField(); + return PM3_ESOFT; } // begin dump @@ -1136,7 +1240,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { uint8_t isOK = resp.oldarg[0] & 0xff; if (!isOK && !blocksRead) { PrintAndLogEx(WARNING, "read block failed"); - return 0; + return PM3_ESOFT; } uint32_t startindex = resp.oldarg[2]; @@ -1148,7 +1252,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // response ok - now get bigbuf content of the dump if (!GetFromDevice(BIG_BUF, tag_data + (blockno * 8), blocksRead * 8, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); - return 0; + return PM3_ETIMEOUT; } size_t gotBytes = blocksRead * 8 + blockno * 8; @@ -1157,16 +1261,22 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { if (have_credit_key) { //turn off hf field before authenticating with different key DropField(); + memset(MAC, 0, 4); + // AA2 authenticate credit key and git c_div_key - later store in dump block 4 - if (!select_and_auth(CreditKEY, MAC, c_div_key, true, elite, rawkey, verbose)) { - //try twice - for some reason it sometimes fails the first time... - if (!select_and_auth(CreditKEY, MAC, c_div_key, true, elite, rawkey, verbose)) { - PrintAndLogEx(WARNING, "failed authenticating with credit key"); - DropField(); - return 0; - } + numberAuthRetries = ICLASS_AUTH_RETRY; + do { + if (select_and_auth(CreditKEY, MAC, c_div_key, true, elite, rawkey, verbose)) + break; + } while (numberAuthRetries--); + + if ( numberAuthRetries <= 0) { + PrintAndLogEx(WARNING, "failed authenticating with credit key"); + DropField(); + return PM3_ESOFT; } + // do we still need to read more block? (aa2 enabled?) if (maxBlk > blockno + numblks + 1) { // setup dump and start @@ -1174,13 +1284,13 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { SendCommandMIX(CMD_HF_ICLASS_DUMP, blockno + blocksRead, maxBlk - (blockno + blocksRead), 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { PrintAndLogEx(WARNING, "command execute timeout 2"); - return 0; + return PM3_ETIMEOUT; } isOK = resp.oldarg[0] & 0xff; blocksRead = resp.oldarg[1]; if (!isOK && !blocksRead) { PrintAndLogEx(WARNING, "read block failed 2"); - return 0; + return PM3_ESOFT; } startindex = resp.oldarg[2]; @@ -1191,7 +1301,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // get dumped data from bigbuf if (!GetFromDevice(BIG_BUF, tag_data + gotBytes, blocksRead * 8, startindex, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); - return 0; + return PM3_ETIMEOUT; } gotBytes += blocksRead * 8; @@ -1201,52 +1311,88 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { DropField(); // add diversified keys to dump - if (have_debit_key) memcpy(tag_data + (3 * 8), div_key, 8); - if (have_credit_key) memcpy(tag_data + (4 * 8), c_div_key, 8); + if (have_debit_key) + memcpy(tag_data + (3 * 8), div_key, 8); + + if (have_credit_key) + memcpy(tag_data + (4 * 8), c_div_key, 8); + // print the dump - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); - PrintAndLogEx(NORMAL, "CSN |00| %s|\n", sprint_hex(tag_data, 8)); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "------+--+-------------------------+"); + PrintAndLogEx(NORMAL, "CSN |00| %s|", sprint_hex(tag_data, 8)); printIclassDumpContents(tag_data, 1, (gotBytes / 8), gotBytes); if (filename[0] == 0) { - snprintf(filename, FILE_PATH_SIZE, "iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x", - tag_data[0], tag_data[1], tag_data[2], tag_data[3], - tag_data[4], tag_data[5], tag_data[6], tag_data[7]); + //Use the first block (CSN) for filename + strcat(filename, "hf-iclass-"); + FillFileNameByUID(filename, tag_data, "-data", 8); } // save the dump to .bin file PrintAndLogEx(SUCCESS, "saving dump file - %d blocks read", gotBytes / 8); saveFile(filename, ".bin", tag_data, gotBytes); saveFileEML(filename, tag_data, gotBytes, 8); - return 1; + saveFileJSON(filename, jsfIclass, tag_data, gotBytes); + return PM3_SUCCESS; } static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) { - uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) - return 0; - PacketResponseNG resp; + int numberAuthRetries = ICLASS_AUTH_RETRY; + do { + + uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { + numberAuthRetries--; + DropField(); + continue; + } - Calc_wb_mac(blockno, bldata, div_key, MAC); - uint8_t data[12]; - memcpy(data, bldata, 8); - memcpy(data + 8, MAC, 4); + Calc_wb_mac(blockno, bldata, div_key, MAC); - clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_WRITEBL, blockno, 0, 0, data, sizeof(data)); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { - if (verbose) PrintAndLogEx(WARNING, "Write Command execute timeout"); - return 0; + struct p { + uint8_t blockno; + uint8_t data[12]; + } PACKED payload; + payload.blockno = blockno; + + memcpy(payload.data, bldata, 8); + memcpy(payload.data + 8, MAC, 4); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ICLASS_WRITEBL, (uint8_t*)&payload, sizeof(payload)); + PacketResponseNG resp; + + if (WaitForResponseTimeout(CMD_HF_ICLASS_WRITEBL, &resp, 4000) == 0) { + if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); + DropField(); + return PM3_ETIMEOUT; + } + + if ( resp.status != PM3_SUCCESS ) { + if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); + DropField(); + return PM3_EWRONGANSVER; + } + + if (resp.data.asBytes[0] == 1) + break; + + } while (numberAuthRetries); + + DropField(); + + if ( numberAuthRetries > 0 ) { + PrintAndLogEx(SUCCESS, "Write block %02X successful\n", blockno); + } else { + PrintAndLogEx(ERR,"failed to authenticate and write block"); + return PM3_ESOFT; } - uint8_t isOK = resp.oldarg[0] & 0xff; - if (isOK) - PrintAndLogEx(SUCCESS, "Write block successful"); - else - PrintAndLogEx(WARNING, "Write block failed"); - return isOK; + + return PM3_SUCCESS; } static int CmdHFiClass_WriteBlock(const char *Cmd) { @@ -1256,6 +1402,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { uint8_t keyNbr = 0; uint8_t dataLen = 0; char tempStr[50] = {0}; + bool got_blockno = false; bool use_credit_key = false; bool elite = false; bool rawkey = false; @@ -1267,13 +1414,12 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { case 'h': return usage_hf_iclass_writeblock(); case 'b': - if (param_gethex(Cmd, cmdp + 1, &blockno, 2)) { - PrintAndLogEx(WARNING, "Block No must include 2 HEX symbols\n"); - errors = true; - } + blockno = param_get8ex(Cmd, cmdp + 1, 07, 16); + got_blockno = true; cmdp += 2; break; case 'c': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT")); use_credit_key = true; cmdp++; break; @@ -1285,6 +1431,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { cmdp += 2; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1295,6 +1442,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1307,6 +1455,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1320,11 +1469,12 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { break; } } + if ( got_blockno == false) + errors = true; + if (errors || cmdp < 6) return usage_hf_iclass_writeblock(); - int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, verbose); - DropField(); - return ans; + return WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, verbose); } static int CmdHFiClassCloneTag(const char *Cmd) { @@ -1336,6 +1486,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { uint8_t startblock = 0; uint8_t endblock = 0; uint8_t dataLen = 0; + bool got_startblk = false, got_endblk = false; bool use_credit_key = false; bool elite = false; bool rawkey = false; @@ -1347,17 +1498,17 @@ static int CmdHFiClassCloneTag(const char *Cmd) { case 'h': return usage_hf_iclass_clone(); case 'b': - if (param_gethex(Cmd, cmdp + 1, &startblock, 2)) { - PrintAndLogEx(WARNING, "start block No must include 2 HEX symbols\n"); - errors = true; - } + startblock = param_get8ex(Cmd, cmdp + 1, 07, 16); + got_startblk = true; cmdp += 2; break; case 'c': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT")); use_credit_key = true; cmdp++; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1376,6 +1527,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1388,13 +1540,12 @@ static int CmdHFiClassCloneTag(const char *Cmd) { cmdp += 2; break; case 'l': - if (param_gethex(Cmd, cmdp + 1, &endblock, 2)) { - PrintAndLogEx(WARNING, "start Block No must include 2 HEX symbols\n"); - errors = true; - } + endblock = param_get8ex(Cmd, cmdp + 1, 07, 16); + got_endblk = true; cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1408,53 +1559,66 @@ static int CmdHFiClassCloneTag(const char *Cmd) { break; } } + if ( got_endblk == false || got_startblk == false) + errors = true; if (errors || cmdp < 8) return usage_hf_iclass_clone(); - FILE *f; - - iclass_block_t tag_data[PM3_CMD_DATA_SIZE / 12]; - - if ((endblock - startblock + 1) * 12 > PM3_CMD_DATA_SIZE) { - PrintAndLogEx(NORMAL, "Trying to write too many blocks at once. Max: %d", PM3_CMD_DATA_SIZE / 8); + if (startblock < 5) { + PrintAndLogEx(WARNING, "you cannot write key blocks this way. yet... make your start block > 4"); + return PM3_EINVARG; } + + int total_bytes = (((endblock - startblock) + 1) * 12); + + if (total_bytes > PM3_CMD_DATA_SIZE - 2) { + PrintAndLogEx(NORMAL, "Trying to write too many blocks at once. Max: %d", PM3_CMD_DATA_SIZE / 8); + return PM3_EINVARG; + } + // file handling and reading - f = fopen(filename, "rb"); + FILE *f = fopen(filename, "rb"); if (!f) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); return PM3_EFILE; } - if (startblock < 5) { - PrintAndLogEx(WARNING, "you cannot write key blocks this way. yet... make your start block > 4"); - fclose(f); - return 0; - } - // now read data from the file from block 6 --- 19 - // ok we will use this struct [data 8 bytes][MAC 4 bytes] for each block calculate all mac number for each data - // then copy to usbcommand->asbytes; the max is 32 - 6 = 24 block 12 bytes each block 288 bytes then we can only accept to clone 21 blocks at the time, - // else we have to create a share memory + iclass_block_t tag_data[PM3_CMD_DATA_SIZE / 12]; + + // read data from file from block 6 --- 19 + // we will use this struct [data 8 bytes][MAC 4 bytes] for each block calculate all mac number for each data + // then copy to usbcommand->asbytes; + // max is 32 - 6 = 28 block. 28 x 12 bytes gives 336 bytes int i; fseek(f, startblock * 8, SEEK_SET); size_t bytes_read = fread(tag_data, sizeof(iclass_block_t), endblock - startblock + 1, f); + fclose(f); + if (bytes_read == 0) { PrintAndLogEx(ERR, "file reading error."); - fclose(f); - return 2; + return PM3_EFILE; } - fclose(f); - uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) { - return 0; + + int numberAuthRetries = ICLASS_AUTH_RETRY; + do { + if (select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) + break; + } while (numberAuthRetries--); + + if ( numberAuthRetries <= 0 ) { + PrintAndLogEx(ERR, "failed to authenticate"); + DropField(); + return PM3_ESOFT; } - uint8_t data[(endblock - startblock) * 12]; + uint8_t data[total_bytes]; + // calculate all mac for every the block we will write for (i = startblock; i <= endblock; i++) { + Calc_wb_mac(i, tag_data[i - startblock].d, div_key, MAC); // usb command d start pointer = d + (i - 6) * 12 // memcpy(pointer,tag_data[i - 6],8) 8 bytes @@ -1464,54 +1628,113 @@ static int CmdHFiClassCloneTag(const char *Cmd) { memcpy(ptr, &(tag_data[i - startblock].d[0]), 8); memcpy(ptr + 8, MAC, 4); } - uint8_t p[12]; - for (i = 0; i <= endblock - startblock; i++) { - memcpy(p, data + (i * 12), 12); - PrintAndLogEx(NORMAL, "Block |%02x|", i + startblock); - PrintAndLogEx(NORMAL, " %02x%02x%02x%02x%02x%02x%02x%02x |", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - PrintAndLogEx(NORMAL, " MAC |%02x%02x%02x%02x|\n", p[8], p[9], p[10], p[11]); + + if ( verbose ) { + PrintAndLogEx(NORMAL,"------+--------------------------+-------------"); + PrintAndLogEx(NORMAL,"block | data | mac"); + PrintAndLogEx(NORMAL,"------+--------------------------+-------------"); + uint8_t p[12]; + for (i = 0; i <= endblock - startblock; i++) { + memcpy(p, data + (i * 12), 12); + char *s = calloc(70, sizeof(uint8_t)); + sprintf(s, "| %s ", sprint_hex(p, 8)); + sprintf(s + strlen(s), "| %s", sprint_hex(p + 8, 4)); + PrintAndLogEx(NORMAL, " %02X %s", i + startblock, s ); + free(s); + } } + struct p { + uint8_t startblock; + uint8_t endblock; + uint8_t data[PM3_CMD_DATA_SIZE - 2]; + } PACKED payload; + + payload.startblock = startblock; + payload.endblock = endblock; + memcpy(payload.data, data, total_bytes); + PacketResponseNG resp; clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_CLONE, startblock, endblock, 0, data, (endblock - startblock) * 12); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { + SendCommandNG(CMD_HF_ICLASS_CLONE, (uint8_t*)&payload, total_bytes + 2 ); + + if (WaitForResponseTimeout(CMD_HF_ICLASS_CLONE, &resp, 4500) == 0) { PrintAndLogEx(WARNING, "command execute timeout"); - return 0; + DropField(); + return PM3_ETIMEOUT; } - return PM3_SUCCESS; + + if (resp.status == PM3_SUCCESS) { + if ( resp.data.asBytes[0] == 1 ) + PrintAndLogEx(SUCCESS, "Clone successful"); + else + PrintAndLogEx(WARNING, "Clone failed"); + } + return resp.status; } static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) { - // block 0,1 should always be able to read, and block 5 on some cards. - if (auth || blockno >= 2) { - uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose)) - return 0; - } else { - uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_only(CSN, CCNR, (keyType == 0x18), verbose)) - return 0; + + int numberAuthRetries = ICLASS_AUTH_RETRY; + // return data. + struct p { + bool isOK; + uint8_t blockdata[8]; + } PACKED; + + struct p *result = NULL; + + do { + // block 0,1 should always be able to read, and block 5 on some cards. + if (auth || blockno >= 2) { + uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose)) { + numberAuthRetries--; + DropField(); + continue; + } + } else { + uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + if (!select_only(CSN, CCNR, (keyType == 0x18), verbose)) { + numberAuthRetries--; + DropField(); + continue; + } + } + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ICLASS_READBL, (uint8_t*)&blockno, sizeof(uint8_t)); + + if (WaitForResponseTimeout(CMD_HF_ICLASS_READBL, &resp, 2000) == 0) { + if (verbose) PrintAndLogEx(WARNING, "Command execute timeout"); + DropField(); + return PM3_ETIMEOUT; + } + + if ( resp.status != PM3_SUCCESS ) { + if (verbose) PrintAndLogEx(ERR, "failed to communicate with card"); + DropField(); + return PM3_EWRONGANSVER; + } + + result = (struct p*)resp.data.asBytes; + if (result->isOK) + break; + + } while (numberAuthRetries); + + DropField(); + + if ( numberAuthRetries == 0 ) { + PrintAndLogEx(ERR,"failed to authenticate and read block"); + return PM3_ESOFT; } - PacketResponseNG resp; - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ICLASS_READBL, blockno, 0, 0, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) { - PrintAndLogEx(WARNING, "Command execute timeout"); - return 0; - } - - uint8_t isOK = resp.oldarg[0] & 0xff; - if (!isOK) { - PrintAndLogEx(WARNING, "read block failed"); - return 0; - } - //data read is stored in: resp.data.asBytes[0-15] - PrintAndLogEx(NORMAL, "block %02X: %s\n", blockno, sprint_hex(resp.data.asBytes, 8)); - return 1; + PrintAndLogEx(SUCCESS, "block %02X: %s\n", blockno, sprint_hex(result->blockdata, sizeof(result->blockdata))); + return PM3_SUCCESS; } static int CmdHFiClass_ReadBlock(const char *Cmd) { @@ -1521,6 +1744,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { uint8_t keyNbr = 0; uint8_t dataLen = 0; char tempStr[50] = {0}; + bool got_blockno = false; bool elite = false; bool rawkey = false; bool errors = false; @@ -1532,17 +1756,17 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { case 'h': return usage_hf_iclass_readblock(); case 'b': - if (param_gethex(Cmd, cmdp + 1, &blockno, 2)) { - PrintAndLogEx(WARNING, "Block No must include 2 HEX symbols\n"); - errors = true; - } + blockno = param_get8ex(Cmd, cmdp + 1, 7, 16); + got_blockno = true; cmdp += 2; break; case 'c': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT")); keyType = 0x18; cmdp++; break; case 'e': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); elite = true; cmdp++; break; @@ -1554,6 +1778,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr < ICLASS_KEYS_MAX) { + PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 )); memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); @@ -1566,6 +1791,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { cmdp += 2; break; case 'r': + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); rawkey = true; cmdp++; break; @@ -1579,10 +1805,14 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { break; } } + if ( got_blockno == false) + errors = true; + if (errors || cmdp < 4) return usage_hf_iclass_readblock(); if (!auth) PrintAndLogEx(FAILED, "warning: no authentication used with read, only a few specific blocks can be read accurately without authentication."); + return ReadBlock(KEY, blockno, keyType, elite, rawkey, verbose, auth); } @@ -1590,7 +1820,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { char opt = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) < 1 || opt == 'h') - usage_hf_iclass_loclass(); + return usage_hf_iclass_loclass(); if (opt == 'f') { char fileName[FILE_PATH_SIZE] = {0}; @@ -1598,7 +1828,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { return bruteforceFileNoKeys(fileName); } else { PrintAndLogEx(WARNING, "You must specify a filename"); - return 0; + return PM3_EFILE; } } else if (opt == 't') { int errors = testCipherUtils(); @@ -1606,7 +1836,7 @@ static int CmdHFiClass_loclass(const char *Cmd) { errors += doKeyTests(0); errors += testElite(); if (errors) PrintAndLogEx(ERR, "There were errors!!!"); - return errors; + return PM3_ESOFT; } return PM3_SUCCESS; } @@ -1636,13 +1866,13 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e //PrintAndLog ("startblock: %d, endblock: %d, filesize: %d, maxmemcount: %d, filemaxblock: %d",startblock, endblock,filesize, maxmemcount, filemaxblock); int i = startblock; - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); + PrintAndLogEx(NORMAL, "------+--+-------------------------+"); while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); - PrintAndLogEx(NORMAL, " |%02X| %s\n", i, sprint_hex_ascii(blk, 8)); + PrintAndLogEx(NORMAL, " |%02X| %s", i, sprint_hex_ascii(blk, 8)); i++; } - PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); + PrintAndLogEx(NORMAL, "------+--+-------------------------+"); } static int CmdHFiClassReadTagFile(const char *Cmd) { @@ -1813,8 +2043,10 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) { if (!givenCSN) { uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (!select_only(CSN, CCNR, false, true)) + if (!select_only(CSN, CCNR, false, true)) { + DropField(); return 0; + } } HFiClassCalcNewKey(CSN, OLDKEY, NEWKEY, xor_div_key, elite, oldElite, true); @@ -1856,7 +2088,7 @@ static int loadKeys(char *filename) { memcpy(iClass_Key_Table[i], dump + (i * 8), 8); free(dump); - PrintAndLogEx(SUCCESS, "%u keys loaded", i); + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") "keys from %s", i, filename); return PM3_SUCCESS; } @@ -1879,8 +2111,12 @@ static int saveKeys(char *filename) { static int printKeys(void) { PrintAndLogEx(NORMAL, ""); - for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) - PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8)); + for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { + if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) + PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8)); + else + PrintAndLogEx(NORMAL, "%u: "_YELLOW_("%s"), i, sprint_hex(iClass_Key_Table[i], 8)); + } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1911,7 +2147,7 @@ static int CmdHFiClassManageKeys(const char *Cmd) { case 'n': keyNbr = param_get8(Cmd, cmdp + 1); if (keyNbr >= ICLASS_KEYS_MAX) { - PrintAndLogEx(ERR, "Invalid block number, MAX is "_YELLOW_("%d"), ICLASS_KEYS_MAX); + PrintAndLogEx(ERR, "Invalid block number, MAX is " _YELLOW_("%d"), ICLASS_KEYS_MAX); errors = true; } cmdp += 2; @@ -1963,14 +2199,13 @@ static int CmdHFiClassManageKeys(const char *Cmd) { switch (operation) { case 3: memcpy(iClass_Key_Table[keyNbr], KEY, 8); - return 1; + return PM3_SUCCESS; case 4: return printKeys(); case 5: return loadKeys(filename); case 6: return saveKeys(filename); - break; } return PM3_SUCCESS; } @@ -1995,10 +2230,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; uint8_t fileNameLen = 0; - - uint8_t *keyBlock = NULL; iclass_premac_t *pre = NULL; - int keycnt = 0; // time uint64_t t1 = msclock(); @@ -2010,7 +2242,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { case 'f': fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); if (fileNameLen < 1) { - PrintAndLogEx(WARNING, "no filename found after f"); + PrintAndLogEx(WARNING, _RED_("no filename found after f")); errors = true; } cmdp += 2; @@ -2036,62 +2268,64 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { if (errors) return usage_hf_iclass_chk(); + uint8_t *keyBlock = NULL; + uint16_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { + free(keyBlock); + return res; + } + // Get CSN / UID and CCNR PrintAndLogEx(SUCCESS, "Reading tag CSN"); - for (uint8_t i = 0; i < 10 && !got_csn; i++) { - if (select_only(CSN, CCNR, false, false)) { - got_csn = true; - } else { - PrintAndLogEx(WARNING, "one more try\n"); - } + for (uint8_t i = 0; i < ICLASS_AUTH_RETRY && !got_csn; i++) { + got_csn = select_only(CSN, CCNR, false, false); + if (got_csn == false) + PrintAndLogEx(WARNING, "one more try"); } - if (!got_csn) { - PrintAndLogEx(WARNING, "can't select card, aborting..."); - return 1; + if (got_csn == false) { + PrintAndLogEx(WARNING, "Tried 10 times. Can't select card, aborting..."); + DropField(); + return PM3_ESOFT; } - // load keys into keyblock - int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { - free(keyBlock); - return 1; - } - - pre = calloc(keycnt, sizeof(iclass_premac_t)); + pre = calloc(keycount, sizeof(iclass_premac_t)); if (!pre) { + DropField(); free(keyBlock); - return 1; + return PM3_EMALLOC; } - PrintAndLogEx(SUCCESS, "Generating diversified keys, MAC"); + PrintAndLogEx(SUCCESS, "Generating diversified keys"); if (use_elite) - PrintAndLogEx(SUCCESS, "Using elite algo"); + PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); if (use_raw) - PrintAndLogEx(SUCCESS, "Using raw mode"); + PrintAndLogEx(SUCCESS, "Using " _YELLOW_(" raw mode")); - PrintAndLogEx(SUCCESS, "Searching for %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))); - res = GenerateMacFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, pre); - if (res > 0) { - free(keyBlock); - free(pre); - return 1; - } + + GenerateMacFrom(CSN, CCNR, use_raw, use_elite, keyBlock, keycount, pre); //PrintPreCalcMac(keyBlock, keycnt, pre); // max 42 keys inside USB_COMMAND. 512/4 = 103 mac - uint32_t chunksize = keycnt > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycnt; + uint32_t chunksize = keycount > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycount; bool lastChunk = false; // fast push mode conn.block_after_ACK = true; + // keep track of position of found key + uint8_t found_offset = 0; + uint32_t key_offset = 0; // main keychunk loop - for (uint32_t i = 0; i < keycnt; i += chunksize) { + for (uint32_t key_offset = 0; key_offset < keycount; key_offset += chunksize) { uint64_t t2 = msclock(); uint8_t timeout = 0; @@ -2101,10 +2335,10 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { goto out; } - uint32_t keys = ((keycnt - i) > chunksize) ? chunksize : keycnt - i; + uint32_t keys = ((keycount - key_offset) > chunksize) ? chunksize : keycount - key_offset; // last chunk? - if (keys == keycnt - i) { + if (keys == keycount - key_offset) { lastChunk = true; // Disable fast mode on last command conn.block_after_ACK = false; @@ -2116,7 +2350,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { flags |= (use_credit_key << 16); clearCommandBuffer(); - SendCommandOLD(CMD_HF_ICLASS_CHKKEYS, flags, keys, 0, pre + i, 4 * keys); + SendCommandOLD(CMD_HF_ICLASS_CHKKEYS, flags, keys, 0, pre + key_offset, 4 * keys); PacketResponseNG resp; while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { @@ -2129,7 +2363,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { } } - uint8_t found = resp.oldarg[1] & 0xFF; + found_offset = resp.oldarg[1] & 0xFF; uint8_t isOK = resp.oldarg[0] & 0xFF; t2 = msclock() - t2; @@ -2137,20 +2371,20 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { case 1: { found_debit = true; - PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] found key %s (index %u)" - , i - , keycnt + PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d]: %.1fs [%s] idx [%u] - found key "_YELLOW_("%s") + , key_offset + , keycount , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" - , sprint_hex(keyBlock + (i + found) * 8, 8) - , found + , found_offset + , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) ); break; } case 0: { PrintAndLogEx(NORMAL, "\n[-] Chunk [%d/%d] : %.1fs [%s]" - , i - , keycnt + , key_offset + , keycount , (float)(t2 / 1000.0) , (use_credit_key) ? "credit" : "debit" ); @@ -2174,8 +2408,22 @@ out: t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "\nTime in iclass checkkeys: %.0f seconds\n", (float)t1 / 1000.0); - DropField(); + + // add to managekeys + if (found_debit) { + for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { + // simple check for preexistences + if (memcmp(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8) == 0) break; + + if (memcmp(iClass_Key_Table[i], "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) { + memcpy(iClass_Key_Table[i], keyBlock + (key_offset + found_offset) * 8, 8); + PrintAndLogEx(SUCCESS, "Added key to keyslot [%d] - "_YELLOW_("`hf iclass managekeys p`")" to view", i); + break; + } + } + } + free(pre); free(keyBlock); return PM3_SUCCESS; @@ -2212,12 +2460,9 @@ static int CmdHFiClassLookUp(const char *Cmd) { uint8_t cmdp = 0x00; char filename[FILE_PATH_SIZE] = {0}; - uint8_t fileNameLen = 0; - uint8_t *keyBlock = NULL; iclass_prekey_t *prekey = NULL; - int keycnt = 0, len = 0; - + int len = 0; // if empty string if (strlen(Cmd) == 0) errors = true; // time @@ -2228,8 +2473,7 @@ static int CmdHFiClassLookUp(const char *Cmd) { case 'h': return usage_hf_iclass_lookup(); case 'f': - fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - if (fileNameLen < 1) { + if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) < 1) { PrintAndLogEx(WARNING, "No filename found after f"); errors = true; } @@ -2288,103 +2532,67 @@ static int CmdHFiClassLookUp(const char *Cmd) { PrintAndLogEx(SUCCESS, "CCNR | %s", sprint_hex(CCNR, sizeof(CCNR))); PrintAndLogEx(SUCCESS, "MAC_TAG | %s", sprint_hex(MAC_TAG, sizeof(MAC_TAG))); - int res = LoadDictionaryKeyFile(filename, &keyBlock, &keycnt); - if (res > 0) { + uint8_t *keyBlock = NULL; + uint16_t keycount = 0; + + // load keys + int res = loadFileDICTIONARY_safe(filename, (void **)&keyBlock, 8, &keycount); + if (res != PM3_SUCCESS || keycount == 0) { free(keyBlock); - return 1; + return res; } + //iclass_prekey_t - prekey = calloc(keycnt, sizeof(iclass_prekey_t)); + prekey = calloc(keycount, sizeof(iclass_prekey_t)); if (!prekey) { free(keyBlock); - return 1; + return PM3_EMALLOC; } - PrintAndLogEx(FAILED, "Generating diversified keys and MAC"); - res = GenerateFromKeyFile(CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, prekey); - if (res > 0) { - free(keyBlock); - free(prekey); - return 1; - } + PrintAndLogEx(INFO, "Generating diversified keys"); + GenerateMacKeyFrom(CSN, CCNR, use_raw, use_elite, keyBlock, keycount, prekey); - PrintAndLogEx(FAILED, "Sorting"); + PrintAndLogEx(INFO, "Sorting"); // sort mac list. - qsort(prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); + qsort(prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); //PrintPreCalc(prekey, keycnt); - PrintAndLogEx(FAILED, "Searching"); + PrintAndLogEx(INFO, "Searching"); iclass_prekey_t *item; iclass_prekey_t lookup; memcpy(lookup.mac, MAC_TAG, 4); // binsearch - item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycnt, sizeof(iclass_prekey_t), cmp_uint32); - if (item != NULL) - PrintAndLogEx(SUCCESS, "\n[debit] found key %s", sprint_hex(item->key, 8)); + item = (iclass_prekey_t *) bsearch(&lookup, prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); t1 = msclock() - t1; PrintAndLogEx(NORMAL, "\nTime in iclass : %.0f seconds\n", (float)t1 / 1000.0); + + // foudn + if (item != NULL) { + PrintAndLogEx(SUCCESS, "[debit] found key " _YELLOW_("%s"), sprint_hex(item->key, 8)); + for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) { + // simple check for preexistences + if (memcmp(item->key, iClass_Key_Table[i], 8) == 0) break; + + 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); + break; + } + } + } + free(prekey); free(keyBlock); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt) { - - char buf[17]; - FILE *f; - uint8_t *p; - int keyitems = 0; - - if (!(f = fopen(filename, "r"))) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - return 1; - } - - while (fgets(buf, sizeof(buf), f)) { - if (strlen(buf) < 16 || buf[15] == '\n') - continue; - - //goto next line - while (fgetc(f) != '\n' && !feof(f)) {}; - - //The line start with # is comment, skip - if (buf[0] == '#') - continue; - - // doesn't this only test first char only? - if (!isxdigit(buf[0])) { - PrintAndLogEx(ERR, "file content error. '%s' must include 16 HEX symbols", buf); - continue; - } - - // null terminator (skip the rest of the line) - buf[16] = 0; - - p = realloc(*keys, 8 * (keyitems += 64)); - if (!p) { - PrintAndLogEx(ERR, "cannot allocate memory for default keys"); - fclose(f); - return 2; - } - *keys = p; - - memset(*keys + 8 * (*keycnt), 0, 8); - num_to_bytes(strtoull(buf, NULL, 16), 8, *keys + 8 * (*keycnt)); - (*keycnt)++; - memset(buf, 0, sizeof(buf)); - } - fclose(f); - PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from %s", *keycnt, filename); - return PM3_SUCCESS; -} - // precalc diversified keys and their MAC -int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list) { uint8_t key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -2399,10 +2607,9 @@ int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_e doMAC(CCNR, div_key, list[i].mac); } - return PM3_SUCCESS; } -int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list) { uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -2419,7 +2626,6 @@ int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit // generate MAC doMAC(CCNR, div_key, list[i].mac); } - return PM3_SUCCESS; } // print diversified keys @@ -2553,25 +2759,26 @@ static int CmdHFiClassPermuteKey(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"calcnewkey", CmdHFiClassCalcNewKey, AlwaysAvailable, "[options..] Calc Diversified keys (blocks 3 & 4) to write new keys"}, - {"chk", CmdHFiClassCheckKeys, AlwaysAvailable, " Check keys"}, - {"clone", CmdHFiClassCloneTag, IfPm3Iclass, "[options..] Authenticate and Clone from iClass bin file"}, - {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[f ] Decrypt tagdump" }, - {"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Authenticate and Dump iClass tag's AA1"}, - {"eload", CmdHFiClassELoad, IfPm3Iclass, "[f ] (experimental) Load data into iClass emulator memory"}, - {"encryptblk", CmdHFiClassEncryptBlk, AlwaysAvailable, " Encrypt given block data"}, - {"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"}, - {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce of reader attack dump"}, + {"calcnewkey", CmdHFiClassCalcNewKey, AlwaysAvailable, "[options..] Calc diversified keys (blocks 3 & 4) to write new keys"}, + {"chk", CmdHFiClassCheckKeys, AlwaysAvailable, "[options..] Check keys"}, + {"clone", CmdHFiClassCloneTag, IfPm3Iclass, "[options..] Restore a dump file onto a iClass tag"}, + {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[options..] Decrypt given block data or tag dump file" }, + {"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Dump iClass tag to file"}, + {"eload", CmdHFiClassELoad, IfPm3Iclass, "[f ] Load iClass dump file into emulator memory"}, + {"encrypt", CmdHFiClassEncryptBlk, AlwaysAvailable, "[options..] Encrypt given block data"}, + {"info", CmdHFiClassInfo, AlwaysAvailable, " Tag information"}, + {"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"}, + {"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce reader attack"}, {"lookup", CmdHFiClassLookUp, AlwaysAvailable, "[options..] Uses authentication trace to check for key in dictionary file"}, - {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage the keys to use with iClass"}, + {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage keys to use with iClass"}, {"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"}, - {"readblk", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Authenticate and Read iClass block"}, + {"rdbl", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"}, {"reader", CmdHFiClassReader, IfPm3Iclass, " Act like an iClass reader"}, - {"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display Content from tagfile"}, - {"replay", CmdHFiClassReader_Replay, IfPm3Iclass, " Read an iClass tag via Replay Attack"}, + {"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display content from tag dump file"}, + {"replay", CmdHFiClassReader_Replay, IfPm3Iclass, " Read iClass tag via replay attack"}, {"sim", CmdHFiClassSim, IfPm3Iclass, "[options..] Simulate iClass tag"}, {"sniff", CmdHFiClassSniff, IfPm3Iclass, " Eavesdrop iClass communication"}, - {"writeblk", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Authenticate and Write iClass block"}, + {"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"}, {NULL, NULL, NULL, NULL} }; @@ -2603,26 +2810,28 @@ int readIclass(bool loop, bool verbose) { uint8_t readStatus = resp.oldarg[0] & 0xff; uint8_t *data = resp.data.asBytes; - if (verbose) PrintAndLogEx(NORMAL, "Readstatus:%02x", readStatus); + if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus); + // no tag found or button pressed if ((readStatus == 0 && !loop) || readStatus == 0xFF) { // abort - if (verbose) { - PrintAndLogEx(FAILED, "Quitting..."); - DropField(); - return 0; - } + DropField(); + return PM3_EOPABORTED; } + if (readStatus & FLAG_ICLASS_READER_CSN) { PrintAndLogEx(NORMAL, " CSN: %s", sprint_hex(data, 8)); tagFound = true; } + if (readStatus & FLAG_ICLASS_READER_CC) { PrintAndLogEx(NORMAL, " CC: %s", sprint_hex(data + 16, 8)); } + if (readStatus & FLAG_ICLASS_READER_CONF) { printIclassDumpInfo(data); } + if (readStatus & FLAG_ICLASS_READER_AIA) { bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0); @@ -2639,7 +2848,7 @@ int readIclass(bool loop, bool verbose) { if (tagFound && !loop) { DropField(); - return 1; + return PM3_SUCCESS; } } else { if (verbose) diff --git a/client/cmdhficlass.h b/client/cmdhficlass.h index 9f2b5caac..73304d4d0 100644 --- a/client/cmdhficlass.h +++ b/client/cmdhficlass.h @@ -12,6 +12,7 @@ #define CMDHFICLASS_H__ #include "common.h" +#include "fileutils.h" typedef struct iclass_block { uint8_t d[8]; @@ -32,9 +33,8 @@ int readIclass(bool loop, bool verbose); void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize); void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite); -int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt); -int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); -int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); +void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list); +void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list); void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list); void PrintPreCalc(iclass_prekey_t *list, int itemcnt); #endif diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index af56807b1..fe1f53785 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -17,7 +17,7 @@ #include "cmdtrace.h" #include "crc.h" #include "crc16.h" -#include "loclass/fileutils.h" //saveFile +#include "fileutils.h" //saveFile static int CmdHelp(const char *Cmd); diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 5a2ff5248..d44ac635c 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -323,10 +323,31 @@ void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { - switch (cmd[0]) { + uint8_t c = cmd[0] & 0x0F; + uint8_t parity = 0; + for ( uint8_t i=0; i<7; i++) { + parity ^= (cmd[0] >> i) & 1; + } + + switch (c) { + case ICLASS_CMD_HALT: + snprintf(exp, size, "HALT"); + break; + case ICLASS_CMD_SELECT: + snprintf(exp, size, "SELECT"); + break; case ICLASS_CMD_ACTALL: snprintf(exp, size, "ACTALL"); break; + case ICLASS_CMD_DETECT: + snprintf(exp, size, "DETECT"); + break; + case ICLASS_CMD_CHECK: + snprintf(exp, size, "CHECK"); + break; + case ICLASS_CMD_READ4: + snprintf(exp, size, "READ4(%d)", cmd[1]); + break; case ICLASS_CMD_READ_OR_IDENTIFY: { if (cmdsize > 1) { snprintf(exp, size, "READ(%d)", cmd[1]); @@ -335,36 +356,22 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } break; } - case ICLASS_CMD_SELECT: - snprintf(exp, size, "SELECT"); - break; case ICLASS_CMD_PAGESEL: snprintf(exp, size, "PAGESEL(%d)", cmd[1]); break; - case ICLASS_CMD_READCHECK_KC: - snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]); - break; - case ICLASS_CMD_READCHECK_KD: - snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]); - break; - case ICLASS_CMD_CHECK: - snprintf(exp, size, "CHECK"); - break; - case ICLASS_CMD_DETECT: - snprintf(exp, size, "DETECT"); - break; - case ICLASS_CMD_HALT: - snprintf(exp, size, "HALT"); - break; case ICLASS_CMD_UPDATE: snprintf(exp, size, "UPDATE(%d)", cmd[1]); break; + case ICLASS_CMD_READCHECK: + if ( ICLASS_CREDIT(c) ) { + snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]); + } else { + snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]); + } + break; case ICLASS_CMD_ACT: snprintf(exp, size, "ACT"); break; - case ICLASS_CMD_READ4: - snprintf(exp, size, "READ4(%d)", cmd[1]); - break; default: snprintf(exp, size, "?"); break; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index affc53603..baa999128 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -15,7 +15,7 @@ #include "cmdparser.h" // command_t #include "commonutil.h" // ARRAYLEN #include "comms.h" // clearCommandBuffer -#include "loclass/fileutils.h" +#include "fileutils.h" #include "cmdtrace.h" #include "emv/dump.h" #include "mifare/mifaredefault.h" // mifare default key array @@ -41,7 +41,7 @@ static int CmdHelp(const char *Cmd); static int usage_hf14_ice(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf ice [l] [f] "); + PrintAndLogEx(NORMAL, "Usage: hf mf ice [l ] [f ]"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " l nonces to be collected"); PrintAndLogEx(NORMAL, " f save nonces to instead of hf-mf--nonces.bin"); @@ -53,7 +53,7 @@ static int usage_hf14_ice(void) { } static int usage_hf14_dump(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf dump [card memory] k f "); + PrintAndLogEx(NORMAL, "Usage: hf mf dump [card memory] [k ] [f ]"); PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLogEx(NORMAL, " k : key filename, if no given, UID will be used as filename"); PrintAndLogEx(NORMAL, " f : data filename, if no given, UID will be used as filename"); @@ -65,7 +65,7 @@ static int usage_hf14_dump(void) { } static int usage_hf14_mifare(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf darkside [h] "); + PrintAndLogEx(NORMAL, "Usage: hf mf darkside "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " (Optional) target other block"); @@ -77,7 +77,7 @@ static int usage_hf14_mifare(void) { return 0; } static int usage_hf14_mfsim(void) { - PrintAndLogEx(NORMAL, "Usage: hf mf sim [h] u n [i] [x] [e] [v]"); + PrintAndLogEx(NORMAL, "Usage: hf mf sim [u ] [n ] [t] [a ] [s ] [i] [x] [e] [v]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " u (Optional) UID 4,7 or 10bytes. If not specified, the UID 4b/7b from emulator memory will be used"); @@ -166,6 +166,42 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); return 0; } +static int usage_hf14_autopwn(void) { + PrintAndLogEx(NORMAL, "Usage:"); + PrintAndLogEx(NORMAL, " hf mf autopwn [k] "); + PrintAndLogEx(NORMAL, " [* ] [f [.dic]] [s] [i ] [l] [v]"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Description:"); + PrintAndLogEx(NORMAL, " This command automates the key recovery process on Mifare classic cards."); + PrintAndLogEx(NORMAL, " It uses the darkside, nested and hardnested attack to extract the keys and card content."); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " k known key is supplied"); + PrintAndLogEx(NORMAL, " f [.dic] key dictionary file"); + PrintAndLogEx(NORMAL, " s slower acquisition for hardnested (required by some non standard cards)"); + PrintAndLogEx(NORMAL, " v verbose output (statistics)"); + PrintAndLogEx(NORMAL, " l legacy mode (use the slow 'mf chk' for the key enumeration)"); + PrintAndLogEx(NORMAL, " * all sectors based on card memory"); + PrintAndLogEx(NORMAL, " * 0 = MINI(320 bytes)"); + PrintAndLogEx(NORMAL, " * 1 = 1k (default)"); + PrintAndLogEx(NORMAL, " * 2 = 2k"); + PrintAndLogEx(NORMAL, " * 4 = 4k"); + PrintAndLogEx(NORMAL, " i set type of SIMD instructions for hardnested. Default: autodetection."); + PrintAndLogEx(NORMAL, " i 5 = AVX512"); + PrintAndLogEx(NORMAL, " i 2 = AVX2"); + PrintAndLogEx(NORMAL, " i a = AVX"); + PrintAndLogEx(NORMAL, " i s = SSE2"); + PrintAndLogEx(NORMAL, " i m = MMX"); + PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mf autopwn -- target Mifare classic card with default keys"); + PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- target Mifare classic card (size 1k) with default dictionary"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- target Mifare classic card with Sector0 typeA with known key 'FFFFFFFFFFFF'"); + PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); + return 0; +} static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, "Usage: hf mf chk [h] |<*card memory> [t|d] [] []"); PrintAndLogEx(NORMAL, "Options:"); @@ -179,10 +215,10 @@ static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, " t write keys to emulator memory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf chk 0 A 1234567890ab -- target block 0, Key A using key 1234567890ab"); - PrintAndLogEx(NORMAL, " hf mf chk 0 A default_keys.dic -- target block 0, Key A using default dictionary file"); - PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); + PrintAndLogEx(NORMAL, " hf mf chk 0 A 1234567890ab -- target block 0, Key A using key 1234567890ab"); + PrintAndLogEx(NORMAL, " hf mf chk 0 A mfc_default_keys.dic -- target block 0, Key A using default dictionary file"); + PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); return 0; } static int usage_hf14_chk_fast(void) { @@ -200,14 +236,15 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " m use dictionary from flashmemory\n"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 1234567890ab -- target 1K using key 1234567890ab"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 default_keys.dic -- target 1K using default dictionary file"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 t -- target 1K, write to emulator memory"); - PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 1234567890ab -- target 1K using key 1234567890ab"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 mfc_default_keys.dic -- target 1K using default dictionary file"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 t -- target 1K, write to emulator memory"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); if (IfPm3Flash()) - PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); + PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); return 0; } +/* static int usage_hf14_keybrute(void) { PrintAndLogEx(NORMAL, "J_Run's 2nd phase of multiple sector nested authentication key recovery"); PrintAndLogEx(NORMAL, "You have a known 4 last bytes of a key recovered with mf_nonce_brute tool."); @@ -225,6 +262,7 @@ static int usage_hf14_keybrute(void) { PrintAndLogEx(NORMAL, " hf mf keybrute 1 A 000011223344"); return 0; } +*/ static int usage_hf14_restore(void) { PrintAndLogEx(NORMAL, "Usage: hf mf restore [card memory] u k f "); PrintAndLogEx(NORMAL, "Options:"); @@ -716,6 +754,55 @@ static uint8_t NumBlocksPerSector(uint8_t sectorNo) { } } +static uint8_t GetSectorFromBlockNo(uint8_t blockNo) { + if (blockNo < 128) + return blockNo / 4; + else + return 32 + ((128 - blockNo) / 16); +} + +static char GetFormatFromSector(uint8_t sectorNo) { + switch (sectorNo) { + case MIFARE_MINI_MAXSECTOR: + return '0'; + case MIFARE_1K_MAXSECTOR: + return '1'; + case MIFARE_2K_MAXSECTOR: + return '2'; + case MIFARE_4K_MAXSECTOR: + return '4'; + default : + return ' '; + } +} + +static int FastDumpWithEcFill(uint8_t numsectors) { + PacketResponseNG resp; + + mfc_eload_t payload; + payload.sectorcnt = numsectors; + payload.keytype = 0; + + // ecfill key A + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + + int res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); + if (res != PM3_SUCCESS) { + } + + // ecfill key B + payload.keytype = 1; + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); + res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000); + if (res != PM3_SUCCESS) { + + } + return PM3_SUCCESS; +} + static int CmdHF14AMfDump(const char *Cmd) { uint64_t t1 = msclock(); @@ -922,9 +1009,11 @@ static int CmdHF14AMfDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "\nSucceded in dumping all blocks"); if (strlen(dataFilename) < 1) { - fptr = dataFilename; - fptr += sprintf(fptr, "hf-mf-"); - FillFileNameByUID(fptr, (uint8_t *)carddata, "-data", 4); + fptr = GenerateFilename("hf-mf-", "-data"); + if (fptr == NULL) + return PM3_ESOFT; + + strcpy(dataFilename, fptr); } uint16_t bytes = 16 * (FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1)); @@ -1186,6 +1275,10 @@ static int CmdHF14AMfNested(const char *Cmd) { e_sector = calloc(SectorsCnt, sizeof(sector_t)); if (e_sector == NULL) return PM3_EMALLOC; + // add our known key + e_sector[GetSectorFromBlockNo(blockNo)].foundKey[keyType] = 1; + e_sector[GetSectorFromBlockNo(blockNo)].Key[keyType] = key64; + //test current key and additional standard keys first // add parameter key memcpy(keyBlock + (ARRAYLEN(g_mifare_default_keys) * 6), key, 6); @@ -1195,7 +1288,12 @@ static int CmdHF14AMfNested(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt); - mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); + int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); + if (res == PM3_SUCCESS) { + // all keys found + PrintAndLogEx(SUCCESS, "Fast check found all keys"); + goto jumptoend; + } uint64_t t2 = msclock() - t1; PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0); @@ -1205,9 +1303,9 @@ static int CmdHF14AMfNested(const char *Cmd) { // int iterations = 0; bool calibrate = true; - for (int i = 0; i < MIFARE_SECTOR_RETRY; i++) { + for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; ++sectorNo) { - for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { + for (int i = 0; i < MIFARE_SECTOR_RETRY; i++) { if (e_sector[sectorNo].foundKey[trgKeyType]) continue; @@ -1282,6 +1380,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } } +jumptoend: //print them printKeyTable(SectorsCnt, e_sector); @@ -1530,6 +1629,679 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { return 0; } +static int CmdHF14AMfAutoPWN(const char *Cmd) { + // Nested and Hardnested parameter + uint8_t blockNo = 0; + uint8_t keyType = 0; + uint8_t key[6] = {0}; + uint64_t key64 = 0; + bool calibrate = true; + // Attack key storage variables + uint8_t *keyBlock = NULL; + uint16_t key_cnt = 0; + sector_t *e_sector; + uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; + int block_cnt = MIFARE_1K_MAXBLOCK; + uint8_t tmp_key[6] = {0}; + bool know_target_key = false; + // For the timier + uint64_t t1; + // Parameters and dictionary file + char filename[FILE_PATH_SIZE] = {0}; + uint8_t cmdp = 0; + char ctmp; + // Nested and Hardnested returned status + uint64_t foundkey = 0; + int16_t isOK = 0; + int current_sector_i = 0, current_key_type_i = 0; + // Dumping and transfere to simulater memory + uint8_t block[16] = {0x00}; + uint8_t *dump; + int bytes; + char *fnameptr = filename; + // Settings + bool slow = false; + bool legacy_mfchk = false; + int prng_type = PM3_EUNDEF; + bool verbose = false; + bool has_filename = false; + bool errors = false; + + // Parse the options given by the user + while ((ctmp = param_getchar(Cmd, cmdp)) && !errors) { + switch (tolower(ctmp)) { + case 'h': + return usage_hf14_autopwn(); + case 'f': + if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { + PrintAndLogEx(FAILED, "Filename too long"); + errors = true; + } else { + has_filename = true; + } + cmdp += 2; + break; + case 'l': + legacy_mfchk = true; + cmdp++; + break; + case 'v': + verbose = true; + cmdp++; + break; + case '*': + // Get the number of sectors + sectors_cnt = NumOfSectors(param_getchar(Cmd, cmdp + 1)); + block_cnt = NumOfBlocks(param_getchar(Cmd, cmdp + 1)); + cmdp += 2; + break; + case 'k': + // Get the known block number + if (param_getchar(Cmd, cmdp + 1) == 0x00) { + errors = true; + break; + } + + blockNo = param_get8(Cmd, cmdp + 1); + + // Get the knonwn block type + ctmp = tolower(param_getchar(Cmd, cmdp + 2)); + if (ctmp != 'a' && ctmp != 'b') { + PrintAndLogEx(WARNING, "Key type must be A or B"); + errors = true; + break; + } + + if (ctmp != 'a') { + keyType = 1; + } + + // Get the known block key + if (param_gethex(Cmd, cmdp + 3, key, 12)) { + PrintAndLogEx(WARNING, "Key must include 12 HEX symbols"); + errors = true; + return PM3_EINVARG; + } + know_target_key = true; + cmdp += 3; + case 's': + slow = true; + cmdp++; + break; + case 'i': + SetSIMDInstr(SIMD_AUTO); + ctmp = tolower(param_getchar(Cmd, cmdp + 1)); + switch (ctmp) { + case '5': + SetSIMDInstr(SIMD_AVX512); + break; + case '2': + SetSIMDInstr(SIMD_AVX2); + break; + case 'a': + SetSIMDInstr(SIMD_AVX); + break; + case 's': + SetSIMDInstr(SIMD_SSE2); + break; + case 'm': + SetSIMDInstr(SIMD_MMX); + break; + case 'n': + SetSIMDInstr(SIMD_NONE); + break; + default: + PrintAndLogEx(WARNING, "Unknown SIMD type. %c", ctmp); + return PM3_EINVARG; + } + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp); + return usage_hf14_autopwn(); + } + } + + if (errors) { + return usage_hf14_autopwn(); + } + + // Create the key storage stucture + e_sector = calloc(sectors_cnt, sizeof(sector_t)); + if (e_sector == NULL) return PM3_EMALLOC; + + // clear the key storage + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + e_sector[i].Key[j] = 0; + e_sector[i].foundKey[j] = 0; + } + } + + // card prng type (weak=1 / hard=0 / select/card comm error = negative value) + prng_type = detect_classic_prng(); + if (prng_type < 0){ + PrintAndLogEx(FAILED, "\nNo tag detected or other tag communication error"); + free(e_sector); + return prng_type; + } + + // print parameters + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= SETTINGS =======================")); + PrintAndLogEx(INFO, " card sectors .. " _YELLOW_("%d"), sectors_cnt); + PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); + PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), blockNo); + PrintAndLogEx(INFO, " keytype ....... " _YELLOW_("%c"), keyType ? 'B' : 'A'); + PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex(key, sizeof(key))); + PrintAndLogEx(INFO, " card PRNG ..... " _YELLOW_("%s"), prng_type ? "WEAK" : "HARD"); + PrintAndLogEx(INFO, " dictionary .... " _YELLOW_("%s"), strlen(filename) ? filename : "NONE"); + PrintAndLogEx(INFO, " legacy mode ... " _YELLOW_("%s"), legacy_mfchk ? "True" : "False"); + PrintAndLogEx(INFO, _YELLOW_("======================= SETTINGS =======================")); + } + + // Start the timer + t1 = msclock(); + + // check the user supplied key + if (know_target_key == false) + PrintAndLogEx(WARNING, "no known key was supplied, key recovery might fail"); + else { + if (verbose) { + 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)", + blockNo, + keyType ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); + + // Store the key for the nested / hardnested attack (if supplied by the user) + e_sector[blockNo].Key[keyType] = key64; + } else { + know_target_key = false; + PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"), + blockNo, + keyType ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); + PrintAndLogEx(WARNING, "falling back to dictionary"); + } + + // Check if the user supplied key is used by other sectors + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + if (e_sector[i].foundKey[j] == 0) { + if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num(key, 6); + e_sector[i].foundKey[j] = 'U'; + + // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) + if (know_target_key == false) { + num_to_bytes(e_sector[i].Key[j], 6, key); + 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)", + i, + j ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); + } else { + PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]", + i, + j ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); + } + } + } + } + } + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK =======================")); + } + + bool load_success = true; + // Load the dictionary + if (has_filename) { + int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); + if (res != PM3_SUCCESS || key_cnt == 0 || keyBlock == NULL) { + PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)"); + if (keyBlock != NULL) + free(keyBlock); + + load_success = false; + } + + } + + if (has_filename == false || load_success == false) { + keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); + if (keyBlock == NULL) { + free(e_sector); + return PM3_EMALLOC; + } + + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) { + 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); + } + + // Use the dictionary to find sector keys on the card + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START DICTIONARY ATTACK =======================")); + + if (legacy_mfchk) { + // Check all the sectors + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + // Check if the key is known + if (e_sector[i].foundKey[j] == 0) { + for (int k = 0; k < key_cnt; k++) { + printf("."); + fflush(stdout); + if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num((keyBlock + (6 * k)), 6); + e_sector[i].foundKey[j] = 'D'; + break; + } + } + } + } + } + printf("\n"); + fflush(stdout); + } else { + + int chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt; + bool firstChunk = true, lastChunk = false; + + for (uint8_t strategy = 1; strategy < 3; strategy++) { + PrintAndLogEx(INFO, "running strategy %u", strategy); + // main keychunk loop + for (int i = 0; i < key_cnt; i += chunksize) { + + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); + i = key_cnt; + strategy = 3; + break; // Exit the loop + } + uint32_t size = ((key_cnt - i) > chunksize) ? chunksize : key_cnt - i; + // last chunk? + if (size == key_cnt - i) + lastChunk = true; + + int res = mfCheckKeys_fast(sectors_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); + if (firstChunk) + firstChunk = false; + // all keys, aborted + if (res == PM3_SUCCESS) { + i = key_cnt; + strategy = 3; + break; // Exit the loop + } + } // end chunks of keys + firstChunk = true; + lastChunk = false; + } // end strategy + } + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP DICTIONARY ATTACK =======================")); + + + // Analyse the dictionary attack + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + if (e_sector[i].foundKey[j] == 1) { + e_sector[i].foundKey[j] = 'D'; + num_to_bytes(e_sector[i].Key[j], 6, tmp_key); + + // Store valid credentials for the nested / hardnested attack if none exist + if (know_target_key == false) { + num_to_bytes(e_sector[i].Key[j], 6, key); + 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)", + 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") "]", + i, + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); + } + } + } + } + + // Check if at least one sector key was found + if (know_target_key == false) { + // Check if the darkside attack can be used + if (prng_type) { + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START DARKSIDE ATTACK =======================")); + int isOK = mfDarkside(FirstBlockOfSector(blockNo), keyType, &key64); + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP DARKSIDE ATTACK =======================")); + switch (isOK) { + case -1 : + PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); + goto noValidKeyFound; + case -2 : + PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); + goto noValidKeyFound; + case -3 : + PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (its random number generator is not predictable)."); + goto noValidKeyFound; + case -4 : + PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); + PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour."); + goto noValidKeyFound; + case -5 : + PrintAndLogEx(WARNING, "\nAborted via keyboard."); + goto noValidKeyFound; + default : + PrintAndLogEx(SUCCESS, "\nFound valid key: %012" PRIx64 "\n", key64); + break; + } + + // 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)", + blockNo, + keyType ? 'B' : 'A', + sprint_hex(key, sizeof(key)) + ); + } else { +noValidKeyFound: + PrintAndLogEx(FAILED, "No usable key was found!"); + free(keyBlock); + free(e_sector); + return PM3_ESOFT; + } + } + + free(keyBlock); + // Clear the needed variables + num_to_bytes(0, 6, tmp_key); + bool nested_failed = false; + + // Iterate over each sector and key(A/B) + for (current_sector_i = 0; current_sector_i < sectors_cnt; current_sector_i++) { + for (current_key_type_i = 0; current_key_type_i < 2; current_key_type_i++) { + + // If the key is already known, just skip it + if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { + + // Try the found keys are reused + if (bytes_to_num(tmp_key, 6) != 0) { + // The fast check --> mfCheckKeys_fast(sectors_cnt, true, true, 2, 1, tmp_key, e_sector, false); + // Returns false keys, so we just stick to the slower mfchk. + for (int i = 0; i < sectors_cnt; i++) { + for (int j = 0; j < 2; j++) { + // Check if the sector key is already broken + if (e_sector[i].foundKey[j]) + continue; + + // Check if the key works + 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") "]", + i, + j ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); + } + } + } + } + // Clear the last found key + num_to_bytes(0, 6, tmp_key); + + if (current_key_type_i == 1) { + if (e_sector[current_sector_i].foundKey[0] && !e_sector[current_sector_i].foundKey[1]) { + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= START READ B KEY ATTACK =======================")); + PrintAndLogEx(INFO, "reading B key: sector: %3d key type: %c", + current_sector_i, + current_key_type_i ? 'B' : 'A'); + } + uint8_t sectrail = (FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1); + + mf_readblock_t payload; + payload.blockno = sectrail; + payload.keytype = 0; + + num_to_bytes(e_sector[current_sector_i].Key[0], 6, payload.key); // KEY A + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) goto skipReadBKey; + + if (resp.status != PM3_SUCCESS) goto skipReadBKey; + + uint8_t *data = resp.data.asBytes; + key64 = bytes_to_num(data + 10, 6); + if (key64) { + 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") "]", + current_sector_i, + current_key_type_i ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); + } else { + if (verbose) PrintAndLogEx(WARNING, "unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ", + current_sector_i, + current_key_type_i ? 'B' : 'A' + ); + } + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP READ B KEY ATTACK =======================")); + } + } + + // Use the nested / hardnested attack +skipReadBKey: + if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { + if (prng_type && (! nested_failed)) { + uint8_t retries = 0; + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= START NESTED ATTACK =======================")); + PrintAndLogEx(INFO, "sector no: %3d, target key type: %c", + current_sector_i, + current_key_type_i ? 'B' : 'A'); + } +tryNested: + isOK = mfnested(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, tmp_key, calibrate); + switch (isOK) { + case -1 : + PrintAndLogEx(ERR, "\nError: No response from Proxmark3."); + free(e_sector); + return PM3_ESOFT; + case -2 : + PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); + free(e_sector); + return PM3_ESOFT; + case -3 : + PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is probably not predictable)."); + PrintAndLogEx(FAILED, "Nested attack failed --> try hardnested"); + goto tryHardnested; + case -4 : //key not found + calibrate = false; + // this can happen on some old cards, it's worth trying some more before switching to slower hardnested + if (retries++ < MIFARE_SECTOR_RETRY) { + PrintAndLogEx(FAILED, "Nested attack failed, trying again (%i/%i)", retries, MIFARE_SECTOR_RETRY); + goto tryNested; + } else { + PrintAndLogEx(FAILED, "Nested attack failed, moving to hardnested"); + nested_failed = true; + goto tryHardnested; + } + break; + case -5 : + calibrate = false; + e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6); + e_sector[current_sector_i].foundKey[current_key_type_i] = 'N'; + break; + default : + PrintAndLogEx(ERR, "unknown Error.\n"); + free(e_sector); + return PM3_ESOFT; + } + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP NESTED ATTACK =======================")); + } else { +tryHardnested: // If the nested attack fails then we try the hardnested attack + if (verbose) { + PrintAndLogEx(INFO, _YELLOW_("======================= START HARDNESTED ATTACK =======================")); + PrintAndLogEx(INFO, "sector no: %3d, target key type: %c, Slow: %s", + current_sector_i, + current_key_type_i ? 'B' : 'A', + slow ? "Yes" : "No"); + } + + isOK = mfnestedhard(FirstBlockOfSector(blockNo), keyType, key, FirstBlockOfSector(current_sector_i), current_key_type_i, NULL, false, false, slow, 0, &foundkey, NULL); + DropField(); + if (isOK) { + switch (isOK) { + case 1 : + PrintAndLogEx(ERR, "\nError: No response from Proxmark3."); + break; + case 2 : + PrintAndLogEx(NORMAL, "\nButton pressed. Aborted."); + break; + default : + break; + } + free(e_sector); + return PM3_ESOFT; + } + + // Copy the found key to the tmp_key variale (for the following print statement, and the mfCheckKeys above) + num_to_bytes(foundkey, 6, tmp_key); + e_sector[current_sector_i].Key[current_key_type_i] = foundkey; + e_sector[current_sector_i].foundKey[current_key_type_i] = 'H'; + + if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP 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") "]", + current_sector_i, + current_key_type_i ? 'B' : 'A', + sprint_hex(tmp_key, sizeof(tmp_key)) + ); + } + } + } + } + } + + // Show the results to the user + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "found Keys:"); + + char strA[12 + 1] = {0}; + char strB[12 + 1] = {0}; + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(NORMAL, "|sec|key A |res|key B |res|"); + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + for (uint8_t i = 0; i < sectors_cnt; ++i) { + + snprintf(strA, sizeof(strA), "------------"); + snprintf(strB, sizeof(strB), "------------"); + + if (e_sector[i].foundKey[0]) + snprintf(strA, sizeof(strA), "%012" PRIx64, e_sector[i].Key[0]); + + if (e_sector[i].foundKey[1]) + snprintf(strB, sizeof(strB), "%012" PRIx64, e_sector[i].Key[1]); + + + PrintAndLogEx(NORMAL, "|%03d| %s | " _YELLOW_("%c")"| %s | " _YELLOW_("%c")"|" + , i + , strA, e_sector[i].foundKey[0] + , strB, e_sector[i].foundKey[1] + ); + } + PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); + PrintAndLogEx(NORMAL, "( " + _YELLOW_("D") ":Dictionary / " + _YELLOW_("S") ":darkSide / " + _YELLOW_("U") ":User / " + _YELLOW_("R") ":Reused / " + _YELLOW_("N") ":Nested / " + _YELLOW_("H") ":Hardnested / " + _YELLOW_("A") ":keyA " + ")" + ); + + // Dump the keys + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "saving keys"); + createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin")); + + PrintAndLogEx(SUCCESS, "transferring keys to simulator memory (Cmd Error: 04 can occur)"); + + for (current_sector_i = 0; current_sector_i < sectors_cnt; current_sector_i++) { + mfEmlGetMem(block, current_sector_i, 1); + if (e_sector[current_sector_i].foundKey[0]) + num_to_bytes(e_sector[current_sector_i].Key[0], 6, block); + if (e_sector[current_sector_i].foundKey[1]) + num_to_bytes(e_sector[current_sector_i].Key[1], 6, block + 10); + + mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1); + } + + // use ecfill trick + FastDumpWithEcFill(sectors_cnt); + + bytes = block_cnt * MFBLOCK_SIZE; + dump = calloc(bytes, sizeof(uint8_t)); + if (!dump) { + PrintAndLogEx(ERR, "Fail, cannot allocate memory"); + free(e_sector); + return PM3_EMALLOC; + } + memset(dump, 0, bytes); + + PrintAndLogEx(INFO, "downloading the card content from emulator memory"); + if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(ERR, "Fail, transfer from device time-out"); + free(e_sector); + free(dump); + return PM3_ETIMEOUT; + } + + fnameptr = GenerateFilename("hf-mf-", "-data"); + if (fnameptr == NULL) { + free(dump); + free(e_sector); + return PM3_ESOFT; + } + strcpy(filename, fnameptr); + + saveFile(filename, ".bin", dump, bytes); + saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); + saveFileJSON(filename, jsfCardMemory, dump, bytes); + + // Generate and show statistics + t1 = msclock() - t1; + PrintAndLogEx(INFO, "autopwn execution time: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0); + + free(dump); + free(e_sector); + return PM3_SUCCESS; +} + /* static int randInRange(int min, int max) { return min + (int)(rand() / (double)(RAND_MAX) * (max - min + 1)); @@ -1563,7 +2335,6 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; char buf[13]; char *fptr; - uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t *keyBlock, *p; uint8_t sectorsCnt = 1; int i, keycnt = 0; @@ -1575,7 +2346,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { sector_t *e_sector = NULL; keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); - if (keyBlock == NULL) return 1; + if (keyBlock == NULL) return PM3_EMALLOC; for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6); @@ -1615,7 +2386,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (!p) { PrintAndLogEx(FAILED, "Cannot allocate memory for Keys"); free(keyBlock); - return 2; + return PM3_EMALLOC; } keyBlock = p; } @@ -1629,14 +2400,24 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { // May be a dic file if (param_getstr(Cmd, i, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "Filename too long"); - continue; + free(keyBlock); + return PM3_EINVARG; } - f = fopen(filename, "r"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - continue; + char *dict_path; + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic", false); + if (res != PM3_SUCCESS) { + free(keyBlock); + return res; } + f = fopen(dict_path, "r"); + if (!f) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); + free(dict_path); + free(keyBlock); + return PM3_EFILE; + } + free(dict_path); // read file while (fgets(buf, sizeof(buf), f)) { @@ -1659,7 +2440,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { PrintAndLogEx(FAILED, "Cannot allocate memory for default keys"); free(keyBlock); fclose(f); - return 2; + return PM3_EMALLOC; } keyBlock = p; } @@ -1686,7 +2467,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { e_sector = calloc(sectorsCnt, sizeof(sector_t)); if (e_sector == NULL) { free(keyBlock); - return 1; + return PM3_EMALLOC; } uint32_t chunksize = keycnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : keycnt; @@ -1724,7 +2505,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { firstChunk = false; // all keys, aborted - if (res == 0 || res == 2) + if (res == PM3_SUCCESS || res == 2) goto out; } // end chunks of keys firstChunk = true; @@ -1752,6 +2533,13 @@ out: printKeyTable(sectorsCnt, e_sector); + if (use_flashmemory && found_keys == (sectorsCnt << 1)) { + PrintAndLogEx(SUCCESS, "Card dumped aswell. run " _YELLOW_("`%s %c`"), + "hf mf esave", + GetFormatFromSector(sectorsCnt) + ); + } + if (transferToEml) { // fast push mode conn.block_after_ACK = true; @@ -1770,34 +2558,15 @@ out: mfEmlSetMem(block, blockno, 1); } PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory"); + + if (found_keys == (sectorsCnt << 1)) { + FastDumpWithEcFill(sectorsCnt); + } } if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) - return 1; - - FILE *fkeys = fopen(fptr, "wb"); - if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); - free(keyBlock); - free(e_sector); - return 1; - } - PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); - - for (i = 0; i < sectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[0], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - - for (i = 0; i < sectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[1], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - - fclose(fkeys); - PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); + createMfcKeyDump(sectorsCnt, e_sector, fptr); } } @@ -1823,7 +2592,6 @@ static int CmdHF14AMfChk(const char *Cmd) { uint8_t keyType = 0; uint32_t keyitems = ARRAYLEN(g_mifare_default_keys); uint64_t key64 = 0; - uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; char *fptr; int clen = 0; int transferToEml = 0; @@ -1894,14 +2662,24 @@ static int CmdHF14AMfChk(const char *Cmd) { // May be a dic file if (param_getstr(Cmd, i, filename, sizeof(filename)) >= FILE_PATH_SIZE) { PrintAndLogEx(FAILED, "File name too long"); - continue; + free(keyBlock); + return PM3_EINVARG; } - f = fopen(filename, "r"); - if (!f) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename); - continue; + char *dict_path; + int res = searchFile(&dict_path, DICTIONARIES_SUBDIR, filename, ".dic", false); + if (res != PM3_SUCCESS) { + free(keyBlock); + return PM3_EFILE; } + f = fopen(dict_path, "r"); + if (!f) { + PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", dict_path); + free(dict_path); + free(keyBlock); + return PM3_EFILE; + } + free(dict_path); // load keys from dictionary file while (fgets(buf, sizeof(buf), f)) { @@ -2078,31 +2856,7 @@ out: if (createDumpFile) { fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) { - free(keyBlock); - free(e_sector); - return PM3_EFILE; - } - - FILE *fkeys = fopen(fptr, "wb"); - if (fkeys == NULL) { - PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); - free(keyBlock); - free(e_sector); - return PM3_EFILE; - } - PrintAndLogEx(INFO, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); - - for (i = 0; i < SectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[0], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - for (i = 0; i < SectorsCnt; i++) { - num_to_bytes(e_sector[i].Key[1], 6, tempkey); - fwrite(tempkey, 1, 6, fkeys); - } - fclose(fkeys); - PrintAndLogEx(SUCCESS, "Found keys have been dumped to file " _YELLOW_("%s")". 0xffffffffffff has been inserted for unknown keys.", fptr); + createMfcKeyDump(SectorsCnt, e_sector, fptr); } free(keyBlock); @@ -2498,6 +3252,8 @@ static int CmdHF14AMfSniff(const char *Cmd) { return PM3_SUCCESS; } */ + +/* static int CmdHF14AMfKeyBrute(const char *Cmd) { uint8_t blockNo = 0, keytype = 0; @@ -2528,6 +3284,7 @@ static int CmdHF14AMfKeyBrute(const char *Cmd) { PrintAndLogEx(SUCCESS, "\ntime in keybrute: %.0f seconds\n", (float)t1 / 1000.0); return PM3_SUCCESS; } +*/ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { char strA[12 + 1] = {0}; @@ -2556,6 +3313,7 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); } + // EMULATOR COMMANDS static int CmdHF14AMfEGet(const char *Cmd) { char c = tolower(param_getchar(Cmd, 0)); @@ -2785,8 +3543,12 @@ static int CmdHF14AMfECFill(const char *Cmd) { } PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B'); + + mfc_eload_t payload; + payload.sectorcnt = numSectors; + payload.keytype = keyType; clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, numSectors, keyType, 0, NULL, 0); + SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload)); return PM3_SUCCESS; } @@ -3634,12 +4396,13 @@ static int CmdHF14AMfList(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHF14AMfList, AlwaysAvailable, "List Mifare history"}, - {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack. read parity error messages."}, - {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack. Test nested authentication"}, - {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened Mifare cards"}, - {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, - {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for Mifare NACK bug"}, + {"list", CmdHF14AMfList, AlwaysAvailable, "List MIFARE history"}, + {"darkside", CmdHF14AMfDarkside, IfPm3Iso14443a, "Darkside attack"}, + {"nested", CmdHF14AMfNested, IfPm3Iso14443a, "Nested attack"}, + {"hardnested", CmdHF14AMfNestedHard, AlwaysAvailable, "Nested attack for hardened MIFARE Classic cards"}, + {"autopwn", CmdHF14AMfAutoPWN, IfPm3Iso14443a, "Automatic key recovery tool for MIFARE Classic"}, +// {"keybrute", CmdHF14AMfKeyBrute, IfPm3Iso14443a, "J_Run's 2nd phase of multiple sector nested authentication key recovery"}, + {"nack", CmdHf14AMfNack, IfPm3Iso14443a, "Test for MIFARE NACK bug"}, {"chk", CmdHF14AMfChk, IfPm3Iso14443a, "Check keys"}, {"fchk", CmdHF14AMfChk_fast, IfPm3Iso14443a, "Check keys fast, targets all keys on card"}, {"decrypt", CmdHf14AMfDecryptBytes, AlwaysAvailable, "[nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace"}, @@ -3653,7 +4416,7 @@ static command_t CommandTable[] = { {"auth4", CmdHF14AMfAuth4, IfPm3Iso14443a, "ISO14443-4 AES authentication"}, // {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, - {"sim", CmdHF14AMfSim, IfPm3Iso14443a, "Simulate MIFARE card"}, + {"sim", CmdHF14AMfSim, IfPm3Iso14443a, "Simulate MIFARE card"}, {"eclr", CmdHF14AMfEClear, IfPm3Iso14443a, "Clear simulator memory"}, {"eget", CmdHF14AMfEGet, IfPm3Iso14443a, "Get simulator memory block"}, {"eset", CmdHF14AMfESet, IfPm3Iso14443a, "Set simulator memory block"}, @@ -3672,7 +4435,7 @@ static command_t CommandTable[] = { {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, - {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect Mifare Classic nonces to file"}, + {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index d66df7eae..c38c4022e 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -36,13 +36,14 @@ #include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bitarray_core.h" #include "zlib.h" +#include "fileutils.h" #define NUM_CHECK_BITFLIPS_THREADS (num_CPUs()) #define NUM_REDUCTION_WORKING_THREADS (num_CPUs()) #define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states -#define STATE_FILES_DIRECTORY "hardnested/tables/" +#define STATE_FILES_DIRECTORY "hardnested_tables/" #define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z" #define DEBUG_KEY_ELIMINATION @@ -248,10 +249,15 @@ static void init_bitflip_bitarrays(void) { bitflip_bitarrays[odd_even][bitflip] = NULL; count_bitflip_bitarrays[odd_even][bitflip] = 1 << 24; sprintf(state_file_name, STATE_FILE_TEMPLATE, odd_even, bitflip); - strcpy(state_files_path, get_my_executable_directory()); - strcat(state_files_path, STATE_FILES_DIRECTORY); + strcpy(state_files_path, STATE_FILES_DIRECTORY); strcat(state_files_path, state_file_name); - FILE *statesfile = fopen(state_files_path, "rb"); + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, state_files_path, "", true) != PM3_SUCCESS) { + continue; + } + + FILE *statesfile = fopen(path, "rb"); + free(path); if (statesfile == NULL) { continue; } else { diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 8c7cfcc5c..58eb5db1a 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -86,7 +86,7 @@ static int CmdHFMFPInfo(const char *cmd) { // check SL0 uint8_t data[250] = {0}; int datalen = 0; - // https://github.com/Proxmark/proxmark3/blob/master/client/scripts/mifarePlus.lua#L161 + // https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161 uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen); if (!res && datalen > 1 && data[0] == 0x09) { diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index e2c64a004..7c81ebfd6 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -18,7 +18,7 @@ #include "cmdhfmf.h" #include "cmdhf14a.h" #include "comms.h" -#include "loclass/fileutils.h" +#include "fileutils.h" #include "protocols.h" #define MAX_UL_BLOCKS 0x0F @@ -2191,7 +2191,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { // convert old format to new format, if need int res = convertOldMfuDump(&dump, &bytes_read); - if (res) { + if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format"); free(dump); return res; @@ -2519,7 +2519,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { if (param_gethex(Cmd, 0, uid, 14)) { PrintAndLogEx(WARNING, "UID must include 14 HEX symbols"); - return 1; + return PM3_EINVARG; } // read block2. @@ -2527,7 +2527,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandMIX(CMD_HF_MIFAREU_READBL, 2, 0, 0, NULL, 0); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 2; + return PM3_ETIMEOUT; } // save old block2. @@ -2544,7 +2544,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 3; + return PM3_ETIMEOUT; } // block 1. @@ -2556,7 +2556,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 4; + return PM3_ETIMEOUT; } // block 2. @@ -2568,9 +2568,9 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) { SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data)); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "Command execute timeout"); - return 5; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { @@ -2681,8 +2681,9 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey))); PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd))); + mbedtls_des3_free(&ctx); // next. from the diversify_key method. - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfUPwdGen(const char *Cmd) { @@ -2709,11 +2710,11 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { // 3: proprietary Anticollision if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return 1; + return PM3_ESOFT; } if (card.uidlen != 7) { PrintAndLogEx(WARNING, "Wrong sized UID, expected 7bytes got %d", card.uidlen); - return 1; + return PM3_ESOFT; } memcpy(uid, card.uid, sizeof(uid)); } else { @@ -2732,7 +2733,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(NORMAL, "------+----------+-----"); PrintAndLogEx(NORMAL, " Vingcard algo"); PrintAndLogEx(NORMAL, "--------------------"); - return 0; + return PM3_SUCCESS; } //------------------------------------ // Menu Stuff @@ -2757,7 +2758,7 @@ static command_t CommandTable[] = { static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); - return 0; + return PM3_SUCCESS; } int CmdHFMFUltra(const char *Cmd) { diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 2e9ab7a85..a32aa8f59 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -60,10 +60,11 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); - PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); } else { - PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); + PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail")); } + PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len*8, (barcode_len==16||barcode_len==32) ? _GREEN_("OK") : _YELLOW_("warning")); PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len)); if (barcode_len < 4) // too few to go to next decoding stages return PM3_ESOFT; diff --git a/client/cmdhw.c b/client/cmdhw.c index 7fec7a40c..c81efda9e 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -493,7 +493,7 @@ static int CmdTune(const char *Cmd) { static int CmdVersion(const char *Cmd) { (void)Cmd; // Cmd is not used so far - pm3_version(true); + pm3_version(true, false); return PM3_SUCCESS; } @@ -617,7 +617,66 @@ int CmdHW(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -void pm3_version(bool verbose) { +void pm3_version(bool verbose, bool oneliner) { + +#if defined(__MINGW64__) +# define PM3CLIENTCOMPILER "MinGW-w64 " +#elif defined(__MINGW32__) +# define PM3CLIENTCOMPILER "MinGW " +#elif defined(__clang__) +# define PM3CLIENTCOMPILER "Clang/LLVM " +#elif defined(__GNUC__) || defined(__GNUG__) +# define PM3CLIENTCOMPILER "GCC " +#else +# define PM3CLIENTCOMPILER "unknown compiler " +#endif + +#if defined(__APPLE__) || defined(__MACH__) +# define PM3HOSTOS " OS:OSX" +#elif defined(__ANDROID__) || defined(ANDROID) +// must be tested before __linux__ +# define PM3HOSTOS " OS:Android" +#elif defined(__linux__) +# define PM3HOSTOS " OS:Linux" +#elif defined(__FreeBSD__) +# define PM3HOSTOS " OS:FreeBSD" +#elif defined(__NetBSD__) +# define PM3HOSTOS " OS:NetBSD" +#elif defined(__OpenBSD__) +# define PM3HOSTOS " OS:OpenBSD" +#elif defined(__CYGWIN__) +# define PM3HOSTOS " OS:Cygwin" +#elif defined(_WIN64) | defined(__WIN64__) +// must be tested before _WIN32 +# define PM3HOSTOS " OS:Windows (64b)" +#elif defined(_WIN32) | defined(__WIN32__) +# define PM3HOSTOS " OS:Windows (32b)" +#else +# define PM3HOSTOS " OS:unknown" +#endif + +#if defined(__x86_64__) +# define PM3HOSTARCH " ARCH:x86_64" +#elif defined(__i386__) +# define PM3HOSTARCH " ARCH:x86" +#elif defined(__aarch64__) +# define PM3HOSTARCH " ARCH:aarch64" +#elif defined(__arm__) +# define PM3HOSTARCH " ARCH:arm" +#elif defined(__powerpc64__) +# define PM3HOSTARCH " ARCH:powerpc64" +#elif defined(__mips__) +# define PM3HOSTARCH " ARCH:mips" +#else +# define PM3HOSTARCH " ARCH:unknown" +#endif + + if (oneliner) { + // For "proxmark3 -v", simple printf, avoid logging + printf("Client: RRG/Iceman compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH "\n"); + return; + } + if (!verbose) return; @@ -630,11 +689,7 @@ void pm3_version(bool verbose) { PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n"); PrintAndLogEx(NORMAL, "\n [ CLIENT ]"); PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info? -#if defined(__clang__) - PrintAndLogEx(NORMAL, " compiled with Clang/LLVM "__VERSION__); -#elif defined(__GNUC__) || defined(__GNUG__) - PrintAndLogEx(NORMAL, " compiled with GCC "__VERSION__); -#endif + PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH); PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]"); PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); diff --git a/client/cmdhw.h b/client/cmdhw.h index 1a378e70f..bf40b70a8 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -15,6 +15,6 @@ int CmdHW(const char *Cmd); -void pm3_version(bool verbose); +void pm3_version(bool verbose, bool oneliner); #endif diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index b574af772..2360906a4 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -58,7 +58,7 @@ static int usage_lf_awid_sim(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf awid sim 26 224 1337"); - PrintAndLogEx(NORMAL, " lf awid sim 50 2001 deadc0de"); + PrintAndLogEx(NORMAL, " lf awid sim 50 2001 13371337"); return PM3_SUCCESS; } diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 190b84283..2bcd476ea 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -15,7 +15,7 @@ #include "cmdtrace.h" #include "commonutil.h" #include "hitag.h" -#include "loclass/fileutils.h" // savefile +#include "fileutils.h" // savefile static int CmdHelp(const char *Cmd); diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index 8a1a940c5..5ef21992b 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -22,7 +22,7 @@ #include "cmdlf.h" #include "lfdemod.h" static int CmdHelp(const char *Cmd); - +/* static int usage_lf_paradox_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); @@ -38,6 +38,7 @@ static int usage_lf_paradox_sim(void) { PrintAndLogEx(NORMAL, " lf paradox sim 123 11223"); return PM3_SUCCESS; } +*/ //by marshmellow //Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded) @@ -111,8 +112,12 @@ static int CmdParadoxRead(const char *Cmd) { return CmdParadoxDemod(Cmd); } -static int CmdParadoxSim(const char *Cmd) { +static int CmdParadoxSim(const char *Cmd) { + PrintAndLogEx(INFO," To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} +/* char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_paradox_sim(); @@ -155,7 +160,7 @@ static int CmdParadoxSim(const char *Cmd) { return resp.status; return PM3_SUCCESS; } - +*/ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"}, diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index d5f66496d..cefb40cc6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -25,7 +25,7 @@ #include "cmddata.h" #include "lfdemod.h" #include "cmdhf14a.h" // for getTagInfo -#include "loclass/fileutils.h" // loadDictionary +#include "fileutils.h" // loadDictionary #include "util_posix.h" @@ -91,6 +91,17 @@ static int usage_t55xx_read() { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } +static int usage_t55xx_resetread() { + PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); + PrintAndLogEx(NORMAL, "Options:"); + print_usage_t55xx_downloadlink(); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " lf t55xx resetread"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static int usage_t55xx_write() { PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t]"); PrintAndLogEx(NORMAL, "Options:"); @@ -108,26 +119,26 @@ static int usage_t55xx_write() { return PM3_SUCCESS; } static int usage_t55xx_trace() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [r mode]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); PrintAndLogEx(NORMAL, "Options:"); print_usage_t55xx_downloadlink(); - // Command did not seem to support the 1 option (yet) so have removed the help lines - // PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); + PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx trace"); - // PrintAndLogEx(NORMAL, " lf t55xx trace 1"); + PrintAndLogEx(NORMAL, " lf t55xx trace 1"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int usage_t55xx_info() { PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [d [q]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " (default) - read data from tag."); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); - PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); - PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); - PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); + PrintAndLogEx(NORMAL, " (default) - read data from tag."); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); + PrintAndLogEx(NORMAL, " d - 4 bytes of data (8 hex characters)"); + PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); + PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); @@ -135,19 +146,20 @@ static int usage_t55xx_info() { PrintAndLogEx(NORMAL, " lf t55xx info 1"); PrintAndLogEx(NORMAL, " lf t55xx info d 00083040"); PrintAndLogEx(NORMAL, " lf t55xx info d 6001805A q"); + PrintAndLogEx(NORMAL, " lf t55xx info p 11223344"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int usage_t55xx_dump() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [ [o]]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [p [o]]"); PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); + PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); + PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); print_usage_t55xx_downloadlink(); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx dump"); - PrintAndLogEx(NORMAL, " lf t55xx dump feedbeef o"); + PrintAndLogEx(NORMAL, " lf t55xx dump p feedbeef o"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -206,7 +218,7 @@ static int usage_t55xx_chk() { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx chk m"); - PrintAndLogEx(NORMAL, " lf t55xx chk i default_pwd.dic"); + PrintAndLogEx(NORMAL, " lf t55xx chk i t55xx_default_pwds"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -215,16 +227,16 @@ static int usage_t55xx_bruteforce() { PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "Try reading block 7 before\n"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r ] "); + PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r ] [s ] [e ]"); PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); print_usage_t55xx_downloadlink(); - PrintAndLogEx(NORMAL, " - 4 byte hex value to start pwd search at"); - PrintAndLogEx(NORMAL, " - 4 byte hex value to end pwd search at"); + PrintAndLogEx(NORMAL, " s - 4 byte hex value to start pwd search at"); + PrintAndLogEx(NORMAL, " e - 4 byte hex value to end pwd search at"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 aaaaaa77 aaaaaa99"); + PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 s aaaaaa77 e aaaaaa99"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -248,15 +260,15 @@ static int usage_t55xx_recoverpw() { return PM3_SUCCESS; } static int usage_t55xx_wipe() { - PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5]"); + PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p ]"); PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " Q5 - indicates to use the T5555 (Q5) default configuration block"); + PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); - PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004"); + PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); + PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004"); return PM3_SUCCESS; } static int usage_lf_deviceconfig() { @@ -292,6 +304,9 @@ void printT5xxHeader(uint8_t page) { static int CmdT55xxSetConfig(const char *Cmd) { + // No args + if (strlen(Cmd) == 0) return printConfiguration(config); + uint8_t offset = 0, bitRate = 0; char modulation[6] = {0x00}; uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; @@ -395,9 +410,6 @@ static int CmdT55xxSetConfig(const char *Cmd) { } } - // No args - if (cmdp == 0) return printConfiguration(config); - //Validations if (errors) return usage_t55xx_config(); @@ -409,41 +421,42 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin //Password mode if (usepwd) { // try reading the config block and verify that PWD bit is set before doing this! - if (!override) { + if (override == 0) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT; if (!tryDetectModulation()) { PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); - return 0; + return PM3_ESOFT; } else { PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password..."); usepwd = false; - page1 = false; + page1 = false; // ?? } - } else { + } else if (override == 1) { // Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display) - if ((override & 2) != 2) - PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); + PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk"); } } + if (!AquireData(page1, block, usepwd, password, downlink_mode)) + return PM3_ESOFT; - if (!AquireData(page1, block, usepwd, password, downlink_mode)) return PM3_ESOFT; - if (!DecodeT55xxBlock()) return PM3_ESOFT; + if (!DecodeT55xxBlock()) + return PM3_ESOFT; printT55xxBlock(block); return PM3_SUCCESS; } static int CmdT55xxReadBlock(const char *Cmd) { - uint8_t block = REGULAR_READ_MODE_BLOCK; - uint32_t password = 0; //default to blank Block 7 - bool usepwd = false; - bool override = false; - bool page1 = false; - bool errors = false; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; + uint8_t block = REGULAR_READ_MODE_BLOCK; + uint8_t override = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint32_t password = 0; //default to blank Block 7 + bool usepwd = false; + bool page1 = false; + bool errors = false; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -454,7 +467,7 @@ static int CmdT55xxReadBlock(const char *Cmd) { cmdp += 2; break; case 'o': - override = true; + override = 1; cmdp++; break; case 'p': @@ -467,9 +480,10 @@ static int CmdT55xxReadBlock(const char *Cmd) { cmdp++; break; case 'r': - case 'R': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; @@ -479,7 +493,7 @@ static int CmdT55xxReadBlock(const char *Cmd) { break; } } - if (errors) return usage_t55xx_read(); + if (errors || cmdp == 0) return usage_t55xx_read(); if (block > 7 && block != REGULAR_READ_MODE_BLOCK) { PrintAndLogEx(NORMAL, "Block must be between 0 and 7"); @@ -593,15 +607,13 @@ void T55xx_Print_DownlinkMode(uint8_t downlink_mode) { // static int CmdT55xxDetect(const char *Cmd) { - bool errors = false; - bool useGB = false; - bool usepwd = false; - bool try_all_dl_modes = false; - bool found = false; - uint32_t password = 0; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint8_t dl_mode = 0; + bool errors = false; + bool useGB = false; + bool usepwd = false; + bool try_all_dl_modes = false; + uint32_t password = 0; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -613,14 +625,15 @@ static int CmdT55xxDetect(const char *Cmd) { cmdp += 2; break; case '1': - // use Graphbuffer data useGB = true; cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode >= 4) { + try_all_dl_modes = true; + downlink_mode = 4; + } cmdp += 2; break; default: @@ -632,48 +645,32 @@ static int CmdT55xxDetect(const char *Cmd) { if (errors) return usage_t55xx_detect(); // sanity check. - if (SanityOfflineCheck(useGB) != PM3_SUCCESS) return PM3_ENODATA; + if (SanityOfflineCheck(useGB) != PM3_SUCCESS) + return PM3_ESOFT; - if (!useGB) { - for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) { - found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode); + if (useGB == false) { + if ( try_all_dl_modes ) { + for (uint8_t mode = 0; mode < 4; mode++) { + + if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, mode) == false ) { + continue; + } - // found = false if password is supplied but wrong d/l mode - // so keep trying other modes (if requested) - /* - if (!found) { - printf ("Aquire not found"); - return PM3_ENODATA; + if (tryDetectModulation()) { + T55xx_Print_DownlinkMode(mode); + return PM3_SUCCESS; + } } - */ - if (tryDetectModulation()) { - T55xx_Print_DownlinkMode(dl_mode); - dl_mode = 4; - found = true; - } else found = false; - - if (!try_all_dl_modes) dl_mode = 4; + return PM3_ESOFT; + } else { + if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode) == false ) + return PM3_ENODATA; } } - - if (useGB) found = tryDetectModulation(); - - if (!found) + if (tryDetectModulation() == false) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - - /* - if (!useGB) { - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode)) - return PM3_ENODATA; - } - if (!tryDetectModulation()) - PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - else - T55xx_Print_DownlinkMode (downlink_mode); - */ - return PM3_SUCCESS; } // detect configuration? @@ -1107,24 +1104,23 @@ int special(const char *Cmd) { } int printConfiguration(t55xx_conf_block_t b) { - PrintAndLogEx(NORMAL, "Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); - PrintAndLogEx(NORMAL, "Modulation : %s", GetSelectedModulationStr(b.modulation)); - PrintAndLogEx(NORMAL, "Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); - PrintAndLogEx(NORMAL, "Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, "Offset : %d", b.offset); - PrintAndLogEx(NORMAL, "Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, "Block0 : 0x%08X", b.block0); + PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); + PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation)); + PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); + PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(NORMAL, " Offset : %d", b.offset); + PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int CmdT55xxWakeUp(const char *Cmd) { - uint32_t password = 0; - uint8_t cmdp = 0; - bool errors = false; - uint8_t downlink_mode = 0; - uint8_t flags = 0; + uint32_t password = 0; + uint8_t cmdp = 0; + bool errors = false; + uint8_t downlink_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1133,11 +1129,12 @@ static int CmdT55xxWakeUp(const char *Cmd) { case 'p': password = param_get32ex(Cmd, cmdp + 1, 0, 16); cmdp += 2; - errors = false; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1149,24 +1146,35 @@ static int CmdT55xxWakeUp(const char *Cmd) { if (errors) return usage_t55xx_wakup(); - flags = (downlink_mode & 3) << 3; + struct p { + uint32_t password; + uint8_t flags; + } PACKED payload; + + payload.password = password; + payload.flags = (downlink_mode & 3) << 3; + clearCommandBuffer(); - SendCommandMIX(CMD_LF_T55XX_WAKEUP, password, flags, 0, NULL, 0); + SendCommandNG(CMD_LF_T55XX_WAKEUP, (uint8_t *)&payload, sizeof(payload)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WAKEUP, NULL, 1000)) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } + PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now"); - return PM3_SUCCESS; } static int CmdT55xxWriteBlock(const char *Cmd) { - uint8_t block = 0xFF; //default to invalid block - uint32_t data = 0; //default to blank Block - uint32_t password = 0; //default to blank Block 7 - bool usepwd = false; - bool page1 = false; - bool gotdata = false; - bool testMode = false; - bool errors = false; - uint8_t cmdp = 0; + uint8_t block = 0xFF; // default to invalid block + uint32_t data = 0; // default to blank Block + uint32_t password = 0; // default to blank Block 7 + bool usepwd = false; + bool page1 = false; + bool gotdata = false; + bool testMode = false; + bool errors = false; + uint8_t cmdp = 0; uint32_t downlink_mode = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -1201,8 +1209,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) { cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1252,29 +1262,47 @@ static int CmdT55xxWriteBlock(const char *Cmd) { } static int CmdT55xxReadTrace(const char *Cmd) { - uint8_t cmd_len = 0; + + bool frombuff = false; uint8_t downlink_mode = 0; - - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'r') { - downlink_mode = param_getchar(Cmd, 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - cmd_len = 3; + uint8_t cmdp = 0; + bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_trace(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + case '1': + frombuff = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - if ((strlen(Cmd) != cmd_len) || (cmdp == 'h')) return usage_t55xx_trace(); - if (strlen(Cmd) == cmd_len) { + if (errors) return usage_t55xx_trace(); + + if (!frombuff) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; bool pwdmode = false; uint32_t password = 0; -// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. -// if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, pwdmode, password,downlink_mode)) + + // REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset. if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode)) return PM3_ENODATA; } - + if (config.Q5) { if (!DecodeT5555TraceBlock()) return PM3_ESOFT; } else { @@ -1467,7 +1495,7 @@ static void printT5x7KnownBlock0(uint32_t b0) { snprintf(s + strlen(s), sizeof(s) - strlen(s), "FDXB "); break; case T55X7_HID_26_CONFIG_BLOCK: - snprintf(s + strlen(s), sizeof(s) - strlen(s), "HID 26b "); + snprintf(s + strlen(s), sizeof(s) - strlen(s), "HID 26b (ProxCard) "); break; case T55X7_PYRAMID_CONFIG_BLOCK: snprintf(s + strlen(s), sizeof(s) - strlen(s), "Pyramid "); @@ -1513,10 +1541,10 @@ static int CmdT55xxInfo(const char *Cmd) { Normal mode Extended mode */ - bool frombuff = false, gotdata = false, dataasq5 = false; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - uint32_t block0 = 0; + bool frombuff = false, gotdata = false, dataasq5 = false, usepwd = false; + uint8_t cmdp = 0; + uint8_t downlink_mode = 0; + uint32_t block0 = 0, password = 0; while (param_getchar(Cmd, cmdp) != 0x00) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1527,6 +1555,11 @@ static int CmdT55xxInfo(const char *Cmd) { gotdata = true; cmdp += 2; break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; case '1': frombuff = true; cmdp += 2; @@ -1536,8 +1569,10 @@ static int CmdT55xxInfo(const char *Cmd) { cmdp += 2; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -1556,11 +1591,10 @@ static int CmdT55xxInfo(const char *Cmd) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; - bool pwdmode = false; - uint32_t password = 0; - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password, downlink_mode)) + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) return PM3_ENODATA; } + if (!gotdata) { if (!DecodeT55xxBlock()) return PM3_ESOFT; @@ -1653,34 +1687,47 @@ static int CmdT55xxInfo(const char *Cmd) { static int CmdT55xxDump(const char *Cmd) { - uint32_t password = 0; - uint8_t override = false; - uint8_t cmd_opt_idx = 0; - uint8_t downlink_mode = 0; - uint8_t pwd_offset = 0; - char cmdp = tolower(param_getchar(Cmd, 0)); + uint32_t password = 0; + uint8_t override = 0; + uint8_t downlink_mode = 0; + bool usepwd = false; + bool errors = false; + uint8_t cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_dump(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; - if (cmdp == 'h') return usage_t55xx_dump(); - if (cmdp == 'r') { - cmd_opt_idx++; - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 3) downlink_mode = 0; - pwd_offset = 3; - } - bool usepwd = (strlen(Cmd) > pwd_offset); - if (usepwd) { - password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); - if (param_getchar(Cmd, cmd_opt_idx++) == 'o') - override = true; + cmdp += 2; + break; + case 'p': + password = param_get32ex(Cmd, cmdp + 1, 0, 16); + usepwd = true; + cmdp += 2; + break; + case 'o': + override = 1; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } + if (errors) return usage_t55xx_dump(); printT5xxHeader(0); for (uint8_t i = 0; i < 8; ++i) { T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode); // idea for better user experience and display. // only show override warning on the first block read - if (override) override |= 2; // flag not to show safty for 2nd and on. + if (override == 1) override++; // flag not to show safty for 2nd and on. } printT5xxHeader(1); for (uint8_t i = 0; i < 4; i++) @@ -1970,16 +2017,34 @@ static void t55x7_create_config_block(int tagtype) { static int CmdResetRead(const char *Cmd) { uint8_t downlink_mode = 0; - uint8_t flags = 0; + uint8_t flags = 0; + uint8_t cmdp = 0; + bool errors = false; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_resetread(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } - if (strlen(Cmd) == 3) - downlink_mode = param_getchar(Cmd, 1) - '0'; + if (errors) return usage_t55xx_resetread(); - if (downlink_mode > 3) downlink_mode = 0; - - printf("DL : %d\n", downlink_mode); + PrintAndLogEx(INFO, "DL : %d\n", downlink_mode); + flags = downlink_mode << 3; + clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags)); if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) { @@ -1997,29 +2062,62 @@ static int CmdResetRead(const char *Cmd) { } static int CmdT55xxWipe(const char *Cmd) { - char writeData[20] = {0}; + char writeData[36] = {0}; char *ptrData = writeData; - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_t55xx_wipe(); + uint32_t password = 0; + bool usepwd = false; + bool Q5 = false; + uint8_t cmdp = 0; + bool errors = false; - bool Q5 = (cmdp == 'q'); + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_wipe(); + case 'p': + // password used by handheld cloners + password = param_get32ex(Cmd, cmdp + 1, 0x51243648, 16); + usepwd = true; + cmdp += 2; + break; + case 'q': + Q5 = true; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors) return usage_t55xx_wipe(); // Try with the default password to reset block 0 // With a pwd should work even if pwd bit not set PrintAndLogEx(INFO, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); - if (Q5) - snprintf(ptrData, sizeof(writeData), "b 0 d 6001F004 p 0"); - else - snprintf(ptrData, sizeof(writeData), "b 0 d 000880E0 p 0"); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); + if (usepwd) { + snprintf(ptrData, sizeof(writeData), "b 0 p %08x ", password); + } else { + snprintf(ptrData, sizeof(writeData), "b 0 "); + } + + if (Q5) + snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 6001F004"); + else + snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 000880E0"); + + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk 0"); for (uint8_t blk = 1; blk < 8; blk++) { snprintf(ptrData, sizeof(writeData), "b %d d 0", blk); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); memset(writeData, 0x00, sizeof(writeData)); } @@ -2037,44 +2135,50 @@ static bool IsCancelled(void) { // load a default pwd file. static int CmdT55xxChkPwds(const char *Cmd) { - char filename[FILE_PATH_SIZE] = {0}; - bool found = false; + char filename[FILE_PATH_SIZE] = {0}; + bool found = false; uint8_t timeout = 0; uint8_t *keyBlock = NULL; - bool from_flash = false; - bool try_all_dl_modes = false; + bool from_flash = false; + bool try_all_dl_modes = false; uint8_t downlink_mode = 0; - int len; - char cmdp; - bool use_pwd_file = false; - int dl_mode; // to try each downlink mode for each password + bool use_pwd_file = false; + int dl_mode; // to try each downlink mode for each password + uint8_t cmdp = 0; + bool errors = false; - - cmdp = tolower(param_getchar(Cmd, 0)); - - if (cmdp == 'h') return usage_t55xx_chk(); - if (cmdp == 'm') { - from_flash = true; - Cmd += 2; - cmdp = tolower(param_getchar(Cmd, 0)); - } - if (cmdp == 'r') { - Cmd += 2; - downlink_mode = param_getchar(Cmd, 0) - '0'; // get 2nd option, as this is fixed order. - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; - Cmd += 2; - cmdp = param_getchar(Cmd, 0); - } - if (cmdp == 'i') { - Cmd += 2; - len = strlen(Cmd); - if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); - use_pwd_file = true; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_chk(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode >= 4) { + try_all_dl_modes = true; + downlink_mode = 4; + } + cmdp += 2; + break; + case 'm': + from_flash = true; + cmdp++; + break; + case 'i': + if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0 ) { + PrintAndLogEx(ERR, "Error, no filename after 'f' was found"); + errors = true; + } + use_pwd_file = true; + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - + if (errors) return usage_t55xx_chk(); /* // block 7, page1 = false, usepwd = false, override = false, pwd = 00000000 @@ -2127,19 +2231,13 @@ static int CmdT55xxChkPwds(const char *Cmd) { if (use_pwd_file) { uint16_t keycount = 0; - size_t datalen = 0; - // TODO, a way of reallocating memory if file was larger - keyBlock = calloc(4 * 200, sizeof(uint8_t)); - if (keyBlock == NULL) { - PrintAndLogEx(ERR, "error, cannot allocate memory "); - return PM3_ESOFT; - } - - int res = loadFileDICTIONARY(filename, keyBlock, &datalen, 4, &keycount); - if (res || keycount == 0) { + int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 4, &keycount); + if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) { PrintAndLogEx(WARNING, "No keys found in file"); - free(keyBlock); + if (keyBlock != NULL) + free(keyBlock); + return PM3_ESOFT; } @@ -2194,33 +2292,48 @@ out: static int CmdT55xxBruteForce(const char *Cmd) { uint32_t start_password = 0x00000000; //start password - uint32_t end_password = 0xFFFFFFFF; //end password - uint32_t curr = 0; - uint8_t downlink_mode = 0; - uint8_t cmd_opt_idx = 0; - uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found + uint32_t end_password = 0xFFFFFFFF; //end password + uint32_t curr = 0; + uint8_t downlink_mode = 0; + uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found + uint8_t cmdp = 0; + bool errors = false; - char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); - - if (cmdp == 'h') return usage_t55xx_bruteforce(); - if (cmdp == 'r') { // downlink mode supplied - cmd_opt_idx++; // skip over 'r' - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 4) downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_bruteforce(); + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 4) + downlink_mode = 0; + + cmdp += 2; + break; + case 's': + start_password = param_get32ex(Cmd, cmdp + 1, 0, 16); + cmdp += 2; + break; + case 'e': + end_password = param_get32ex(Cmd, cmdp + 1, 0, 16); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - - - uint64_t t1 = msclock(); - - start_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); - end_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16); - - curr = start_password; - if (start_password >= end_password) { return usage_t55xx_bruteforce(); } + if (errors) return usage_t55xx_bruteforce(); + + uint64_t t1 = msclock(); + + curr = start_password; + PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password); while (found == 0) { @@ -2281,25 +2394,41 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { } static int CmdT55xxRecoverPW(const char *Cmd) { - int bit = 0; + int bit = 0; uint32_t orig_password = 0x0; uint32_t curr_password = 0x0; uint32_t prev_password = 0xffffffff; - uint32_t mask = 0x0; - uint8_t downlink_mode = 0; - uint8_t found = 0; - uint8_t cmd_opt_idx = 0; + uint32_t mask = 0x0; + uint8_t downlink_mode = 0; + uint8_t found = 0; + uint8_t cmdp = 0; + bool errors = false; - char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx)); - - if (cmdp == 'h') return usage_t55xx_recoverpw(); - if (cmdp == 'r') { // downlink mode supplied - cmd_opt_idx++; // skip over 'r' - downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0'; - if (downlink_mode > 4) downlink_mode = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_t55xx_recoverpw(); + case 'p': + // password used by handheld cloners + orig_password = param_get32ex(Cmd, cmdp + 1, 0x51243648, 16); + cmdp += 2; + break; + case 'r': + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 4) + downlink_mode = 0; + + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } - orig_password = param_get32ex(Cmd, cmd_opt_idx++, 0x51243648, 16); //password used by handheld cloners + if (errors) return usage_t55xx_recoverpw(); + // first try fliping each bit in the expected password while (bit < 32) { @@ -2514,9 +2643,13 @@ static int CmdT55xxDetectPage1(const char *Cmd) { cmdp++; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode == 4) try_all_dl_modes = true; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode == 4) + try_all_dl_modes = true; + + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; default: @@ -2592,8 +2725,10 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) { cmdp += 2; break; case 'r': - downlink_mode = param_getchar(Cmd, cmdp + 1) - '0'; - if (downlink_mode > 3) downlink_mode = 0; + downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); + if (downlink_mode > 3) + downlink_mode = 0; + cmdp += 2; break; case 'p': diff --git a/client/cmdparser.c b/client/cmdparser.c index 768941e10..9e7b83afa 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -176,6 +176,9 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { memset(cmd_name, 0, sizeof(cmd_name)); sscanf(Cmd, "%127s%n", cmd_name, &len); str_lower(cmd_name); + // Comment + if (cmd_name[0] == '#') + return PM3_SUCCESS; int i = 0; while (Commands[i].Name) { if (0 == strcmp(Commands[i].Name, cmd_name)) { diff --git a/client/cmdscript.c b/client/cmdscript.c index 28dd8608f..6d7858d54 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -8,10 +8,6 @@ // Some lua scripting glue to proxmark core. //----------------------------------------------------------------------------- -// this define is needed for scandir/alphasort to work -#define _GNU_SOURCE - -#include #include #include @@ -26,36 +22,10 @@ #include "lauxlib.h" #include "proxmark3.h" #include "ui.h" - -#ifdef _WIN32 -#include "scandir.h" -#endif +#include "fileutils.h" static int CmdHelp(const char *Cmd); -static int str_ends_with(const char *str, const char *suffix) { - - if (str == NULL || suffix == NULL) - return 0; - - size_t str_len = strlen(str); - size_t suffix_len = strlen(suffix); - - if (suffix_len > str_len) - return 0; - - return 0 == strncmp(str + str_len - suffix_len, suffix, suffix_len); -} - -/** - * Utility to check the ending of a string (used to check file suffix) - */ -static bool endsWith(const char *base, const char *str) { - int blen = strlen(base); - int slen = strlen(str); - return (blen >= slen) && (0 == strcmp(base + blen - slen, str)); -} - /** * Generate a sorted list of available commands, what it does is * generate a file listing of the script-directory for files @@ -63,31 +33,10 @@ static bool endsWith(const char *base, const char *str) { */ static int CmdScriptList(const char *Cmd) { (void)Cmd; // Cmd is not used so far - - char const *exedir = get_my_executable_directory(); - if (exedir == NULL) - return 0; - char script_directory_path[strlen(exedir) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; - strcpy(script_directory_path, exedir); - strcpy(script_directory_path, get_my_executable_directory()); - strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); - - struct dirent **namelist; - int n; - - n = scandir(script_directory_path, &namelist, NULL, alphasort); - if (n == -1) { - PrintAndLogEx(FAILED, "Couldn't open the scripts-directory"); - return 1; - } - - for (uint16_t i = 0; i < n; i++) { - if (str_ends_with(namelist[i]->d_name, ".lua")) - PrintAndLogEx(NORMAL, "%-21s", namelist[i]->d_name); - free(namelist[i]); - } - free(namelist); - return 0; + int ret = searchAndList(LUA_SCRIPTS_SUBDIR, ".lua"); + if (ret != PM3_SUCCESS) + return ret; + return searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd"); } /** @@ -97,67 +46,81 @@ static int CmdScriptList(const char *Cmd) { * @return */ static int CmdScriptRun(const char *Cmd) { - // create new Lua state - lua_State *lua_state; - lua_state = luaL_newstate(); - // load Lua libraries - luaL_openlibs(lua_state); - - //Sets the pm3 core libraries, that go a bit 'under the hood' - set_pm3_libraries(lua_state); - - //Add the 'bin' library - set_bin_library(lua_state); - - //Add the 'bit' library - set_bit_library(lua_state); - - char script_name[128] = {0}; + char preferredName[128] = {0}; char arguments[256] = {0}; int name_len = 0; int arg_len = 0; - sscanf(Cmd, "%127s%n %255[^\n\r]%n", script_name, &name_len, arguments, &arg_len); + static uint8_t luascriptfile_idx = 0; + sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len); - const char *suffix = ""; - if (!endsWith(script_name, ".lua")) { - suffix = ".lua"; + char *script_path; + if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) { + int error; + if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) { + PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", script_path); + return PM3_EMALLOC; + } + PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments); + luascriptfile_idx++; + + // create new Lua state + lua_State *lua_state; + lua_state = luaL_newstate(); + + // load Lua libraries + luaL_openlibs(lua_state); + + //Sets the pm3 core libraries, that go a bit 'under the hood' + set_pm3_libraries(lua_state); + + //Add the 'bin' library + set_bin_library(lua_state); + + //Add the 'bit' library + set_bit_library(lua_state); + + error = luaL_loadfile(lua_state, script_path); + free(script_path); + if (!error) { + lua_pushstring(lua_state, arguments); + lua_setglobal(lua_state, "args"); + + //Call it with 0 arguments + error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error, + } + if (error) { // if non-0, then an error + // the top of the stack should be the error string + if (!lua_isstring(lua_state, lua_gettop(lua_state))) + PrintAndLogEx(FAILED, "Error - but no error (?!)"); + + // get the top of the stack as the error and pop it off + const char *str = lua_tostring(lua_state, lua_gettop(lua_state)); + lua_pop(lua_state, 1); + puts(str); + } + + //luaL_dofile(lua_state, buf); + // close the Lua state + lua_close(lua_state); + luascriptfile_idx--; + PrintAndLogEx(SUCCESS, "\nFinished %s\n", preferredName); + return PM3_SUCCESS; } - - char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; - strcpy(script_path, get_my_executable_directory()); - strcat(script_path, LUA_SCRIPTS_DIRECTORY); - strcat(script_path, script_name); - strcat(script_path, suffix); - - PrintAndLogEx(SUCCESS, "Executing: %s%s, args '%s'\n", script_name, suffix, arguments); - - // run the Lua script - int error = luaL_loadfile(lua_state, script_path); - if (!error) { - lua_pushstring(lua_state, arguments); - lua_setglobal(lua_state, "args"); - - //Call it with 0 arguments - error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error, + if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) { + PrintAndLogEx(SUCCESS, "Executing Cmd script: %s, args '%s'\n", script_path, arguments); + int ret = push_cmdscriptfile(script_path, true); + if (ret != PM3_SUCCESS) + PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_path); + free(script_path); + return ret; } - if (error) { // if non-0, then an error - // the top of the stack should be the error string - if (!lua_isstring(lua_state, lua_gettop(lua_state))) - PrintAndLogEx(FAILED, "Error - but no error (?!)"); - - // get the top of the stack as the error and pop it off - const char *str = lua_tostring(lua_state, lua_gettop(lua_state)); - lua_pop(lua_state, 1); - puts(str); - } - - //luaL_dofile(lua_state, buf); - // close the Lua state - lua_close(lua_state); - PrintAndLogEx(SUCCESS, "\nFinished\n"); - return 0; + // file not found, let's search again to display the error messages + int ret = PM3_EUNDEF; + if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false); + if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false); + return ret; } static command_t CommandTable[] = { @@ -175,7 +138,7 @@ static command_t CommandTable[] = { */ static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far - PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place lua-scripts within the scripts/-folder. "); + PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place Lua-scripts within the luascripts/-folder. "); return 0; } diff --git a/client/cmdscripts/rdv4_init_extflash.cmd b/client/cmdscripts/rdv4_init_extflash.cmd new file mode 100755 index 000000000..2cae05294 --- /dev/null +++ b/client/cmdscripts/rdv4_init_extflash.cmd @@ -0,0 +1,6 @@ +#!/usr/bin/env -S pm3 -s + +mem load f mfc_default_keys m +mem load f t55xx_default_pwds t +mem load f iclass_default_keys i +lf t55xx deviceconfig z p diff --git a/client/cmdsmartcard.c b/client/cmdsmartcard.c index f1fd2b917..c9dde7063 100644 --- a/client/cmdsmartcard.c +++ b/client/cmdsmartcard.c @@ -22,6 +22,7 @@ #include "crypto/libpcrypto.h" // sha512hash #include "emv/dump.h" #include "ui.h" +#include "fileutils.h" static int CmdHelp(const char *Cmd); @@ -68,7 +69,7 @@ static int usage_sm_upgrade(void) { PrintAndLogEx(NORMAL, " f : firmware file name"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/SIM011.BIN"); + PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/sim011.bin"); return 0; } static int usage_sm_setclock(void) { @@ -92,33 +93,35 @@ static int usage_sm_brute(void) { return 0; } -static int smart_loadjson(const char *preferredName, const char *suffix, json_t **root) { +static int smart_loadjson(const char *preferredName, json_t **root) { json_error_t error; if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; - int retval = 0; - int size = sizeof(char) * (strlen(get_my_executable_directory()) + strlen(preferredName) + strlen(suffix) + 10); - char *fileName = calloc(size, sizeof(char)); - sprintf(fileName, "%s%s.%s", get_my_executable_directory(), preferredName, suffix); - *root = json_load_file(fileName, 0, &error); + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json", false); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + int retval = PM3_SUCCESS; + *root = json_load_file(path, 0, &error); if (!*root) { - PrintAndLogEx(ERR, "json (%s) error on line %d: %s", fileName, error.line, error.text); - retval = 2; + PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text); + retval = PM3_ESOFT; goto out; } if (!json_is_array(*root)) { - PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", fileName); - retval = 3; + PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path); + retval = PM3_ESOFT; goto out; } - PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", fileName); + PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path); out: - free(fileName); + free(path); return retval; } @@ -1035,7 +1038,7 @@ static int CmdSmartBruteforceSFI(const char *Cmd) { PrintAndLogEx(INFO, "Importing AID list"); json_t *root = NULL; - smart_loadjson("aidlist", "json", &root); + smart_loadjson("aidlist", &root); uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t)); if (!buf) diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 15416a8a6..010621498 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -16,7 +16,7 @@ #include "parity.h" // oddparity #include "cmdhflist.h" // annotations #include "comms.h" // for sending cmds to device. GetFromBigBuf -#include "loclass/fileutils.h" // for saveFile +#include "fileutils.h" // for saveFile static int CmdHelp(const char *Cmd); @@ -294,6 +294,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr uint8_t parityBits = parityBytes[j >> 3]; if (protocol != LEGIC && protocol != ISO_14443B + && protocol != ISO_15693 + && protocol != ICLASS && protocol != ISO_7816_4 && protocol != PROTO_HITAG && protocol != THINFILM @@ -301,7 +303,18 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); - } else { + } else if ( protocol == ICLASS && isResponse == false) { + uint8_t parity = 0; + for (int i=0; i<6; i++) { + parity ^= ((frame[0] >> i) & 1); + } + if ( parity == ((frame[0] >> 7) & 1)) { + snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); + } else { + snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]); + } + + } else { snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]); } diff --git a/client/cmdusart.c b/client/cmdusart.c index 0b668bbe7..26b972f82 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -763,8 +763,8 @@ static int CmdUsartRXhex(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"btpin", CmdUsartBtPin, IfPm3FpcUsartHostFromUsb, "Change BT add-on PIN"}, - {"btfactory", CmdUsartBtFactory, IfPm3FpcUsartHostFromUsb, "Reset BT add-on to factory settings"}, + {"btpin", CmdUsartBtPin, IfPm3FpcUsartFromUsb, "Change BT add-on PIN"}, + {"btfactory", CmdUsartBtFactory, IfPm3FpcUsartFromUsb, "Reset BT add-on to factory settings"}, {"tx", CmdUsartTX, IfPm3FpcUsartDevFromUsb, "Send string over USART"}, {"rx", CmdUsartRX, IfPm3FpcUsartDevFromUsb, "Receive string over USART"}, {"txrx", CmdUsartTXRX, IfPm3FpcUsartDevFromUsb, "Send string over USART and wait for response"}, diff --git a/client/crypto/asn1dump.c b/client/crypto/asn1dump.c index 356dd3591..91b04216a 100644 --- a/client/crypto/asn1dump.c +++ b/client/crypto/asn1dump.c @@ -25,6 +25,8 @@ #include "emv/emvjson.h" #include "util.h" #include "proxmark3.h" +#include "fileutils.h" +#include "pm3_cmd.h" #ifndef PRINT_INDENT # define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} @@ -235,25 +237,17 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag * static char *asn1_oid_description(const char *oid, bool with_group_desc) { json_error_t error; json_t *root = NULL; - char fname[300] = {0}; static char res[300]; memset(res, 0x00, sizeof(res)); - size_t len = strlen(get_my_executable_directory()); - if (len >= 300) len = 299; - - strncpy(fname, get_my_executable_directory(), len); - strcat(fname, "crypto/oids.json"); - if (access(fname, F_OK) < 0) { - strncpy(fname, get_my_executable_directory(), len); - strcat(fname, "oids.json"); - if (access(fname, F_OK) < 0) { - goto error; // file not found - } + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, "oids", ".json", false) != PM3_SUCCESS) { + return NULL; } // load `oids.json` - root = json_load_file(fname, 0, &error); + root = json_load_file(path, 0, &error); + free(path); if (!root || !json_is_object(root)) { goto error; diff --git a/client/default_iclass_keys.dic b/client/default_iclass_keys.dic deleted file mode 100644 index 829ba521e..000000000 --- a/client/default_iclass_keys.dic +++ /dev/null @@ -1,11 +0,0 @@ -# -# iClass Default Keys -# -- iceman fork version -- -# -- contribute to this list, sharing is caring -- -AEA684A6DAB23278 -- AA1 -7665544332211000 -- key1/Kc from PicoPass 2k documentation -0123456789ABCDEF -- SAGEM -5b7c62c491c11b39 -- from loclass demo file. -F0E1D2C3B4A59687 -- Kd from PicoPass 2k documentation -5CBCF1DA45D5FB4F -- PicoPass Default Exchange Key -31ad7ebd2f282168 -- From HID multiclassSE reader diff --git a/client/default_keys.dic b/client/default_keys.dic deleted file mode 100644 index 54c355de4..000000000 --- a/client/default_keys.dic +++ /dev/null @@ -1,966 +0,0 @@ -# -# Mifare Default Keys -# -- iceman fork version -- -# -- contribute to this list, sharing is caring -- -# -ffffffffffff,//Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) -000000000000,//Blankkey -a0a1a2a3a4a5,//NFCForumMADkey -b0b1b2b3b4b5, -c0c1c2c3c4c5, -d0d1d2d3d4d5, -aabbccddeeff, -4d3a99c351dd, -1a982c7e459a, -d3f7d3f7d3f7,// key A Wien -5a1b85fce20a,// key B Wien -714c5c886e97, -587ee5f9350f, -a0478cc39091, -533cb6c723f6, -8fd0a4f256e9, -# -d2ece8b9395e, //lib -# -# more Keys from mf_default_keys.lua -000000000001, -000000000002, -00000000000a, -00000000000b, -00000ffe2488,--VästtrafikenKeyB -010203040506, -0123456789ab, -0297927c0f77,--VästtrafikenKeyA -100000000000, -111111111111, -123456789abc, -12f2ee3478c1, -14d446e33363, -1999a3554a55, -200000000000, -222222222222, -26940b21ff5d,--RKFSLKeyA -27dd91f1fcf1, -2BA9621E0A36,--DirectoryandeventlogKeyB -333333333333, -33f974b42769, -34d1df9934c5, -434f4d4d4f41,--RKFJOJOGROUPKeyA -434f4d4d4f42,--RKFJOJOGROUPKeyB -43ab19ef5c31, -444444444444, -47524f555041,--RKFJOJOGROUPKeyA -47524f555042,--RKFJOJOGROUPKeyB -4AF9D7ADEBE4,--DirectoryandeventlogKeyA -4b0b20107ccb,--TNP3xxx -505249564141,--RKFJOJOPRIVAKeyA -505249564142,--RKFJOJOPRIVAKeyB -505249565441, -505249565442, -54726176656c,--VästtrafikenKeyA -555555555555, -55f5a5dd38c9, -569369c5a0e5,--kiev -5c598c9c58b5,--RKFSLKeyB -632193be1c3c,--kiev -644672bd4afe,--kiev -666666666666, -722bfcc5375f,--RKFRejskortDanmarkKeyA -776974687573,--VästtrafikenKeyB -777777777777, -888888888888, -8fe644038790,--kiev -999999999999, -99c636334433, -9de89e070277,--kiev -a00000000000, -a053a292a4af, -a64598a77478,--RKFSLKeyA -a94133013401, -aaaaaaaaaaaa, -abcdef123456,--Keyfromladyada.net -b00000000000, -b127c6f41436, -b5ff67cba951,--kiev -bbbbbbbbbbbb, -bd493a3962b6, -c934fe34d934, -cccccccccccc, -dddddddddddd, -e4d2770a89be,--RKFSLKeyB -ee0042f88840,--VästtrafikenKeyB -eeeeeeeeeeee, -eff603e1efe9,--kiev -f14ee7cae863,--kiev -f1a97341a9fc, -f1d83f964314,--RKFRejskortDanmarkKeyB -fc00018778f7,--VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA -44ab09010845,-- hotel system -85fed980ea5a,-- hotel system -314B49474956 --VIGIK1 A -564c505f4d41 --VIGIK1 B -ba5b895da162 --VIGIK1 B -# Vigik mystery Keys Mifare 1k EV1 (S50) -5c8ff9990da2, 16 A -75ccb59c9bed, 17 A -d01afeeb890a, 16 B -4b791bea7bcc, 17 B -# -4143414F5250, -a9b43414F585,--Tehran Railway -1FB235AC1388,--Tehran Railway -# -# Data from: http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ -f4a9ef2afc6d,--BCARD KeyB -# -# Data from: ... -89eac97f8c2a // S0 B -43c7600dee6b // S4 A -0120bf672a64 // S6 A -fb0b20df1f34 // S6 B -# -a9f953def0a3, -# -# Here be BIP keys... -3A42F33AF429, -1FC235AC1309, -6338A371C0ED, -243F160918D1, -F124C2578AD0, -9AFC42372AF1, -32AC3B90AC13, -682D401ABB09, -4AD1E273EAF1, -067DB45454A9, -E2C42591368A, -15FC4C7613FE, -2A3C347A1200, -68D30288910A, -16F3D5AB1139, -F59A36A2546D, -937A4FFF3011, -64E3C10394C2, -35C3D2CAEE88, -B736412614AF, -693143F10368, -324F5DF65310, -A3F97428DD01, -643FB6DE2217, -63F17A449AF0, -82F435DEDF01, -C4652C54261C, -0263DE1278F3, -D49E2826664F, -51284C3686A6, -3DF14C8000A1, -6A470D54127C, -# -# Data from: http://pastebin.com/AK9Bftpw -48ffe71294a0, -- Länstrafiken i Västerbotten -e3429281efc1, -- Länstrafiken i Västerbotten -16f21a82ec84, -- Länstrafiken i Västerbotten -460722122510, -- Länstrafiken i Västerbotten -# -# 3dprinter -AAFB06045877, --EPI Envisionte# 3dprinter -# -# gym -3e65e4fb65b3, --Fysiken A -25094df6f148, --Fysiken B -a05dbd98e0fc, -- CleverFit -# -d3b595e9dd63, -- Hotel KeyCard -afbecd121004, -- Hotel KeyCard -6471a5ef2d1a, -- SimonsVoss -# -# 24-7 -D21762B2DE3B, -0E83A374B513, -1F1FFE000000, -A10F303FC879, -1322285230b8, -0C71BCFB7E72, -C3C88C6340B8, -F101622750B7, -1F107328DC8D, -710732200D34, -7C335FB121B5, -B39AE17435DC, -# -# -454841585443, -- key A -# -# Data from: http://pastebin.com/gQ6nk38G -D39BB83F5297, -85675B200017, -528C9DFFE28C, -C82EC29E3235, -3E3554AF0E12, -491CDCFB7752, -22C1BAE1AACD, -5F146716E373, -740E9A4F9AAF, -AC0E24C75527, -97184D136233, -E444D53D359F, -17758856B182, -A8966C7CC54B, -C6AD00254562, -AE3FF4EEA0DB, -5EB8F884C8D1, -FEE470A4CB58, -75D8690F21B6, -871B8C085997, -97D1101F18B0, -75EDE6A84460, -DF27A8F1CB8E, -B0C9DD55DD4D, -# -# Data from: http://bit.ly/1bdSbJl -A0B0C0D0E0F0, -A1B1C1D1E1F1, -# -# Data from: msk social -2735fc181807, -2aba9519f574, -84fd7f7a12b6, -186d8c4b93f9, -3a4bba8adaf0, -8765b17968a2, -40ead80721ce, -0db5e6523f7c, -51119dae5216, -83e3549ce42d, -136bdb246cac, -7de02a7f6025, -bf23a53c1f63, -cb9a1f2d7368, -c7c0adb3284f, -9f131d8c2057, -67362d90f973, -6202a38f69e2, -100533b89331, -653a87594079, -d8a274b2e026, -b20b83cb145c, -9afa6cb4fc3d, -# -# Data from http://pastebin.com/RRJUEDCM -0d258fe90296, -e55a3ca71826, -a4f204203f56, -eeb420209d0c, -911e52fd7ce4, -752fbb5b7b45, -66b03aca6ee9, -48734389edc3, -17193709adf4, -1acc3189578c, -c2b7ec7d4eb1, -369a4663acd2, -# -# Data from https://github.com/zhangjingye03/zxcardumper -# zxcard Key A/B -668770666644, -003003003003, -# -# Data from: http://phreakerclub.com/forum/showthread.php?p=41266 -26973ea74321, -71f3a315ad26, -51044efb5aab, -ac70ca327a04, -eb0a8ff88ade, -# -# Data from: https://github.com/RadioWar/NFCGUI -44dd5a385aaf, -21a600056cb0, -b1aca33180a5, -dd61eb6bce22, -1565a172770f, -3e84d2612e2a, -f23442436765, -79674f96c771, -87df99d496cb, -c5132c8980bc, -a21680c27773, -f26e21edcee2, -675557ecc92e, -f4396e468114, -6db17c16b35b, -4186562a5bb2, -2feae851c199, -db1a3338b2eb, -157b10d84c6b, -a643f952ea57, -df37dcb6afb3, -4c32baf326e0, -91ce16c07ac5, -3c5d1c2bcd18, -c3f19ec592a2, -f72a29005459, -185fa3438949, -321a695bd266, -d327083a60a7, -45635ef66ef3, -5481986d2d62, -cba6ae869ad5, -645a166b1eeb, -a7abbc77cc9e, -f792c4c76a5c, -bfb6796a11db, -# -# Data from Salto A/B -6A1987C40A21, -7F33625BC129, -# -# Data from forum -2338b4913111, -# -# Data from stoye -cb779c50e1bd, -a27d3804c259, -003cc420001a, -f9861526130f, -381ece050fbd, -a57186bdd2b9, -48c739e21a04, -36abf5874ed7, -649d2abbbd20, -bbe8fffcf363, -ab4e7045e97d, -340e40f81cd8, -e4f65c0ef32c, -d2a597d76936, -a920f32fe93a, -86afd95200f7, -9b832a9881ff, -26643965b16e, -0c669993c776, -b468d1991af9, -d9a37831dce5, -2fc1f32f51b1, -0ffbf65b5a14, -c5cfe06d9ea3, -c0dece673829, -# -a56c2df9a26d, -# -# Data from: https://pastebin.com/vbwast74 -# -68d3f7307c89, -568c9083f71c,--Smart Rider. Western Australian Public Transport Cards -# Vigik Keys -# Various sources : -# * https://github.com/DumpDos/Vigik -# * http://newffr.com/viewtopic.php?&forum=235&topic=11559 -# * Own dumps -021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key -2ef720f2af76, -414c41524f4e, -424c41524f4e, -4a6352684677, -bf1f4424af76, -536653644c65, -# -# Intratone Cogelec -# Data from http://bouzdeck.com/rfid/32-cloning-a-mifare-classic-1k-tag.html -484558414354, -a22ae129c013, -49fae4e3849f, -38fcf33072e0, -8ad5517b4b18, -509359f131b1, -6c78928e1317, -aa0720018738, -a6cac2886412, -62d0c424ed8e, -e64a986a5d94, -8fa1d601d0a2, -89347350bd36, -66d2b7dc39ef, -6bc1e1ae547d, -22729a9bd40f, -# -# Data from https://dfir.lu/blog/cloning-a-mifare-classic-1k-tag.html -925b158f796f, -fad63ecb5891, -bba840ba1c57, -cc6b3b3cd263, -6245e47352e6, -8ed41e8b8056, -2dd39a54e1f3, -6d4c5b3658d2, -1877ed29435a, -52264716efde, -961c0db4a7ed, -703140fd6d86, -157c9a513fa5, -e2a5dc8e066f, -# -# Data from a oyster card -374bf468607f, -bfc8e353af63, -15cafd6159f6, -62efd80ab715, -987a7f7f1a35, -c4104fa3c526, -4c961f23e6be, -67546972bc69, -f4cd5d4c13ff, -94414c1a07dc, -16551d52fd20, -9cb290282f7d, -77a84170b574, -ed646c83a4f3, -e703589db50b, -513c85d06cde, -95093f0b2e22, -543b01b27a95, -c6d375b99972, -ee4cc572b40e, -5106ca7e4a69, -c96bd1ce607f, -167a1be102e0, -a8d0d850a606, -a2abb693ce34, -7b296c40c486, -91f93a5564c9, -e10623e7a016, -b725f9cbf183, -# -# Data from FDi tag -8829da9daf76, -# -# Data from GitHub issue -0A7932DC7E65, -11428B5BCE06, -11428B5BCE07, -11428B5BCE08, -11428B5BCE09, -11428B5BCE0A, -11428B5BCE0F, -18971D893494, -25D60050BF6E, -3FA7217EC575, -44F0B5FBE344, -7B296F353C6B, -8553263F4FF0, -8E5D33A6ED51, -9F42971E8322, -C620318EF179, -D4FE03CE5B06, -D4FE03CE5B07, -D4FE03CE5B08, -D4FE03CE5B09, -D4FE03CE5B0A, -D4FE03CE5B0F, -E241E8AFCBAF, -# -# Data from forum post -123F8888F322, -050908080008, -# -# Data from hoist -4f9f59c9c875, -# -# Data from pastebin -66f3ed00fed7, -f7a39753d018, -# -# Data from https://pastebin.com/Z7pEeZif -386B4D634A65, -666E564F4A44, -564777315276, -476242304C53, -6A696B646631, -4D3248735131, -425A73484166, -57784A533069, -345547514B4D, -4C6B69723461, -4E4175623670, -4D5076656D58, -686A736A356E, -484A57696F4A, -6F4B6D644178, -744E326B3441, -70564650584F, -584F66326877, -6D4E334B6C48, -6A676C315142, -77494C526339, -623055724556, -356D46474348, -4E32336C6E38, -57734F6F6974, -436A46587552, -5544564E6E67, -6F506F493353, -31646241686C, -77646B633657, -# -# Data from TransPert -2031d1e57a3b, -53c11f90822a, -9189449ea24e, -# -# data from Github -410b9b40b872, -2cb1a90071c8, -# -# data from -8697389ACA26, -1AB23CD45EF6, -013889343891, -# -# -0000000018de, -16ddcb6b3f24, -# -# Data from https://pastebin.com/vwDRZW7d -EC0A9B1A9E06,--Vingcard Mifare 4k Staff card -6C94E1CED026,--Vingcard Mifare 4k Staff card -0F230695923F,--Vingcard Mifare 4k Staff card -0000014B5C31,--Vingcard Mifare 4k Staff card -# -BEDB604CC9D1, -B8A1F613CF3D, -B578F38A5C61, -B66AC040203A -6D0B6A2A0003 -2E641D99AD5B -AD4FB33388BF, -69FB7B7CD8EE, -2A6D9205E7CA, -2a2c13cc242a, -27FBC86A00D0, -01FA3FC68349, -# -6D44B5AAF464,--Smart Rider. Western Australian Public Transport Cards -1717E34A7A8A,--Smart Rider. Western Australian Public Transport Cards -# -6B6579737472,--RFIDeas -# -484944204953,--HID MIFARE Classic 1k Key -204752454154,--HID MIFARE Classic 1k Key -3B7E4FD575AD,--HID MIFARE SO -11496F97752A,--HID MIFARE SO -# -415A54454B4D,--Luxeo/Aztek cashless vending -# -321958042333,--BQT -# -160A91D29A9C,--Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48 -# -b7bf0c13066e,--Gallagher -# -# Boston, MA, USA Transit - MBTA Charlie Card -3060206f5b0a,-- charlie -5ec39b022f2b,-- charlie -3a09594c8587,-- charlie -f1b9f5669cc8,-- charlie -f662248e7e89,-- charlie -62387b8d250d,-- charlie -f238d78ff48f,-- charlie -9dc282d46217,-- charlie -afd0ba94d624,-- charlie -92ee4dc87191,-- charlie -b35a0e4acc09,-- charlie -756ef55e2507,-- charlie -447ab7fd5a6b,-- charlie -932b9cb730ef,-- charlie -1f1a0a111b5b,-- charlie -ad9e0a1ca2f7,-- charlie -d58023ba2bdc,-- charlie -62ced42a6d87,-- charlie -2548a443df28,-- charlie -2ed3b15e7c0f,-- charlie -# -60012e9ba3fa, -# -de1fcbec764b, -81bfbe8cacba, -bff123126c9b, -2f47741062a0, -b4166b0a27ea, -a170d9b59f95, -400bc9be8976, -d80511fc2ab4, -1fcef3005bcf, -bb467463acd6, -e67c8010502d, -ff58ba1b4478, -# Data from https://pastebin.com/Kz8xp4ev -fbf225dc5d58, -# -# Data https://pastebin.com/BEm6bdAE -# vingcard.txt -4708111c8604, -3d50d902ea48, -96a301bce267, -6700f10fec09, -7a09cc1db70a, -560f7cff2d81, -66b31e64ca4b, -9e53491f685b, -3a09911d860c, -8a036920ac0c, -361f69d2c462, -d9bcde7fc489, -0c03a720f208, -6018522fac02, -# -# Data from https://pastebin.com/4t2yFMgt -# Mifare technische Universität Graz TUG -D58660D1ACDE, -50A11381502C, -C01FC822C6E5, -0854BF31111E, -# More keys: -8a19d40cf2b5, -ae8587108640, -135b88a94b8b, SafLock standalone door locks. -# -# Russian Troika card -08B386463229, -0E8F64340BA4, -0F1C63013DBA, -2AA05ED1856F, -2B7F3253FAC5, -69A32F1C2F19, -73068F118C13, -9BECDF3D9273, -A73F5DC1D333, -A82607B01C0D, -AE3D65A3DAD4, -CD4C61C26E3D, -D3EAFB5DF46D, -E35173494A81, -FBC2793D540B, -5125974CD391, -ECF751084A80, -7545DF809202, -AB16584C972A, -7A38E3511A38, -C8454C154CB5, -04C297B91308, -EFCB0E689DB3, -07894FFEC1D6, -FBA88F109B32, -2FE3CB83EA43, -B90DE525CEB6, -1CC219E9FEC1, -A74332F74994, -764CD061F1E6, -8F79C4FD8A01, -CD64E567ABCD, -CE26ECB95252, -ABA208516740, -9868925175BA, -16A27AF45407, -372CC880F216, -3EBCE0925B2F, -73E5B9D9D3A4, -0DB520C78C1C, -70D901648CB9, -C11F4597EFB5, -B39D19A280DF, -403D706BA880, -7038CD25C408, -6B02733BB6EC, -EAAC88E5DC99, -4ACEC1205D75, -2910989B6880, -31C7610DE3B0, -5EFBAECEF46B, -F8493407799D, -6B8BD9860763, -D3A297DC2698, -# -# Keys from MifareClassicTool project -044CE1872BC3, -045CECA15535, -0BE5FAC8B06A, -0CE7CD2CC72B, -0EB23CC8110B, -0F01CEFF2742, -0F318130ED18, -114D6BE9440C, -18E3A02B5EFF, -19FC84A3784B, -1B61B2E78C75, -22052B480D11, -3367BFAA91DB, -3A8A139C20B4, -42E9B54E51AB, -46D78E850A7E, -4B609876BBA3, -518DC6EEA089, -6B07877E2C5C, -7259FA0197C6, -72F96BDD3714, -7413B599C4EA, -77DABC9825E1, -7A396F0D633D, -7A86AA203788, -8791B2CCB5C4, -8A8D88151A00, -8C97CD7A0E56, -8E26E45E7D65, -9D993C5D4EF4, -9EA3387A63C1, -A3FAA6DAFF67, -A7141147D430, -AAFB06045877, -ACFFFFFFFFFF, -AFCEF64C9913, -B27ADDFB64B0, -B81F2B0C2F66, -B9F8A7D83978, -BAFF3053B496, -BB52F8CCE07F, -BC2D1791DEC1, -BC4580B7F20B, -C65D4EAA645B, -C76BF71A2509, -D5524F591EED, -E328A1C7156D, -E4821A377B75, -E56AC127DD45, -EA0FD73CB149, -FC0001877BF7, -FD8705E721B0, -00ada2cd516d, -# -# -D3F7D3F7D3F7 -## -237a4d0d9119, -0ed7846c2bc9, -FFFFD06F83E3, -FFFFAE82366C, -F89C86B2A961, -F83466888612, -ED3A7EFBFF56, -E96246531342, -E1DD284379D4, -DFED39FFBB76, -DB5181C92CBE, -CFC738403AB0, -BCFE01BCFE01, -BA28CFD15EE8, -B0699AD03D17, -AABBCC660429, -A4EF6C3BB692, -A2B2C9D187FB, -9B1DD7C030A1, -9AEDF9931EC1, -8F9B229047AC, -872B71F9D15A, -833FBD3CFE51, -5D293AFC8D7E, -5554AAA96321, -474249437569, -435330666666, -1A2B3C4D5E6F, -123456ABCDEF, -83BAB5ACAD62, -64E2283FCF5E, -64A2EE93B12B, -46868F6D5677, -40E5EA1EFC00, -37D4DCA92451, -2012053082AD, -2011092119F1, -200306202033, -1795902DBAF9, -17505586EF02, -022FE48B3072, -013940233313, -# -# Hotel Adina -9EBC3EB37130, -# -# mostlikely diverised individual keys. -# data from: https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c -491CDC863104, -A2F63A485632, -98631ED2B229, -19F1FFE02563, -563A22C01FC8, -- Argentina -43CA22C13091, -- Argentina -25094DF2C1BD, -- Argentina -# -# OMNITEC.ES HOTEL TIMECARD / MAINTENANCECARD -AFBECD120454, -# -# OMNITEC.ES HOTEL EMERGENCYCARD -842146108088, -# -# TAPCARD PUBLIC TRANSPORT LA -# -EA1B88DF0A76, -D1991E71E2C5, -05F89678CFCF, -D31463A7AB6D, -C38197C36420, -772219470B38, -1C1532A6F1BC, -FA38F70215AD, -E907470D31CC, -160F4B7AB806, -1D28C58BBE8A, -B3830B95CA34, -6A0E215D1EEB, -E41E6199318F, -C4F271F5F0B3, -1E352F9E19E5, -0E0E8C6D8EB6, -C342F825B01B, -CB911A1A1929, -E65B66089AFC, -B81846F06EDF, -37FC71221B46, -880C09CFA23C, -6476FA0746E7, -419A13811554, -2C60E904539C, -4ECCA6236400, -10F2BBAA4D1C, -4857DD68ECD9, -C6A76CB2F3B5, -E3AD9E9BA5D4, -6C9EC046C1A4, -# -# ROC HIGHSCHOOL ACCESSCARD -# -B021669B44BB, -B18CDCDE52B7, -A22647F422AE, -B268F7C9CA63, -A37A30004AC9, -B3630C9F11C8, -A4CDFF3B1848, -B42C4DFD7A90, -A541538F1416, -B5F454568271, -A6C028A12FBB, -B6323F550F54, -A7D71AC06DC2, -B7C344A36D88, -A844F4F52385, -B8457ACC5F5D, -A9A4045DCE77, -B9B8B7B6B5B3, -AA4D051954AC, -BA729428E808, -AB28A44AD5F5, -BB320A757099, -AC45AD2D620D, -BCF5A6B5E13F, -AD5645062534, -BDF837787A71, -AE43F36C1A9A, -BE7C4F6C7A9A, -5EC7938F140A, -82D58AA49CCB, -# -# MELONCARD -# -323334353637, -# -# -CEE3632EEFF5, -827ED62B31A7, -03EA4053C6ED, -C0BEEFEC850B, -F57F410E18FF, -0AF7DB99AEE4, -A7FB4824ACBF, -207FFED492FD, -1CFA22DBDFC3, -30FFB6B056F5, -39CF885474DD, -00F0BD116D70, -4CFF128FA3EF, -10F3BEBC01DF, -# -# Transportes Insular La Palma -# -0172066b2f03, -0000085f0000, -1a80b93f7107, -70172066b2f0, -b1a80c94f710, -0b0172066b2f, -0f1a81c95071, -f0f0172066b2, -1131a81d9507, -2f130172066b, -71171a82d951, -b2f170172066, -1711b1a82e96, -6b2f1b017206, -62711f1a83e9, -66b2f1f01720, -97271231a83f, -066b2f230172, -f97371271a84, -2066b2f27017, -50983712b1a8, -72066b2f2b01, -850984712f1a, -172066b2f2f0, -a85198481331, -0172066b2f33, -1a8619858137, -70172066b2f3, -b1a862985913, -3b0172066b2f, -3f1a87298691, -f3f0172066b2, -# -# Tehran ezpay -# -38A88AEC1C43 -CBD2568BC7C6 -7BCB4774EC8F -22ECE9316461 -AE4B497A2527 -EEC0626B01A1 -2C71E22A32FE -91142568B22F -7D56759A974A -D3B1C7EA5C53 -41C82D231497 -0B8B21C692C2 -604Ac8D87C7E -8E7B29460F12 -BB3D7B11D224 -# -# Chaco -# -b210cfa436d2 -b8b1cfa646a8 -a9f95891f0a4 -# -# Keys from APK application "Scan Badge" -4A4C474F524D -444156494442 -434143445649 -434456495243 -A00002000021 -EF61A3D48E2A -A23456789123 -010000000000 -363119000001 -A00003000084 -675A32413770 -395244733978 -A0004A000036 -2C9F3D45BA13 -4243414F5250 -DFE73BE48AC6 -# -B069D0D03D17 -000131B93F28 diff --git a/client/default_pwd.dic b/client/default_pwd.dic deleted file mode 100644 index aa2b23719..000000000 --- a/client/default_pwd.dic +++ /dev/null @@ -1,123 +0,0 @@ -# known cloners -# ref. http://www.proxmark.org/forum/viewtopic.php?id=2022 -51243648, -000D8787, -19920427, -65857569, //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com) -# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77 -05D73B9F, -# ref. http://www.proxmark.org/forum/viewtopic.php?= -89A69E60, -# ref lock -314159E0, -# ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115 -AA55BBBB, -# ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376 -A5B4C3D2, -# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379 -1C0B5848, -# http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075 -00434343, -44B44CAE, -88661858, -# paxton bullit? -575F4F4B, -# -50520901, -# Default pwd, simple: -00000000, -11111111, -22222222, -33333333, -44444444, -55555555, -66666666, -77777777, -88888888, -99999999, -AAAAAAAA, -BBBBBBBB, -CCCCCCCC, -DDDDDDDD, -EEEEEEEE, -FFFFFFFF, -a0a1a2a3, -b0b1b2b3, -aabbccdd, -bbccddee, -ccddeeff, -50415353, -00000001, -00000002, -0000000a, -0000000b, -01020304, -02030405, -03040506, -04050607, -05060708, -06070809, -0708090A, -08090A0B, -090A0B0C, -0A0B0C0D, -0B0C0D0E, -0C0D0E0F, -01234567, -12345678, -10000000, -20000000, -30000000, -40000000, -50000000, -60000000, -70000000, -80000000, -90000000, -A0000000, -B0000000, -C0000000, -D0000000, -E0000000, -F0000000, -10101010, -01010101, -11223344, -22334455, -33445566, -44556677, -55667788, -66778899, -778899AA, -8899AABB, -99AABBCC, -AABBCCDD, -BBCCDDEE, -CCDDEEFF, -0CB7E7FC, //rfidler? -FABADA11, //china? -# 20 most common len==8 -87654321, -12341234, -69696969, -12121212, -12344321, -1234ABCD, -11112222, -13131313, -10041004, -# -31415926, //pii -abcd1234, -20002000, -19721972, -aa55aa55, // amiboo -55aa55aa, // rev amiboo -4f271149, // seeds ul-ev1 -07d7bb0b, // seeds ul-ev1 -9636ef8f, // seeds ul-ev1 -b5f44686, // seeds ul-ev1 -9E3779B9, // TEA -C6EF3720, // TEA -7854794A, // xbox tea constant :) -F1EA5EED, // burtle diff --git a/client/dictionaries/bmp_sort_keys.dic b/client/dictionaries/bmp_sort_keys.dic deleted file mode 100644 index 0f8acdcf3..000000000 --- a/client/dictionaries/bmp_sort_keys.dic +++ /dev/null @@ -1,1000 +0,0 @@ -002DE0301481, -004173272D18, -0058A4884CA5, -00BAC32761D8, -00BB79731B00, -00E8C85DB172, -02096124DA70, -024988BC4D5E, -0271B7C4B015, -028137A705DB, -02827C286AB4, -02C10DA600D0, -0340643D5E27, -037A5DA4682B, -037AC43CBD9D, -037B9B8AA219, -037EE3DE21B7, -0380A9A3CBDE, -03D10A75B56A, -03E8CD22E691, -04109ED8EA79, -04361330B35C, -043D8B66D569, -045E5588845C, -048DE5148DE7, -0490921D0194, -04B717BD92EB, -04D49C76623B, -051518B3301E, -0529E8827A52, -052B16064085, -05DC4016B500, -06124317A9A6, -06147D199266, -0670AEB833CE, -0686A9E6D6E0, -06A34E5E6639, -06B78AD0C4BB, -0710E7818AB8, -07121B8C633A, -07176713C0ED, -0793533A5087, -081D1B1C3110, -0849495E1CCA, -09429512046E, -0966C3B28E04, -098A92C3660A, -098B48278122, -099672009EEA, -0A7632943926, -0AEE126549DA, -0B3B8C2833BC, -0B733C13E2C9, -0B764247D00E, -0BE811559D69, -0C208AD4E4B3, -0C270BC0BDDC, -0C5D782CB183, -0C82C94EB11B, -0CCDE948878A, -0CCE39820AAE, -0CDE3E716B32, -0CE06C96DB4C, -0CE87813E389, -0D3385CEA152, -0D5C5B8BCC5B, -0DB0A87AB882, -0DE247593B93, -0E0AD1796003, -0E62E6CAC3D3, -106E2D6E55E6, -1096A7830C82, -11549C141AD9, -116A92C793D6, -116C31526819, -11C68052AAE9, -1234B5BE8E78, -1268C7D104E1, -12A21B5671A8, -13359D5AE9A5, -1426EC62BB6C, -144489B1056E, -14A22C112090, -14C9BBB5361B, -14EB6286AC57, -14EE72B27223, -153BB53ACE71, -157B03405B38, -15A45083D24E, -15DACCE8D5EC, -16124677BBC5, -16373A44D5D7, -1663659384DC, -167828B6105C, -16B25A453093, -1706B1BE25C7, -171B15888483, -17BC8EED9A0C, -17C6299D5A37, -17E9C4C416EB, -1804087C7166, -1841CC4E3E79, -18AB05761CC5, -18ADAAC2B08B, -18E566417E5C, -191390328752, -1A47959E7DB4, -1A9A970CC370, -1B095E78BB33, -1B1717043D2B, -1B1A054566D9, -1B4654AE9454, -1B9CD1ED3420, -1B9E00780953, -1BB6A9CE71E2, -1C1250A36A13, -1C2316079532, -1C2855ED7A10, -1CD1AE73CA8C, -1CD3D4E690B7, -1D0322005969, -1D09B23EB116, -1D67A32045ED, -1D89D900968A, -1DAE8D2CEA5C, -1E1873799CD7, -1E60CE7C5179, -1E6A67909B8D, -1E8516585792, -1EB0864E9134, -1ECE3D04A020, -2009828E4A21, -200A6A3AA65D, -20188A599582, -20267CB20256, -20628CA7D92D, -2077C980EB2E, -2089B5D68B27, -209481EC6256, -20B6691C64B1, -20CC5A00C677, -211473555436, -2170E9D0D448, -219529A90EDD, -21A5B6481B7D, -224A308017D1, -227D16EA455A, -22A1245CA266, -22A95CB798DC, -230E26964171, -231173B68E46, -2332BB9A2452, -234323BC2992, -234E50256146, -235C9338D5B6, -23789D9ADD0D, -23997DD240AB, -23A5BA53AD4D, -23BB58853461, -24CAD4153036, -24CE79506842, -25228ED714BC, -257377227B34, -2584287A0174, -2616192EEB22, -265C03B50877, -26D641E834DC, -27073B57132B, -279060E3DEE9, -284BA0A0A29C, -285C6604C5B4, -28B20331245A, -28D042242A83, -28DDD4C3E9C4, -292C2CCD157E, -299ABB519354, -2A41BE015C1D, -2A4A55052A51, -2A94CBCD7A6E, -2AB6536187C7, -2B2D2DC3D319, -2BD607CA70B2, -2C6C7957EB3E, -2C9E9E4D0895, -2D2A97DD45E3, -2D41850A8AA6, -2DAC030D1AB9, -2E12426D8847, -2E25AD1D6D8D, -2E2E85E0E6C9, -2E4340CC1C63, -2E6803BE2E11, -2EB24B573DCD, -2EC6450A47C7, -2ECDA9A5EA96, -2EDE1C155023, -302D5D37342B, -303645E47667, -303B30A460E8, -3048EBB8A18E, -30BD652BED24, -30CCE5ECB397, -310241E1CB36, -312670228372, -319E8895EAB5, -31E3A933BC4A, -3250D2E661DA, -32560224418D, -32589E221D10, -326657A8E9C0, -329AC7C59311, -32A091B89995, -3312C094BD20, -336C8CBA5AE2, -34240649314A, -3493D84E6317, -349A347186D7, -349BEAC5210E, -34A939B49EDC, -34CC7E36C8C4, -34D71347877E, -34DC25B4D0CE, -35895EB472C4, -358A6A398211, -360A08C66042, -36306A9CA571, -37284428A250, -377EC8A78B8D, -37BD90A68613, -37E602347133, -382DE6AB2D1A, -385D498B5390, -38B67589E47D, -393CCCCCDA4A, -39682B3E10B5, -397619525709, -39A83A32909B, -3A5834C46513, -3A70C7A4BCE4, -3A818D01E093, -3AA5AC1CDC21, -3AAE07339954, -3B4497052B42, -3B784087DB2D, -3B86A20C16EA, -3B8E321AB1B4, -3BC4A3099B0D, -3BC741376E71, -3C4C95D0A0C7, -3C84B55A5E54, -3C888A88C59D, -3D5C8240B2D2, -3DB004172BE7, -3E23271C1C15, -3E3188294ED1, -3E84144A770E, -3EA227893101, -3EB914E70076, -3EE6D4A85643, -40DABA780B41, -4119340759A2, -415210E0C6BB, -416D21717779, -41B1839829A9, -4201A36DE766, -4261A795D5A7, -42AA0B29626E, -430265958BEB, -4317C5C16EAD, -431D799E0C89, -4342794AD7BB, -4387ADE263DB, -43982124C310, -4436CB060568, -44449507B736, -44E858C82975, -459BC12982B1, -45AE5DDA9830, -45C414CDC347, -45CE4E504C06, -461744C8EABD, -46D012CA3BEC, -47170BD112B6, -47C43D5DD234, -47CD4AC26271, -47D410D1C7C4, -4808C5AD0115, -485BEEDBC293, -486001404A80, -488CCC60B70A, -49204E3CA169, -495657C78147, -4970714D53D9, -4AA715A0BBB4, -4B9901AEC16E, -4BE0B912A5A3, -4CBC34D10D83, -4CD3ACABC6A3, -4CE00134DE1E, -4CEB27151C49, -4D02A3D7CE48, -4D13683C7960, -4D1A263BA48B, -4D23919463A3, -4D9763C083D9, -4DAC8EE52C68, -4DCB89C7B2E6, -4DD9D9B637C4, -4DE6CB63A920, -4DEBA10CC85D, -4E232A8C2E30, -4E2879A411E7, -4EA7B0BED74B, -4EB8761372EA, -4EC2B23135AB, -4EC71DB088DE, -4EC9AB4B5519, -50179E461EE6, -50265ED9D468, -5047DC2975BE, -508357498162, -508BE54D326E, -510A8C52AAC4, -511335CC92CD, -518229589A81, -5184D04315D7, -51B4AE31B246, -526EDB918BEE, -529CE44BEBCC, -52A843082BB3, -52AE9A909674, -5313E9079489, -532DE5E7E0E9, -535508AA6C91, -53691569B669, -540A5B789761, -547B86E57596, -54C649075B57, -552249203848, -55430B5318E9, -5570D22DC66B, -55710879E113, -55D2E4AC0446, -56207539825A, -564664475726, -566441C5C28C, -56A7930913C3, -56C944B04618, -56D455A8BBEA, -5726991C8C28, -5726AA3BE37B, -573314090BA5, -577C31903867, -577C528E786C, -57AD9604ED24, -580C377283C7, -587329CE3EBE, -587C34557B36, -58B11E803B58, -5902E4DCC95D, -5A060A64C535, -5A36898CA7C5, -5A4740D952EC, -5A6ED7966868, -5A99578CAA13, -5AAD6814E68B, -5B065568048A, -5B6CE0B3AD0A, -5B70E0B11758, -5B926E3751EB, -5B9CA63C4267, -5BDC1391B289, -5C1D3898D537, -5C34B8E4A456, -5C36456EA1E5, -5C43A75C65A0, -5C5752328A47, -5C9D20250D74, -5CBA3CEE351A, -5CD5E98A2864, -5CE0EB9C01B6, -5D384E6A4145, -5D9DB8445155, -5DE8717BB640, -5E1A4EE98748, -5E45A227B391, -5E8E50B3048B, -5EB0EA0A9412, -6032C47B7676, -60E0C84ADDEE, -612A447A2149, -612D81821854, -616B820EAD01, -616D75A4A022, -61DE2B085AC9, -62312EC272A0, -6232C5262CC6, -62B7C7C9B0D0, -62C531C6E29C, -63E6AAAB4433, -644ABCC3DD12, -64AE7BEA1784, -6515B38077D6, -65972038CC25, -65E120DE5E55, -66141DDE8320, -66718BD91332, -668082242328, -668920AEE063, -6696C4332D46, -66C9880D1DC2, -67150CB11E95, -671737BA0054, -673551D0A99E, -676D682C4336, -678B98AA2E86, -6847808E63EE, -6887A122AA62, -6888C514DEAD, -688BD5B7B4E9, -68A99E258692, -68C312391560, -68C9D33E3735, -6900A069E3D7, -690155BE8D8E, -69174742042D, -69B9CE233517, -6A0B123D7595, -6AB8E2B49E25, -6ABD4C4A72D9, -6B1CC539A1B2, -6B30B6B0925D, -6B638C1C950D, -6BAAAB1D4589, -6BAD01EBE736, -6BB4ED5E1682, -6CA178E036DA, -6CE210B529C4, -6D23D505D2B1, -6D3CBD12BC6D, -6D83563EB521, -6D98AB9CCC71, -6E3D7366E78C, -6E5582237608, -6E6602904925, -6E77B8EB6444, -6E978A7B16C6, -6EEC05EB651C, -70284824B26C, -702CDACE0C14, -704E1B85BED8, -70BB123776D6, -70CCC3A2D7C0, -716A747CB931, -7173E199A420, -71BC9C9E31E4, -71CAEEA3B771, -71D8BA423D55, -72253C7DD951, -7260377CD286, -7280858E8B20, -72913BDAB647, -72B5B87BBC6E, -72C83B1D098A, -72DA8050A38E, -735C2AB60A97, -736B602A93D9, -738D7833E7DE, -73E7B22D6E54, -74133B1E2DED, -74A929877793, -74E3670C045A, -7531E3E2A41C, -7542A9B65EB4, -7564993C91C7, -760ED0AB626E, -762E0E021E38, -763D7E6BB40E, -764B38E2903D, -768016001C8D, -76A616C3D42C, -76AE99D9A294, -76BAAA710D25, -76E3B23696BC, -77322DD2E184, -77B40902B6D9, -77C0AC14972D, -77C1CE0E7674, -77D7B7E2C8BA, -78279397A68E, -7836593AB838, -783859EB51A6, -78CCDB50C193, -7932684154AE, -79604362370E, -796630ED27B3, -799E4E270953, -79A00573947A, -79B798D66B01, -7A0455D0A7EC, -7A33D19B7248, -7B0A8AE18817, -7B0BA045AB35, -7B0DE8504D57, -7B21781EC649, -7B7224C1AB79, -7B90C2BA9B23, -7BB90D382672, -7BBC9DC92836, -7C09DC408C47, -7C418B493454, -7C491D518242, -7C7A86CC727C, -7CE836EBD228, -7D49042C530D, -7E5744EC286C, -7E680A48C383, -7EC45CCEC35A, -7EDADA19EB57, -8005BD088847, -8022E705B640, -8031E3565825, -80499BAA5959, -807466CCBAB5, -810518578380, -810D24CB13CC, -812B02C34A64, -8163A5DDE1CD, -8186CE2B363E, -81DE6062B9D7, -822017D8929A, -8247C78188C5, -8270D538D5E8, -82D8E8DDE296, -831207CA6E8A, -83378A077357, -83A05B477535, -840160379EEE, -84044BAB78A7, -84366C6D7781, -8442CC9AA777, -8470AAD30447, -8498740493BB, -84A35A698E93, -84ABDE484425, -84B24DBB9A67, -84B723B2A237, -852BEB133D74, -854501E98239, -854A0ED2E77D, -85A066D39785, -8619557091AA, -86228C3742A4, -8637BB3BA795, -8642D9310B46, -86538085966D, -86EE9C410811, -870A042C1B34, -873B47C457E6, -873CE44DDC6B, -874D123262E7, -87513C960770, -877641436923, -878A091B74B7, -87927467808B, -88C2E39B5990, -88D252AC1A8A, -891EDA20BDEA, -89267DEE07ED, -892CB89ACCC6, -8A2423E9D100, -8A6BC2E3811B, -8A8EB5771EE9, -8A906B4B3211, -8AB21B524C5C, -8AB823BDC2AE, -8AC3B2ADE77B, -8AC4317D049B, -8ACD6B86EC44, -8AD966CA3B4D, -8B0A3B3DCDD4, -8B1B6C705C1A, -8B1C75E27153, -8B2A5E0332A1, -8B6216E412DB, -8B7CCA9DB004, -8B9999AE9703, -8BABAD9A65C6, -8C32D0AE3DB7, -8C99807368A5, -8CC1133D7D5B, -8CD2C872187A, -8D0563B86DD4, -8D43D81E37B4, -8D96A800B21A, -8D97B475C957, -8DA62EC0C524, -8DACA1BC0636, -8DE3B131D728, -8E55316D3B3D, -8EE497C9A869, -90210DDAB57D, -9026977EB8A6, -903AA4305025, -9083158A49A1, -9092D12E7967, -90D8713352D1, -911E097A27A9, -9140EC087241, -918A67D05479, -919B1D357E91, -9210BBA2AB26, -9224B6555E30, -9226D4D1236A, -922E7955CC67, -929CC86B1B26, -929E1556110E, -9302DEB79C5A, -9384841B4702, -93B4BD1CB47C, -93D985D55712, -940B37939AC6, -94673AE73823, -947A8147E0AE, -94CD6A4B6391, -94CEEAC5A8D7, -95ABD3A7C631, -95E1C233EDE2, -9607AE17AD09, -960C98566E52, -96435BD1D29B, -965D66E19245, -965D72659982, -9695167B4149, -96D0C3996714, -97274C21BD6C, -973186B345BB, -973A28C983A3, -979686C51AB6, -97992CE2DD31, -97E9D0C89DA8, -97EB8A44C49D, -98314DC363C5, -9860DC044565, -988D023C15A5, -9917BDA7B4D7, -9996A233442A, -9A2132B5B625, -9A694755A978, -9A7911ECC275, -9AA1E6CE588C, -9ABCCD2AE7C7, -9B39A60D3841, -9C0630361CC5, -9C4E19AB64B1, -9CE96BADE4D8, -9D442B28BD11, -9D4C35AE1A08, -9E02910C691A, -9E46407C9024, -9E74D104ACEA, -9EDD416A7912, -A026642D13AD, -A12908B38536, -A16EE9666D5A, -A199132A4043, -A1AEC2B58BBA, -A1BE42A15EDE, -A1D0844C2C63, -A1E0103A1879, -A253602B9445, -A2B019B46CB9, -A2BBCC3B546C, -A2C325A73A9C, -A2CB60E815A0, -A314B97C1A6A, -A3647146C335, -A3A580799BB4, -A3D30CC8EB97, -A402B5137D86, -A42158CC74B5, -A435DD64AD17, -A4693D21013B, -A479A91EED49, -A4B30D146A01, -A5142D626200, -A54056E87CBB, -A57DBD287491, -A588C918E327, -A593071D4758, -A5CC0EE7B9E3, -A6375E98A5B5, -A666347B3B4B, -A6A203994202, -A6BAE1A1520D, -A6E9885AA49D, -A705087E89A8, -A7072D4324C7, -A745AD7D6789, -A750456E7C5E, -A783A8774651, -A787C822020C, -A78BB575EAC5, -A7905680A254, -A805534D84E9, -A86C2595A1C3, -A89903B6ADDB, -A9182707A219, -A9391782A846, -A96B08E3A50B, -A98DEB0733C9, -A9C37CE71D23, -AA2D69C757D9, -AA4E4558A9EE, -AA6C835C9124, -AAC0C35C43EB, -AB30CB2CB354, -AB6191DB240A, -AB8953D3560C, -ABBB521319E6, -AC47461358D7, -AC58C25A1559, -AC7D4B201D92, -AD061A23287D, -AD105D52DB36, -AD4EA84D7185, -AD5038D15490, -AD97523144B2, -ADB24E78784B, -ADCBD453B232, -AE516A187825, -AE52116C234C, -AE817239CAB5, -AEA5A5A0E46B, -AECC93678543, -B0452769A83C, -B04D71906C60, -B0805C191424, -B09172DDBE43, -B13AE369390C, -B14080E570D1, -B1419B62772C, -B14775DEA2E2, -B188BA649EA1, -B1BB0DB95C67, -B1BB19BDD424, -B1E8B5054DAD, -B1EBB537CC0D, -B2174092CDC5, -B2554CC8AD6E, -B2C5A2E88304, -B312E56ED250, -B37B48D8C1C5, -B39C699CD208, -B3B121208E34, -B3C3C6E4395B, -B410B958C3B8, -B4204546A74E, -B45171C5A67D, -B4B103E693ED, -B4DACABCAB07, -B506567A2B84, -B51083D5C2BD, -B54D7674CB90, -B570E5EA1DA3, -B598984AD584, -B5D7E1135821, -B60D053A36D9, -B63957593E23, -B64558CAC0C9, -B68175BCA864, -B6CD1A3EC5BC, -B72468A7710D, -B75176C82A8B, -B7AA0CA5D94A, -B7B9D7E523B8, -B808D87AB75C, -B93A6432E51A, -B941A9D99B6C, -B9DA40920237, -BA6C2E10086A, -BA7384AB949E, -BA8DEEE045E8, -BADC2149EC42, -BB1924266B36, -BB41640E6340, -BBB475DB2B03, -BBD4C4699719, -BC0B2C897267, -BC7BEE6B71C4, -BC8B21AD8802, -BCA2D8118631, -BCB7A7006400, -BCBC6637499B, -BCBD2B8BE4B3, -BD213E28C568, -BD32E4EC7080, -BD401D63C3E9, -BD463C3693A4, -BD749E85586A, -BD7CA11B9551, -BD96355CBE36, -BD9E6EB7B524, -BDADE6111218, -BDB576D1E88C, -BDB5DC09C522, -BE19C75D6B7E, -BE5B3ED935AC, -BEA20C972E70, -BEEB4A159B37, -C01E8740DE38, -C0411C28857D, -C045544AD1E4, -C04660B76831, -C0C4CA21B876, -C0E0E092C8B4, -C0EE394D3D95, -C14601C6B411, -C16EBAE928B2, -C189A791A85B, -C1ACDB8C1890, -C1C55A7A99EA, -C1D72A47755A, -C1D8B91D65AA, -C1E6149B386D, -C22D8E2B1E37, -C23E999B6298, -C314E31A670D, -C3D275A9B8C7, -C3EE19B61C89, -C427B93DC2ED, -C443EEC4330D, -C477B966D328, -C4C6CAE4784C, -C55875BCB82C, -C581CA998910, -C5ABC0A455C5, -C5BE33E6B1E2, -C629E0D34581, -C65194543D6B, -C67B8E869D90, -C6BC3B9CCB41, -C7034BC581A6, -C748500B6947, -C757C15E9E0D, -C798A8465ACB, -C7B6702AC17B, -C849133B7CCC, -C870C98A4E91, -C90B7AD266D3, -C90D996C3A2D, -C953797CCE61, -C9639352EEC8, -C983685AA86B, -C9CCA6D095A3, -C9CE81D47EDB, -C9D449AD9970, -CA0D9CCC4C38, -CA277AC09859, -CA56EB045188, -CAB92B865BAD, -CAE8572C2657, -CB1CE185575C, -CB2ECC3D9C22, -CB642A081A89, -CBBAD2DA0EC5, -CC1B5BD45315, -CC2C02300D34, -CC559969D0CC, -CC5646BD7AEB, -CC6A93BD93D1, -CC726DD08765, -CCBBAB6504A4, -CCC1EA3E27B8, -CD16EAB946E9, -CDB4EEE02E14, -CDC21E1E1EC7, -CE09B3870EA2, -CE5AA0C8B5A8, -CE63DE29E069, -D0368B24CA49, -D0489010A72C, -D075379A21A6, -D09893B4EE04, -D0A7A2787570, -D0B8C06C02E4, -D106E94A4C3B, -D11E7D1BBEEA, -D12B25B8DDE2, -D1972D6CE2C3, -D1B91D224946, -D2752E53679D, -D35B2B75CC52, -D40E935117A2, -D4C37528DC05, -D4C818A5455E, -D4CD56DB8AEB, -D5190BD5CED6, -D55E5AA3406D, -D576E9D856D9, -D5E444E9D82D, -D61A3231790D, -D669B3AE1E11, -D6C075899D06, -D6C3503456C4, -D7AC70A05A0C, -D80A37B6D7ED, -D82E6938C58C, -D85E51344EB6, -D8809EB9BA7D, -D8913C2D48E9, -D9109460D912, -D94E36427E20, -D97E55B1816A, -D99425130C1A, -D99C3222A190, -D9A207103ED7, -D9C70CC5818A, -DA3379D12773, -DA705702248C, -DA818C56CE43, -DAE1888DCC0B, -DBA0A2DCA8E0, -DBD9799E15B1, -DC242193D7E3, -DCB5AC62946C, -DCB75AEC61A0, -DD6E0587A821, -DD7B1A7C6A82, -DDA22A189095, -DDDAE53AA711, -DDE7304E78B6, -DE1B4DA681B9, -DEAC67E2D7C1, -DEB7D7E4C62B, -E127434AB3B7, -E1ACC6742AB7, -E1E59574ADBC, -E1EA6BAA03D9, -E222553A59A2, -E2230B8E84C9, -E33E807EC3BA, -E341574B2E32, -E42868808B70, -E43562C624B0, -E43D54DC3511, -E466090D2123, -E47069DA0C44, -E49DD6062901, -E4ACA0ADBA0D, -E4B976AD6687, -E526BB7888DB, -E53354B71B10, -E57581CE8617, -E61A1DA5A60E, -E6293BDA5EDC, -E64C2A07CA9B, -E6600C4D6A44, -E6655B6425DC, -E6BADC631036, -E70143BE0091, -E75E07A010D1, -E76962E3B8B4, -E8028A6DCC90, -E80C5E3E8227, -E8779E40450E, -E8A9E2D87D36, -E8B5A0BDD993, -E933DA9735C4, -E93A2E63189D, -E9447637E40D, -E94836269887, -E94D82A564BA, -E98DC3B561B5, -E9EB2DE57AE9, -EA490920877D, -EA4C494C9353, -EA9B1695DD91, -EAD0E31A6834, -EB16B6462B66, -EB276C9AB68D, -EB3C9732C3BA, -EB44DDC408CE, -EB8536C958B2, -EBC825C186B3, -EC1A55BB58EB, -EC2B12107313, -EC8CB5758097, -ECD4C42EA3D1, -ED22B7115435, -ED2CE17A590C, -ED65A9B6469C, -ED6748113E0D, -ED8CEB8B7102, -EDCE0890472D, -EDD4A2EA7493, -EE17C426D25E, -EE487A4C806E, -EE5931913A8D, -EED56840AEBA, diff --git a/client/dictionaries/icbpm_sort_keys.dic b/client/dictionaries/icbpm_sort_keys.dic deleted file mode 100644 index b4a635d44..000000000 --- a/client/dictionaries/icbpm_sort_keys.dic +++ /dev/null @@ -1,1001 +0,0 @@ - -00383D96411D, -005307DB7853, -009A4C4C6C49, -00C447B8A2D2, -01124119AB54, -0117BAE4D8D9, -018861488381, -0267B4922681, -02974B9786C9, -02A46AC9233A, -02BED876BD48, -02D8A7729ED3, -02EB32B92D30, -03C34821DE9A, -03D87397E9A8, -042CDEE5D0BA, -044ED79417E1, -04524659496E, -04602A40C037, -048451A79DA1, -0490AD0C9283, -04E16965C142, -05138E278443, -052B99EC186E, -056D4B5D2915, -0578E317C419, -05865124E5CA, -0599E014139E, -05DB68DB9364, -066C127C208D, -06966B31A285, -06B577E0E480, -071B57D258CE, -072B300309C9, -0759955331EE, -0769855EEC13, -079B8DA54DB1, -082B68A67491, -0832E4783600, -08506533E741, -0853A982D793, -08629D1DD0D6, -087C0CDA3B46, -08AE4ECD7CE3, -0965220D2ECE, -09A14A80754E, -09ACEA48DD0D, -09DB8EE5458C, -09E6CB76C080, -0A44A754B592, -0A7328887DC2, -0A906663EE1C, -0AB08938E3DA, -0AD8AD0739A6, -0B00220EAE75, -0B1960681E79, -0B31815E6A7C, -0B3690D4B122, -0BB8414CB6EA, -0BEC525E3463, -0C296648344D, -0CB6CC83AC45, -0CCAD03DDBC6, -0D6C26AB25CD, -0DC9143735D1, -0DE8A36CBBCC, -0E175033BD77, -0E6478123917, -0E7D4AC83133, -0E8420B04083, -0EA607E1C4E3, -105743704432, -107A6AB6B305, -110BB6D5539D, -1114A47CC39A, -116AA873ACC8, -120616C6208E, -120C83C06317, -12343D71106C, -123A082E2AEA, -12E50BE60524, -133DC845505E, -138153A4351A, -1395C108B6B6, -1428C04BAAD1, -147D93848C70, -14A353C60820, -1504C1846399, -1523A1E39D03, -1532A2511A8B, -157308368E8E, -16065CC411E0, -1637D8ACA71E, -1639134699C7, -167358BB268E, -168DE72B3B5A, -16A05D5C31C3, -16B4442EAE97, -17197B247A4A, -1774DB1A8CA1, -17820DAA47B2, -1782BEDBD347, -17B561AA82B4, -17C548CBC3A6, -17DA5C873BC5, -18025130661E, -184B95B4E3C6, -18A3196D364B, -18A97BD26818, -18BE810A83DD, -18C3AC2A7E90, -194D4E1DE89D, -196E279BE9A9, -1A2C8D855336, -1A3A76ED470A, -1A55D4849951, -1A9872D00EC9, -1ACD5433BBDD, -1ADC527D5BDA, -1AE29C8CD672, -1B14CAC3D0C2, -1B20A6E1D06B, -1B30A7825B23, -1B3E45AEE657, -1B75E7B007DB, -1B9DABDEBAE0, -1BAB19D01495, -1BD3119E0363, -1BDA0D87A575, -1CD38D77090B, -1D12BBB575B1, -1E1A0DB8729C, -1E2DE60A477A, -1E3C71643766, -1E6ED46CE258, -1EE60A4A8D22, -200D45263629, -2013899194BB, -206CE78E0C6C, -20B51C977E54, -2142B57D369D, -2172D827D3E2, -2178ED80D581, -21B4BE97AE07, -21B91A26133A, -21C7650673CD, -220D815D366A, -22C2176E1CD6, -22C3AB41B123, -233D7B324CEE, -2340CBD61A71, -2348251AD23E, -2381B8214025, -23BAE8DA1AC5, -23C317B8D6DA, -243A41574A39, -248EA5E91987, -2491457885A7, -255A9E590BCC, -257192699E32, -25892216C620, -2595E5B1DE76, -25AE69DED1B4, -25BA8775B3C4, -25D967D4DD35, -25DB996D56ED, -25EE21CDE4B9, -2625E408276B, -26B744C673DB, -26C6D38B8257, -26D787613684, -27689527E201, -27743B5A5736, -27D1635ED1B3, -27D5B8D2642E, -28035CA5B300, -2812EB6A427C, -28133B46730A, -281499DD16A0, -281DD9E6C98E, -2870E08CEDBA, -28B8685B1B22, -28C3D17E4DEC, -2953C63E9E58, -295D3C9A8B28, -297B74853CAA, -29ACACC2828E, -29EA97BC4A6B, -29EB3CA1C0DE, -2A079CC2AD37, -2A27E0602400, -2A45A0D8D6EE, -2A47CDD3A322, -2A4C4DB1D71D, -2AA82B4B6711, -2ABD68BDC5A3, -2AE7BDB10CB4, -2B051C90BE82, -2B490231E063, -2BAB94372644, -2C03252C10E7, -2C3EE5E98804, -2CB671E6365D, -2CC55B46705B, -2CD09D3C0A1B, -2CECBC323E31, -2D302827C9B4, -2D716C9C467B, -2D8856109732, -2E15681A4355, -2E79209B9519, -2EEE063290C1, -301C9AA3DECA, -30C520D6A2B9, -30D6324910AB, -3113AADC9D6B, -3124ACA5491C, -315AD0D6E6D2, -31A16DAC864D, -31EC44581294, -32DE3CD81C24, -32E532232C29, -33256E443128, -33293485AD61, -33305B0365AA, -3343B72BAA71, -3372C9C5D4AE, -33754E0D1687, -33A444334869, -33B54345C32E, -34002AAEE45D, -343C556CEE59, -3444DDE6D7E5, -345B62452538, -3495A04A9270, -34EB673C863B, -35123500C1EA, -353A7167576B, -3599856810B2, -35E7DE9899EE, -35EDABB506D8, -36C54912D10E, -36CA0101B6DC, -36D268442846, -373E5827E0B8, -376D6C446746, -37E2EAE635B5, -381B0A70E135, -3862B259DC71, -386676C44A13, -3905679DEEC4, -39070618BB17, -394181105544, -395D38815892, -39A00E856381, -39C0E2ED99B5, -3A1E82E2CDB7, -3A5D13E05B6A, -3A6DE2081CDD, -3A8498924010, -3A9D49E8BEB2, -3AD0EE1031A9, -3B052E65D40A, -3B4986981212, -3B4C51ACC53D, -3B99486097C6, -3BB36BC22CE4, -3BB4B3025B79, -3BBB7BD8D7B7, -3C09C971D835, -3C4A12E7A107, -3C633B3474DD, -3CB9E31D6022, -3CD344A7EB21, -3CD8C6705954, -3CE887B9D091, -3D5EA1C71953, -3D89120EB993, -3D9C3245AE76, -3DED9D496478, -3E0913A96E74, -3E34909990B5, -3E7DD7953DDD, -3EEB33434C1A, -4015D16B5C1C, -401C81A72C56, -40E7B8D60242, -41016C0CB8DE, -4124864B0D40, -415BAA0CAB15, -418184DBB4A0, -419513740558, -4195EE7238CC, -41B727883B27, -41BC44A8C3C6, -41DDC3A48EEA, -420445087613, -42068108DE36, -4245921D73CA, -42A959953C45, -430E67734C18, -4314D9D03B95, -43166BCA83EB, -43400A093A7E, -434CE764DE91, -43595AC786EE, -438099331C1E, -43814087A7B5, -438C3CD95B58, -43B3E895B281, -44074C461042, -444D37149B20, -44A04DAA30CB, -4537282554C5, -4584EACB6087, -45DB3799C150, -45E599AE38EA, -462305611C4A, -4636195CDA2D, -46752993E2E9, -4684316440D6, -46C7246C1958, -4751A5274848, -4761E34CB054, -476388408D8E, -478947735B45, -47AD81972D5B, -47C23398EA52, -47E9D4D4BE35, -4812AEC4B01A, -48276645A4EA, -48644467A214, -489C783B3514, -48C860AA4B74, -495C6639575B, -49681C20A00D, -49E8249DD677, -49E93C110AA1, -4A24470C19C5, -4A4755BC4A2A, -4A4D5E3A9011, -4A65D627625C, -4A6B36C5BCCC, -4AB725ED89B5, -4B39E3923D0D, -4B59316C10E0, -4C275C8BB2DA, -4C2E9455D296, -4C44DB1D0C3A, -4C67059B0006, -4CA30E1A298A, -4CA74DAC7C01, -4CB212D72D57, -4CD3B228EBB4, -4CE1972E090C, -4CEE1794E0EA, -4D06DBCA167E, -4D2CC85EB338, -4D40BC7A44DB, -4D769DA515D3, -4D79C95DAD2D, -4DBAC8ECE167, -4E3CB839E87D, -4E3D548E1267, -4E8250E29617, -4E94C7962769, -5038884E4178, -505B5A8EB20A, -50642C36DA00, -5083664D8C09, -50B77DA96DE2, -511E269A9BAE, -51798AEAAE9E, -51ED5833AB6D, -525335E4CD34, -5261CDDA279E, -526E55542A54, -529C16A720AB, -52A230B1C50E, -52AADA374811, -52D20D6E3E35, -534BB4A6984E, -5352CCC3DCD2, -540B15E8019D, -54AA2915E815, -558DB8891A90, -55A691710B48, -55D1E91B1D35, -55D95774E9A0, -563C6B96D59D, -567032E13B54, -56741B108D22, -57029D991123, -5714E9D33034, -5734CD8A65DA, -5785EE00049E, -57B8B111491D, -57CC9D0AA32B, -57D7D4D746DA, -583C936DCB4B, -586B470A43B3, -5876E1D34183, -58B6AE62DB88, -58C35C8BC9AB, -597E98000ED4, -59DB4DBB5D7A, -5A150653E624, -5A211CE57C4B, -5A6272CDBE9C, -5ACB8043C10C, -5B41CEBC2213, -5B59BCC4321E, -5BA03479BB8C, -5BC64C42281C, -5C9B1A8E31CD, -5C9BD0AC1DB1, -5D223E990AD8, -5D8C3A5C5761, -5DA57EACA38C, -5E41DD5D1154, -5E6ABB51EC75, -5E7CC04C3A58, -5E810C48C8D8, -5E8943D9A836, -5ED616273468, -60100DD0E023, -6033A1C0E431, -6088A566CC60, -60B20ADA0471, -60B8411D876E, -60C742D8D9C0, -6135433CC5EA, -6153ADD80A15, -61718ED2C94D, -6175241B035A, -61780BCB0C57, -61B701698050, -61C4E56629A3, -61D59C284952, -61E57B490A55, -622E5E0812D7, -6251CE7E547A, -62953A89B137, -62D6EAA06CD6, -630228659A47, -632931BE8EC7, -63539BB89DEE, -636CB69BB10C, -63783393E20D, -639DB16995B7, -63AA2A5B076C, -63B636458E94, -6443E64DCC4B, -64695084C575, -6493D06D5710, -649B302A97C5, -64B8632B54D4, -654BACB21C3B, -65A3D5823819, -65DEDABD1B34, -6608944EE186, -665B8B24C20D, -6685D0BE19E0, -66933A9E7982, -674C7BB59A16, -675E35EE359E, -67AA98E362C9, -67D47C1B6425, -67DE22850162, -67E8B986B2A7, -681EA28BA6CD, -6828B52B6507, -6874E54471E8, -6879B1CA44A3, -68C00A810D41, -68C9E8AA5C3E, -697A8ED07418, -69B5357A617A, -6A7B3A7B6735, -6AA40421D23C, -6AB676B4DB9D, -6B00420BE41C, -6B0B7B967871, -6B9D041136B4, -6BB1A14768A8, -6BCAE24D9700, -6C0458728774, -6C57CBD51995, -6C5E10B86CDE, -6CA491A8C7B8, -6CBC25C1DA2E, -6CD430D99958, -6CEC27647CC0, -6D4D29CEB9B5, -6D6E9A6B725D, -6D801AC74572, -6D97408C6D60, -6DDE6E871C64, -6DEA848B6195, -6E05B5C44A54, -6E751666AE9A, -6E7DBCDA05B3, -7004BA1763ED, -7016ECD01559, -7076D48D5E49, -7091621EA016, -709311997549, -70984C14D3DB, -70D73BE22CDD, -70D9461C5E90, -712BC18422CB, -712E6CAA74A4, -7164042BA89E, -7175E14A4D62, -718B39561350, -718BDA352E28, -719B1418323E, -71A8D54D82B3, -71DC30168C27, -7221E016597B, -7234CC6BD65D, -727A80DD5296, -72B393D6E8A9, -732C9BE4DDBA, -736B4A835B2B, -73EA81968900, -740AB5126199, -741A31054E6B, -74498C1D4B3D, -745276053CB6, -74684B0B4B1D, -74772915E24C, -74A24BE33BE2, -74A778236D5A, -74AA58008A31, -74C27A96CB3A, -754AD5773746, -756C15E54212, -759403A563D8, -759D2130312B, -75A0E10D8C84, -75A807E46B96, -75E454785C6C, -76078A25C088, -76140285B768, -763D835BD5ED, -767C33468C72, -76962C07EC9E, -76984E62CCE4, -769AE4646931, -76E5DA67A1EC, -7708D5CAD58B, -77383BAA4D90, -7789E646A556, -779A248E098C, -77DB71037644, -77E0A57DD456, -7853D464E2A4, -78EA6EB04463, -7909427EC8B9, -7910A31ECD19, -79271963B6E8, -793D98517D33, -79B7A4C58DE0, -79B9148761B3, -7A2893B75AD1, -7A4C61A1B48D, -7A7469B69C6A, -7AA84B1A527D, -7B00211CA416, -7B118EABC7BB, -7B1D9A2E22AA, -7B583D350740, -7B9D3A6BD061, -7C2DAC2CC775, -7C4CBBD2DDE1, -7CD52B5B8E77, -7D412100532B, -7D46C149DAD9, -7D4CA630E229, -7DAC0E83D335, -7DC935E220A0, -7DCA66BACA13, -7E30778792D2, -7E43C3BAB3CB, -7E475BA186E6, -7EE2A624851A, -80CED5362B2C, -80D2CC78E10B, -80D62251E20C, -816875D55ED1, -81950D0517AC, -81B519418C3E, -8211571B9D16, -823C7CC6E06A, -826DD63B9032, -827303C574B5, -82C5ADED4B81, -82E344329D34, -83588E140165, -835D33B48113, -8384148AE52D, -8394B57153D6, -83A0184757C0, -83D86835B48B, -8502EE9A7E85, -852C2B72659D, -8534A6CE0911, -85ABD94CD7A9, -85DA8099CD7E, -85E0B6B26945, -864CA2A6BE93, -868A33A44447, -86EDEABCC357, -87DDD5A188EE, -8830379B50B7, -883803A3360C, -883DA78EC87D, -88482A12C2C6, -888EBD3DB945, -88D026793359, -88DD4B7C5991, -8931DC3733D4, -894D8E2DCDEE, -897B845C2680, -89B638BD909E, -89D2C28BE578, -8A1869848D1A, -8A39D09508C9, -8ACCC7290C8C, -8AD8B41EC218, -8B028B7E6D60, -8B6A95C7D2E2, -8BA1226EBA21, -8BD586B21ABC, -8C0EA504B635, -8CA939DC6DE4, -8CAE5D688443, -8CEC639E64DC, -8DECE0DD29DE, -8E0EC762E883, -8E958D8B8C52, -8EB64D710C88, -8ED4A17717D9, -8EE9D9C03A0D, -9014E1430AEB, -90965DEBC8B9, -90E56E616DDD, -912CD8E04437, -912E33563E1B, -918048032247, -919402EC39CB, -91D28E2B126D, -9216EEE5B677, -9232215296B2, -925A070E9096, -925A5521D48D, -92CC200886A2, -932035869655, -937144459949, -93B260DBC70A, -94552B863E37, -95327A0A3600, -954275CDD7E0, -957E6EE3EB55, -95B920CACC84, -96382E1C8E12, -964E8E5338BD, -96706C8D6ECC, -96759A0D5566, -96D5213C5DDB, -97300764797A, -973BDDBE7434, -974838AE17A0, -9752A6B316D5, -97926543783B, -97EB373096CA, -982D6054B83D, -989D127BD496, -98A54AD58A43, -98A92128364C, -98CD5AA2A4DB, -98E8C543688E, -99207A00AA4A, -99243E754CB8, -9925893ABAC7, -9937553A965E, -9976E6ADE0C9, -9982E3E6A4A0, -9984C1A3229E, -99C487AB85EC, -99E2A19C9673, -9A05EBE41D7D, -9A138D1A5CB7, -9A179148B824, -9A6EC0A9ECB8, -9A720CBD7BB1, -9AB22BBDDD87, -9AC43B5A06D8, -9AD8150BE648, -9AD97423190D, -9B4ADDDEB749, -9B7603341727, -9C45237377BE, -9D090AE1A15E, -9D59641E40A5, -9DA4528CEB8C, -9DA728164176, -9DAC62A346B7, -9E0E9D983B9A, -9E5271763D3D, -9EE95586D024, -9EEE39E00CBB, -A04671256EE2, -A091485B4B5D, -A1B5577ED36E, -A1EB280E3901, -A2789E1DD888, -A293A90AE72C, -A309E3AEBDB9, -A3196E77B072, -A31E72DCC826, -A34DEA01690E, -A36031D6ECB2, -A38044A3E18E, -A421D7A04C4B, -A424C686CA39, -A44590A779A5, -A47AD3895C63, -A5041E8B8E22, -A50DC0830AA5, -A52B8929D665, -A5BCBA6BE592, -A61D5137E6B3, -A6344C0418DC, -A690A817B9D9, -A7E3B3459240, -A81E6D3C8E11, -A8C0BE436685, -A8DE205120A8, -A91E2BE6C308, -A9258D6B06B5, -A992B5E070C1, -AAC6E3205D48, -AB101546634E, -AB6EE0761ACA, -AB9BCA200547, -AC4BC5B2D3C0, -AC7A0B47B03E, -AC88B26AC1D0, -ACAEB3456AD9, -ACB906631D8A, -ACE07B45C0C5, -AD1992AE37CA, -AD5586744A60, -AD674E4ADB79, -ADA093B06831, -AE7C3AE5334A, -AE9EB8CAB2C3, -AEAE9E5CE65D, -B002D1BDC29B, -B0463E703098, -B063B209BB20, -B0788BE3BAA4, -B0C3B3299090, -B128298D9073, -B160677E7035, -B19D3D57176A, -B1CCDB7999B9, -B231AA398B90, -B250E9590215, -B28BE0D819ED, -B292C9554CBA, -B2D8485C2460, -B31763D9D0DE, -B328014DDD6A, -B378C424C9E2, -B3D8C03C78E0, -B41D18E3B980, -B46824B972E9, -B50383A32302, -B509D631967C, -B56CA847A7C3, -B56EC9A20D28, -B5B763215C82, -B6550EAC573A, -B66060201705, -B6614EBEAAA2, -B6A18CBD4DA6, -B6ABB62E437E, -B6C6558E58CA, -B7009204D512, -B71D5B22B1C2, -B7392DD1E497, -B7709ED7CE60, -B7A26320A491, -B7A9DA22E9C6, -B7DEC863369D, -B7E9A91174CB, -B8178A34E2DC, -B83092098A7D, -B84C50E56DEC, -B89BD135E935, -B8E87380D361, -B9485A9648C6, -B9ED829C22AE, -BA227EE91818, -BA7BBD9683B1, -BA8224EA7A80, -BA84C974B356, -BAD293A45C8A, -BB850C7E4934, -BBC1256810A4, -BC1CD369549E, -BC5C76E5909C, -BC66E9270049, -BC6AB08B03CC, -BC74CA2C2B06, -BC7C64828C1D, -BCCC3A719013, -BD06E96EB7D7, -BD196D0A74E0, -BE02790E84AC, -BE1266314B9D, -BE518C742B74, -BE5695316117, -BE5D8EBA120D, -BE8286DA7D12, -BE9CE00EE4DD, -C003962B3462, -C0067E095049, -C015A21E0146, -C03BC03AD437, -C06CE7D57A0D, -C07EE1E10B56, -C0885A29251E, -C198163ABECE, -C1EB7337A035, -C225479C7064, -C2740E1665A8, -C27924128A00, -C2A701656B8B, -C2C30D21C53E, -C2CBB2ACD38D, -C38D19A9C8D1, -C3B1BB7E7492, -C3BA2438A981, -C3CD74758DE2, -C4033B3BB1D7, -C404D280640E, -C4467DE80B2D, -C46A048C88DD, -C52877867C05, -C56D005E258E, -C56D052D5533, -C5BB2CCCB9C3, -C5C272694A1E, -C6121BC4A29C, -C65EEAE02433, -C661C4AE1DD1, -C76C94B495CA, -C7BD49777A79, -C7CD131E9B60, -C7E35D6294BA, -C8E173DB04CC, -C95855AE08E8, -C98147E69033, -C99A004E6133, -C9E893C4090B, -CA119C79A197, -CA309D2CBC41, -CA4BAA390BC4, -CA92DD257E21, -CA968EBEB9C7, -CADED0C50AC4, -CB18774EA550, -CB1999D19E10, -CB75C1BAE669, -CC2517AB2346, -CC2AC1AD29CA, -CD11359C7A90, -CD14C8553CB9, -CD333295BBE2, -CD3DB8C27E5C, -CDA811AD5055, -CDABDCA23986, -CDCA8BD7B002, -CE0456AB0DCE, -CE58AE1C51E9, -CE76E8A600DC, -CE95875316C8, -CEB105E65289, -CEB651752D4C, -CEE02D97E5BD, -D023DB35ED05, -D0BE546CC06B, -D0CE7EB0D379, -D10329D366C8, -D15C004DBC8D, -D16E6B668254, -D1CEEC977644, -D1DC0E1CC09E, -D2550925679B, -D28B2D42DE1A, -D2926519AC09, -D313116A45B4, -D3DC10453857, -D431C8C73BDC, -D4C67846791C, -D5629384CE7D, -D5ABE7180600, -D62A4A0E57C2, -D660CE9E3080, -D66AE9282140, -D6A91C14AC47, -D6E23B4E75C6, -D726C4979654, -D76DE12943B4, -D7A405AD9E4E, -D7BD3AE48E93, -D7D49700BBCC, -D7E8A5089E7A, -D84C81EE910D, -D8545199A949, -D86243C1380E, -D88A12EB3622, -D89B5EA419C1, -D8A3690B0115, -D94646A4C65B, -D982B4846A96, -DA303BADB013, -DAD9A48A8C33, -DAEB5D63920B, -DB01A99DD94C, -DB22BB7D6818, -DB37160CBB4B, -DB7E3687E450, -DC7697E37A9B, -DCC44C4E9269, -DCCE477E785E, -DD68DE9CDA5A, -DE1B08C6D94B, -DE41BBD7E68D, -DE6E04AE4475, -DE8CD4277A9E, -DEA8098D6E51, -DEB2BEE8858A, -DEB550958AD9, -E045E6309471, -E0E21213C611, -E0E457054B62, -E1097C69DA4A, -E1EA831EA514, -E20716902884, -E2C9CB14C06C, -E33B66EA2705, -E34C5B12BABA, -E38A1C654E82, -E3905BA54194, -E3E3919444CA, -E4450EC1010C, -E49A03306224, -E5100AC4C6C3, -E5124DB665A6, -E5491B5E3DD6, -E5BE9C989A29, -E5C3A9A27D3E, -E65111EB1E40, -E65792427D4C, -E7004C5EA94A, -E705087DECBB, -E7CB93E68155, -E81512343BAD, -E8428C8B0740, -E859EBC22318, -E87267A508DB, -E886AE7D1BE0, -E8B008239600, -E8C4B4A4E482, -E8D53410B736, -E902964DA28D, -E9203D5BD2DA, -E9526CACA8B2, -E9C11D763BEC, -EA3BDAA4E498, -EA61AC8B4969, -EA8E8ADC26B9, -EB5588EAE5E8, -EBA964C07075, -EC71B679D3AA, -ECB4019ADD97, -ED14D0A14B0C, -ED296C79266C, -EDBA3C943EA8, -EDC7CEBD4000, -EDE2747DA6C3, -EE3029556CEB, -EE49610E6121, -EEB704D69BCA, -EED69A391464, diff --git a/client/dictionaries/iclass_default_keys.dic b/client/dictionaries/iclass_default_keys.dic new file mode 100644 index 000000000..22e1ee653 --- /dev/null +++ b/client/dictionaries/iclass_default_keys.dic @@ -0,0 +1,12 @@ +# +# iClass Default Keys +# -- iceman fork version -- +# -- contribute to this list, sharing is caring -- +# +AEA684A6DAB23278 # AA1 +7665544332211000 # key1/Kc from PicoPass 2k documentation +0123456789ABCDEF # SAGEM +5b7c62c491c11b39 # from loclass demo file. +F0E1D2C3B4A59687 # Kd from PicoPass 2k documentation +5CBCF1DA45D5FB4F # PicoPass Default Exchange Key +31ad7ebd2f282168 # From HID multiclassSE reader diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic new file mode 100644 index 000000000..a12291199 --- /dev/null +++ b/client/dictionaries/mfc_default_keys.dic @@ -0,0 +1,1022 @@ +# +# Mifare Default Keys +# -- iceman fork version -- +# -- contribute to this list, sharing is caring -- +# +ffffffffffff # Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) +000000000000 # Blankkey +a0a1a2a3a4a5 # NFCForumMADkey +b0b1b2b3b4b5 +c0c1c2c3c4c5 +d0d1d2d3d4d5 +aabbccddeeff +4d3a99c351dd +1a982c7e459a +d3f7d3f7d3f7 # key A Wien +5a1b85fce20a # key B Wien +714c5c886e97 +587ee5f9350f +a0478cc39091 +533cb6c723f6 +8fd0a4f256e9 +# +d2ece8b9395e # lib +# +# more Keys from mfc_default_keys.lua +000000000001 +000000000002 +00000000000a +00000000000b +00000ffe2488 # VästtrafikenKeyB +010203040506 +0123456789ab +0297927c0f77 # VästtrafikenKeyA +100000000000 +111111111111 +123456789abc +12f2ee3478c1 +14d446e33363 +1999a3554a55 +200000000000 +222222222222 +26940b21ff5d # RKFSLKeyA +27dd91f1fcf1 +2BA9621E0A36 # DirectoryandeventlogKeyB +333333333333 +33f974b42769 +34d1df9934c5 +434f4d4d4f41 # RKFJOJOGROUPKeyA +434f4d4d4f42 # RKFJOJOGROUPKeyB +43ab19ef5c31 +444444444444 +47524f555041 # RKFJOJOGROUPKeyA +47524f555042 # RKFJOJOGROUPKeyB +4AF9D7ADEBE4 # DirectoryandeventlogKeyA +4b0b20107ccb # TNP3xxx +505249564141 # RKFJOJOPRIVAKeyA +505249564142 # RKFJOJOPRIVAKeyB +505249565441 +505249565442 +54726176656c # VästtrafikenKeyA +555555555555 +55f5a5dd38c9 +569369c5a0e5 # kiev +5c598c9c58b5 # RKFSLKeyB +632193be1c3c # kiev +644672bd4afe # kiev +666666666666 +722bfcc5375f # RKFRejskortDanmarkKeyA +776974687573 # VästtrafikenKeyB +777777777777 +888888888888 +8fe644038790 # kiev +999999999999 +99c636334433 +9de89e070277 # kiev +a00000000000 +a053a292a4af +a64598a77478 # RKFSLKeyA +a94133013401 +aaaaaaaaaaaa +abcdef123456 # Keyfromladyada.net +b00000000000 +b127c6f41436 +b5ff67cba951 # kiev +bbbbbbbbbbbb +bd493a3962b6 +c934fe34d934 +cccccccccccc +dddddddddddd +e4d2770a89be # RKFSLKeyB +ee0042f88840 # VästtrafikenKeyB +eeeeeeeeeeee +eff603e1efe9 # kiev +f14ee7cae863 # kiev +f1a97341a9fc +f1d83f964314 # RKFRejskortDanmarkKeyB +fc00018778f7 # VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA +44ab09010845 # hotel system +85fed980ea5a # hotel system +314B49474956 # VIGIK1 A +564c505f4d41 # VIGIK1 B +ba5b895da162 # VIGIK1 B +# Vigik mystery Keys Mifare 1k EV1 (S50) +5c8ff9990da2 # 16 A +75ccb59c9bed # 17 A +d01afeeb890a # 16 B +4b791bea7bcc # 17 B +# +43454952534E # ARD (fr) key A +4A2B29111213 # ARD (fr) key B +# +4143414F5250 +a9b43414F585 # Tehran Railway +1FB235AC1388 # Tehran Railway +# +# Data from http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ +f4a9ef2afc6d # BCARD KeyB +# +# Data from ... +89eac97f8c2a # S0 B +43c7600dee6b # S4 A +0120bf672a64 # S6 A +fb0b20df1f34 # S6 B +# +a9f953def0a3 +# +# Here be BIP keys... +3A42F33AF429 +1FC235AC1309 +6338A371C0ED +243F160918D1 +F124C2578AD0 +9AFC42372AF1 +32AC3B90AC13 +682D401ABB09 +4AD1E273EAF1 +067DB45454A9 +E2C42591368A +15FC4C7613FE +2A3C347A1200 +68D30288910A +16F3D5AB1139 +F59A36A2546D +937A4FFF3011 +64E3C10394C2 +35C3D2CAEE88 +B736412614AF +693143F10368 +324F5DF65310 +A3F97428DD01 +643FB6DE2217 +63F17A449AF0 +82F435DEDF01 +C4652C54261C +0263DE1278F3 +D49E2826664F +51284C3686A6 +3DF14C8000A1 +6A470D54127C +# +# Data from http://pastebin.com/AK9Bftpw +48ffe71294a0 # Länstrafiken i Västerbotten +e3429281efc1 # Länstrafiken i Västerbotten +16f21a82ec84 # Länstrafiken i Västerbotten +460722122510 # Länstrafiken i Västerbotten +# +# 3dprinter +AAFB06045877 # EPI Envisionte# 3dprinter +# +# gym +3e65e4fb65b3 # Fysiken A +25094df6f148 # Fysiken B +a05dbd98e0fc # CleverFit +# +d3b595e9dd63 # Hotel KeyCard +afbecd121004 # Hotel KeyCard +6471a5ef2d1a # SimonsVoss +# +# 24-7 +D21762B2DE3B +0E83A374B513 +1F1FFE000000 +A10F303FC879 +1322285230b8 +0C71BCFB7E72 +C3C88C6340B8 +F101622750B7 +1F107328DC8D +710732200D34 +7C335FB121B5 +B39AE17435DC +# +# +454841585443 # key A +# +# Data from http://pastebin.com/gQ6nk38G +D39BB83F5297 +85675B200017 +528C9DFFE28C +C82EC29E3235 +3E3554AF0E12 +491CDCFB7752 +22C1BAE1AACD +5F146716E373 +740E9A4F9AAF +AC0E24C75527 +97184D136233 +E444D53D359F +17758856B182 +A8966C7CC54B +C6AD00254562 +AE3FF4EEA0DB +5EB8F884C8D1 +FEE470A4CB58 +75D8690F21B6 +871B8C085997 +97D1101F18B0 +75EDE6A84460 +DF27A8F1CB8E +B0C9DD55DD4D +# +# Data from http://bit.ly/1bdSbJl +A0B0C0D0E0F0 +A1B1C1D1E1F1 +# +# Data from msk social +2735fc181807 +2aba9519f574 +84fd7f7a12b6 +186d8c4b93f9 +3a4bba8adaf0 +8765b17968a2 +40ead80721ce +0db5e6523f7c +51119dae5216 +83e3549ce42d +136bdb246cac +7de02a7f6025 +bf23a53c1f63 +cb9a1f2d7368 +c7c0adb3284f +9f131d8c2057 +67362d90f973 +6202a38f69e2 +100533b89331 +653a87594079 +d8a274b2e026 +b20b83cb145c +9afa6cb4fc3d +# +# Data from http://pastebin.com/RRJUEDCM +0d258fe90296 +e55a3ca71826 +a4f204203f56 +eeb420209d0c +911e52fd7ce4 +752fbb5b7b45 +66b03aca6ee9 +48734389edc3 +17193709adf4 +1acc3189578c +c2b7ec7d4eb1 +369a4663acd2 +# +# Data from https://github.com/zhangjingye03/zxcardumper +# zxcard Key A/B +668770666644 +003003003003 +# +# Data from http://phreakerclub.com/forum/showthread.php?p=41266 +26973ea74321 +71f3a315ad26 +51044efb5aab +ac70ca327a04 +eb0a8ff88ade +# +# Data from https://github.com/RadioWar/NFCGUI +44dd5a385aaf +21a600056cb0 +b1aca33180a5 +dd61eb6bce22 +1565a172770f +3e84d2612e2a +f23442436765 +79674f96c771 +87df99d496cb +c5132c8980bc +a21680c27773 +f26e21edcee2 +675557ecc92e +f4396e468114 +6db17c16b35b +4186562a5bb2 +2feae851c199 +db1a3338b2eb +157b10d84c6b +a643f952ea57 +df37dcb6afb3 +4c32baf326e0 +91ce16c07ac5 +3c5d1c2bcd18 +c3f19ec592a2 +f72a29005459 +185fa3438949 +321a695bd266 +d327083a60a7 +45635ef66ef3 +5481986d2d62 +cba6ae869ad5 +645a166b1eeb +a7abbc77cc9e +f792c4c76a5c +bfb6796a11db +# +# Data from Salto A/B +6A1987C40A21 +7F33625BC129 +# +# Data from forum +2338b4913111 +# +# Data from stoye +cb779c50e1bd +a27d3804c259 +003cc420001a +f9861526130f +381ece050fbd +a57186bdd2b9 +48c739e21a04 +36abf5874ed7 +649d2abbbd20 +bbe8fffcf363 +ab4e7045e97d +340e40f81cd8 +e4f65c0ef32c +d2a597d76936 +a920f32fe93a +86afd95200f7 +9b832a9881ff +26643965b16e +0c669993c776 +b468d1991af9 +d9a37831dce5 +2fc1f32f51b1 +0ffbf65b5a14 +c5cfe06d9ea3 +c0dece673829 +# +a56c2df9a26d +# +# Data from https://pastebin.com/vbwast74 +# +68d3f7307c89 +568c9083f71c # Smart Rider. Western Australian Public Transport Cards +# Vigik Keys +# Various sources : +# * https://github.com/DumpDos/Vigik +# * http://newffr.com/viewtopic.php?&forum=235&topic=11559 +# * Own dumps +021209197591 # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key +2ef720f2af76 +414c41524f4e +424c41524f4e +4a6352684677 +bf1f4424af76 +536653644c65 +# +# Intratone Cogelec +# Data from http://bouzdeck.com/rfid/32-cloning-a-mifare-classic-1k-tag.html +484558414354 +a22ae129c013 +49fae4e3849f +38fcf33072e0 +8ad5517b4b18 +509359f131b1 +6c78928e1317 +aa0720018738 +a6cac2886412 +62d0c424ed8e +e64a986a5d94 +8fa1d601d0a2 +89347350bd36 +66d2b7dc39ef +6bc1e1ae547d +22729a9bd40f +# +# Data from https://dfir.lu/blog/cloning-a-mifare-classic-1k-tag.html +925b158f796f +fad63ecb5891 +bba840ba1c57 +cc6b3b3cd263 +6245e47352e6 +8ed41e8b8056 +2dd39a54e1f3 +6d4c5b3658d2 +1877ed29435a +52264716efde +961c0db4a7ed +703140fd6d86 +157c9a513fa5 +e2a5dc8e066f +# +# Data from a oyster card +374bf468607f +bfc8e353af63 +15cafd6159f6 +62efd80ab715 +987a7f7f1a35 +c4104fa3c526 +4c961f23e6be +67546972bc69 +f4cd5d4c13ff +94414c1a07dc +16551d52fd20 +9cb290282f7d +77a84170b574 +ed646c83a4f3 +e703589db50b +513c85d06cde +95093f0b2e22 +543b01b27a95 +c6d375b99972 +ee4cc572b40e +5106ca7e4a69 +c96bd1ce607f +167a1be102e0 +a8d0d850a606 +a2abb693ce34 +7b296c40c486 +91f93a5564c9 +e10623e7a016 +b725f9cbf183 +# +# Data from FDi tag +8829da9daf76 +# +# Data from GitHub issue +0A7932DC7E65 +11428B5BCE06 +11428B5BCE07 +11428B5BCE08 +11428B5BCE09 +11428B5BCE0A +11428B5BCE0F +18971D893494 +25D60050BF6E +3FA7217EC575 +44F0B5FBE344 +7B296F353C6B +8553263F4FF0 +8E5D33A6ED51 +9F42971E8322 +C620318EF179 +D4FE03CE5B06 +D4FE03CE5B07 +D4FE03CE5B08 +D4FE03CE5B09 +D4FE03CE5B0A +D4FE03CE5B0F +E241E8AFCBAF +# +# Data from forum post +123F8888F322 +050908080008 +# +# Data from hoist +4f9f59c9c875 +# +# Data from pastebin +66f3ed00fed7 +f7a39753d018 +# +# Data from https://pastebin.com/Z7pEeZif +386B4D634A65 +666E564F4A44 +564777315276 +476242304C53 +6A696B646631 +4D3248735131 +425A73484166 +57784A533069 +345547514B4D +4C6B69723461 +4E4175623670 +4D5076656D58 +686A736A356E +484A57696F4A +6F4B6D644178 +744E326B3441 +70564650584F +584F66326877 +6D4E334B6C48 +6A676C315142 +77494C526339 +623055724556 +356D46474348 +4E32336C6E38 +57734F6F6974 +436A46587552 +5544564E6E67 +6F506F493353 +31646241686C +77646B633657 +# +# Data from TransPert +2031d1e57a3b +53c11f90822a +9189449ea24e +# +# data from Github +410b9b40b872 +2cb1a90071c8 +# +# data from +8697389ACA26 +1AB23CD45EF6 +013889343891 +# +# +0000000018de +16ddcb6b3f24 +# +# Data from https://pastebin.com/vwDRZW7d +EC0A9B1A9E06 # Vingcard Mifare 4k Staff card +6C94E1CED026 # Vingcard Mifare 4k Staff card +0F230695923F # Vingcard Mifare 4k Staff card +0000014B5C31 # Vingcard Mifare 4k Staff card +# +BEDB604CC9D1 +B8A1F613CF3D +B578F38A5C61 +B66AC040203A +6D0B6A2A0003 +2E641D99AD5B +AD4FB33388BF +69FB7B7CD8EE +2A6D9205E7CA +2a2c13cc242a +27FBC86A00D0 +01FA3FC68349 +# +6D44B5AAF464 # Smart Rider. Western Australian Public Transport Cards +1717E34A7A8A # Smart Rider. Western Australian Public Transport Cards +# +6B6579737472 # RFIDeas +# +484944204953 # HID MIFARE Classic 1k Key +204752454154 # HID MIFARE Classic 1k Key +3B7E4FD575AD # HID MIFARE SO +11496F97752A # HID MIFARE SO +# +415A54454B4D # Luxeo/Aztek cashless vending +# +321958042333 # BQT +# +160A91D29A9C # Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48 +# +b7bf0c13066e # Gallagher +# +# Boston, MA, USA Transit - MBTA Charlie Card +3060206f5b0a # charlie +5ec39b022f2b # charlie +3a09594c8587 # charlie +f1b9f5669cc8 # charlie +f662248e7e89 # charlie +62387b8d250d # charlie +f238d78ff48f # charlie +9dc282d46217 # charlie +afd0ba94d624 # charlie +92ee4dc87191 # charlie +b35a0e4acc09 # charlie +756ef55e2507 # charlie +447ab7fd5a6b # charlie +932b9cb730ef # charlie +1f1a0a111b5b # charlie +ad9e0a1ca2f7 # charlie +d58023ba2bdc # charlie +62ced42a6d87 # charlie +2548a443df28 # charlie +2ed3b15e7c0f # charlie +# +60012e9ba3fa +# +de1fcbec764b +81bfbe8cacba +bff123126c9b +2f47741062a0 +b4166b0a27ea +a170d9b59f95 +400bc9be8976 +d80511fc2ab4 +1fcef3005bcf +bb467463acd6 +e67c8010502d +ff58ba1b4478 +# Data from https://pastebin.com/Kz8xp4ev +fbf225dc5d58 +# +# Data https://pastebin.com/BEm6bdAE +# vingcard.txt +4708111c8604 +3d50d902ea48 +96a301bce267 +6700f10fec09 +7a09cc1db70a +560f7cff2d81 +66b31e64ca4b +9e53491f685b +3a09911d860c +8a036920ac0c +361f69d2c462 +d9bcde7fc489 +0c03a720f208 +6018522fac02 +# +# Data from https://pastebin.com/4t2yFMgt +# Mifare technische Universität Graz TUG +D58660D1ACDE +50A11381502C +C01FC822C6E5 +0854BF31111E +# More keys: +8a19d40cf2b5 +ae8587108640 +135b88a94b8b, SafLock standalone door locks. +# +# Russian Troika card +08B386463229 +0E8F64340BA4 +0F1C63013DBA +2AA05ED1856F +2B7F3253FAC5 +69A32F1C2F19 +73068F118C13 +9BECDF3D9273 +A73F5DC1D333 +A82607B01C0D +AE3D65A3DAD4 +CD4C61C26E3D +D3EAFB5DF46D +E35173494A81 +FBC2793D540B +5125974CD391 +ECF751084A80 +7545DF809202 +AB16584C972A +7A38E3511A38 +C8454C154CB5 +04C297B91308 +EFCB0E689DB3 +07894FFEC1D6 +FBA88F109B32 +2FE3CB83EA43 +B90DE525CEB6 +1CC219E9FEC1 +A74332F74994 +764CD061F1E6 +8F79C4FD8A01 +CD64E567ABCD +CE26ECB95252 +ABA208516740 +9868925175BA +16A27AF45407 +372CC880F216 +3EBCE0925B2F +73E5B9D9D3A4 +0DB520C78C1C +70D901648CB9 +C11F4597EFB5 +B39D19A280DF +403D706BA880 +7038CD25C408 +6B02733BB6EC +EAAC88E5DC99 +4ACEC1205D75 +2910989B6880 +31C7610DE3B0 +5EFBAECEF46B +F8493407799D +6B8BD9860763 +D3A297DC2698 +# +# Keys from MifareClassicTool project +044CE1872BC3 +045CECA15535 +0BE5FAC8B06A +0CE7CD2CC72B +0EB23CC8110B +0F01CEFF2742 +0F318130ED18 +114D6BE9440C +18E3A02B5EFF +19FC84A3784B +1B61B2E78C75 +22052B480D11 +3367BFAA91DB +3A8A139C20B4 +42E9B54E51AB +46D78E850A7E +4B609876BBA3 +518DC6EEA089 +6B07877E2C5C +7259FA0197C6 +72F96BDD3714 +7413B599C4EA +77DABC9825E1 +7A396F0D633D +7A86AA203788 +8791B2CCB5C4 +8A8D88151A00 +8C97CD7A0E56 +8E26E45E7D65 +9D993C5D4EF4 +9EA3387A63C1 +A3FAA6DAFF67 +A7141147D430 +AAFB06045877 +ACFFFFFFFFFF +AFCEF64C9913 +B27ADDFB64B0 +B81F2B0C2F66 +B9F8A7D83978 +BAFF3053B496 +BB52F8CCE07F +BC2D1791DEC1 +BC4580B7F20B +C65D4EAA645B +C76BF71A2509 +D5524F591EED +E328A1C7156D +E4821A377B75 +E56AC127DD45 +EA0FD73CB149 +FC0001877BF7 +FD8705E721B0 +00ada2cd516d +# +# +D3F7D3F7D3F7 +## +237a4d0d9119 +0ed7846c2bc9 +FFFFD06F83E3 +FFFFAE82366C +F89C86B2A961 +F83466888612 +ED3A7EFBFF56 +E96246531342 +E1DD284379D4 +DFED39FFBB76 +DB5181C92CBE +CFC738403AB0 +BCFE01BCFE01 +BA28CFD15EE8 +B0699AD03D17 +AABBCC660429 +A4EF6C3BB692 +A2B2C9D187FB +9B1DD7C030A1 +9AEDF9931EC1 +8F9B229047AC +872B71F9D15A +833FBD3CFE51 +5D293AFC8D7E +5554AAA96321 +474249437569 +435330666666 +1A2B3C4D5E6F +123456ABCDEF +83BAB5ACAD62 +64E2283FCF5E +64A2EE93B12B +46868F6D5677 +40E5EA1EFC00 +37D4DCA92451 +2012053082AD +2011092119F1 +200306202033 +1795902DBAF9 +17505586EF02 +022FE48B3072 +013940233313 +# +# Hotel Adina +9EBC3EB37130 +# +# most likely diversed individual keys. +# data from https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c +491CDC863104 +A2F63A485632 +98631ED2B229 +19F1FFE02563 +563A22C01FC8 # Argentina +43CA22C13091 # Argentina +25094DF2C1BD # Argentina +# +# OMNITEC.ES HOTEL TIMECARD / MAINTENANCECARD +AFBECD120454 +# +# OMNITEC.ES HOTEL EMERGENCYCARD +842146108088 +# +# TAPCARD PUBLIC TRANSPORT LA +# +EA1B88DF0A76 +D1991E71E2C5 +05F89678CFCF +D31463A7AB6D +C38197C36420 +772219470B38 +1C1532A6F1BC +FA38F70215AD +E907470D31CC +160F4B7AB806 +1D28C58BBE8A +B3830B95CA34 +6A0E215D1EEB +E41E6199318F +C4F271F5F0B3 +1E352F9E19E5 +0E0E8C6D8EB6 +C342F825B01B +CB911A1A1929 +E65B66089AFC +B81846F06EDF +37FC71221B46 +880C09CFA23C +6476FA0746E7 +419A13811554 +2C60E904539C +4ECCA6236400 +10F2BBAA4D1C +4857DD68ECD9 +C6A76CB2F3B5 +E3AD9E9BA5D4 +6C9EC046C1A4 +# +# ROC HIGHSCHOOL ACCESSCARD +# +B021669B44BB +B18CDCDE52B7 +A22647F422AE +B268F7C9CA63 +A37A30004AC9 +B3630C9F11C8 +A4CDFF3B1848 +B42C4DFD7A90 +A541538F1416 +B5F454568271 +A6C028A12FBB +B6323F550F54 +A7D71AC06DC2 +B7C344A36D88 +A844F4F52385 +B8457ACC5F5D +A9A4045DCE77 +B9B8B7B6B5B3 +AA4D051954AC +BA729428E808 +AB28A44AD5F5 +BB320A757099 +AC45AD2D620D +BCF5A6B5E13F +AD5645062534 +BDF837787A71 +AE43F36C1A9A +BE7C4F6C7A9A +5EC7938F140A +82D58AA49CCB +# +# MELONCARD +# +323334353637 +# +# +CEE3632EEFF5 +827ED62B31A7 +03EA4053C6ED +C0BEEFEC850B +F57F410E18FF +0AF7DB99AEE4 +A7FB4824ACBF +207FFED492FD +1CFA22DBDFC3 +30FFB6B056F5 +39CF885474DD +00F0BD116D70 +4CFF128FA3EF +10F3BEBC01DF +# +# Transportes Insular La Palma +# +0172066b2f03 +0000085f0000 +1a80b93f7107 +70172066b2f0 +b1a80c94f710 +0b0172066b2f +0f1a81c95071 +f0f0172066b2 +1131a81d9507 +2f130172066b +71171a82d951 +b2f170172066 +1711b1a82e96 +6b2f1b017206 +62711f1a83e9 +66b2f1f01720 +97271231a83f +066b2f230172 +f97371271a84 +2066b2f27017 +50983712b1a8 +72066b2f2b01 +850984712f1a +172066b2f2f0 +a85198481331 +0172066b2f33 +1a8619858137 +70172066b2f3 +b1a862985913 +3b0172066b2f +3f1a87298691 +f3f0172066b2 +# +# Tehran ezpay +# +38A88AEC1C43 +CBD2568BC7C6 +7BCB4774EC8F +22ECE9316461 +AE4B497A2527 +EEC0626B01A1 +2C71E22A32FE +91142568B22F +7D56759A974A +D3B1C7EA5C53 +41C82D231497 +0B8B21C692C2 +604Ac8D87C7E +8E7B29460F12 +BB3D7B11D224 +# +# Chaco +# +b210cfa436d2 +b8b1cfa646a8 +a9f95891f0a4 +# +# Keys from APK application "Scan Badge" +4A4C474F524D +444156494442 +434143445649 +434456495243 +A00002000021 +EF61A3D48E2A +A23456789123 +010000000000 +363119000001 +A00003000084 +675A32413770 +395244733978 +A0004A000036 +2C9F3D45BA13 +4243414F5250 +DFE73BE48AC6 +# +B069D0D03D17 +000131B93F28 +# +# From the DFW Area, TX, USA +# +a506370e7c0f +26396f2042e7 +70758fdd31e0 +9f9d8eeddcce +06ff5f03aa1a +4098653289d3 +904735f00f9e +b4c36c79da8d +68f9a1f0b424 +5a85536395b3 +7dd399d4e897 +ef4c5a7ac6fc +b47058139187 +8268046cd154 +67cc03b7d577 +# +# From the HTL Mödling, NÖ, AT +# +a5524645cd91 +d964406e67b4 +99858a49c119 +7b7e752b6a2d +c27d999912ea +66a163ba82b4 +4c60f4b15ba8 +# +# CAFE + CO, AT +# +35d850d10a24 +4b511f4d28dd +e45230e7a9e8 +535f47d35e39 +fb6c88b7e279 +# +# Metro Card, AT +# +223C3427108A +# +# Unknown, AT +# +23d4cdff8da3 +e6849fcc324b +12fd3a94df0e +# +# Unknown, AT +# +0b83797a9c64 +39ad2963d3d1 +34b16cd59ff8 # Hotel Berlin Classic room A KEY +bb2c0007d022 # Hotel Berlin Classic room B KEY diff --git a/client/dictionaries/mfc_keys_bmp_sorted.dic b/client/dictionaries/mfc_keys_bmp_sorted.dic new file mode 100644 index 000000000..85ab141e0 --- /dev/null +++ b/client/dictionaries/mfc_keys_bmp_sorted.dic @@ -0,0 +1,1000 @@ +002DE0301481 +004173272D18 +0058A4884CA5 +00BAC32761D8 +00BB79731B00 +00E8C85DB172 +02096124DA70 +024988BC4D5E +0271B7C4B015 +028137A705DB +02827C286AB4 +02C10DA600D0 +0340643D5E27 +037A5DA4682B +037AC43CBD9D +037B9B8AA219 +037EE3DE21B7 +0380A9A3CBDE +03D10A75B56A +03E8CD22E691 +04109ED8EA79 +04361330B35C +043D8B66D569 +045E5588845C +048DE5148DE7 +0490921D0194 +04B717BD92EB +04D49C76623B +051518B3301E +0529E8827A52 +052B16064085 +05DC4016B500 +06124317A9A6 +06147D199266 +0670AEB833CE +0686A9E6D6E0 +06A34E5E6639 +06B78AD0C4BB +0710E7818AB8 +07121B8C633A +07176713C0ED +0793533A5087 +081D1B1C3110 +0849495E1CCA +09429512046E +0966C3B28E04 +098A92C3660A +098B48278122 +099672009EEA +0A7632943926 +0AEE126549DA +0B3B8C2833BC +0B733C13E2C9 +0B764247D00E +0BE811559D69 +0C208AD4E4B3 +0C270BC0BDDC +0C5D782CB183 +0C82C94EB11B +0CCDE948878A +0CCE39820AAE +0CDE3E716B32 +0CE06C96DB4C +0CE87813E389 +0D3385CEA152 +0D5C5B8BCC5B +0DB0A87AB882 +0DE247593B93 +0E0AD1796003 +0E62E6CAC3D3 +106E2D6E55E6 +1096A7830C82 +11549C141AD9 +116A92C793D6 +116C31526819 +11C68052AAE9 +1234B5BE8E78 +1268C7D104E1 +12A21B5671A8 +13359D5AE9A5 +1426EC62BB6C +144489B1056E +14A22C112090 +14C9BBB5361B +14EB6286AC57 +14EE72B27223 +153BB53ACE71 +157B03405B38 +15A45083D24E +15DACCE8D5EC +16124677BBC5 +16373A44D5D7 +1663659384DC +167828B6105C +16B25A453093 +1706B1BE25C7 +171B15888483 +17BC8EED9A0C +17C6299D5A37 +17E9C4C416EB +1804087C7166 +1841CC4E3E79 +18AB05761CC5 +18ADAAC2B08B +18E566417E5C +191390328752 +1A47959E7DB4 +1A9A970CC370 +1B095E78BB33 +1B1717043D2B +1B1A054566D9 +1B4654AE9454 +1B9CD1ED3420 +1B9E00780953 +1BB6A9CE71E2 +1C1250A36A13 +1C2316079532 +1C2855ED7A10 +1CD1AE73CA8C +1CD3D4E690B7 +1D0322005969 +1D09B23EB116 +1D67A32045ED +1D89D900968A +1DAE8D2CEA5C +1E1873799CD7 +1E60CE7C5179 +1E6A67909B8D +1E8516585792 +1EB0864E9134 +1ECE3D04A020 +2009828E4A21 +200A6A3AA65D +20188A599582 +20267CB20256 +20628CA7D92D +2077C980EB2E +2089B5D68B27 +209481EC6256 +20B6691C64B1 +20CC5A00C677 +211473555436 +2170E9D0D448 +219529A90EDD +21A5B6481B7D +224A308017D1 +227D16EA455A +22A1245CA266 +22A95CB798DC +230E26964171 +231173B68E46 +2332BB9A2452 +234323BC2992 +234E50256146 +235C9338D5B6 +23789D9ADD0D +23997DD240AB +23A5BA53AD4D +23BB58853461 +24CAD4153036 +24CE79506842 +25228ED714BC +257377227B34 +2584287A0174 +2616192EEB22 +265C03B50877 +26D641E834DC +27073B57132B +279060E3DEE9 +284BA0A0A29C +285C6604C5B4 +28B20331245A +28D042242A83 +28DDD4C3E9C4 +292C2CCD157E +299ABB519354 +2A41BE015C1D +2A4A55052A51 +2A94CBCD7A6E +2AB6536187C7 +2B2D2DC3D319 +2BD607CA70B2 +2C6C7957EB3E +2C9E9E4D0895 +2D2A97DD45E3 +2D41850A8AA6 +2DAC030D1AB9 +2E12426D8847 +2E25AD1D6D8D +2E2E85E0E6C9 +2E4340CC1C63 +2E6803BE2E11 +2EB24B573DCD +2EC6450A47C7 +2ECDA9A5EA96 +2EDE1C155023 +302D5D37342B +303645E47667 +303B30A460E8 +3048EBB8A18E +30BD652BED24 +30CCE5ECB397 +310241E1CB36 +312670228372 +319E8895EAB5 +31E3A933BC4A +3250D2E661DA +32560224418D +32589E221D10 +326657A8E9C0 +329AC7C59311 +32A091B89995 +3312C094BD20 +336C8CBA5AE2 +34240649314A +3493D84E6317 +349A347186D7 +349BEAC5210E +34A939B49EDC +34CC7E36C8C4 +34D71347877E +34DC25B4D0CE +35895EB472C4 +358A6A398211 +360A08C66042 +36306A9CA571 +37284428A250 +377EC8A78B8D +37BD90A68613 +37E602347133 +382DE6AB2D1A +385D498B5390 +38B67589E47D +393CCCCCDA4A +39682B3E10B5 +397619525709 +39A83A32909B +3A5834C46513 +3A70C7A4BCE4 +3A818D01E093 +3AA5AC1CDC21 +3AAE07339954 +3B4497052B42 +3B784087DB2D +3B86A20C16EA +3B8E321AB1B4 +3BC4A3099B0D +3BC741376E71 +3C4C95D0A0C7 +3C84B55A5E54 +3C888A88C59D +3D5C8240B2D2 +3DB004172BE7 +3E23271C1C15 +3E3188294ED1 +3E84144A770E +3EA227893101 +3EB914E70076 +3EE6D4A85643 +40DABA780B41 +4119340759A2 +415210E0C6BB +416D21717779 +41B1839829A9 +4201A36DE766 +4261A795D5A7 +42AA0B29626E +430265958BEB +4317C5C16EAD +431D799E0C89 +4342794AD7BB +4387ADE263DB +43982124C310 +4436CB060568 +44449507B736 +44E858C82975 +459BC12982B1 +45AE5DDA9830 +45C414CDC347 +45CE4E504C06 +461744C8EABD +46D012CA3BEC +47170BD112B6 +47C43D5DD234 +47CD4AC26271 +47D410D1C7C4 +4808C5AD0115 +485BEEDBC293 +486001404A80 +488CCC60B70A +49204E3CA169 +495657C78147 +4970714D53D9 +4AA715A0BBB4 +4B9901AEC16E +4BE0B912A5A3 +4CBC34D10D83 +4CD3ACABC6A3 +4CE00134DE1E +4CEB27151C49 +4D02A3D7CE48 +4D13683C7960 +4D1A263BA48B +4D23919463A3 +4D9763C083D9 +4DAC8EE52C68 +4DCB89C7B2E6 +4DD9D9B637C4 +4DE6CB63A920 +4DEBA10CC85D +4E232A8C2E30 +4E2879A411E7 +4EA7B0BED74B +4EB8761372EA +4EC2B23135AB +4EC71DB088DE +4EC9AB4B5519 +50179E461EE6 +50265ED9D468 +5047DC2975BE +508357498162 +508BE54D326E +510A8C52AAC4 +511335CC92CD +518229589A81 +5184D04315D7 +51B4AE31B246 +526EDB918BEE +529CE44BEBCC +52A843082BB3 +52AE9A909674 +5313E9079489 +532DE5E7E0E9 +535508AA6C91 +53691569B669 +540A5B789761 +547B86E57596 +54C649075B57 +552249203848 +55430B5318E9 +5570D22DC66B +55710879E113 +55D2E4AC0446 +56207539825A +564664475726 +566441C5C28C +56A7930913C3 +56C944B04618 +56D455A8BBEA +5726991C8C28 +5726AA3BE37B +573314090BA5 +577C31903867 +577C528E786C +57AD9604ED24 +580C377283C7 +587329CE3EBE +587C34557B36 +58B11E803B58 +5902E4DCC95D +5A060A64C535 +5A36898CA7C5 +5A4740D952EC +5A6ED7966868 +5A99578CAA13 +5AAD6814E68B +5B065568048A +5B6CE0B3AD0A +5B70E0B11758 +5B926E3751EB +5B9CA63C4267 +5BDC1391B289 +5C1D3898D537 +5C34B8E4A456 +5C36456EA1E5 +5C43A75C65A0 +5C5752328A47 +5C9D20250D74 +5CBA3CEE351A +5CD5E98A2864 +5CE0EB9C01B6 +5D384E6A4145 +5D9DB8445155 +5DE8717BB640 +5E1A4EE98748 +5E45A227B391 +5E8E50B3048B +5EB0EA0A9412 +6032C47B7676 +60E0C84ADDEE +612A447A2149 +612D81821854 +616B820EAD01 +616D75A4A022 +61DE2B085AC9 +62312EC272A0 +6232C5262CC6 +62B7C7C9B0D0 +62C531C6E29C +63E6AAAB4433 +644ABCC3DD12 +64AE7BEA1784 +6515B38077D6 +65972038CC25 +65E120DE5E55 +66141DDE8320 +66718BD91332 +668082242328 +668920AEE063 +6696C4332D46 +66C9880D1DC2 +67150CB11E95 +671737BA0054 +673551D0A99E +676D682C4336 +678B98AA2E86 +6847808E63EE +6887A122AA62 +6888C514DEAD +688BD5B7B4E9 +68A99E258692 +68C312391560 +68C9D33E3735 +6900A069E3D7 +690155BE8D8E +69174742042D +69B9CE233517 +6A0B123D7595 +6AB8E2B49E25 +6ABD4C4A72D9 +6B1CC539A1B2 +6B30B6B0925D +6B638C1C950D +6BAAAB1D4589 +6BAD01EBE736 +6BB4ED5E1682 +6CA178E036DA +6CE210B529C4 +6D23D505D2B1 +6D3CBD12BC6D +6D83563EB521 +6D98AB9CCC71 +6E3D7366E78C +6E5582237608 +6E6602904925 +6E77B8EB6444 +6E978A7B16C6 +6EEC05EB651C +70284824B26C +702CDACE0C14 +704E1B85BED8 +70BB123776D6 +70CCC3A2D7C0 +716A747CB931 +7173E199A420 +71BC9C9E31E4 +71CAEEA3B771 +71D8BA423D55 +72253C7DD951 +7260377CD286 +7280858E8B20 +72913BDAB647 +72B5B87BBC6E +72C83B1D098A +72DA8050A38E +735C2AB60A97 +736B602A93D9 +738D7833E7DE +73E7B22D6E54 +74133B1E2DED +74A929877793 +74E3670C045A +7531E3E2A41C +7542A9B65EB4 +7564993C91C7 +760ED0AB626E +762E0E021E38 +763D7E6BB40E +764B38E2903D +768016001C8D +76A616C3D42C +76AE99D9A294 +76BAAA710D25 +76E3B23696BC +77322DD2E184 +77B40902B6D9 +77C0AC14972D +77C1CE0E7674 +77D7B7E2C8BA +78279397A68E +7836593AB838 +783859EB51A6 +78CCDB50C193 +7932684154AE +79604362370E +796630ED27B3 +799E4E270953 +79A00573947A +79B798D66B01 +7A0455D0A7EC +7A33D19B7248 +7B0A8AE18817 +7B0BA045AB35 +7B0DE8504D57 +7B21781EC649 +7B7224C1AB79 +7B90C2BA9B23 +7BB90D382672 +7BBC9DC92836 +7C09DC408C47 +7C418B493454 +7C491D518242 +7C7A86CC727C +7CE836EBD228 +7D49042C530D +7E5744EC286C +7E680A48C383 +7EC45CCEC35A +7EDADA19EB57 +8005BD088847 +8022E705B640 +8031E3565825 +80499BAA5959 +807466CCBAB5 +810518578380 +810D24CB13CC +812B02C34A64 +8163A5DDE1CD +8186CE2B363E +81DE6062B9D7 +822017D8929A +8247C78188C5 +8270D538D5E8 +82D8E8DDE296 +831207CA6E8A +83378A077357 +83A05B477535 +840160379EEE +84044BAB78A7 +84366C6D7781 +8442CC9AA777 +8470AAD30447 +8498740493BB +84A35A698E93 +84ABDE484425 +84B24DBB9A67 +84B723B2A237 +852BEB133D74 +854501E98239 +854A0ED2E77D +85A066D39785 +8619557091AA +86228C3742A4 +8637BB3BA795 +8642D9310B46 +86538085966D +86EE9C410811 +870A042C1B34 +873B47C457E6 +873CE44DDC6B +874D123262E7 +87513C960770 +877641436923 +878A091B74B7 +87927467808B +88C2E39B5990 +88D252AC1A8A +891EDA20BDEA +89267DEE07ED +892CB89ACCC6 +8A2423E9D100 +8A6BC2E3811B +8A8EB5771EE9 +8A906B4B3211 +8AB21B524C5C +8AB823BDC2AE +8AC3B2ADE77B +8AC4317D049B +8ACD6B86EC44 +8AD966CA3B4D +8B0A3B3DCDD4 +8B1B6C705C1A +8B1C75E27153 +8B2A5E0332A1 +8B6216E412DB +8B7CCA9DB004 +8B9999AE9703 +8BABAD9A65C6 +8C32D0AE3DB7 +8C99807368A5 +8CC1133D7D5B +8CD2C872187A +8D0563B86DD4 +8D43D81E37B4 +8D96A800B21A +8D97B475C957 +8DA62EC0C524 +8DACA1BC0636 +8DE3B131D728 +8E55316D3B3D +8EE497C9A869 +90210DDAB57D +9026977EB8A6 +903AA4305025 +9083158A49A1 +9092D12E7967 +90D8713352D1 +911E097A27A9 +9140EC087241 +918A67D05479 +919B1D357E91 +9210BBA2AB26 +9224B6555E30 +9226D4D1236A +922E7955CC67 +929CC86B1B26 +929E1556110E +9302DEB79C5A +9384841B4702 +93B4BD1CB47C +93D985D55712 +940B37939AC6 +94673AE73823 +947A8147E0AE +94CD6A4B6391 +94CEEAC5A8D7 +95ABD3A7C631 +95E1C233EDE2 +9607AE17AD09 +960C98566E52 +96435BD1D29B +965D66E19245 +965D72659982 +9695167B4149 +96D0C3996714 +97274C21BD6C +973186B345BB +973A28C983A3 +979686C51AB6 +97992CE2DD31 +97E9D0C89DA8 +97EB8A44C49D +98314DC363C5 +9860DC044565 +988D023C15A5 +9917BDA7B4D7 +9996A233442A +9A2132B5B625 +9A694755A978 +9A7911ECC275 +9AA1E6CE588C +9ABCCD2AE7C7 +9B39A60D3841 +9C0630361CC5 +9C4E19AB64B1 +9CE96BADE4D8 +9D442B28BD11 +9D4C35AE1A08 +9E02910C691A +9E46407C9024 +9E74D104ACEA +9EDD416A7912 +A026642D13AD +A12908B38536 +A16EE9666D5A +A199132A4043 +A1AEC2B58BBA +A1BE42A15EDE +A1D0844C2C63 +A1E0103A1879 +A253602B9445 +A2B019B46CB9 +A2BBCC3B546C +A2C325A73A9C +A2CB60E815A0 +A314B97C1A6A +A3647146C335 +A3A580799BB4 +A3D30CC8EB97 +A402B5137D86 +A42158CC74B5 +A435DD64AD17 +A4693D21013B +A479A91EED49 +A4B30D146A01 +A5142D626200 +A54056E87CBB +A57DBD287491 +A588C918E327 +A593071D4758 +A5CC0EE7B9E3 +A6375E98A5B5 +A666347B3B4B +A6A203994202 +A6BAE1A1520D +A6E9885AA49D +A705087E89A8 +A7072D4324C7 +A745AD7D6789 +A750456E7C5E +A783A8774651 +A787C822020C +A78BB575EAC5 +A7905680A254 +A805534D84E9 +A86C2595A1C3 +A89903B6ADDB +A9182707A219 +A9391782A846 +A96B08E3A50B +A98DEB0733C9 +A9C37CE71D23 +AA2D69C757D9 +AA4E4558A9EE +AA6C835C9124 +AAC0C35C43EB +AB30CB2CB354 +AB6191DB240A +AB8953D3560C +ABBB521319E6 +AC47461358D7 +AC58C25A1559 +AC7D4B201D92 +AD061A23287D +AD105D52DB36 +AD4EA84D7185 +AD5038D15490 +AD97523144B2 +ADB24E78784B +ADCBD453B232 +AE516A187825 +AE52116C234C +AE817239CAB5 +AEA5A5A0E46B +AECC93678543 +B0452769A83C +B04D71906C60 +B0805C191424 +B09172DDBE43 +B13AE369390C +B14080E570D1 +B1419B62772C +B14775DEA2E2 +B188BA649EA1 +B1BB0DB95C67 +B1BB19BDD424 +B1E8B5054DAD +B1EBB537CC0D +B2174092CDC5 +B2554CC8AD6E +B2C5A2E88304 +B312E56ED250 +B37B48D8C1C5 +B39C699CD208 +B3B121208E34 +B3C3C6E4395B +B410B958C3B8 +B4204546A74E +B45171C5A67D +B4B103E693ED +B4DACABCAB07 +B506567A2B84 +B51083D5C2BD +B54D7674CB90 +B570E5EA1DA3 +B598984AD584 +B5D7E1135821 +B60D053A36D9 +B63957593E23 +B64558CAC0C9 +B68175BCA864 +B6CD1A3EC5BC +B72468A7710D +B75176C82A8B +B7AA0CA5D94A +B7B9D7E523B8 +B808D87AB75C +B93A6432E51A +B941A9D99B6C +B9DA40920237 +BA6C2E10086A +BA7384AB949E +BA8DEEE045E8 +BADC2149EC42 +BB1924266B36 +BB41640E6340 +BBB475DB2B03 +BBD4C4699719 +BC0B2C897267 +BC7BEE6B71C4 +BC8B21AD8802 +BCA2D8118631 +BCB7A7006400 +BCBC6637499B +BCBD2B8BE4B3 +BD213E28C568 +BD32E4EC7080 +BD401D63C3E9 +BD463C3693A4 +BD749E85586A +BD7CA11B9551 +BD96355CBE36 +BD9E6EB7B524 +BDADE6111218 +BDB576D1E88C +BDB5DC09C522 +BE19C75D6B7E +BE5B3ED935AC +BEA20C972E70 +BEEB4A159B37 +C01E8740DE38 +C0411C28857D +C045544AD1E4 +C04660B76831 +C0C4CA21B876 +C0E0E092C8B4 +C0EE394D3D95 +C14601C6B411 +C16EBAE928B2 +C189A791A85B +C1ACDB8C1890 +C1C55A7A99EA +C1D72A47755A +C1D8B91D65AA +C1E6149B386D +C22D8E2B1E37 +C23E999B6298 +C314E31A670D +C3D275A9B8C7 +C3EE19B61C89 +C427B93DC2ED +C443EEC4330D +C477B966D328 +C4C6CAE4784C +C55875BCB82C +C581CA998910 +C5ABC0A455C5 +C5BE33E6B1E2 +C629E0D34581 +C65194543D6B +C67B8E869D90 +C6BC3B9CCB41 +C7034BC581A6 +C748500B6947 +C757C15E9E0D +C798A8465ACB +C7B6702AC17B +C849133B7CCC +C870C98A4E91 +C90B7AD266D3 +C90D996C3A2D +C953797CCE61 +C9639352EEC8 +C983685AA86B +C9CCA6D095A3 +C9CE81D47EDB +C9D449AD9970 +CA0D9CCC4C38 +CA277AC09859 +CA56EB045188 +CAB92B865BAD +CAE8572C2657 +CB1CE185575C +CB2ECC3D9C22 +CB642A081A89 +CBBAD2DA0EC5 +CC1B5BD45315 +CC2C02300D34 +CC559969D0CC +CC5646BD7AEB +CC6A93BD93D1 +CC726DD08765 +CCBBAB6504A4 +CCC1EA3E27B8 +CD16EAB946E9 +CDB4EEE02E14 +CDC21E1E1EC7 +CE09B3870EA2 +CE5AA0C8B5A8 +CE63DE29E069 +D0368B24CA49 +D0489010A72C +D075379A21A6 +D09893B4EE04 +D0A7A2787570 +D0B8C06C02E4 +D106E94A4C3B +D11E7D1BBEEA +D12B25B8DDE2 +D1972D6CE2C3 +D1B91D224946 +D2752E53679D +D35B2B75CC52 +D40E935117A2 +D4C37528DC05 +D4C818A5455E +D4CD56DB8AEB +D5190BD5CED6 +D55E5AA3406D +D576E9D856D9 +D5E444E9D82D +D61A3231790D +D669B3AE1E11 +D6C075899D06 +D6C3503456C4 +D7AC70A05A0C +D80A37B6D7ED +D82E6938C58C +D85E51344EB6 +D8809EB9BA7D +D8913C2D48E9 +D9109460D912 +D94E36427E20 +D97E55B1816A +D99425130C1A +D99C3222A190 +D9A207103ED7 +D9C70CC5818A +DA3379D12773 +DA705702248C +DA818C56CE43 +DAE1888DCC0B +DBA0A2DCA8E0 +DBD9799E15B1 +DC242193D7E3 +DCB5AC62946C +DCB75AEC61A0 +DD6E0587A821 +DD7B1A7C6A82 +DDA22A189095 +DDDAE53AA711 +DDE7304E78B6 +DE1B4DA681B9 +DEAC67E2D7C1 +DEB7D7E4C62B +E127434AB3B7 +E1ACC6742AB7 +E1E59574ADBC +E1EA6BAA03D9 +E222553A59A2 +E2230B8E84C9 +E33E807EC3BA +E341574B2E32 +E42868808B70 +E43562C624B0 +E43D54DC3511 +E466090D2123 +E47069DA0C44 +E49DD6062901 +E4ACA0ADBA0D +E4B976AD6687 +E526BB7888DB +E53354B71B10 +E57581CE8617 +E61A1DA5A60E +E6293BDA5EDC +E64C2A07CA9B +E6600C4D6A44 +E6655B6425DC +E6BADC631036 +E70143BE0091 +E75E07A010D1 +E76962E3B8B4 +E8028A6DCC90 +E80C5E3E8227 +E8779E40450E +E8A9E2D87D36 +E8B5A0BDD993 +E933DA9735C4 +E93A2E63189D +E9447637E40D +E94836269887 +E94D82A564BA +E98DC3B561B5 +E9EB2DE57AE9 +EA490920877D +EA4C494C9353 +EA9B1695DD91 +EAD0E31A6834 +EB16B6462B66 +EB276C9AB68D +EB3C9732C3BA +EB44DDC408CE +EB8536C958B2 +EBC825C186B3 +EC1A55BB58EB +EC2B12107313 +EC8CB5758097 +ECD4C42EA3D1 +ED22B7115435 +ED2CE17A590C +ED65A9B6469C +ED6748113E0D +ED8CEB8B7102 +EDCE0890472D +EDD4A2EA7493 +EE17C426D25E +EE487A4C806E +EE5931913A8D +EED56840AEBA diff --git a/client/dictionaries/mfc_keys_icbmp_sorted.dic b/client/dictionaries/mfc_keys_icbmp_sorted.dic new file mode 100644 index 000000000..2fe3c0235 --- /dev/null +++ b/client/dictionaries/mfc_keys_icbmp_sorted.dic @@ -0,0 +1,1000 @@ +00383D96411D +005307DB7853 +009A4C4C6C49 +00C447B8A2D2 +01124119AB54 +0117BAE4D8D9 +018861488381 +0267B4922681 +02974B9786C9 +02A46AC9233A +02BED876BD48 +02D8A7729ED3 +02EB32B92D30 +03C34821DE9A +03D87397E9A8 +042CDEE5D0BA +044ED79417E1 +04524659496E +04602A40C037 +048451A79DA1 +0490AD0C9283 +04E16965C142 +05138E278443 +052B99EC186E +056D4B5D2915 +0578E317C419 +05865124E5CA +0599E014139E +05DB68DB9364 +066C127C208D +06966B31A285 +06B577E0E480 +071B57D258CE +072B300309C9 +0759955331EE +0769855EEC13 +079B8DA54DB1 +082B68A67491 +0832E4783600 +08506533E741 +0853A982D793 +08629D1DD0D6 +087C0CDA3B46 +08AE4ECD7CE3 +0965220D2ECE +09A14A80754E +09ACEA48DD0D +09DB8EE5458C +09E6CB76C080 +0A44A754B592 +0A7328887DC2 +0A906663EE1C +0AB08938E3DA +0AD8AD0739A6 +0B00220EAE75 +0B1960681E79 +0B31815E6A7C +0B3690D4B122 +0BB8414CB6EA +0BEC525E3463 +0C296648344D +0CB6CC83AC45 +0CCAD03DDBC6 +0D6C26AB25CD +0DC9143735D1 +0DE8A36CBBCC +0E175033BD77 +0E6478123917 +0E7D4AC83133 +0E8420B04083 +0EA607E1C4E3 +105743704432 +107A6AB6B305 +110BB6D5539D +1114A47CC39A +116AA873ACC8 +120616C6208E +120C83C06317 +12343D71106C +123A082E2AEA +12E50BE60524 +133DC845505E +138153A4351A +1395C108B6B6 +1428C04BAAD1 +147D93848C70 +14A353C60820 +1504C1846399 +1523A1E39D03 +1532A2511A8B +157308368E8E +16065CC411E0 +1637D8ACA71E +1639134699C7 +167358BB268E +168DE72B3B5A +16A05D5C31C3 +16B4442EAE97 +17197B247A4A +1774DB1A8CA1 +17820DAA47B2 +1782BEDBD347 +17B561AA82B4 +17C548CBC3A6 +17DA5C873BC5 +18025130661E +184B95B4E3C6 +18A3196D364B +18A97BD26818 +18BE810A83DD +18C3AC2A7E90 +194D4E1DE89D +196E279BE9A9 +1A2C8D855336 +1A3A76ED470A +1A55D4849951 +1A9872D00EC9 +1ACD5433BBDD +1ADC527D5BDA +1AE29C8CD672 +1B14CAC3D0C2 +1B20A6E1D06B +1B30A7825B23 +1B3E45AEE657 +1B75E7B007DB +1B9DABDEBAE0 +1BAB19D01495 +1BD3119E0363 +1BDA0D87A575 +1CD38D77090B +1D12BBB575B1 +1E1A0DB8729C +1E2DE60A477A +1E3C71643766 +1E6ED46CE258 +1EE60A4A8D22 +200D45263629 +2013899194BB +206CE78E0C6C +20B51C977E54 +2142B57D369D +2172D827D3E2 +2178ED80D581 +21B4BE97AE07 +21B91A26133A +21C7650673CD +220D815D366A +22C2176E1CD6 +22C3AB41B123 +233D7B324CEE +2340CBD61A71 +2348251AD23E +2381B8214025 +23BAE8DA1AC5 +23C317B8D6DA +243A41574A39 +248EA5E91987 +2491457885A7 +255A9E590BCC +257192699E32 +25892216C620 +2595E5B1DE76 +25AE69DED1B4 +25BA8775B3C4 +25D967D4DD35 +25DB996D56ED +25EE21CDE4B9 +2625E408276B +26B744C673DB +26C6D38B8257 +26D787613684 +27689527E201 +27743B5A5736 +27D1635ED1B3 +27D5B8D2642E +28035CA5B300 +2812EB6A427C +28133B46730A +281499DD16A0 +281DD9E6C98E +2870E08CEDBA +28B8685B1B22 +28C3D17E4DEC +2953C63E9E58 +295D3C9A8B28 +297B74853CAA +29ACACC2828E +29EA97BC4A6B +29EB3CA1C0DE +2A079CC2AD37 +2A27E0602400 +2A45A0D8D6EE +2A47CDD3A322 +2A4C4DB1D71D +2AA82B4B6711 +2ABD68BDC5A3 +2AE7BDB10CB4 +2B051C90BE82 +2B490231E063 +2BAB94372644 +2C03252C10E7 +2C3EE5E98804 +2CB671E6365D +2CC55B46705B +2CD09D3C0A1B +2CECBC323E31 +2D302827C9B4 +2D716C9C467B +2D8856109732 +2E15681A4355 +2E79209B9519 +2EEE063290C1 +301C9AA3DECA +30C520D6A2B9 +30D6324910AB +3113AADC9D6B +3124ACA5491C +315AD0D6E6D2 +31A16DAC864D +31EC44581294 +32DE3CD81C24 +32E532232C29 +33256E443128 +33293485AD61 +33305B0365AA +3343B72BAA71 +3372C9C5D4AE +33754E0D1687 +33A444334869 +33B54345C32E +34002AAEE45D +343C556CEE59 +3444DDE6D7E5 +345B62452538 +3495A04A9270 +34EB673C863B +35123500C1EA +353A7167576B +3599856810B2 +35E7DE9899EE +35EDABB506D8 +36C54912D10E +36CA0101B6DC +36D268442846 +373E5827E0B8 +376D6C446746 +37E2EAE635B5 +381B0A70E135 +3862B259DC71 +386676C44A13 +3905679DEEC4 +39070618BB17 +394181105544 +395D38815892 +39A00E856381 +39C0E2ED99B5 +3A1E82E2CDB7 +3A5D13E05B6A +3A6DE2081CDD +3A8498924010 +3A9D49E8BEB2 +3AD0EE1031A9 +3B052E65D40A +3B4986981212 +3B4C51ACC53D +3B99486097C6 +3BB36BC22CE4 +3BB4B3025B79 +3BBB7BD8D7B7 +3C09C971D835 +3C4A12E7A107 +3C633B3474DD +3CB9E31D6022 +3CD344A7EB21 +3CD8C6705954 +3CE887B9D091 +3D5EA1C71953 +3D89120EB993 +3D9C3245AE76 +3DED9D496478 +3E0913A96E74 +3E34909990B5 +3E7DD7953DDD +3EEB33434C1A +4015D16B5C1C +401C81A72C56 +40E7B8D60242 +41016C0CB8DE +4124864B0D40 +415BAA0CAB15 +418184DBB4A0 +419513740558 +4195EE7238CC +41B727883B27 +41BC44A8C3C6 +41DDC3A48EEA +420445087613 +42068108DE36 +4245921D73CA +42A959953C45 +430E67734C18 +4314D9D03B95 +43166BCA83EB +43400A093A7E +434CE764DE91 +43595AC786EE +438099331C1E +43814087A7B5 +438C3CD95B58 +43B3E895B281 +44074C461042 +444D37149B20 +44A04DAA30CB +4537282554C5 +4584EACB6087 +45DB3799C150 +45E599AE38EA +462305611C4A +4636195CDA2D +46752993E2E9 +4684316440D6 +46C7246C1958 +4751A5274848 +4761E34CB054 +476388408D8E +478947735B45 +47AD81972D5B +47C23398EA52 +47E9D4D4BE35 +4812AEC4B01A +48276645A4EA +48644467A214 +489C783B3514 +48C860AA4B74 +495C6639575B +49681C20A00D +49E8249DD677 +49E93C110AA1 +4A24470C19C5 +4A4755BC4A2A +4A4D5E3A9011 +4A65D627625C +4A6B36C5BCCC +4AB725ED89B5 +4B39E3923D0D +4B59316C10E0 +4C275C8BB2DA +4C2E9455D296 +4C44DB1D0C3A +4C67059B0006 +4CA30E1A298A +4CA74DAC7C01 +4CB212D72D57 +4CD3B228EBB4 +4CE1972E090C +4CEE1794E0EA +4D06DBCA167E +4D2CC85EB338 +4D40BC7A44DB +4D769DA515D3 +4D79C95DAD2D +4DBAC8ECE167 +4E3CB839E87D +4E3D548E1267 +4E8250E29617 +4E94C7962769 +5038884E4178 +505B5A8EB20A +50642C36DA00 +5083664D8C09 +50B77DA96DE2 +511E269A9BAE +51798AEAAE9E +51ED5833AB6D +525335E4CD34 +5261CDDA279E +526E55542A54 +529C16A720AB +52A230B1C50E +52AADA374811 +52D20D6E3E35 +534BB4A6984E +5352CCC3DCD2 +540B15E8019D +54AA2915E815 +558DB8891A90 +55A691710B48 +55D1E91B1D35 +55D95774E9A0 +563C6B96D59D +567032E13B54 +56741B108D22 +57029D991123 +5714E9D33034 +5734CD8A65DA +5785EE00049E +57B8B111491D +57CC9D0AA32B +57D7D4D746DA +583C936DCB4B +586B470A43B3 +5876E1D34183 +58B6AE62DB88 +58C35C8BC9AB +597E98000ED4 +59DB4DBB5D7A +5A150653E624 +5A211CE57C4B +5A6272CDBE9C +5ACB8043C10C +5B41CEBC2213 +5B59BCC4321E +5BA03479BB8C +5BC64C42281C +5C9B1A8E31CD +5C9BD0AC1DB1 +5D223E990AD8 +5D8C3A5C5761 +5DA57EACA38C +5E41DD5D1154 +5E6ABB51EC75 +5E7CC04C3A58 +5E810C48C8D8 +5E8943D9A836 +5ED616273468 +60100DD0E023 +6033A1C0E431 +6088A566CC60 +60B20ADA0471 +60B8411D876E +60C742D8D9C0 +6135433CC5EA +6153ADD80A15 +61718ED2C94D +6175241B035A +61780BCB0C57 +61B701698050 +61C4E56629A3 +61D59C284952 +61E57B490A55 +622E5E0812D7 +6251CE7E547A +62953A89B137 +62D6EAA06CD6 +630228659A47 +632931BE8EC7 +63539BB89DEE +636CB69BB10C +63783393E20D +639DB16995B7 +63AA2A5B076C +63B636458E94 +6443E64DCC4B +64695084C575 +6493D06D5710 +649B302A97C5 +64B8632B54D4 +654BACB21C3B +65A3D5823819 +65DEDABD1B34 +6608944EE186 +665B8B24C20D +6685D0BE19E0 +66933A9E7982 +674C7BB59A16 +675E35EE359E +67AA98E362C9 +67D47C1B6425 +67DE22850162 +67E8B986B2A7 +681EA28BA6CD +6828B52B6507 +6874E54471E8 +6879B1CA44A3 +68C00A810D41 +68C9E8AA5C3E +697A8ED07418 +69B5357A617A +6A7B3A7B6735 +6AA40421D23C +6AB676B4DB9D +6B00420BE41C +6B0B7B967871 +6B9D041136B4 +6BB1A14768A8 +6BCAE24D9700 +6C0458728774 +6C57CBD51995 +6C5E10B86CDE +6CA491A8C7B8 +6CBC25C1DA2E +6CD430D99958 +6CEC27647CC0 +6D4D29CEB9B5 +6D6E9A6B725D +6D801AC74572 +6D97408C6D60 +6DDE6E871C64 +6DEA848B6195 +6E05B5C44A54 +6E751666AE9A +6E7DBCDA05B3 +7004BA1763ED +7016ECD01559 +7076D48D5E49 +7091621EA016 +709311997549 +70984C14D3DB +70D73BE22CDD +70D9461C5E90 +712BC18422CB +712E6CAA74A4 +7164042BA89E +7175E14A4D62 +718B39561350 +718BDA352E28 +719B1418323E +71A8D54D82B3 +71DC30168C27 +7221E016597B +7234CC6BD65D +727A80DD5296 +72B393D6E8A9 +732C9BE4DDBA +736B4A835B2B +73EA81968900 +740AB5126199 +741A31054E6B +74498C1D4B3D +745276053CB6 +74684B0B4B1D +74772915E24C +74A24BE33BE2 +74A778236D5A +74AA58008A31 +74C27A96CB3A +754AD5773746 +756C15E54212 +759403A563D8 +759D2130312B +75A0E10D8C84 +75A807E46B96 +75E454785C6C +76078A25C088 +76140285B768 +763D835BD5ED +767C33468C72 +76962C07EC9E +76984E62CCE4 +769AE4646931 +76E5DA67A1EC +7708D5CAD58B +77383BAA4D90 +7789E646A556 +779A248E098C +77DB71037644 +77E0A57DD456 +7853D464E2A4 +78EA6EB04463 +7909427EC8B9 +7910A31ECD19 +79271963B6E8 +793D98517D33 +79B7A4C58DE0 +79B9148761B3 +7A2893B75AD1 +7A4C61A1B48D +7A7469B69C6A +7AA84B1A527D +7B00211CA416 +7B118EABC7BB +7B1D9A2E22AA +7B583D350740 +7B9D3A6BD061 +7C2DAC2CC775 +7C4CBBD2DDE1 +7CD52B5B8E77 +7D412100532B +7D46C149DAD9 +7D4CA630E229 +7DAC0E83D335 +7DC935E220A0 +7DCA66BACA13 +7E30778792D2 +7E43C3BAB3CB +7E475BA186E6 +7EE2A624851A +80CED5362B2C +80D2CC78E10B +80D62251E20C +816875D55ED1 +81950D0517AC +81B519418C3E +8211571B9D16 +823C7CC6E06A +826DD63B9032 +827303C574B5 +82C5ADED4B81 +82E344329D34 +83588E140165 +835D33B48113 +8384148AE52D +8394B57153D6 +83A0184757C0 +83D86835B48B +8502EE9A7E85 +852C2B72659D +8534A6CE0911 +85ABD94CD7A9 +85DA8099CD7E +85E0B6B26945 +864CA2A6BE93 +868A33A44447 +86EDEABCC357 +87DDD5A188EE +8830379B50B7 +883803A3360C +883DA78EC87D +88482A12C2C6 +888EBD3DB945 +88D026793359 +88DD4B7C5991 +8931DC3733D4 +894D8E2DCDEE +897B845C2680 +89B638BD909E +89D2C28BE578 +8A1869848D1A +8A39D09508C9 +8ACCC7290C8C +8AD8B41EC218 +8B028B7E6D60 +8B6A95C7D2E2 +8BA1226EBA21 +8BD586B21ABC +8C0EA504B635 +8CA939DC6DE4 +8CAE5D688443 +8CEC639E64DC +8DECE0DD29DE +8E0EC762E883 +8E958D8B8C52 +8EB64D710C88 +8ED4A17717D9 +8EE9D9C03A0D +9014E1430AEB +90965DEBC8B9 +90E56E616DDD +912CD8E04437 +912E33563E1B +918048032247 +919402EC39CB +91D28E2B126D +9216EEE5B677 +9232215296B2 +925A070E9096 +925A5521D48D +92CC200886A2 +932035869655 +937144459949 +93B260DBC70A +94552B863E37 +95327A0A3600 +954275CDD7E0 +957E6EE3EB55 +95B920CACC84 +96382E1C8E12 +964E8E5338BD +96706C8D6ECC +96759A0D5566 +96D5213C5DDB +97300764797A +973BDDBE7434 +974838AE17A0 +9752A6B316D5 +97926543783B +97EB373096CA +982D6054B83D +989D127BD496 +98A54AD58A43 +98A92128364C +98CD5AA2A4DB +98E8C543688E +99207A00AA4A +99243E754CB8 +9925893ABAC7 +9937553A965E +9976E6ADE0C9 +9982E3E6A4A0 +9984C1A3229E +99C487AB85EC +99E2A19C9673 +9A05EBE41D7D +9A138D1A5CB7 +9A179148B824 +9A6EC0A9ECB8 +9A720CBD7BB1 +9AB22BBDDD87 +9AC43B5A06D8 +9AD8150BE648 +9AD97423190D +9B4ADDDEB749 +9B7603341727 +9C45237377BE +9D090AE1A15E +9D59641E40A5 +9DA4528CEB8C +9DA728164176 +9DAC62A346B7 +9E0E9D983B9A +9E5271763D3D +9EE95586D024 +9EEE39E00CBB +A04671256EE2 +A091485B4B5D +A1B5577ED36E +A1EB280E3901 +A2789E1DD888 +A293A90AE72C +A309E3AEBDB9 +A3196E77B072 +A31E72DCC826 +A34DEA01690E +A36031D6ECB2 +A38044A3E18E +A421D7A04C4B +A424C686CA39 +A44590A779A5 +A47AD3895C63 +A5041E8B8E22 +A50DC0830AA5 +A52B8929D665 +A5BCBA6BE592 +A61D5137E6B3 +A6344C0418DC +A690A817B9D9 +A7E3B3459240 +A81E6D3C8E11 +A8C0BE436685 +A8DE205120A8 +A91E2BE6C308 +A9258D6B06B5 +A992B5E070C1 +AAC6E3205D48 +AB101546634E +AB6EE0761ACA +AB9BCA200547 +AC4BC5B2D3C0 +AC7A0B47B03E +AC88B26AC1D0 +ACAEB3456AD9 +ACB906631D8A +ACE07B45C0C5 +AD1992AE37CA +AD5586744A60 +AD674E4ADB79 +ADA093B06831 +AE7C3AE5334A +AE9EB8CAB2C3 +AEAE9E5CE65D +B002D1BDC29B +B0463E703098 +B063B209BB20 +B0788BE3BAA4 +B0C3B3299090 +B128298D9073 +B160677E7035 +B19D3D57176A +B1CCDB7999B9 +B231AA398B90 +B250E9590215 +B28BE0D819ED +B292C9554CBA +B2D8485C2460 +B31763D9D0DE +B328014DDD6A +B378C424C9E2 +B3D8C03C78E0 +B41D18E3B980 +B46824B972E9 +B50383A32302 +B509D631967C +B56CA847A7C3 +B56EC9A20D28 +B5B763215C82 +B6550EAC573A +B66060201705 +B6614EBEAAA2 +B6A18CBD4DA6 +B6ABB62E437E +B6C6558E58CA +B7009204D512 +B71D5B22B1C2 +B7392DD1E497 +B7709ED7CE60 +B7A26320A491 +B7A9DA22E9C6 +B7DEC863369D +B7E9A91174CB +B8178A34E2DC +B83092098A7D +B84C50E56DEC +B89BD135E935 +B8E87380D361 +B9485A9648C6 +B9ED829C22AE +BA227EE91818 +BA7BBD9683B1 +BA8224EA7A80 +BA84C974B356 +BAD293A45C8A +BB850C7E4934 +BBC1256810A4 +BC1CD369549E +BC5C76E5909C +BC66E9270049 +BC6AB08B03CC +BC74CA2C2B06 +BC7C64828C1D +BCCC3A719013 +BD06E96EB7D7 +BD196D0A74E0 +BE02790E84AC +BE1266314B9D +BE518C742B74 +BE5695316117 +BE5D8EBA120D +BE8286DA7D12 +BE9CE00EE4DD +C003962B3462 +C0067E095049 +C015A21E0146 +C03BC03AD437 +C06CE7D57A0D +C07EE1E10B56 +C0885A29251E +C198163ABECE +C1EB7337A035 +C225479C7064 +C2740E1665A8 +C27924128A00 +C2A701656B8B +C2C30D21C53E +C2CBB2ACD38D +C38D19A9C8D1 +C3B1BB7E7492 +C3BA2438A981 +C3CD74758DE2 +C4033B3BB1D7 +C404D280640E +C4467DE80B2D +C46A048C88DD +C52877867C05 +C56D005E258E +C56D052D5533 +C5BB2CCCB9C3 +C5C272694A1E +C6121BC4A29C +C65EEAE02433 +C661C4AE1DD1 +C76C94B495CA +C7BD49777A79 +C7CD131E9B60 +C7E35D6294BA +C8E173DB04CC +C95855AE08E8 +C98147E69033 +C99A004E6133 +C9E893C4090B +CA119C79A197 +CA309D2CBC41 +CA4BAA390BC4 +CA92DD257E21 +CA968EBEB9C7 +CADED0C50AC4 +CB18774EA550 +CB1999D19E10 +CB75C1BAE669 +CC2517AB2346 +CC2AC1AD29CA +CD11359C7A90 +CD14C8553CB9 +CD333295BBE2 +CD3DB8C27E5C +CDA811AD5055 +CDABDCA23986 +CDCA8BD7B002 +CE0456AB0DCE +CE58AE1C51E9 +CE76E8A600DC +CE95875316C8 +CEB105E65289 +CEB651752D4C +CEE02D97E5BD +D023DB35ED05 +D0BE546CC06B +D0CE7EB0D379 +D10329D366C8 +D15C004DBC8D +D16E6B668254 +D1CEEC977644 +D1DC0E1CC09E +D2550925679B +D28B2D42DE1A +D2926519AC09 +D313116A45B4 +D3DC10453857 +D431C8C73BDC +D4C67846791C +D5629384CE7D +D5ABE7180600 +D62A4A0E57C2 +D660CE9E3080 +D66AE9282140 +D6A91C14AC47 +D6E23B4E75C6 +D726C4979654 +D76DE12943B4 +D7A405AD9E4E +D7BD3AE48E93 +D7D49700BBCC +D7E8A5089E7A +D84C81EE910D +D8545199A949 +D86243C1380E +D88A12EB3622 +D89B5EA419C1 +D8A3690B0115 +D94646A4C65B +D982B4846A96 +DA303BADB013 +DAD9A48A8C33 +DAEB5D63920B +DB01A99DD94C +DB22BB7D6818 +DB37160CBB4B +DB7E3687E450 +DC7697E37A9B +DCC44C4E9269 +DCCE477E785E +DD68DE9CDA5A +DE1B08C6D94B +DE41BBD7E68D +DE6E04AE4475 +DE8CD4277A9E +DEA8098D6E51 +DEB2BEE8858A +DEB550958AD9 +E045E6309471 +E0E21213C611 +E0E457054B62 +E1097C69DA4A +E1EA831EA514 +E20716902884 +E2C9CB14C06C +E33B66EA2705 +E34C5B12BABA +E38A1C654E82 +E3905BA54194 +E3E3919444CA +E4450EC1010C +E49A03306224 +E5100AC4C6C3 +E5124DB665A6 +E5491B5E3DD6 +E5BE9C989A29 +E5C3A9A27D3E +E65111EB1E40 +E65792427D4C +E7004C5EA94A +E705087DECBB +E7CB93E68155 +E81512343BAD +E8428C8B0740 +E859EBC22318 +E87267A508DB +E886AE7D1BE0 +E8B008239600 +E8C4B4A4E482 +E8D53410B736 +E902964DA28D +E9203D5BD2DA +E9526CACA8B2 +E9C11D763BEC +EA3BDAA4E498 +EA61AC8B4969 +EA8E8ADC26B9 +EB5588EAE5E8 +EBA964C07075 +EC71B679D3AA +ECB4019ADD97 +ED14D0A14B0C +ED296C79266C +EDBA3C943EA8 +EDC7CEBD4000 +EDE2747DA6C3 +EE3029556CEB +EE49610E6121 +EEB704D69BCA +EED69A391464 diff --git a/client/dictionaries/mfc_keys_mrzd_sorted.dic b/client/dictionaries/mfc_keys_mrzd_sorted.dic new file mode 100644 index 000000000..f2ebafc10 --- /dev/null +++ b/client/dictionaries/mfc_keys_mrzd_sorted.dic @@ -0,0 +1,57 @@ +010203040506 +013940233313 +022FE48B3072 +123456789ABC +123456ABCDEF +17505586EF02 +1795902DBAF9 +1A2B3C4D5E6F +1A982C7E459A +200306202033 +2011092119F1 +2012053082AD +37D4DCA92451 +40E5EA1EFC00 +435330666666 +46868F6D5677 +474249437569 +4D3A99C351DD +533CB6C723F6 +5554AAA96321 +587EE5F9350F +5A1B85FCE20A +5D293AFC8D7E +64A2EE93B12B +64E2283FCF5E +714C5C886E97 +833FBD3CFE51 +83BAB5ACAD62 +872B71F9D15A +8F9B229047AC +8FD0A4F256E9 +9AEDF9931EC1 +9B1DD7C030A1 +A0478CC39091 +A0A1A2A3A4A5 +A2B2C9D187FB +A4EF6C3BB692 +AABBCC660429 +AABBCCDDEEFF +ABCDEF123456 +B0699AD03D17 +B0B1B2B3B4B5 +BA28CFD15EE8 +BCFE01BCFE01 +C0C1C2C3C4C5 +CFC738403AB0 +D0D1D2D3D4D5 +D3F7D3F7D3F7 +DB5181C92CBE +DFED39FFBB76 +E1DD284379D4 +E96246531342 +ED3A7EFBFF56 +F83466888612 +F89C86B2A961 +FFFFAE82366C +FFFFD06F83E3 diff --git a/client/default_ultralight_keys.dic b/client/dictionaries/mfulc_default_keys.dic similarity index 63% rename from client/default_ultralight_keys.dic rename to client/dictionaries/mfulc_default_keys.dic index 3c0c01acd..51b4b9365 100644 --- a/client/default_ultralight_keys.dic +++ b/client/dictionaries/mfulc_default_keys.dic @@ -2,4 +2,5 @@ # Mifare Ultralight Default Keys # -- iceman fork version -- # -- contribute to this list, sharing is caring -- -425245414B4D454946594F5543414E21 -- Sample Key (BREAKMEIFYOUCAN!) +# +425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!) diff --git a/client/dictionaries/mrzd_sort_keys.dic b/client/dictionaries/mrzd_sort_keys.dic deleted file mode 100644 index 025f1b995..000000000 --- a/client/dictionaries/mrzd_sort_keys.dic +++ /dev/null @@ -1,57 +0,0 @@ -010203040506, -013940233313, -022FE48B3072, -123456789ABC, -123456ABCDEF, -17505586EF02, -1795902DBAF9, -1A2B3C4D5E6F, -1A982C7E459A, -200306202033, -2011092119F1, -2012053082AD, -37D4DCA92451, -40E5EA1EFC00, -435330666666, -46868F6D5677, -474249437569, -4D3A99C351DD, -533CB6C723F6, -5554AAA96321, -587EE5F9350F, -5A1B85FCE20A, -5D293AFC8D7E, -64A2EE93B12B, -64E2283FCF5E, -714C5C886E97, -833FBD3CFE51, -83BAB5ACAD62, -872B71F9D15A, -8F9B229047AC, -8FD0A4F256E9, -9AEDF9931EC1, -9B1DD7C030A1, -A0478CC39091, -A0A1A2A3A4A5, -A2B2C9D187FB, -A4EF6C3BB692, -AABBCC660429, -AABBCCDDEEFF, -ABCDEF123456, -B0699AD03D17, -B0B1B2B3B4B5, -BA28CFD15EE8, -BCFE01BCFE01, -C0C1C2C3C4C5, -CFC738403AB0, -D0D1D2D3D4D5, -D3F7D3F7D3F7, -DB5181C92CBE, -DFED39FFBB76, -E1DD284379D4, -E96246531342, -ED3A7EFBFF56, -F83466888612, -F89C86B2A961, -FFFFAE82366C, -FFFFD06F83E3, diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic new file mode 100644 index 000000000..511be26d1 --- /dev/null +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -0,0 +1,123 @@ +# known cloners +# ref. http://www.proxmark.org/forum/viewtopic.php?id=2022 +51243648 +000D8787 +19920427 +65857569 //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com) +# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77 +05D73B9F +# ref. http://www.proxmark.org/forum/viewtopic.php?= +89A69E60 +# ref lock +314159E0 +# ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115 +AA55BBBB +# ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376 +A5B4C3D2 +# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379 +1C0B5848 +# ref. http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075 +00434343 +44B44CAE +88661858 +# paxton bullit? +575F4F4B +# +50520901 +# Default pwd, simple: +00000000 +11111111 +22222222 +33333333 +44444444 +55555555 +66666666 +77777777 +88888888 +99999999 +AAAAAAAA +BBBBBBBB +CCCCCCCC +DDDDDDDD +EEEEEEEE +FFFFFFFF +a0a1a2a3 +b0b1b2b3 +aabbccdd +bbccddee +ccddeeff +50415353 +00000001 +00000002 +0000000a +0000000b +01020304 +02030405 +03040506 +04050607 +05060708 +06070809 +0708090A +08090A0B +090A0B0C +0A0B0C0D +0B0C0D0E +0C0D0E0F +01234567 +12345678 +10000000 +20000000 +30000000 +40000000 +50000000 +60000000 +70000000 +80000000 +90000000 +A0000000 +B0000000 +C0000000 +D0000000 +E0000000 +F0000000 +10101010 +01010101 +11223344 +22334455 +33445566 +44556677 +55667788 +66778899 +778899AA +8899AABB +99AABBCC +AABBCCDD +BBCCDDEE +CCDDEEFF +0CB7E7FC # rfidler? +FABADA11 # china? +# 20 most common len==8 +87654321 +12341234 +69696969 +12121212 +12344321 +1234ABCD +11112222 +13131313 +10041004 +# +31415926 # pii +abcd1234 +20002000 +19721972 +aa55aa55 # amiboo +55aa55aa # rev amiboo +4f271149 # seeds ul-ev1 +07d7bb0b # seeds ul-ev1 +9636ef8f # seeds ul-ev1 +b5f44686 # seeds ul-ev1 +9E3779B9 # TEA +C6EF3720 # TEA +7854794A # xbox tea constant :) +F1EA5EED # burtle diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 3891bdb48..348840cb3 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -232,7 +232,7 @@ static int CmdEMVGPO(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("kK", "keep", "keep field ON for next command"), - arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"), + arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"), arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), @@ -398,7 +398,7 @@ static int CmdEMVAC(const char *Cmd) { arg_lit0("kK", "keep", "keep field ON for next command"), arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."), arg_str0("dD", "decision", "", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"), - arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"), + arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"), arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), @@ -564,7 +564,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("kK", "keep", "keep field ON for next command"), - arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"), + arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"), arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"), arg_lit0("aA", "apdu", "show APDU reqests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), @@ -785,7 +785,7 @@ static int CmdEMVExec(const char *Cmd) { arg_lit0("sS", "select", "activate field and select card."), arg_lit0("aA", "apdu", "show APDU reqests and responses."), arg_lit0("tT", "tlv", "TLV decode results."), - arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."), + arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."), arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."), arg_rem("By default:", "Transaction type - MSD"), arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."), @@ -1376,7 +1376,7 @@ static int CmdEMVScan(const char *Cmd) { arg_lit0("aA", "apdu", "show APDU reqests and responses."), arg_lit0("tT", "tlv", "TLV decode results."), arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"), - arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."), + arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."), arg_rem("By default:", "Transaction type - MSD"), arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."), arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."), diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index e273480c8..8465a6e95 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -29,6 +29,8 @@ #include "ui.h" #include "crypto.h" #include "proxmark3.h" +#include "fileutils.h" +#include "pm3_cmd.h" #define BCD(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \ -1) @@ -483,13 +485,12 @@ struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) { } } */ - const char *relfname = "emv/capk.txt"; - - char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1]; - strcpy(fname, get_my_executable_directory()); - strcat(fname, relfname); - - pk = emv_pk_get_ca_pk_from_file(fname, rid, idx); + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, "capk", ".txt", false) != PM3_SUCCESS) { + return NULL; + } + pk = emv_pk_get_ca_pk_from_file(path, rid, idx); + free(path); if (!pk) return NULL; diff --git a/client/emv/emv_tags.c b/client/emv/emv_tags.c index 72c1fe78e..296dcdf82 100644 --- a/client/emv/emv_tags.c +++ b/client/emv/emv_tags.c @@ -401,11 +401,11 @@ static const struct emv_tag emv_tags[] = { { 0xdf811b, "Kernel Configuration", EMV_TAG_GENERIC, NULL }, { 0xdf811c, "Max Lifetime of Torn Transaction Log Record", EMV_TAG_GENERIC, NULL }, { 0xdf811d, "Max Number of Torn Transaction Log Records", EMV_TAG_GENERIC, NULL }, - { 0xdf811e, "Mag-stripe CVM Capability – CVM Required", EMV_TAG_GENERIC, NULL }, + { 0xdf811e, "Mag-stripe CVM Capability - CVM Required", EMV_TAG_GENERIC, NULL }, { 0xdf811f, "Security Capability", EMV_TAG_GENERIC, NULL }, - { 0xdf8120, "Terminal Action Code – Default", EMV_TAG_GENERIC, NULL }, - { 0xdf8121, "Terminal Action Code – Denial", EMV_TAG_GENERIC, NULL }, - { 0xdf8122, "Terminal Action Code – Online", EMV_TAG_GENERIC, NULL }, + { 0xdf8120, "Terminal Action Code - Default", EMV_TAG_GENERIC, NULL }, + { 0xdf8121, "Terminal Action Code - Denial", EMV_TAG_GENERIC, NULL }, + { 0xdf8122, "Terminal Action Code - Online", EMV_TAG_GENERIC, NULL }, { 0xdf8123, "Reader Contactless Floor Limit", EMV_TAG_GENERIC, NULL }, { 0xdf8124, "Reader Contactless Transaction Limit (No On-device CVM)", EMV_TAG_GENERIC, NULL }, { 0xdf8125, "Reader Contactless Transaction Limit (On-device CVM)", EMV_TAG_GENERIC, NULL }, @@ -415,7 +415,7 @@ static const struct emv_tag emv_tags[] = { { 0xdf8129, "Outcome Parameter Set", EMV_TAG_GENERIC, NULL }, { 0xdf812a, "DD Card (Track1)", EMV_TAG_GENERIC, NULL }, { 0xdf812b, "DD Card (Track2)", EMV_TAG_GENERIC, NULL }, - { 0xdf812c, "Mag-stripe CVM Capability – No CVM Required", EMV_TAG_GENERIC, NULL }, + { 0xdf812c, "Mag-stripe CVM Capability - No CVM Required", EMV_TAG_GENERIC, NULL }, { 0xdf812d, "Message Hold Time", EMV_TAG_GENERIC, NULL }, { 0xff8101, "Torn Record", EMV_TAG_GENERIC, NULL }, diff --git a/client/emv/emvjson.c b/client/emv/emvjson.c index 88d886c6e..785b6b8e7 100644 --- a/client/emv/emvjson.c +++ b/client/emv/emvjson.c @@ -17,6 +17,8 @@ #include "util.h" #include "proxmark3.h" #include "emv_tags.h" +#include "fileutils.h" +#include "pm3_cmd.h" static const ApplicationDataElm ApplicationData[] = { {0x82, "AIP"}, @@ -303,13 +305,12 @@ bool ParamLoadFromJson(struct tlvdb *tlv) { return false; } - // current path + file name - const char *relfname = "emv/defparams.json"; - char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1]; - strcpy(fname, get_my_executable_directory()); - strcat(fname, relfname); - - root = json_load_file(fname, 0, &error); + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, "emv_defparams", ".json", false) != PM3_SUCCESS) { + return false; + } + root = json_load_file(path, 0, &error); + free(path); if (!root) { PrintAndLogEx(ERR, "Load params: json error on line " _YELLOW_("%d") ": %s", error.line, error.text); return false; diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index 29c4fdaa3..937ff7e8e 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -58,7 +58,13 @@ int ExecuteCryptoTests(bool verbose) { res = mbedtls_entropy_self_test(verbose); if (res) TestFail = true; - res = mbedtls_timing_self_test(verbose); + // retry for CI (when resources too low) + for (int i = 0; i < 3; i++) { + res = mbedtls_timing_self_test(verbose); + if (!res) + break; + PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1); + } if (res) TestFail = true; res = mbedtls_ctr_drbg_self_test(verbose); diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 21d9d80f6..7ea103004 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -36,6 +36,7 @@ // Name: Yubico U2F Root CA Serial 457200631 // Issued: 2014-08-01 +// https://github.com/Yubico/developers.yubico.com/tree/master/static/U2F #define YUBICO_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ "MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \ diff --git a/client/loclass/fileutils.c b/client/fileutils.c similarity index 55% rename from client/loclass/fileutils.c rename to client/fileutils.c index b89925334..23553d15c 100644 --- a/client/loclass/fileutils.c +++ b/client/fileutils.c @@ -34,18 +34,23 @@ * * ****************************************************************************/ + +// this define is needed for scandir/alphasort to work +#define _GNU_SOURCE #include "fileutils.h" +#include #include #include "pm3_cmd.h" #include "commonutil.h" +#include "proxmark3.h" #include "util.h" +#ifdef _WIN32 +#include "scandir.h" +#endif - -#ifndef ON_DEVICE - -#define PATH_MAX_LENGTH 100 +#define PATH_MAX_LENGTH 200 /** * @brief checks if a file exists @@ -98,9 +103,9 @@ static char *newfilenamemcopy(const char *preferredName, const char *suffix) { int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, suffix); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; /* We should have a valid filename now, e.g. dumpdata-3.bin */ @@ -121,9 +126,9 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; int retval = PM3_SUCCESS; int blocks = datalen / blocksize; @@ -166,9 +171,9 @@ out: int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = newfilenamemcopy(preferredName, ".json"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; int retval = PM3_SUCCESS; @@ -276,6 +281,19 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } break; } + case jsfIclass: { + JsonSaveStr(root, "FileType", "iclass"); + uint8_t csn[8] = {0}; + memcpy(csn, data, 8); + JsonSaveBufAsHexCompact(root, "$.Card.CSN", csn, sizeof(csn)); + + for (size_t i = 0; i < (datalen / 8); i++) { + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, data + (i * 8), 8); + } + break; + } } int res = json_dump_file(root, fileName, JSON_INDENT(2)); @@ -293,11 +311,42 @@ out: return retval; } +int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) { + uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + int i; + + if (fptr == NULL) { + return PM3_EINVARG; + } + + FILE *fkeys = fopen(fptr, "wb"); + if (fkeys == NULL) { + PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr); + return PM3_EFILE; + } + PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr); + + for (i = 0; i < sectorsCnt; i++) { + num_to_bytes(e_sector[i].Key[0], 6, tmpKey); + fwrite(tmpKey, 1, 6, fkeys); + } + + for (i = 0; i < sectorsCnt; i++) { + num_to_bytes(e_sector[i].Key[1], 6, tmpKey); + fwrite(tmpKey, 1, 6, fkeys); + } + + fclose(fkeys); + PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr); + return PM3_SUCCESS; +} + + int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { if (data == NULL) return 1; char *fileName = filenamemcopy(preferredName, suffix); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EINVARG; int retval = PM3_SUCCESS; @@ -315,23 +364,24 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m if (fsize <= 0) { PrintAndLogEx(FAILED, "error, when getting filesize"); - retval = 1; + retval = PM3_EFILE; goto out; } uint8_t *dump = calloc(fsize, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(FAILED, "error, cannot allocate memory"); - retval = 2; + retval = PM3_EMALLOC; goto out; } size_t bytes_read = fread(dump, 1, fsize, f); + fclose(f); if (bytes_read != fsize) { PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); free(dump); - retval = 3; + retval = PM3_EFILE; goto out; } @@ -348,17 +398,66 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m *datalen = bytes_read; out: - fclose(f); free(fileName); + return retval; +} +int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) { + + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + int retval = PM3_SUCCESS; + + FILE *f = fopen(path, "rb"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + free(path); + return PM3_EFILE; + } + free(path); + + // get filesize in order to malloc memory + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + if (fsize <= 0) { + PrintAndLogEx(FAILED, "error, when getting filesize"); + fclose(f); + return PM3_EFILE; + } + + *pdata = calloc(fsize, sizeof(uint8_t)); + if (!pdata) { + PrintAndLogEx(FAILED, "error, cannot allocate memory"); + fclose(f); + return PM3_EMALLOC; + } + + size_t bytes_read = fread(*pdata, 1, fsize, f); + + fclose(f); + + if (bytes_read != fsize) { + PrintAndLogEx(FAILED, "error, bytes read mismatch file size"); + return PM3_EFILE; + } + + *datalen = bytes_read; + + PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName); return retval; } int loadFileEML(const char *preferredName, void *data, size_t *datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = filenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; size_t counter = 0; int retval = PM3_SUCCESS, hexlen = 0; @@ -384,7 +483,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) { break; fclose(f); PrintAndLogEx(FAILED, "File reading error."); - retval = 2; + retval = PM3_EFILE; goto out; } @@ -410,9 +509,9 @@ out: int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) { - if (data == NULL) return 1; + if (data == NULL) return PM3_EINVARG; char *fileName = filenamemcopy(preferredName, ".json"); - if (fileName == NULL) return 1; + if (fileName == NULL) return PM3_EMALLOC; *datalen = 0; json_t *root; @@ -423,13 +522,13 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ root = json_load_file(fileName, 0, &error); if (!root) { PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text); - retval = 2; + retval = PM3_ESOFT; goto out; } if (!json_is_object(root)) { PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName); - retval = 3; + retval = PM3_ESOFT; goto out; } @@ -445,7 +544,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (int i = 0; i < 256; i++) { if (sptr + 16 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -467,7 +566,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (int i = 0; i < 256; i++) { if (sptr + 4 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -489,7 +588,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ size_t sptr = 0; for (size_t i = 0; i < (maxdatalen / 4); i++) { if (sptr + 4 > maxdatalen) { - retval = 5; + retval = PM3_EMALLOC; goto out; } @@ -507,6 +606,27 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ *datalen = sptr; } + if (!strcmp(ctype, "iclass")) { + size_t sptr = 0; + for (size_t i = 0; i < (maxdatalen / 8); i++) { + if (sptr + 8 > maxdatalen) { + retval = PM3_EMALLOC; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%zu", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 8, &len); + if (!len) + break; + + sptr += len; + } + *datalen = sptr; + } + PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); out: json_decref(root); @@ -516,10 +636,10 @@ out: int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { - - if (data == NULL) return 1; - char *fileName = filenamemcopy(preferredName, ".dic"); - if (fileName == NULL) return 1; + if (data == NULL) return PM3_EINVARG; + char *path; + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) + return PM3_EFILE; // t5577 == 4bytes // mifare == 6 bytes @@ -537,9 +657,9 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u size_t counter = 0; int retval = PM3_SUCCESS; - FILE *f = fopen(fileName, "r"); + FILE *f = fopen(path, "r"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); retval = PM3_EFILE; goto out; } @@ -571,12 +691,98 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u counter += (keylen >> 1); } fclose(f); - PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path); if (datalen) *datalen = counter; out: - free(fileName); + free(path); + return retval; +} + +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) { + + int retval = PM3_SUCCESS; + + char *path; + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) + return PM3_EFILE; + + // t5577 == 4bytes + // mifare == 6 bytes + // iclass == 8 bytes + // default to 6 bytes. + if (keylen != 4 && keylen != 6 && keylen != 8) { + keylen = 6; + } + + size_t mem_size; + size_t block_size = 10 * keylen; + + // double up since its chars + keylen <<= 1; + + char line[255]; + + // allocate some space for the dictionary + *pdata = calloc(block_size, sizeof(uint8_t)); + if (*pdata == NULL) + return PM3_EFILE; + + mem_size = block_size; + + FILE *f = fopen(path, "r"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + retval = PM3_EFILE; + goto out; + } + + // read file + while (fgets(line, sizeof(line), f)) { + + // check if we have enough space (if not allocate more) + if ((*keycnt * (keylen >> 1)) >= mem_size) { + + mem_size += block_size; + *pdata = realloc(*pdata, mem_size); + + if (*pdata == NULL) { + return PM3_EFILE; + } else { + memset(*pdata + (mem_size - block_size), 0, block_size); + } + } + + // add null terminator + line[keylen] = 0; + + // smaller keys than expected is skipped + if (strlen(line) < keylen) + continue; + + // The line start with # is comment, skip + if (line[0] == '#') + continue; + + if (!isxdigit(line[0])) { + PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen); + continue; + } + + uint64_t key = strtoull(line, NULL, 16); + + num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1))); + + (*keycnt)++; + + memset(line, 0, sizeof(line)); + } + fclose(f); + PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path); + +out: + free(path); return retval; } @@ -612,7 +818,211 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) { return PM3_SUCCESS; } +static int filelist(const char *path, const char *ext, bool last, bool tentative) { + struct dirent **namelist; + int n; -#else //if we're on ARM + n = scandir(path, &namelist, NULL, alphasort); + if (n == -1) { + if (!tentative) + PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); + return PM3_EFILE; + } -#endif + PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path); + for (uint16_t i = 0; i < n; i++) { + if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) { + PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name); + } + free(namelist[i]); + } + free(namelist); + return PM3_SUCCESS; +} + +int searchAndList(const char *pm3dir, const char *ext) { + // display in same order as searched by searchFile + // try pm3 dirs in current workdir (dev mode) + if (get_my_executable_directory() != NULL) { + char script_directory_path[strlen(get_my_executable_directory()) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, get_my_executable_directory()); + strcat(script_directory_path, pm3dir); + filelist(script_directory_path, ext, false, true); + } + // try pm3 dirs in user .proxmark3 (user mode) + const char *user_path = get_my_user_directory(); + if (user_path != NULL) { + char script_directory_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, user_path); + strcat(script_directory_path, PM3_USER_DIRECTORY); + strcat(script_directory_path, pm3dir); + filelist(script_directory_path, ext, false, false); + } + // try pm3 dirs in pm3 installation dir (install mode) + const char *exec_path = get_my_executable_directory(); + if (exec_path != NULL) { + char script_directory_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + 1]; + strcpy(script_directory_path, exec_path); + strcat(script_directory_path, PM3_SHARE_RELPATH); + strcat(script_directory_path, pm3dir); + filelist(script_directory_path, ext, true, false); + } + return PM3_SUCCESS; +} + +static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname, bool silent) { + if ((foundpath == NULL) || (pm3dir == NULL) || (searchname == NULL)) return PM3_ESOFT; + // explicit absolute (/) or relative path (./) => try only to match it directly + char *filename = calloc(strlen(searchname) + 1, sizeof(char)); + if (filename == NULL) return PM3_EMALLOC; + strcpy(filename, searchname); + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Searching %s", filename); + } + if (((strlen(filename) > 1) && (filename[0] == '/')) || + ((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) { + if (fileExists(filename)) { + *foundpath = filename; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } else { + goto out; + } + } + // else + + // try implicit relative path + { + if (fileExists(filename)) { + *foundpath = filename; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } + } + // try pm3 dirs in user .proxmark3 (user mode) + const char *user_path = get_my_user_directory(); + if (user_path != NULL) { + char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + if (path == NULL) + goto out; + strcpy(path, user_path); + strcat(path, PM3_USER_DIRECTORY); + strcat(path, pm3dir); + strcat(path, filename); + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Searching %s", path); + } + if (fileExists(path)) { + free(filename); + *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } else { + free(path); + } + } + // try pm3 dirs in current client workdir (dev mode) + const char *exec_path = get_my_executable_directory(); + if ((exec_path != NULL) && + ((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) || + (strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) || + (strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) || + (strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) || + (strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) { + char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + if (path == NULL) + goto out; + strcpy(path, exec_path); + strcat(path, pm3dir); + strcat(path, filename); + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Searching %s", path); + } + if (fileExists(path)) { + free(filename); + *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } else { + free(path); + } + } + // try pm3 dirs in current repo workdir (dev mode) + if ((exec_path != NULL) && + ((strcmp(TRACES_SUBDIR, pm3dir) == 0) || + (strcmp(FIRMWARES_SUBDIR, pm3dir) == 0) || + (strcmp(BOOTROM_SUBDIR, pm3dir) == 0) || + (strcmp(FULLIMAGE_SUBDIR, pm3dir) == 0))) { + char *above = "../"; + char *path = calloc(strlen(exec_path) + strlen(above) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + if (path == NULL) + goto out; + strcpy(path, exec_path); + strcat(path, above); + strcat(path, pm3dir); + strcat(path, filename); + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Searching %s", path); + } + if (fileExists(path)) { + free(filename); + *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } else { + free(path); + } + } + // try pm3 dirs in pm3 installation dir (install mode) + { + char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); + if (path == NULL) + goto out; + strcpy(path, exec_path); + strcat(path, PM3_SHARE_RELPATH); + strcat(path, pm3dir); + strcat(path, filename); + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Searching %s", path); + } + if (fileExists(path)) { + free(filename); + *foundpath = path; + if ((g_debugMode == 2) && (!silent)) { + PrintAndLogEx(INFO, "Found %s", *foundpath); + } + return PM3_SUCCESS; + } else { + free(path); + } + } +out: + free(filename); + return PM3_EFILE; +} + +int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { + if (foundpath == NULL) + return PM3_EINVARG; + char *filename = filenamemcopy(searchname, suffix); + if (filename == NULL) return PM3_EMALLOC; + int res = searchFinalFile(foundpath, pm3dir, filename, silent); + if (res != PM3_SUCCESS) { + if ((res == PM3_EFILE) && (!silent)) + PrintAndLogEx(FAILED, "Error - can't find %s", filename); + free(filename); + return res; + } + free(filename); + return PM3_SUCCESS; +} diff --git a/client/loclass/fileutils.h b/client/fileutils.h similarity index 77% rename from client/loclass/fileutils.h rename to client/fileutils.h index 74d54000b..5432aa816 100644 --- a/client/loclass/fileutils.h +++ b/client/fileutils.h @@ -38,17 +38,16 @@ #ifndef FILEUTILS_H #define FILEUTILS_H -#ifndef ON_DEVICE - #include #include #include #include #include #include -#include "../ui.h" -#include "../emv/emvjson.h" +#include "ui.h" +#include "emv/emvjson.h" #include "mifare/mifare4.h" +#include "mifare/mifarehost.h" #include "cmdhfmfu.h" typedef enum { @@ -56,12 +55,20 @@ typedef enum { jsfCardMemory, jsfMfuMemory, jsfHitag, + jsfIclass, // jsf14b, // jsf15, // jsfLegic, // jsfT55xx, } JSONFileType; +typedef enum { + BIN = 0, + EML, + JSON, + DICTIONARY, +} DumpFileType_t; + int fileExists(const char *filename); /** @@ -103,7 +110,17 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t */ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen); -/** STUB +/** + * @brief Utility function to save a keydump. + * + * @param sectorsCnt the used sectors + * @param e_sector the keys in question + * @param fptr string pointer to the filename + * @return 0 for ok, 1 for failz + */ +int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr); + +/** * @brief Utility function to load data from a binary file. This method takes a preferred name. * E.g. dumpdata-15.bin * @@ -112,10 +129,22 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s * @param data The data array to store the loaded bytes from file * @param maxdatalen the number of bytes that your data array has * @param datalen the number of bytes loaded from file - * @return 0 for ok, 1 for failz + * @return PM3_SUCCESS for ok, PM3_E* for failz */ int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen); + +/** + * @brief Utility function to load data from a binary file. This method takes a preferred name. + * E.g. dumpdata-15.bin, tries to search for it, and allocated memory. + * + * @param preferredName + * @param suffix the file suffix. Including the ".". + * @param data The data array to store the loaded bytes from file + * @param datalen the number of bytes loaded from file + * @return PM3_SUCCESS for ok, PM3_E* for failz +*/ +int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen); /** * @brief Utility function to load data from a textfile (EML). This method takes a preferred name. * E.g. dumpdata-15.txt @@ -139,10 +168,9 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen); */ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen); - /** * @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name. - * E.g. default_keys.dic + * E.g. mfc_default_keys.dic * * @param preferredName * @param data The data array to store the loaded bytes from file @@ -153,6 +181,17 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ */ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +/** + * @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name. + * E.g. mfc_default_keys.dic + * + * @param preferredName + * @param pdata A pointer to a pointer (for reverencing the loaded dictionary) + * @param keylen the number of bytes a key per row is + * @return 0 for ok, 1 for failz +*/ +int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt); + /** * @brief Utility function to check and convert old mfu dump format to new * @@ -162,20 +201,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u */ int convertOldMfuDump(uint8_t **dump, size_t *dumplen); -#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args) -#else - -/** -* Utility function to print to console. This is used consistently within the library instead -* of printf, but it actually only calls printf. The reason to have this method is to -*make it simple to plug this library into proxmark, which has this function already to -* write also to a logfile. When doing so, just point this function to use PrintAndLog -* @param fmt -*/ -#define PrintAndLogEx(level, format, args...) { } - - - -#endif //ON_DEVICE +int searchAndList(const char *pm3dir, const char *ext); +int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent); #endif // FILEUTILS_H diff --git a/client/flash.c b/client/flash.c index 84e1d687b..5bbb669c0 100644 --- a/client/flash.c +++ b/client/flash.c @@ -83,7 +83,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t)); if (!ctx->segments) { PrintAndLogEx(ERR, "Out of memory"); - return -1; + return PM3_EMALLOC; } ctx->num_segs = 0; seg = ctx->segments; @@ -113,19 +113,19 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, if (filesz != memsz) { PrintAndLogEx(ERR, "Error: PHDR file size does not equal memory size\n" "(DATA+BSS PHDRs do not make sense on ROM platforms!)"); - return -1; + return PM3_EFILE; } if (paddr < last_end) { PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap"); - return -1; + return PM3_EFILE; } if (paddr < FLASH_START || (paddr + filesz) > flash_end) { PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash"); - return -1; + return PM3_EFILE; } if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) { PrintAndLogEx(ERR, "Error: Flash VMA segment is writable"); - return -1; + return PM3_EFILE; } uint8_t *data; @@ -133,12 +133,12 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t)); if (!data) { PrintAndLogEx(ERR, "Error: Out of memory"); - return -1; + return PM3_EMALLOC; } if (fseek(fd, offset, SEEK_SET) < 0 || fread(data, 1, filesz, fd) != filesz) { PrintAndLogEx(ERR, "Error while reading PHDR payload"); free(data); - return -1; + return PM3_EFILE; } uint32_t block_offset = paddr & (BLOCK_SIZE - 1); @@ -157,7 +157,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, if (!new_data) { PrintAndLogEx(ERR, "Error: Out of memory"); free(data); - return -1; + return PM3_EMALLOC; } memset(new_data, 0xff, new_length); memcpy(new_data, prev_seg->data, prev_seg->length); @@ -191,7 +191,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, last_end = paddr + filesz; phdr++; } - return 0; + return PM3_SUCCESS; } // Sanity check segments and check for bootloader writes @@ -201,26 +201,26 @@ static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) { if (seg->start & (BLOCK_SIZE - 1)) { PrintAndLogEx(ERR, "Error: Segment is not aligned"); - return -1; + return PM3_EFILE; } if (seg->start < FLASH_START) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); - return -1; + return PM3_EFILE; } if (seg->start + seg->length > flash_end) { PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds"); - return -1; + return PM3_EFILE; } if (!can_write_bl && seg->start < BOOTLOADER_END) { PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled"); - return -1; + return PM3_EINVARG; } if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) { PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds"); - return -1; + return PM3_EFILE; } } - return 0; + return PM3_SUCCESS; } // Load an ELF file and prepare it for flashing @@ -230,11 +230,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ Elf32_Phdr *phdrs = NULL; uint16_t num_phdrs; uint32_t flash_end = FLASH_START + flash_size; - int res; + int res = PM3_EUNDEF; fd = fopen(name, "rb"); if (!fd) { PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name); + res = PM3_EFILE; goto fail; } @@ -242,28 +243,34 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) { PrintAndLogEx(ERR, "Error while reading ELF file header"); + res = PM3_EFILE; goto fail; } if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident)) || le32(ehdr.e_version) != 1) { PrintAndLogEx(ERR, "Not an ELF file or wrong ELF type"); + res = PM3_EFILE; goto fail; } if (le16(ehdr.e_type) != ET_EXEC) { PrintAndLogEx(ERR, "ELF is not executable"); + res = PM3_EFILE; goto fail; } if (le16(ehdr.e_machine) != EM_ARM) { PrintAndLogEx(ERR, "Wrong ELF architecture"); + res = PM3_EFILE; goto fail; } if (!ehdr.e_phnum || !ehdr.e_phoff) { PrintAndLogEx(ERR, "ELF has no PHDRs"); + res = PM3_EFILE; goto fail; } if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) { // could be a structure padding issue... PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail"); + res = PM3_EFILE; goto fail; } num_phdrs = le16(ehdr.e_phnum); @@ -271,28 +278,31 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_ phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t)); if (!phdrs) { PrintAndLogEx(ERR, "Out of memory"); + res = PM3_EMALLOC; goto fail; } if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) { PrintAndLogEx(ERR, "Error while reading ELF PHDRs"); + res = PM3_EFILE; goto fail; } if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) { + res = PM3_EFILE; PrintAndLogEx(ERR, "Error while reading ELF PHDRs"); goto fail; } res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end); - if (res < 0) + if (res != PM3_SUCCESS) goto fail; res = check_segs(ctx, can_write_bl, flash_end); - if (res < 0) + if (res != PM3_SUCCESS) goto fail; free(phdrs); fclose(fd); ctx->filename = name; - return 0; + return PM3_SUCCESS; fail: if (phdrs) @@ -300,7 +310,7 @@ fail: if (fd) fclose(fd); flash_free(ctx); - return -1; + return res; } // Get the state of the proxmark, backwards compatible @@ -326,22 +336,23 @@ static int get_proxmark_state(uint32_t *state) { break; default: PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd); - return -1; + return PM3_EFATAL; break; } - return 0; + return PM3_SUCCESS; } // Enter the bootloader to be able to start flashing static int enter_bootloader(char *serial_port_name) { uint32_t state; + int ret; - if (get_proxmark_state(&state) < 0) - return -1; + if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS) + return ret; /* Already in flash state, we're done. */ if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) - return 0; + return PM3_SUCCESS; if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) { PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader...")); @@ -364,15 +375,15 @@ static int enter_bootloader(char *serial_port_name) { if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { PrintAndLogEx(NORMAL, " " _GREEN_("Found")); - return 0; + return PM3_SUCCESS; } else { PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found."); - return -1; + return PM3_ETIMEOUT; } } PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode"); - return -1; + return PM3_EFATAL; } static int wait_for_ack(PacketResponseNG *ack) { @@ -383,9 +394,9 @@ static int wait_for_ack(PacketResponseNG *ack) { ack->cmd, (ack->cmd == CMD_NACK) ? "NACK" : "" ); - return -1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } static void flash_suggest_update_bootloader(void) { @@ -401,12 +412,15 @@ static void flash_suggest_update_flasher(void) { int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) { uint32_t state; uint32_t chipinfo = 0; + int ret; - if (enter_bootloader(serial_port_name) < 0) - return -1; + ret = enter_bootloader(serial_port_name); + if (ret != PM3_SUCCESS) + return ret; - if (get_proxmark_state(&state) < 0) - return -1; + ret = get_proxmark_state(&state); + if (ret != PM3_SUCCESS) + return ret; if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) { SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0); @@ -485,7 +499,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command"))); flash_suggest_update_bootloader(); } - return 0; + return PM3_SUCCESS; } static int write_block(uint32_t address, uint8_t *data, uint32_t length) { @@ -531,7 +545,7 @@ int flash_write(flash_file_t *ctx) { if (write_block(baddr, data, block_size) < 0) { PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks); - return -1; + return PM3_EFATAL; } data += block_size; @@ -544,7 +558,7 @@ int flash_write(flash_file_t *ctx) { PrintAndLogEx(NORMAL, " " _GREEN_("OK")); fflush(stdout); } - return 0; + return PM3_SUCCESS; } // free a file context @@ -564,5 +578,5 @@ void flash_free(flash_file_t *ctx) { int flash_stop_flashing(void) { SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0); msleep(100); - return 0; + return PM3_SUCCESS; } diff --git a/client/flash.h b/client/flash.h index eca4d9ccc..23dd28079 100644 --- a/client/flash.h +++ b/client/flash.h @@ -11,6 +11,9 @@ #include "common.h" +#define FLASH_MAX_FILES 4 +#define ONE_KB 1024 + typedef struct { void *data; uint32_t start; diff --git a/client/flasher.c b/client/flasher.c deleted file mode 100644 index 931976997..000000000 --- a/client/flasher.c +++ /dev/null @@ -1,130 +0,0 @@ -//----------------------------------------------------------------------------- -// This code is licensed to you under the terms of the GNU GPL, version 2 or, -// at your option, any later version. See the LICENSE.txt file for the text of -// the license. -//----------------------------------------------------------------------------- -// Flasher frontend tool -//----------------------------------------------------------------------------- - -#include -#include -#include "usart_defs.h" -#include "flash.h" -#include "comms.h" -#include "ui.h" - -#define MAX_FILES 4 -#define ONE_KB 1024 - -static void usage(char *argv0) { - PrintAndLogEx(NORMAL, "Usage: %s [-b] image.elf [image.elf...]", argv0); - PrintAndLogEx(NORMAL, " %s -i\n", argv0); - PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)"); - PrintAndLogEx(NORMAL, "\t-i\tProbe the connected Proxmark3 to retrieve its memory size"); - PrintAndLogEx(NORMAL, "\nExamples:\n\t %s "SERIAL_PORT_EXAMPLE_H" -i", argv0); - PrintAndLogEx(NORMAL, "\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0); -#ifdef __linux__ - PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); - PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); - PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); - PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); - PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); -#endif -} - -int main(int argc, char **argv) { - int can_write_bl = 0; - int num_files = 0; - int res; - int ret = 0; - flash_file_t files[MAX_FILES]; - char *filenames[MAX_FILES]; - bool info = false; - memset(files, 0, sizeof(files)); - - session.supports_colors = false; - session.stdinOnTTY = isatty(STDIN_FILENO); - session.stdoutOnTTY = isatty(STDOUT_FILENO); -#if defined(__linux__) || (__APPLE__) - if (session.stdinOnTTY && session.stdoutOnTTY) - session.supports_colors = true; -#endif - session.help_dump_mode = false; - - if (argc < 3) { - usage(argv[0]); - return -1; - } - - for (int i = 2; i < argc; i++) { - if (argv[i][0] == '-') { - if (!strcmp(argv[i], "-b")) { - can_write_bl = 1; - } else if (!strcmp(argv[i], "-i")) { - info = true; - } else { - usage(argv[0]); - return -1; - } - } else { - filenames[num_files] = argv[i]; - num_files++; - } - } - - char *serial_port_name = argv[1]; - - if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { - PrintAndLogEx(NORMAL, _GREEN_("Found")); - } else { - PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); - return -1; - } - - uint32_t max_allowed = 0; - res = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed); - if (res < 0) { - ret = -1; - goto finish; - } - - if (info) - goto finish; - - for (int i = 0 ; i < num_files; ++i) { - res = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB); - if (res < 0) { - ret = -1; - goto finish; - } - PrintAndLogEx(NORMAL, ""); - } - - PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); - - for (int i = 0; i < num_files; i++) { - res = flash_write(&files[i]); - if (res < 0) { - ret = -1; - goto finish; - } - flash_free(&files[i]); - PrintAndLogEx(NORMAL, "\n"); - } - -finish: - res = flash_stop_flashing(); - if (res < 0) - ret = -1; - - CloseProxmark(); - - if (ret == 0) - PrintAndLogEx(SUCCESS, _BLUE_("All done.")); - else - PrintAndLogEx(ERR, "Aborted on error."); - PrintAndLogEx(NORMAL, "\nHave a nice day!"); - return ret; -} diff --git a/client/hardnested/hardnested_bruteforce.c b/client/hardnested/hardnested_bruteforce.c index 5f93d4811..3aea34a96 100644 --- a/client/hardnested/hardnested_bruteforce.c +++ b/client/hardnested/hardnested_bruteforce.c @@ -65,11 +65,13 @@ THE SOFTWARE. #include "util_posix.h" #include "crapto1/crapto1.h" #include "parity.h" +#include "fileutils.h" +#include "pm3_cmd.h" #define NUM_BRUTE_FORCE_THREADS (num_CPUs()) #define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed #define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark -#define TEST_BENCH_FILENAME "hardnested/bf_bench_data.bin" +#define TEST_BENCH_FILENAME "hardnested_bf_bench_data.bin" //#define WRITE_BENCH_FILE // debugging options @@ -265,8 +267,12 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) { #if defined (WRITE_BENCH_FILE) static void write_benchfile(statelist_t *candidates) { - printf("Writing brute force benchmark data..."); - FILE *benchfile = fopen(TEST_BENCH_FILENAME, "wb"); + PrintAndLogEx(NORMAL, "Writing brute force benchmark data in " RESOURCES_SUBDIR " subdirectory..."); + FILE *benchfile = fopen(RESOURCES_SUBDIR TEST_BENCH_FILENAME, "wb"); + if (benchfile == NULL) { + PrintAndLogEx(ERR, "Can't write " RESOURCES_SUBDIR TEST_BENCH_FILENAME", abort!"); + return; + } fwrite(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { fwrite(&(bf_test_nonce[i]), 1, sizeof(bf_test_nonce[i]), benchfile); @@ -283,7 +289,7 @@ static void write_benchfile(statelist_t *candidates) { fwrite(&(candidates->states[ODD_STATE][i]), 1, sizeof(uint32_t), benchfile); } fclose(benchfile); - printf("done.\n"); + PrintAndLogEx(NORMAL, "Done"); } #endif @@ -360,14 +366,17 @@ static bool read_bench_data(statelist_t *test_candidates) { uint32_t num_states = 0; uint32_t states_read = 0; - char bench_file_path[strlen(get_my_executable_directory()) + strlen(TEST_BENCH_FILENAME) + 1]; - strcpy(bench_file_path, get_my_executable_directory()); - strcat(bench_file_path, TEST_BENCH_FILENAME); - - FILE *benchfile = fopen(bench_file_path, "rb"); - if (benchfile == NULL) { + char *path; + if (searchFile(&path, RESOURCES_SUBDIR, TEST_BENCH_FILENAME, "", false) != PM3_SUCCESS) { return false; } + + FILE *benchfile = fopen(path, "rb"); + if (benchfile == NULL) { + free(path); + return false; + } + free(path); bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); if (bytes_read != sizeof(nonces_to_bruteforce)) { fclose(benchfile); diff --git a/client/jansson/Makefile b/client/jansson/Makefile index e06ffbc76..dc4ae230b 100644 --- a/client/jansson/Makefile +++ b/client/jansson/Makefile @@ -1,81 +1,21 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -include_HEADERS = jansson.h -nodist_include_HEADERS = jansson_config.h - -LIB_A = libjansson.a -libjansson_la_SOURCES = \ +MYSRCPATHS = +MYINCLUDES = -I. +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE -Wno-unused-function +MYDEFS = -DHAVE_STDINT_H +MYSRCS = \ dump.c \ error.c \ hashtable.c \ - hashtable.h \ hashtable_seed.c \ - jansson_private.h \ load.c \ - lookup3.h \ memory.c \ pack_unpack.c \ strbuffer.c \ - strbuffer.h \ strconv.c \ utf.c \ - utf.h \ path.c \ value.c -libjansson_la_LDFLAGS = \ - -no-undefined \ - -export-symbols-regex '^json_' \ - -version-info 15:0:11 +LIB_A = libjansson.a -CFILES = $(filter %.c, $(libjansson_la_SOURCES)) -CMDOBJS = $(CFILES:%.c=%.o) -CLEAN = $(CMDOBJS) - -platform = $(shell uname) - -CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function - -LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS) -LIBS= $(SYSLIBS) $(MYLIBS) -DEFAULT_INCLUDES = -I. -DEFS = -DHAVE_STDINT_H - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -TST= echo - -SYSLDFLAGS= -SYSLIBS= - -MYLIBS= -MYOBJS= - -$(LIB_A): $(CMDOBJS) - $(info [=] AR $@) - $(Q)$(AR) $(LIB_A) $(CMDOBJS) - $(Q)$(RANLIB) $(LIB_A) - -all: $(LIB_A) - -clean: - $(Q)$(RM) $(CLEAN) - $(Q)$(RM) $(LIB_A) - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS) - -.PHONY: all clean - +include ../../Makefile.host diff --git a/client/liblua/Makefile b/client/liblua/Makefile index 2b3d7614f..250f4b7ee 100644 --- a/client/liblua/Makefile +++ b/client/liblua/Makefile @@ -1,106 +1,27 @@ -# Makefile for building Lua -# See ../doc/readme.html for installation and customization instructions. +MYSRCPATHS = +MYINCLUDES = -I. +# Lua lib is not ready for C99 style... +#MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYCFLAGS = +MYDEFS = -DLUA_COMPAT_ALL $(SYSCFLAGS) +MYSRCS = lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \ + lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \ + ltm.c lundump.c lvm.c lzio.c \ + lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c \ + lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c -# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= +SYSCFLAGS= -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +LIB_A= liblua.a # Your platform. See PLATS for possible values. PLAT= none -platform= $(shell uname) - -CC= gcc -CFLAGS= -O3 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) -LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) -LIBS= -lm $(SYSLIBS) $(MYLIBS) - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rc -RANLIB= /usr/bin/ranlib -else -AR= ar rc -RANLIB= ranlib -endif -RM= rm -f - -SYSCFLAGS= -SYSLDFLAGS= -SYSLIBS= - -MYCFLAGS= -MYLDFLAGS= -MYLIBS= -MYOBJS= - -# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< - PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris -LUA_A= liblua.a -CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ - lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ - ltm.o lundump.o lvm.o lzio.o -LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ - lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o -BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) - -LUA_T= lua -LUA_O= lua.o - -LUAC_T= luac -LUAC_O= luac.o - -ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) -ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) -ALL_A= $(LUA_A) - -# Targets start here. default: $(PLAT) -all: $(ALL_T) - -o: $(ALL_O) - -a: $(ALL_A) - -$(LUA_A): $(BASE_O) - $(info [=] AR $@) - $(Q)$(AR) $@ $(BASE_O) - $(Q)$(RANLIB) $@ - -$(LUA_T): $(LUA_O) $(LUA_A) - $(info [=] LD $@) - $(Q)$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) - -$(LUAC_T): $(LUAC_O) $(LUA_A) - $(info [=] LD $@) - $(Q)$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) - -clean: - $(Q)$(RM) $(ALL_T) $(ALL_O) - -depend: - $(info GEN DEPS) - $(Q)$(CC) $(CFLAGS) -MM l*.c - -echo: - @echo "PLAT= $(PLAT)" - @echo "CC= $(CC)" - @echo "CFLAGS= $(CFLAGS)" - @echo "LDFLAGS= $(SYSLDFLAGS)" - @echo "LIBS= $(LIBS)" - @echo "AR= $(AR)" - @echo "RANLIB= $(RANLIB)" - @echo "RM= $(RM)" +include ../../Makefile.host # Convenience targets for popular platforms ALL= all @@ -110,99 +31,32 @@ none: @echo " $(PLATS)" aix: - $(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" + $(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" ansi: $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" bsd: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" freebsd: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" generic: $(ALL) linux: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -ltermcap -lncurses" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" macosx: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" mingw: - $(Q)$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ - "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ - "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe - $(Q)$(MAKE) "LUAC_T=luac.exe" luac.exe + $(Q)$(MAKE) $(ALL) posix: $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" solaris: - $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" - -# list targets that do not create files (but not all makes understand .PHONY) -.PHONY: all $(PLATS) default o a clean depend echo none - -# DO NOT DELETE - -lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ - lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ - lvm.h -lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h -lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h -lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h -lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ - lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ - lstring.h ltable.h lvm.h -lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h -lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h -ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h -ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ - ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ - lfunc.h lstring.h lgc.h ltable.h lvm.h -ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ - lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ - lstring.h ltable.h lundump.h lvm.h -ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ - lzio.h lmem.h lundump.h -lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ - lstate.h ltm.h lzio.h lmem.h -lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h -linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h -liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h -llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ - lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h -lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h -lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h lgc.h -loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h -lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ - lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h -lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h -loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h -lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ - lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ - lstring.h lgc.h ltable.h -lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ - ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ - ltable.h -lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ - ltm.h lzio.h lstring.h lgc.h -lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h -ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h -ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h -ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ - lmem.h lstring.h lgc.h ltable.h -lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h -luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ - ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h -lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h -lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h -lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ - lzio.h + $(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" +.PHONY: all $(PLATS) default clean depend none diff --git a/client/loclass/cipher.c b/client/loclass/cipher.c index 931f0c845..13f686b51 100644 --- a/client/loclass/cipher.c +++ b/client/loclass/cipher.c @@ -226,8 +226,8 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { reverse_arraybytes(dest, sizeof(dest)); memcpy(mac, dest, 4); //free(cc_nr); - return; } + void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]) { uint8_t *address_data; uint8_t div_key[8]; @@ -245,7 +245,6 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke reverse_arraybytes(dest, sizeof(dest)); memcpy(mac, dest, 4); free(address_data); - return; } #ifndef ON_DEVICE @@ -267,8 +266,8 @@ int testMAC() { PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:"); printarr(" Calculated_MAC", calculated_mac, 4); printarr(" Correct_MAC ", correct_MAC, 4); - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } #endif diff --git a/client/loclass/cipher.h b/client/loclass/cipher.h index b79dc47cd..7b1257aa5 100644 --- a/client/loclass/cipher.h +++ b/client/loclass/cipher.h @@ -39,6 +39,7 @@ #ifndef CIPHER_H #define CIPHER_H #include +#include "pm3_cmd.h" void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]); void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]); diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index b11f6883a..b50268697 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -39,7 +39,7 @@ #include #include #include - +#include "util.h" // sprint_hex #include "commonutil.h" // ARRAYLEN #include "fileutils.h" @@ -127,18 +127,21 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) { } return num; } + uint8_t reversebytes(uint8_t b) { b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; } + void reverse_arraybytes(uint8_t *arr, size_t len) { uint8_t i; for (i = 0; i < len ; i++) { arr[i] = reversebytes(arr[i]); } } + void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) { uint8_t i; for (i = 0; i < len ; i++) { @@ -160,23 +163,14 @@ void printarr(const char *name, uint8_t *arr, int len) { } void printvar(const char *name, uint8_t *arr, int len) { - int cx, i; - size_t outsize = 40 + strlen(name) + len * 2; - char *output = calloc(outsize, sizeof(char)); - cx = snprintf(output, outsize, "%s = ", name); - for (i = 0; i < len; i++) { - cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte - } - - PrintAndLogEx(NORMAL, output); - free(output); + PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len)); } void printarr_human_readable(const char *title, uint8_t *arr, int len) { - int cx, i; + int cx = 0, i; size_t outsize = 100 + strlen(title) + len * 4; char *output = calloc(outsize, sizeof(char)); - cx = snprintf(output, outsize, "\n\t%s\n", title); + PrintAndLogEx(NORMAL, "\n %s", title); for (i = 0; i < len; i++) { if (i % 16 == 0) cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i); @@ -211,9 +205,9 @@ static int testBitStream() { for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); } - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } static int testReversedBitstream() { @@ -241,9 +235,9 @@ static int testReversedBitstream() { for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); } - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } diff --git a/client/loclass/cipherutils.h b/client/loclass/cipherutils.h index 70438d33b..6c90326a6 100644 --- a/client/loclass/cipherutils.h +++ b/client/loclass/cipherutils.h @@ -41,6 +41,7 @@ #include #include #include +#include "pm3_cmd.h" typedef struct { uint8_t *buffer; diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index a4296f476..bf9aee5b3 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -475,11 +475,11 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) { memcpy(master_key, key64, 8); if (memcmp(z_0, result, 4) != 0) { - PrintAndLogEx(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong."); + PrintAndLogEx(WARNING, _RED_("Failed to verify") "calculated master key (k_cus)! Something is wrong."); return 1; } else { PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(SUCCESS, "Key verified ok!\n"); + PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!")); } return 0; } @@ -502,11 +502,19 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { for (i = 0 ; i * itemsize < dumpsize ; i++) { memcpy(attack, dump + i * itemsize, itemsize); errors += bruteforceItem(*attack, keytable); + if (errors) + break; } free(attack); t1 = msclock() - t1; PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000); + + if (errors) { + PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data"); + return 1; + } + // Pick out the first 16 bytes of the keytable. // The keytable is now in 16-bit ints, where the upper 8 bits // indicate crack-status. Those must be discarded for the @@ -516,8 +524,10 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { for (i = 0 ; i < 16 ; i++) { first16bytes[i] = keytable[i] & 0xFF; - if (!(keytable[i] & CRACKED)) + if (!(keytable[i] & CRACKED)) { PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); + return 1; + } } errors += calculateMasterKey(first16bytes, NULL); return errors; @@ -530,37 +540,14 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { * @return */ int bruteforceFile(const char *filename, uint16_t keytable[]) { - FILE *f = fopen(filename, "rb"); - if (!f) { - PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename); - return 1; + + size_t dumplen = 0; + uint8_t *dump = NULL; + if (loadFile_safe(filename, "", (void **)&dump, &dumplen) != PM3_SUCCESS) { + return PM3_EFILE; } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - if (fsize <= 0) { - PrintAndLogEx(ERR, "Error, when getting filesize"); - fclose(f); - return 1; - } - - uint8_t *dump = calloc(fsize, sizeof(uint8_t)); - if (!dump) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - fclose(f); - return 2; - } - size_t bytes_read = fread(dump, 1, fsize, f); - - fclose(f); - - if (bytes_read < fsize) { - PrintAndLogEx(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize); - } - - uint8_t res = bruteforceDump(dump, fsize, keytable); + uint8_t res = bruteforceDump(dump, dumplen, keytable); free(dump); return res; } @@ -582,39 +569,30 @@ int bruteforceFileNoKeys(const char *filename) { // TEST CODE BELOW // ---------------------------------------------------------------------------- static int _testBruteforce() { - int errors = 0; - if (true) { - // First test - PrintAndLogEx(INFO, "Testing crack from dumpfile..."); - /** - Expected values for the dumpfile: - High Security Key Table + PrintAndLogEx(INFO, "Testing crack from dumpfile..."); - 00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1 - 10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21 - 20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2 - 30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C - 40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6 - 50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42 - 60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95 - 70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB + /** + Expected values for the dumpfile: + High Security Key Table - **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 **** - **/ - uint16_t keytable[128] = {0}; + 00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1 + 10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21 + 20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2 + 30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C + 40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6 + 50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42 + 60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95 + 70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB - //Test a few variants - if (fileExists("iclass_dump.bin")) { - errors |= bruteforceFile("iclass_dump.bin", keytable); - } else if (fileExists("loclass/iclass_dump.bin")) { - errors |= bruteforceFile("loclass/iclass_dump.bin", keytable); - } else if (fileExists("client/loclass/iclass_dump.bin")) { - errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable); - } else { - PrintAndLogEx(ERR, "Error: The file iclass_dump.bin was not found!"); - } + **** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 **** + **/ + uint16_t keytable[128] = {0}; + int errors = bruteforceFile("iclass_dump.bin", keytable); + if (errors) { + PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!"); } + return errors; } diff --git a/client/loclass/ikeys.c b/client/loclass/ikeys.c index 53f7848de..f14e43eaf 100644 --- a/client/loclass/ikeys.c +++ b/client/loclass/ikeys.c @@ -654,33 +654,21 @@ static int doTestsWithKnownInputs() { return errors; } -static bool readKeyFile(uint8_t key[8]) { - bool retval = false; - //Test a few variants - char filename[30] = {0}; +static bool readKeyFile(uint8_t *key, size_t keylen) { - if (fileExists("iclass_key.bin")) { - sprintf(filename, "%s.bin", "iclass_key"); - } else if (fileExists("loclass/iclass_key.bin")) { - sprintf(filename, "%s.bin", "loclass/iclass_key"); - } else if (fileExists("client/loclass/iclass_key.bin")) { - sprintf(filename, "%s.bin", "client/loclass/iclass_key"); + size_t len = 0; + uint8_t *keyptr = NULL; + if (loadFile_safe("iclass_key.bin", "", (void **)&keyptr, &len) != PM3_SUCCESS) { + return false; } - if (strlen(filename) == 0) - return retval; + if (keylen != len) { + return false; + } - FILE *f = fopen(filename, "rb"); - if (!f) - return retval; - - size_t bytes_read = fread(key, sizeof(uint8_t), 8, f); - if (bytes_read == 8) - retval = true; - - fclose(f); - return retval; + memcpy(key, keyptr, keylen); + return true; } int doKeyTests(uint8_t debuglevel) { @@ -688,7 +676,7 @@ int doKeyTests(uint8_t debuglevel) { PrintAndLogEx(INFO, "Checking if the master key is present (iclass_key.bin)..."); uint8_t key[8] = {0}; - if (!readKeyFile(key)) { + if (readKeyFile(key, sizeof(key)) == false) { PrintAndLogEx(FAILED, "Master key not present, will not be able to do all testcases"); } else { diff --git a/client/loclass/loclass_information.txt b/client/loclass/loclass_information.txt deleted file mode 100644 index 307d28203..000000000 --- a/client/loclass/loclass_information.txt +++ /dev/null @@ -1,12 +0,0 @@ -2017-08-19 iceman, - -iclass_dump.bin -=============== -The file iclass_dump.bin contains CSN's mac results from 128 CSNs. -Hence when running the test mode, - 'hf iclass loclass t' -it shows a long output from the bruteforce test. - -iclass_key.bin -============== -The file iclass_key.bin is where you add the AA1 master key in order for the proxmark3 client to use it with the loclass commands diff --git a/client/scripts/14araw.lua b/client/luascripts/14araw.lua similarity index 100% rename from client/scripts/14araw.lua rename to client/luascripts/14araw.lua diff --git a/client/scripts/Legic_clone.lua b/client/luascripts/Legic_clone.lua similarity index 100% rename from client/scripts/Legic_clone.lua rename to client/luascripts/Legic_clone.lua diff --git a/client/scripts/amiibo.lua b/client/luascripts/amiibo.lua similarity index 100% rename from client/scripts/amiibo.lua rename to client/luascripts/amiibo.lua diff --git a/client/scripts/brutesim.lua b/client/luascripts/brutesim.lua similarity index 100% rename from client/scripts/brutesim.lua rename to client/luascripts/brutesim.lua diff --git a/client/scripts/calc_di.lua b/client/luascripts/calc_di.lua similarity index 100% rename from client/scripts/calc_di.lua rename to client/luascripts/calc_di.lua diff --git a/client/scripts/calc_ev1_it.lua b/client/luascripts/calc_ev1_it.lua similarity index 100% rename from client/scripts/calc_ev1_it.lua rename to client/luascripts/calc_ev1_it.lua diff --git a/client/scripts/calc_mizip.lua b/client/luascripts/calc_mizip.lua similarity index 100% rename from client/scripts/calc_mizip.lua rename to client/luascripts/calc_mizip.lua diff --git a/client/scripts/calypso.lua b/client/luascripts/calypso.lua similarity index 100% rename from client/scripts/calypso.lua rename to client/luascripts/calypso.lua diff --git a/client/scripts/cmdline.lua b/client/luascripts/cmdline.lua old mode 100644 new mode 100755 similarity index 82% rename from client/scripts/cmdline.lua rename to client/luascripts/cmdline.lua index dc1e752c1..baa76eed6 --- a/client/scripts/cmdline.lua +++ b/client/luascripts/cmdline.lua @@ -1,5 +1,8 @@ +#!/usr/bin/env -S pm3 -l + --[[ A sampe script file on how to implement at cmd line inteface. +It also demonstrates how the script can be used with a shebang. --]] print("This is how a cmd-line interface could be implemented\nPrint 'exit' to exit.\n") diff --git a/client/scripts/didump.lua b/client/luascripts/didump.lua similarity index 100% rename from client/scripts/didump.lua rename to client/luascripts/didump.lua diff --git a/client/scripts/dumptoemul-mfu.lua b/client/luascripts/dumptoemul-mfu.lua similarity index 100% rename from client/scripts/dumptoemul-mfu.lua rename to client/luascripts/dumptoemul-mfu.lua diff --git a/client/scripts/dumptoemul.lua b/client/luascripts/dumptoemul.lua similarity index 100% rename from client/scripts/dumptoemul.lua rename to client/luascripts/dumptoemul.lua diff --git a/client/scripts/e.lua b/client/luascripts/e.lua similarity index 100% rename from client/scripts/e.lua rename to client/luascripts/e.lua diff --git a/client/scripts/emul2dump.lua b/client/luascripts/emul2dump.lua similarity index 100% rename from client/scripts/emul2dump.lua rename to client/luascripts/emul2dump.lua diff --git a/client/scripts/emul2html.lua b/client/luascripts/emul2html.lua similarity index 100% rename from client/scripts/emul2html.lua rename to client/luascripts/emul2html.lua diff --git a/client/scripts/formatMifare.lua b/client/luascripts/formatMifare.lua similarity index 100% rename from client/scripts/formatMifare.lua rename to client/luascripts/formatMifare.lua diff --git a/client/scripts/hf_read.lua b/client/luascripts/hf_read.lua similarity index 100% rename from client/scripts/hf_read.lua rename to client/luascripts/hf_read.lua diff --git a/client/scripts/htmldump.lua b/client/luascripts/htmldump.lua similarity index 100% rename from client/scripts/htmldump.lua rename to client/luascripts/htmldump.lua diff --git a/client/scripts/iso15_magic.lua b/client/luascripts/iso15_magic.lua similarity index 100% rename from client/scripts/iso15_magic.lua rename to client/luascripts/iso15_magic.lua diff --git a/client/scripts/legic.lua b/client/luascripts/legic.lua similarity index 100% rename from client/scripts/legic.lua rename to client/luascripts/legic.lua diff --git a/client/scripts/legic_buffer2card.lua b/client/luascripts/legic_buffer2card.lua similarity index 100% rename from client/scripts/legic_buffer2card.lua rename to client/luascripts/legic_buffer2card.lua diff --git a/client/scripts/lf_bulk.lua b/client/luascripts/lf_bulk.lua similarity index 100% rename from client/scripts/lf_bulk.lua rename to client/luascripts/lf_bulk.lua diff --git a/client/scripts/mfkeys.lua b/client/luascripts/mfckeys.lua similarity index 96% rename from client/scripts/mfkeys.lua rename to client/luascripts/mfckeys.lua index f15bb6d5e..128967c37 100644 --- a/client/scripts/mfkeys.lua +++ b/client/luascripts/mfckeys.lua @@ -9,7 +9,7 @@ Copyright (C) 2013 m h swende --]] local cmds = require('commands') -local keylist = require('mf_default_keys') +local keylist = require('mfc_default_keys') local lib14a = require('read14a') local getopt = require('getopt') local utils = require('utils') @@ -19,9 +19,9 @@ author = "Holiman" version = 'v1.0.1' desc = ("This script implements Mifare check keys.\ It utilises a large list of default keys (currently %d keys).\ -If you want to add more, just put them inside /lualibs/mf_default_keys.lua\n"):format(#keylist) +If you want to add more, just put them inside /lualibs/mfc_default_keys.lua\n"):format(#keylist) example = [[ - 1. script run mfkeys + 1. script run mfckeys ]] usage = [[ Arguments: @@ -54,7 +54,7 @@ end -- waits for answer from pm3 device local function checkCommand(response) if not response then - print("Timeout while waiting for response. Increase TIMEOUT in mfkeys.lua to wait longer") + print("Timeout while waiting for response. Increase TIMEOUT in mfckeys.lua to wait longer") return nil, "Timeout while waiting for device to respond" end @@ -230,7 +230,7 @@ local function perform_check(numsectors) local end_time = os.time() print('') - print('[+] mfkeys - Checkkey execution time: '..os.difftime(end_time, start_time)..' sec') + print('[+] mfckeys - Checkkey execution time: '..os.difftime(end_time, start_time)..' sec') core.fast_push_mode(false) diff --git a/client/scripts/mifare_access.lua b/client/luascripts/mifare_access.lua similarity index 100% rename from client/scripts/mifare_access.lua rename to client/luascripts/mifare_access.lua diff --git a/client/scripts/mifare_autopwn.lua b/client/luascripts/mifare_autopwn.lua similarity index 100% rename from client/scripts/mifare_autopwn.lua rename to client/luascripts/mifare_autopwn.lua diff --git a/client/scripts/mifareplus.lua b/client/luascripts/mifareplus.lua similarity index 100% rename from client/scripts/mifareplus.lua rename to client/luascripts/mifareplus.lua diff --git a/client/scripts/ndef_dump.lua b/client/luascripts/ndef_dump.lua similarity index 100% rename from client/scripts/ndef_dump.lua rename to client/luascripts/ndef_dump.lua diff --git a/client/scripts/ntag_3d.lua b/client/luascripts/ntag_3d.lua similarity index 99% rename from client/scripts/ntag_3d.lua rename to client/luascripts/ntag_3d.lua index ff2c68d0f..869590cf2 100644 --- a/client/scripts/ntag_3d.lua +++ b/client/luascripts/ntag_3d.lua @@ -223,7 +223,7 @@ local function configure_magic_ntag(uid) -- -p == set pwd -- -a == set pack args =('-t 12 -u %s -p %08X -a %04X'):format(uid, pwd, pack) - require('../scripts/mfu_magic') + require('mfu_magic') -- Set back args. Not that it's used, just for the karma... args = myargs diff --git a/client/scripts/parameters.lua b/client/luascripts/parameters.lua similarity index 100% rename from client/scripts/parameters.lua rename to client/luascripts/parameters.lua diff --git a/client/scripts/read_pwd_mem.lua b/client/luascripts/read_pwd_mem.lua similarity index 100% rename from client/scripts/read_pwd_mem.lua rename to client/luascripts/read_pwd_mem.lua diff --git a/client/scripts/remagic.lua b/client/luascripts/remagic.lua similarity index 100% rename from client/scripts/remagic.lua rename to client/luascripts/remagic.lua diff --git a/client/scripts/test_t55x7.lua b/client/luascripts/test_t55x7.lua similarity index 100% rename from client/scripts/test_t55x7.lua rename to client/luascripts/test_t55x7.lua diff --git a/client/scripts/test_t55x7_ask.lua b/client/luascripts/test_t55x7_ask.lua similarity index 100% rename from client/scripts/test_t55x7_ask.lua rename to client/luascripts/test_t55x7_ask.lua diff --git a/client/scripts/test_t55x7_bi.lua b/client/luascripts/test_t55x7_bi.lua similarity index 100% rename from client/scripts/test_t55x7_bi.lua rename to client/luascripts/test_t55x7_bi.lua diff --git a/client/scripts/test_t55x7_fsk.lua b/client/luascripts/test_t55x7_fsk.lua similarity index 100% rename from client/scripts/test_t55x7_fsk.lua rename to client/luascripts/test_t55x7_fsk.lua diff --git a/client/scripts/test_t55x7_psk.lua b/client/luascripts/test_t55x7_psk.lua similarity index 100% rename from client/scripts/test_t55x7_psk.lua rename to client/luascripts/test_t55x7_psk.lua diff --git a/client/scripts/tnp3clone.lua b/client/luascripts/tnp3clone.lua similarity index 100% rename from client/scripts/tnp3clone.lua rename to client/luascripts/tnp3clone.lua diff --git a/client/scripts/tnp3dump.lua b/client/luascripts/tnp3dump.lua similarity index 100% rename from client/scripts/tnp3dump.lua rename to client/luascripts/tnp3dump.lua diff --git a/client/scripts/tnp3sim.lua b/client/luascripts/tnp3sim.lua similarity index 100% rename from client/scripts/tnp3sim.lua rename to client/luascripts/tnp3sim.lua diff --git a/client/scripts/tracetest.lua b/client/luascripts/tracetest.lua similarity index 100% rename from client/scripts/tracetest.lua rename to client/luascripts/tracetest.lua diff --git a/client/scripts/ufodump.lua b/client/luascripts/ufodump.lua similarity index 100% rename from client/scripts/ufodump.lua rename to client/luascripts/ufodump.lua diff --git a/client/scripts/ul_uid.lua b/client/luascripts/ul_uid.lua similarity index 100% rename from client/scripts/ul_uid.lua rename to client/luascripts/ul_uid.lua diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index f7c7ce4f2..429605a4e 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -209,7 +209,8 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // initialize storage for found keys icesector_t *tmp = calloc(sectorsCnt, sizeof(icesector_t)); if (tmp == NULL) - return 1; + return PM3_EMALLOC; + memcpy(tmp, resp.data.asBytes, sectorsCnt * sizeof(icesector_t)); for (int i = 0; i < sectorsCnt; i++) { @@ -227,11 +228,11 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, free(tmp); if (curr_keys == sectorsCnt * 2) - return 0; + return PM3_SUCCESS; if (lastChunk) - return 1; + return PM3_ESOFT; } - return 1; + return PM3_ESOFT; } // PM3 imp of J-Run mf_key_brute (part 2) @@ -1041,6 +1042,9 @@ void detect_classic_magic(void) { case 4: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES")); break; + case 5: + PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES")); + break; default: PrintAndLogEx(INFO, "Answers to magic commands: " _YELLOW_("NO")); break; diff --git a/client/obj/.dummy b/client/obj/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/amiitool/.dummy b/client/obj/amiitool/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/cliparser/.dummy b/client/obj/cliparser/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/crapto1/.dummy b/client/obj/crapto1/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/crypto/.dummy b/client/obj/crypto/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/emv/.dummy b/client/obj/emv/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/emv/test/.dummy b/client/obj/emv/test/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/fido/.dummy b/client/obj/fido/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/hardnested/.dummy b/client/obj/hardnested/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/jansson/.dummy b/client/obj/jansson/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/loclass/.dummy b/client/obj/loclass/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/mifare/.dummy b/client/obj/mifare/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/nonce2key/.dummy b/client/obj/nonce2key/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/obj/reveng/.gitignore b/client/obj/reveng/.gitignore deleted file mode 100644 index 07669e14a..000000000 --- a/client/obj/reveng/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# .gitignore -# don't push these files to the repository - -*.log -*.eml -*.o -*.a -*.d -*.elf -*.s19 -*.map -*.bin -*.dll -*.moc.cpp -*.exe -proxmark -proxmark3 -flasher -version.c -lua -luac - -fpga/* -!fpga/tests -!fpga/fpga_lf.bit -!fpga/fpga_hf.bit -!fpga/*.v -!fpga/Makefile -!fpga/fpga.ucf -!fpga/xst_lf.scr -!fpga/xst_hf.scr -!fpga/go.bat -!fpga/sim.tcl - - diff --git a/client/platforms/.gitignore b/client/platforms/.gitignore deleted file mode 100644 index 07669e14a..000000000 --- a/client/platforms/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -# .gitignore -# don't push these files to the repository - -*.log -*.eml -*.o -*.a -*.d -*.elf -*.s19 -*.map -*.bin -*.dll -*.moc.cpp -*.exe -proxmark -proxmark3 -flasher -version.c -lua -luac - -fpga/* -!fpga/tests -!fpga/fpga_lf.bit -!fpga/fpga_hf.bit -!fpga/*.v -!fpga/Makefile -!fpga/fpga.ucf -!fpga/xst_lf.scr -!fpga/xst_hf.scr -!fpga/go.bat -!fpga/sim.tcl - - diff --git a/client/proxguiqt.cpp b/client/proxguiqt.cpp index 344f48b03..6bf99f5a1 100644 --- a/client/proxguiqt.cpp +++ b/client/proxguiqt.cpp @@ -535,7 +535,7 @@ void Plot::paintEvent(QPaintEvent *event) { sprintf(str, "@%d dt=%d [%2.2f] zoom=%2.2f CursorAPos=%d CursorBPos=%d GridX=%d GridY=%d (%s) GridXoffset=%d", GraphStart, CursorBPos - CursorAPos, - (CursorBPos - CursorAPos) / CursorScaleFactor, + ((int32_t)(CursorBPos - CursorAPos)) / CursorScaleFactor, GraphPixelsPerPoint, CursorAPos, CursorBPos, diff --git a/client/proxmark3.c b/client/proxmark3.c index de6fe43af..2ff94b841 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -8,18 +8,15 @@ //----------------------------------------------------------------------------- // Main binary //----------------------------------------------------------------------------- + #include "proxmark3.h" - #include - #include // for Mingw readline #include #include #include #include - #include "usart_defs.h" - #include "util_posix.h" #include "proxgui.h" #include "cmdmain.h" @@ -27,11 +24,13 @@ #include "cmdhw.h" #include "whereami.h" #include "comms.h" -//#include "usart.h" +#include "fileutils.h" +#include "flash.h" + static void showBanner(void) { PrintAndLogEx(NORMAL, "\n"); -#if defined(__linux__) || (__APPLE__) +#if defined(__linux__) || (__APPLE__) || (_WIN32) PrintAndLogEx(NORMAL, _BLUE_("██████╗ ███╗ ███╗ ████╗ ") " ...iceman fork"); PrintAndLogEx(NORMAL, _BLUE_("██╔══██╗████╗ ████║ ══█║") " ...dedicated to " _BLUE_("RDV40")); PrintAndLogEx(NORMAL, _BLUE_("██████╔╝██╔████╔██║ ████╔╝")); @@ -46,7 +45,8 @@ static void showBanner(void) { PrintAndLogEx(NORMAL, "==. ==. ... ==. ====.. https://github.com/rfidresearchgroup/proxmark3/"); PrintAndLogEx(NORMAL, "... ... ... ..... pre-release v4.0"); #endif - PrintAndLogEx(NORMAL, "\nSupport iceman on patreon, https://www.patreon.com/iceman1001/"); + PrintAndLogEx(NORMAL, "\nSupport iceman on patreon - https://www.patreon.com/iceman1001/"); + PrintAndLogEx(NORMAL, " on paypal - https://www.paypal.me/iceman1001"); // printf("\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP"); PrintAndLogEx(NORMAL, "\n"); fflush(stdout); @@ -63,6 +63,38 @@ int check_comm(void) { return 0; } +// first slot is always NULL, indicating absence of script when idx=0 +FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0}; +uint8_t cmdscriptfile_idx = 0; +bool cmdscriptfile_stayafter = false; + +int push_cmdscriptfile(char *path, bool stayafter) { + if (cmdscriptfile_idx == MAX_NESTED_CMDSCRIPT) { + PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", path); + return PM3_EMALLOC; + } + FILE *tmp = fopen(path, "r"); + if (tmp == NULL) + return PM3_EFILE; + if (cmdscriptfile_idx == 0) + cmdscriptfile_stayafter = stayafter; + cmdscriptfile[++cmdscriptfile_idx] = tmp; + return PM3_SUCCESS; +} + +FILE *current_cmdscriptfile() { + return cmdscriptfile[cmdscriptfile_idx]; +} + +bool pop_cmdscriptfile() { + fclose(cmdscriptfile[cmdscriptfile_idx]); + cmdscriptfile[cmdscriptfile_idx--] = NULL; + if (cmdscriptfile_idx == 0) + return cmdscriptfile_stayafter; + else + return true; +} + // Main thread of PM3 Client void #ifdef __has_attribute @@ -80,7 +112,6 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { strcreplace(script_cmd, script_cmd_len, ';', '\0'); } bool stdinOnPipe = !isatty(STDIN_FILENO); - FILE *sf = NULL; char script_cmd_buf[256] = {0x00}; // iceman, needs lua script the same file_path_buffer as the rest PrintAndLogEx(DEBUG, "ISATTY/STDIN_FILENO == %s\n", (stdinOnPipe) ? "true" : "false"); @@ -88,36 +119,48 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { if (session.pm3_present) { // cache Version information now: if (execCommand || script_cmds_file || stdinOnPipe) - pm3_version(false); + pm3_version(false, false); else - pm3_version(true); + pm3_version(true, false); } if (script_cmds_file) { - sf = fopen(script_cmds_file, "r"); - if (sf) - PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", script_cmds_file); - else - PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_cmds_file); + char *path; + int res = searchFile(&path, CMD_SCRIPTS_SUBDIR, script_cmds_file, ".cmd", false); + if (res == PM3_SUCCESS) { + if (push_cmdscriptfile(path, stayInCommandLoop) == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", path); + else + PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", path); + free(path); + } } - read_history(".history"); - + char *my_history_path = NULL; + if (searchHomeFilePath(&my_history_path, PROXHISTORY, true) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "No history will be recorded"); + my_history_path = NULL; + } else { + read_history(my_history_path); + } // loops every time enter is pressed... while (1) { bool printprompt = false; + char *prompt = PROXPROMPT; +check_script: // If there is a script file - if (sf) { + if (current_cmdscriptfile()) { // clear array memset(script_cmd_buf, 0, sizeof(script_cmd_buf)); // read script file - if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), sf)) { - fclose(sf); - sf = NULL; + if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile())) { + if (!pop_cmdscriptfile()) + break; + goto check_script; } else { // remove linebreaks @@ -161,12 +204,12 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { rl_event_hook = check_comm; if (session.pm3_present) { if (conn.send_via_fpc_usart == false) - cmd = readline(PROXPROMPT_USB); + prompt = PROXPROMPT_USB; else - cmd = readline(PROXPROMPT_FPC); + prompt = PROXPROMPT_FPC; } else - cmd = readline(PROXPROMPT_OFFLINE); - + prompt = PROXPROMPT_OFFLINE; + cmd = readline(prompt); fflush(NULL); } } @@ -189,15 +232,20 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { cmd[strlen(cmd) - off] = '\0'; if (cmd[0] != '\0') { - if (printprompt) - PrintAndLogEx(NORMAL, PROXPROMPT"%s", cmd); + if (!printprompt) + g_printAndLog = PRINTANDLOG_LOG; + PrintAndLogEx(NORMAL, "%s%s", prompt, cmd); + g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; + // add to history if not from a script + if (!current_cmdscriptfile()) { + HIST_ENTRY *entry = history_get(history_length); + // add if not identical to latest recorded cmd + if ((!entry) || (strcmp(entry->line, cmd) != 0)) + add_history(cmd); + } + // process cmd int ret = CommandReceived(cmd); - - HIST_ENTRY *entry = history_get(history_length); - if ((!entry) || (strcmp(entry->line, cmd) != 0)) - add_history(cmd); - // exit or quit if (ret == PM3_EFATAL) break; @@ -217,11 +265,13 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { SendCommandNG(CMD_QUIT_SESSION, NULL, 0); msleep(100); // Make sure command is sent before killing client - if (sf) - fclose(sf); - - write_history(".history"); + while (current_cmdscriptfile()) + pop_cmdscriptfile(); + if (my_history_path) { + write_history(my_history_path); + free(my_history_path); + } if (cmd) { free(cmd); cmd = NULL; @@ -265,40 +315,155 @@ static void set_my_executable_path(void) { } } +static char *my_user_directory = NULL; + +const char *get_my_user_directory(void) { + return my_user_directory; +} + +static void set_my_user_directory(void) { + my_user_directory = getenv("HOME"); + // if not found, default to current directory + if (my_user_directory == NULL) + my_user_directory = "."; +} + static void show_help(bool showFullHelp, char *exec_name) { - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "syntax: %s [-h|-t|-m]\n", exec_name); - PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i]\n", exec_name); + PrintAndLogEx(NORMAL, "\nsyntax: %s [-h|-t|-m]", exec_name); + PrintAndLogEx(NORMAL, " %s [[-p] ] [-b] [-w] [-f] [-c ]|[-l ]|[-s ] [-i] [-d <0|1|2>]", exec_name); + PrintAndLogEx(NORMAL, " %s [-p] --flash [--unlock-bootloader] [--image ]+ [-w] [-f] [-d <0|1|2>]", exec_name); if (showFullHelp) { - PrintAndLogEx(NORMAL, "options:"); + + PrintAndLogEx(NORMAL, "\nCommon options:"); PrintAndLogEx(NORMAL, " -h/--help this help"); - PrintAndLogEx(NORMAL, " -t/--text dump all interactive command's help at once"); - PrintAndLogEx(NORMAL, " -m/--markdown dump all interactive help at once in markdown syntax"); + PrintAndLogEx(NORMAL, " -v/--version print client version"); PrintAndLogEx(NORMAL, " -p/--port serial port to connect to"); - PrintAndLogEx(NORMAL, " -b/--baud serial port speed (only needed for physical UART, not for USB-CDC or BT)"); PrintAndLogEx(NORMAL, " -w/--wait 20sec waiting the serial port to appear in the OS"); PrintAndLogEx(NORMAL, " -f/--flush output will be flushed after every print"); + PrintAndLogEx(NORMAL, " -d/--debug <0|1|2> set debugmode"); + PrintAndLogEx(NORMAL, "\nOptions in client mode:"); + PrintAndLogEx(NORMAL, " -t/--text dump all interactive command's help at once"); + PrintAndLogEx(NORMAL, " -m/--markdown dump all interactive help at once in markdown syntax"); + PrintAndLogEx(NORMAL, " -b/--baud serial port speed (only needed for physical UART, not for USB-CDC or BT)"); PrintAndLogEx(NORMAL, " -c/--command execute one Proxmark3 command (or several separated by ';')."); PrintAndLogEx(NORMAL, " -l/--lua execute lua script."); PrintAndLogEx(NORMAL, " -s/--script-file script file with one Proxmark3 command per line"); PrintAndLogEx(NORMAL, " -i/--interactive enter interactive mode after executing the script or the command"); - PrintAndLogEx(NORMAL, "\nsamples:"); - PrintAndLogEx(NORMAL, " %s -h\n", exec_name); - PrintAndLogEx(NORMAL, " %s -m\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -f -- flush output everytime\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -w -- wait for serial port\n", exec_name); - PrintAndLogEx(NORMAL, "\n how to run Proxmark3 client\n"); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -- runs the pm3 client\n", exec_name); - PrintAndLogEx(NORMAL, " %s -- runs the pm3 client in OFFLINE mode\n", exec_name); - PrintAndLogEx(NORMAL, "\n how to execute different commands from terminal\n"); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -c \"hf mf chk 1* ?\" -- execute cmd and quit client\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -l hf_read -- execute lua script " _YELLOW_("`hf_read`")"and quit client\n", exec_name); - PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -s mycmds.txt -- execute each pm3 cmd in file and quit client\n", exec_name); + PrintAndLogEx(NORMAL, "\nOptions in flasher mode:"); + PrintAndLogEx(NORMAL, " --flash flash Proxmark3, requires at least one --image"); + PrintAndLogEx(NORMAL, " --unlock-bootloader Enable flashing of bootloader area *DANGEROUS* (need --flash or --flash-info)"); + PrintAndLogEx(NORMAL, " --image image to flash. Can be specified several times."); + PrintAndLogEx(NORMAL, "\nExamples:"); + PrintAndLogEx(NORMAL, "\n to run Proxmark3 client:\n"); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -- runs the pm3 client", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -f -- flush output everytime", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -w -- wait for serial port", exec_name); + PrintAndLogEx(NORMAL, " %s -- runs the pm3 client in OFFLINE mode", exec_name); + PrintAndLogEx(NORMAL, "\n to execute different commands from terminal:\n"); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -c \"hf mf chk 1* ?\" -- execute cmd and quit client", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -l hf_read -- execute lua script " _YELLOW_("`hf_read`")"and quit client", exec_name); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" -s mycmds.txt -- execute each pm3 cmd in file and quit client", exec_name); + PrintAndLogEx(NORMAL, "\n to flash fullimage and bootloader:\n"); + PrintAndLogEx(NORMAL, " %s "SERIAL_PORT_EXAMPLE_H" --flash --unlock-bootloader --image bootrom.elf --image fullimage.elf", exec_name); +#ifdef __linux__ + PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on ',"); + PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:"); + PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md"); + PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux"); + PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n"); +#endif } } +static int flash_pm3(char *serial_port_name, uint8_t num_files, char *filenames[FLASH_MAX_FILES], bool can_write_bl) { + + int ret = PM3_EUNDEF; + flash_file_t files[FLASH_MAX_FILES]; + memset(files, 0, sizeof(files)); + char *filepaths[FLASH_MAX_FILES]; + + if (serial_port_name == NULL) { + PrintAndLogEx(ERR, "You must specify a port.\n"); + return PM3_EINVARG; + } + + for (int i = 0 ; i < num_files; ++i) { + char *path; + ret = searchFile(&path, FIRMWARES_SUBDIR, filenames[i], ".elf", true); + if (ret != PM3_SUCCESS) { + ret = searchFile(&path, BOOTROM_SUBDIR, filenames[i], ".elf", true); + } + if (ret != PM3_SUCCESS) { + // Last try, let the error msg be displayed if not found + ret = searchFile(&path, FULLIMAGE_SUBDIR, filenames[i], ".elf", false); + } + if (ret != PM3_SUCCESS) { + goto finish2; + } + filepaths[i] = path; + } + + PrintAndLogEx(SUCCESS, "About to use the following file%s:", num_files > 1 ? "s" : ""); + for (int i = 0 ; i < num_files; ++i) { + PrintAndLogEx(SUCCESS, " %s", filepaths[i]); + } + + if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) { + PrintAndLogEx(NORMAL, _GREEN_("Found")); + } else { + PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); + ret = PM3_ETIMEOUT; + goto finish2; + } + + uint32_t max_allowed = 0; + ret = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed); + if (ret != PM3_SUCCESS) { + goto finish; + } + + if (num_files == 0) + goto finish; + + for (int i = 0 ; i < num_files; ++i) { + ret = flash_load(&files[i], filepaths[i], can_write_bl, max_allowed * ONE_KB); + if (ret != PM3_SUCCESS) { + goto finish; + } + PrintAndLogEx(NORMAL, ""); + } + + PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing...")); + + for (int i = 0; i < num_files; i++) { + ret = flash_write(&files[i]); + if (ret != PM3_SUCCESS) { + goto finish; + } + flash_free(&files[i]); + PrintAndLogEx(NORMAL, "\n"); + } + +finish: + ret = flash_stop_flashing(); + CloseProxmark(); +finish2: + for (int i = 0 ; i < num_files; ++i) { + if (filepaths[i] != NULL) + free(filepaths[i]); + } + if (ret == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, _BLUE_("All done.")); + else + PrintAndLogEx(ERR, "Aborted on error."); + PrintAndLogEx(NORMAL, "\nHave a nice day!"); + return ret; +} + int main(int argc, char *argv[]) { srand(time(0)); @@ -329,6 +494,15 @@ int main(int argc, char *argv[]) { } #endif + bool flash_mode = false; + bool flash_can_write_bl = false; + int flash_num_files = 0; + char *flash_filenames[FLASH_MAX_FILES]; + + // set global variables soon enough to get the log path + set_my_executable_path(); + set_my_user_directory(); + for (int i = 1; i < argc; i++) { if (argv[i][0] != '-') { @@ -362,12 +536,14 @@ int main(int argc, char *argv[]) { // short help if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + g_printAndLog = PRINTANDLOG_PRINT; show_help(true, exec_name); return 0; } // dump help if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--text") == 0) { + g_printAndLog = PRINTANDLOG_PRINT; show_help(false, exec_name); dumpAllHelp(0); return 0; @@ -375,9 +551,32 @@ int main(int argc, char *argv[]) { // dump markup if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--markdown") == 0) { + g_printAndLog = PRINTANDLOG_PRINT; dumpAllHelp(1); return 0; } + // print client version + if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) { + pm3_version(true, true); + return 0; + } + + // set debugmode + if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--debug") == 0) { + if (i + 1 == argc) { + PrintAndLogEx(ERR, _RED_("ERROR:") "missing debugmode specification after -d\n"); + show_help(false, exec_name); + return 1; + } + int demod = atoi(argv[i + 1]); + if (demod < 0 || demod > 2) { + PrintAndLogEx(ERR, _RED_("ERROR:") "invalid debugmode: -d " _YELLOW_("%s") "\n", argv[i + 1]); + return 1; + } + g_debugMode = demod; + i++; + continue; + } // flush output if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--flush") == 0) { @@ -449,6 +648,33 @@ int main(int argc, char *argv[]) { continue; } + // go to flash mode + if (strcmp(argv[i], "--flash") == 0) { + flash_mode = true; + continue; + } + + // unlock bootloader area + if (strcmp(argv[i], "--unlock-bootloader") == 0) { + flash_can_write_bl = true; + continue; + } + + // flash file + if (strcmp(argv[i], "--image") == 0) { + if (flash_num_files == FLASH_MAX_FILES) { + PrintAndLogEx(ERR, _RED_("ERROR:") "too many --image, please use it max %i times\n", FLASH_MAX_FILES); + return 1; + } + if (i + 1 == argc) { + PrintAndLogEx(ERR, _RED_("ERROR:") "missing image specification after --image\n"); + show_help(false, exec_name); + return 1; + } + flash_filenames[flash_num_files++] = argv[++i]; + continue; + } + // We got an unknown parameter PrintAndLogEx(ERR, _RED_("ERROR:") "invalid parameter: " _YELLOW_("%s") "\n", argv[i]); show_help(false, exec_name); @@ -469,13 +695,18 @@ int main(int argc, char *argv[]) { session.supports_colors = true; #endif // ascii art only in interactive client - if (!script_cmds_file && !script_cmd && session.stdinOnTTY && session.stdoutOnTTY) + if (!script_cmds_file && !script_cmd && session.stdinOnTTY && session.stdoutOnTTY && !flash_mode) showBanner(); // Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway if (speed == 0) speed = USART_BAUD_RATE; + if (flash_mode) { + flash_pm3(port, flash_num_files, flash_filenames, flash_can_write_bl); + exit(EXIT_SUCCESS); + } + if (script_cmd) { while (script_cmd[strlen(script_cmd) - 1] == ' ') script_cmd[strlen(script_cmd) - 1] = 0x00; @@ -501,9 +732,6 @@ int main(int argc, char *argv[]) { } } - // set global variables - set_my_executable_path(); - // try to open USB connection to Proxmark if (port != NULL) { OpenProxmark(port, waitCOMPort, 20, false, speed); diff --git a/client/proxmark3.h b/client/proxmark3.h index 6d245da10..9313e4c28 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -18,13 +18,19 @@ #define PROXPROMPT_USB "[usb] pm3 --> " #define PROXPROMPT_FPC "[fpc] pm3 --> " #define PROXPROMPT_OFFLINE "[offline] pm3 --> " +#define PROXHISTORY "history.txt" +#define PROXLOG "log_%Y%m%d.txt" +#define MAX_NESTED_CMDSCRIPT 10 +#define MAX_NESTED_LUASCRIPT 10 #ifdef __cplusplus extern "C" { #endif +int push_cmdscriptfile(char *path, bool stayafter); const char *get_my_executable_path(void); const char *get_my_executable_directory(void); +const char *get_my_user_directory(void); void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop); #ifdef __cplusplus diff --git a/client/aidlist.json b/client/resources/aidlist.json similarity index 100% rename from client/aidlist.json rename to client/resources/aidlist.json diff --git a/client/emv/capk.txt b/client/resources/capk.txt similarity index 100% rename from client/emv/capk.txt rename to client/resources/capk.txt diff --git a/client/emv/defparams.json b/client/resources/emv_defparams.json similarity index 100% rename from client/emv/defparams.json rename to client/resources/emv_defparams.json diff --git a/client/hardnested/bf_bench_data.bin b/client/resources/hardnested_bf_bench_data.bin similarity index 100% rename from client/hardnested/bf_bench_data.bin rename to client/resources/hardnested_bf_bench_data.bin diff --git a/client/hardnested/tables/bitflip_0_001_states.bin.z b/client/resources/hardnested_tables/bitflip_0_001_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_001_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_001_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_003_states.bin.z b/client/resources/hardnested_tables/bitflip_0_003_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_003_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_003_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_005_states.bin.z b/client/resources/hardnested_tables/bitflip_0_005_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_005_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_005_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_007_states.bin.z b/client/resources/hardnested_tables/bitflip_0_007_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_007_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_007_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_009_states.bin.z b/client/resources/hardnested_tables/bitflip_0_009_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_009_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_009_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_00b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_00b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_00b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_00d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_00d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_00d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_00f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_00f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_00f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_00f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_010_states.bin.z b/client/resources/hardnested_tables/bitflip_0_010_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_010_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_010_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_014_states.bin.z b/client/resources/hardnested_tables/bitflip_0_014_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_014_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_014_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_01c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_01c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_01c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_01c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_021_states.bin.z b/client/resources/hardnested_tables/bitflip_0_021_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_021_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_021_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_023_states.bin.z b/client/resources/hardnested_tables/bitflip_0_023_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_023_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_023_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_025_states.bin.z b/client/resources/hardnested_tables/bitflip_0_025_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_025_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_025_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_027_states.bin.z b/client/resources/hardnested_tables/bitflip_0_027_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_027_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_027_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_029_states.bin.z b/client/resources/hardnested_tables/bitflip_0_029_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_029_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_029_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_02b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_02b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_02b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_02d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_02d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_02d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_02f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_02f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_02f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_02f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_030_states.bin.z b/client/resources/hardnested_tables/bitflip_0_030_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_030_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_030_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_034_states.bin.z b/client/resources/hardnested_tables/bitflip_0_034_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_034_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_034_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_03c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_03c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_03c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_03c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_040_states.bin.z b/client/resources/hardnested_tables/bitflip_0_040_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_040_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_040_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_044_states.bin.z b/client/resources/hardnested_tables/bitflip_0_044_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_044_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_044_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_04c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_04c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_04c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_04c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_051_states.bin.z b/client/resources/hardnested_tables/bitflip_0_051_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_051_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_051_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_053_states.bin.z b/client/resources/hardnested_tables/bitflip_0_053_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_053_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_053_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_055_states.bin.z b/client/resources/hardnested_tables/bitflip_0_055_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_055_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_055_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_057_states.bin.z b/client/resources/hardnested_tables/bitflip_0_057_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_057_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_057_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_059_states.bin.z b/client/resources/hardnested_tables/bitflip_0_059_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_059_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_059_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_05b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_05b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_05b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_05d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_05d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_05d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_05f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_05f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_05f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_05f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_064_states.bin.z b/client/resources/hardnested_tables/bitflip_0_064_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_064_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_064_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_06c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_06c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_06c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_06c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_071_states.bin.z b/client/resources/hardnested_tables/bitflip_0_071_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_071_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_071_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_073_states.bin.z b/client/resources/hardnested_tables/bitflip_0_073_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_073_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_073_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_075_states.bin.z b/client/resources/hardnested_tables/bitflip_0_075_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_075_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_075_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_077_states.bin.z b/client/resources/hardnested_tables/bitflip_0_077_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_077_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_077_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_079_states.bin.z b/client/resources/hardnested_tables/bitflip_0_079_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_079_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_079_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_07b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_07b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_07b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_07b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_07f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_07f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_07f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_07f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_081_states.bin.z b/client/resources/hardnested_tables/bitflip_0_081_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_081_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_081_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_083_states.bin.z b/client/resources/hardnested_tables/bitflip_0_083_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_083_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_083_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_085_states.bin.z b/client/resources/hardnested_tables/bitflip_0_085_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_085_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_085_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_087_states.bin.z b/client/resources/hardnested_tables/bitflip_0_087_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_087_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_087_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_089_states.bin.z b/client/resources/hardnested_tables/bitflip_0_089_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_089_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_089_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_08b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_08b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_08b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_08d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_08d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_08d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_08f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_08f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_08f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_08f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_090_states.bin.z b/client/resources/hardnested_tables/bitflip_0_090_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_090_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_090_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_094_states.bin.z b/client/resources/hardnested_tables/bitflip_0_094_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_094_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_094_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_09c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_09c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_09c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_09c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0a9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0a9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0a9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ab_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ab_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ab_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ad_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ad_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ad_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0af_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0af_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0af_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0af_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0b0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0b0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0b0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0b4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0b4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0b4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0bc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0bc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0bc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0c0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0c0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0c0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0c4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0c4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0c4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0cc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0cc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0cc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0d9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0d9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0d9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0db_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0db_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0db_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0db_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0dd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0dd_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0dd_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0df_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0df_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0df_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0df_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0e4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0e4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0e4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ec_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ec_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ec_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0f9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0f9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0f9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0fb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0fb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0fb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0fd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0fd_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0fd_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_0ff_states.bin.z b/client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_0ff_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_0ff_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_104_states.bin.z b/client/resources/hardnested_tables/bitflip_0_104_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_104_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_104_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_10c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_10c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_10c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_10c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_111_states.bin.z b/client/resources/hardnested_tables/bitflip_0_111_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_111_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_111_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_113_states.bin.z b/client/resources/hardnested_tables/bitflip_0_113_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_113_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_113_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_115_states.bin.z b/client/resources/hardnested_tables/bitflip_0_115_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_115_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_115_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_117_states.bin.z b/client/resources/hardnested_tables/bitflip_0_117_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_117_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_117_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_119_states.bin.z b/client/resources/hardnested_tables/bitflip_0_119_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_119_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_119_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_11b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_11b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_11b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_11d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_11d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_11d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_11f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_11f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_11f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_11f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_124_states.bin.z b/client/resources/hardnested_tables/bitflip_0_124_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_124_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_124_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_12c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_12c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_12c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_12c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_131_states.bin.z b/client/resources/hardnested_tables/bitflip_0_131_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_131_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_131_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_133_states.bin.z b/client/resources/hardnested_tables/bitflip_0_133_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_133_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_133_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_135_states.bin.z b/client/resources/hardnested_tables/bitflip_0_135_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_135_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_135_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_137_states.bin.z b/client/resources/hardnested_tables/bitflip_0_137_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_137_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_137_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_139_states.bin.z b/client/resources/hardnested_tables/bitflip_0_139_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_139_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_139_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_13b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_13b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_13b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_13d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_13d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_13d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_13f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_13f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_13f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_13f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_141_states.bin.z b/client/resources/hardnested_tables/bitflip_0_141_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_141_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_141_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_143_states.bin.z b/client/resources/hardnested_tables/bitflip_0_143_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_143_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_143_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_145_states.bin.z b/client/resources/hardnested_tables/bitflip_0_145_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_145_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_145_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_147_states.bin.z b/client/resources/hardnested_tables/bitflip_0_147_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_147_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_147_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_149_states.bin.z b/client/resources/hardnested_tables/bitflip_0_149_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_149_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_149_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_14b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_14b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_14b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_14d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_14d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_14d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_14f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_14f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_14f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_14f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_150_states.bin.z b/client/resources/hardnested_tables/bitflip_0_150_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_150_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_150_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_154_states.bin.z b/client/resources/hardnested_tables/bitflip_0_154_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_154_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_154_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_15c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_15c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_15c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_15c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_161_states.bin.z b/client/resources/hardnested_tables/bitflip_0_161_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_161_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_161_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_163_states.bin.z b/client/resources/hardnested_tables/bitflip_0_163_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_163_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_163_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_165_states.bin.z b/client/resources/hardnested_tables/bitflip_0_165_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_165_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_165_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_167_states.bin.z b/client/resources/hardnested_tables/bitflip_0_167_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_167_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_167_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_169_states.bin.z b/client/resources/hardnested_tables/bitflip_0_169_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_169_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_169_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_16b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_16b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_16b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_16d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_16d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_16d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_16f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_16f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_16f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_16f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_170_states.bin.z b/client/resources/hardnested_tables/bitflip_0_170_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_170_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_170_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_174_states.bin.z b/client/resources/hardnested_tables/bitflip_0_174_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_174_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_174_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_17c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_17c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_17c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_17c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_184_states.bin.z b/client/resources/hardnested_tables/bitflip_0_184_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_184_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_184_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_18c_states.bin.z b/client/resources/hardnested_tables/bitflip_0_18c_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_18c_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_18c_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_191_states.bin.z b/client/resources/hardnested_tables/bitflip_0_191_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_191_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_191_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_193_states.bin.z b/client/resources/hardnested_tables/bitflip_0_193_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_193_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_193_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_195_states.bin.z b/client/resources/hardnested_tables/bitflip_0_195_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_195_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_195_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_197_states.bin.z b/client/resources/hardnested_tables/bitflip_0_197_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_197_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_197_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_199_states.bin.z b/client/resources/hardnested_tables/bitflip_0_199_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_199_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_199_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_19b_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_19b_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_19b_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_19d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_19d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_19d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_19f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_19f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_19f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_19f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1a4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1a4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1a4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1ac_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1ac_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1ac_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1b9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1b9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1b9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1bb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1bb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1bb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1bd_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1bd_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1bd_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1bf_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1bf_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1bf_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1c9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1c9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1c9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1cb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1cb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1cb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1d0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1d0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1d0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1d4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1d4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1d4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1dc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1dc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1dc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e5_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e5_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e5_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e7_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e7_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e7_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1e9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1e9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1e9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1eb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1eb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1eb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1ed_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1ed_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1ed_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1ef_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1ef_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1ef_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1f0_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1f0_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1f0_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1f4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1f4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1f4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_1fc_states.bin.z b/client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_1fc_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_1fc_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_210_states.bin.z b/client/resources/hardnested_tables/bitflip_0_210_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_210_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_210_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_225_states.bin.z b/client/resources/hardnested_tables/bitflip_0_225_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_225_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_225_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_227_states.bin.z b/client/resources/hardnested_tables/bitflip_0_227_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_227_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_227_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_22d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_22d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_22d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_22d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_22f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_22f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_22f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_22f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_240_states.bin.z b/client/resources/hardnested_tables/bitflip_0_240_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_240_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_240_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_275_states.bin.z b/client/resources/hardnested_tables/bitflip_0_275_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_275_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_275_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_277_states.bin.z b/client/resources/hardnested_tables/bitflip_0_277_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_277_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_277_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_27f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_27f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_27f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_27f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_294_states.bin.z b/client/resources/hardnested_tables/bitflip_0_294_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_294_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_294_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2a1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2a1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2a1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2a3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2a3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2a3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2a9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2a9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2a9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2ab_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2ab_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2ab_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2c4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2c4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2c4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2f1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2f1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2f1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2f3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2f3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2f3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2f9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2f9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2f9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_2fb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_2fb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_2fb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_335_states.bin.z b/client/resources/hardnested_tables/bitflip_0_335_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_335_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_335_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_337_states.bin.z b/client/resources/hardnested_tables/bitflip_0_337_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_337_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_337_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_33d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_33d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_33d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_33d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_33f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_33f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_33f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_33f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_350_states.bin.z b/client/resources/hardnested_tables/bitflip_0_350_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_350_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_350_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_365_states.bin.z b/client/resources/hardnested_tables/bitflip_0_365_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_365_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_365_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_367_states.bin.z b/client/resources/hardnested_tables/bitflip_0_367_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_367_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_367_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_36d_states.bin.z b/client/resources/hardnested_tables/bitflip_0_36d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_36d_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_36d_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_36f_states.bin.z b/client/resources/hardnested_tables/bitflip_0_36f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_36f_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_36f_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_384_states.bin.z b/client/resources/hardnested_tables/bitflip_0_384_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_384_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_384_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3b1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3b1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3b1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3b3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3b3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3b3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3b9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3b9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3b9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3bb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3bb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3bb_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3d4_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3d4_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3d4_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3e1_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3e1_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3e1_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3e3_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3e3_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3e3_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3e9_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3e9_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3e9_states.bin.z diff --git a/client/hardnested/tables/bitflip_0_3eb_states.bin.z b/client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_0_3eb_states.bin.z rename to client/resources/hardnested_tables/bitflip_0_3eb_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_002_states.bin.z b/client/resources/hardnested_tables/bitflip_1_002_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_002_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_002_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_008_states.bin.z b/client/resources/hardnested_tables/bitflip_1_008_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_008_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_008_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_00a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_00a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_00a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_00a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_012_states.bin.z b/client/resources/hardnested_tables/bitflip_1_012_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_012_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_012_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_018_states.bin.z b/client/resources/hardnested_tables/bitflip_1_018_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_018_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_018_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_01a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_01a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_01a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_01a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_020_states.bin.z b/client/resources/hardnested_tables/bitflip_1_020_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_020_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_020_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_028_states.bin.z b/client/resources/hardnested_tables/bitflip_1_028_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_028_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_028_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_02a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_02a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_02a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_02a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_02e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_02e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_02e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_02e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_032_states.bin.z b/client/resources/hardnested_tables/bitflip_1_032_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_032_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_032_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_036_states.bin.z b/client/resources/hardnested_tables/bitflip_1_036_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_036_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_036_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_038_states.bin.z b/client/resources/hardnested_tables/bitflip_1_038_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_038_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_038_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_03a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_03a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_03a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_03a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_03e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_03e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_03e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_03e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_040_states.bin.z b/client/resources/hardnested_tables/bitflip_1_040_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_040_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_040_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_042_states.bin.z b/client/resources/hardnested_tables/bitflip_1_042_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_042_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_042_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_046_states.bin.z b/client/resources/hardnested_tables/bitflip_1_046_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_046_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_046_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_048_states.bin.z b/client/resources/hardnested_tables/bitflip_1_048_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_048_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_048_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_04a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_04a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_04a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_04a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_04e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_04e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_04e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_04e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_052_states.bin.z b/client/resources/hardnested_tables/bitflip_1_052_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_052_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_052_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_056_states.bin.z b/client/resources/hardnested_tables/bitflip_1_056_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_056_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_056_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_058_states.bin.z b/client/resources/hardnested_tables/bitflip_1_058_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_058_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_058_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_05a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_05a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_05a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_05a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_05e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_05e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_05e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_05e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_060_states.bin.z b/client/resources/hardnested_tables/bitflip_1_060_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_060_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_060_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_062_states.bin.z b/client/resources/hardnested_tables/bitflip_1_062_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_062_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_062_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_066_states.bin.z b/client/resources/hardnested_tables/bitflip_1_066_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_066_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_066_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_068_states.bin.z b/client/resources/hardnested_tables/bitflip_1_068_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_068_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_068_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_06a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_06a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_06a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_06a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_06e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_06e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_06e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_06e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_072_states.bin.z b/client/resources/hardnested_tables/bitflip_1_072_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_072_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_072_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_076_states.bin.z b/client/resources/hardnested_tables/bitflip_1_076_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_076_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_076_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_078_states.bin.z b/client/resources/hardnested_tables/bitflip_1_078_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_078_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_078_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_07a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_07a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_07a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_07a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_07e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_07e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_07e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_07e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_080_states.bin.z b/client/resources/hardnested_tables/bitflip_1_080_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_080_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_080_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_082_states.bin.z b/client/resources/hardnested_tables/bitflip_1_082_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_082_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_082_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_086_states.bin.z b/client/resources/hardnested_tables/bitflip_1_086_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_086_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_086_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_088_states.bin.z b/client/resources/hardnested_tables/bitflip_1_088_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_088_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_088_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_08a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_08a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_08a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_08a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_08e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_08e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_08e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_08e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_092_states.bin.z b/client/resources/hardnested_tables/bitflip_1_092_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_092_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_092_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_096_states.bin.z b/client/resources/hardnested_tables/bitflip_1_096_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_096_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_096_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_098_states.bin.z b/client/resources/hardnested_tables/bitflip_1_098_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_098_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_098_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_09a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_09a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_09a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_09a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_09e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_09e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_09e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_09e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0a8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0a8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0aa_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0aa_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0aa_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ae_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ae_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ae_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0b2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0b2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0b2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0b6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0b6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0b6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0b8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0b8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0b8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ba_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ba_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ba_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0be_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0be_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0be_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0be_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0c8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0c8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0c8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ca_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ca_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ca_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0ce_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0ce_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0ce_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0d2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0d2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0d2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0d6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0d6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0d6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0d8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0d8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0d8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0da_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0da_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0da_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0da_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0de_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0de_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0de_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0de_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0e0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0e0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0e0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0e8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0e8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0e8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_0f8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_0f8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_0f8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_108_states.bin.z b/client/resources/hardnested_tables/bitflip_1_108_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_108_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_108_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_111_states.bin.z b/client/resources/hardnested_tables/bitflip_1_111_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_111_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_111_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_113_states.bin.z b/client/resources/hardnested_tables/bitflip_1_113_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_113_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_113_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_115_states.bin.z b/client/resources/hardnested_tables/bitflip_1_115_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_115_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_115_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_117_states.bin.z b/client/resources/hardnested_tables/bitflip_1_117_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_117_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_117_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_118_states.bin.z b/client/resources/hardnested_tables/bitflip_1_118_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_118_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_118_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_11a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_11a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_11a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_11a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_11b_states.bin.z b/client/resources/hardnested_tables/bitflip_1_11b_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_11b_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_11b_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_120_states.bin.z b/client/resources/hardnested_tables/bitflip_1_120_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_120_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_120_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_122_states.bin.z b/client/resources/hardnested_tables/bitflip_1_122_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_122_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_122_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_128_states.bin.z b/client/resources/hardnested_tables/bitflip_1_128_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_128_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_128_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_131_states.bin.z b/client/resources/hardnested_tables/bitflip_1_131_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_131_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_131_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_135_states.bin.z b/client/resources/hardnested_tables/bitflip_1_135_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_135_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_135_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_138_states.bin.z b/client/resources/hardnested_tables/bitflip_1_138_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_138_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_138_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_145_states.bin.z b/client/resources/hardnested_tables/bitflip_1_145_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_145_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_145_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_147_states.bin.z b/client/resources/hardnested_tables/bitflip_1_147_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_147_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_147_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_148_states.bin.z b/client/resources/hardnested_tables/bitflip_1_148_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_148_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_148_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_158_states.bin.z b/client/resources/hardnested_tables/bitflip_1_158_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_158_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_158_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_160_states.bin.z b/client/resources/hardnested_tables/bitflip_1_160_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_160_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_160_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_161_states.bin.z b/client/resources/hardnested_tables/bitflip_1_161_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_161_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_161_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_163_states.bin.z b/client/resources/hardnested_tables/bitflip_1_163_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_163_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_163_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_165_states.bin.z b/client/resources/hardnested_tables/bitflip_1_165_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_165_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_165_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_168_states.bin.z b/client/resources/hardnested_tables/bitflip_1_168_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_168_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_168_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_178_states.bin.z b/client/resources/hardnested_tables/bitflip_1_178_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_178_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_178_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_180_states.bin.z b/client/resources/hardnested_tables/bitflip_1_180_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_180_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_180_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_188_states.bin.z b/client/resources/hardnested_tables/bitflip_1_188_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_188_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_188_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_191_states.bin.z b/client/resources/hardnested_tables/bitflip_1_191_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_191_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_191_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_198_states.bin.z b/client/resources/hardnested_tables/bitflip_1_198_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_198_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_198_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_199_states.bin.z b/client/resources/hardnested_tables/bitflip_1_199_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_199_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_199_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_19d_states.bin.z b/client/resources/hardnested_tables/bitflip_1_19d_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_19d_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_19d_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_19f_states.bin.z b/client/resources/hardnested_tables/bitflip_1_19f_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_19f_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_19f_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1a0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1a0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1a8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1a8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b3_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b3_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b3_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b5_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b5_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b5_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b7_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b7_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b7_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1b9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1b9_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1b9_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1bd_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1bd_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1bd_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c1_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c1_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c1_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c3_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c3_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c3_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1c9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1c9_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1c9_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1cd_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1cd_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1cd_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1cf_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1cf_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1cf_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1d8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1d8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1d8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e0_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e1_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e1_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e1_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e5_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e5_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e5_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e7_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e7_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e7_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1e9_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1e9_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1e9_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1eb_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1eb_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1eb_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1ed_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1ed_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1ed_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_1f8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_1f8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_1f8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_208_states.bin.z b/client/resources/hardnested_tables/bitflip_1_208_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_208_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_208_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_220_states.bin.z b/client/resources/hardnested_tables/bitflip_1_220_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_220_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_220_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_24a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_24a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_24a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_24a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_24e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_24e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_24e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_24e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_25a_states.bin.z b/client/resources/hardnested_tables/bitflip_1_25a_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_25a_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_25a_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_25e_states.bin.z b/client/resources/hardnested_tables/bitflip_1_25e_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_25e_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_25e_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_262_states.bin.z b/client/resources/hardnested_tables/bitflip_1_262_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_262_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_262_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_266_states.bin.z b/client/resources/hardnested_tables/bitflip_1_266_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_266_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_266_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_272_states.bin.z b/client/resources/hardnested_tables/bitflip_1_272_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_272_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_272_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_276_states.bin.z b/client/resources/hardnested_tables/bitflip_1_276_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_276_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_276_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_280_states.bin.z b/client/resources/hardnested_tables/bitflip_1_280_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_280_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_280_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2a8_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2a8_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2a8_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2c2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2c2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2c2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2c6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2c6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2c6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2d2_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2d2_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2d2_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_2d6_states.bin.z b/client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_2d6_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_2d6_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_328_states.bin.z b/client/resources/hardnested_tables/bitflip_1_328_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_328_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_328_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_388_states.bin.z b/client/resources/hardnested_tables/bitflip_1_388_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_388_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_388_states.bin.z diff --git a/client/hardnested/tables/bitflip_1_3a0_states.bin.z b/client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z similarity index 100% rename from client/hardnested/tables/bitflip_1_3a0_states.bin.z rename to client/resources/hardnested_tables/bitflip_1_3a0_states.bin.z diff --git a/client/loclass/iclass_dump.bin b/client/resources/iclass_dump.bin similarity index 100% rename from client/loclass/iclass_dump.bin rename to client/resources/iclass_dump.bin diff --git a/client/crypto/oids.json b/client/resources/oids.json similarity index 100% rename from client/crypto/oids.json rename to client/resources/oids.json diff --git a/client/reveng/Makefile b/client/reveng/Makefile new file mode 100644 index 000000000..c29538fa5 --- /dev/null +++ b/client/reveng/Makefile @@ -0,0 +1,33 @@ +# reveng will compile without macros, but these may be useful: +# Add -DBMPMACRO to use bitmap size constant macros (edit config.h) +# Add -DNOFORCE to disable the -F switch +# Add -DPRESETS to compile with preset models (edit config.h) + +MYSRCPATHS = +MYINCLUDES = -I. -I.. +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -DPRESETS +MYSRCS = \ + bmpbit.c \ + cli.c \ + getopt.c \ + model.c \ + poly.c \ + preset.c \ + reveng.c + +LIB_A = libreveng.a + +include ../../Makefile.host + +CLEAN += bmptst + +$(BINDIR)/$(LIB_A): $(BINDIR)/bmptst + +$(BINDIR)/bmptst: bmpbit.c config.h reveng.h + $(info [-] CC $<) + $(Q)$(CC) $(CFLAGS) -DBMPTST -o $@ $< + $(info [=] TEST $@) + $(Q)( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) ) + +.PHONY: all clean diff --git a/client/reveng/poly.c b/client/reveng/poly.c index 0fc6555d9..44f5709f4 100644 --- a/client/reveng/poly.c +++ b/client/reveng/poly.c @@ -600,9 +600,6 @@ plast(const poly_t poly) { idx = size - 1UL; while (idx && !(accu = poly.bitmap[idx])) --idx; - if (poly.length == 24) - printf("ICE plast B - poly.length %lu vs size %lu idx %lu bitmap %ld\n", poly.length, size, idx, poly.bitmap[idx]); - if (!idx && !(accu = poly.bitmap[idx])) return (0UL); /* now accu == poly.bitmap[idx] and contains last significant term */ @@ -1080,10 +1077,6 @@ praloc(poly_t *poly, unsigned long length) { if (poly->bitmap) { - if (poly->length == 24) - printf("ICE praloc - poly->length %lu\n", poly->length); - - if (poly->length < length) { /* poly->length >= 0, length > 0, size > 0. * poly expanded. clear old last word and all new words @@ -1094,15 +1087,11 @@ praloc(poly_t *poly, unsigned long length) { while (oldsize < size) poly->bitmap[oldsize++] = BMP_C(0); - if (poly->length == 24) printf("ICE praloc MISS A\n"); - } else if (LOFS(length)) { /* poly->length >= length > 0. * poly shrunk. clear new last word */ poly->bitmap[size - 1UL] &= ~(~BMP_C(0) >> LOFS(length)); - - if (poly->length == 24) printf("ICE praloc B size %lu, bm %lu \n", size, poly->bitmap[size - 1UL]); } poly->length = length; diff --git a/client/scripting.c b/client/scripting.c index 429d96fac..6e35f809f 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -31,6 +31,7 @@ #include "proxmark3.h" #include "crc16.h" #include "protocols.h" +#include "fileutils.h" // searchfile static int returnToLuaWithError(lua_State *L, const char *fmt, ...) { char buffer[200]; @@ -50,7 +51,7 @@ static int l_clearCommandBuffer(lua_State *L) { } /** - * Enable / Disable fast push mode for lua scripts like mfkeys + * Enable / Disable fast push mode for lua scripts like mfckeys * The following params expected: * *@brief l_fast_push_mode @@ -1052,6 +1053,29 @@ static int l_ndefparse(lua_State *L) { return 1; } +static int l_searchfile(lua_State *L) { + //Check number of arguments + int n = lua_gettop(L); + if (n != 2) { + return returnToLuaWithError(L, "Only filename and extension"); + } + + size_t size; + // data + const char *filename = luaL_checklstring(L, 1, &size); + if (size == 0) + return returnToLuaWithError(L, "Must specify filename"); + + const char *suffix = luaL_checklstring(L, 2, &size); + char *path; + int res = searchFile(&path, "", filename, suffix, false); + if (res != PM3_SUCCESS) { + return returnToLuaWithError(L, "Failed to find file"); + } + + lua_pushstring(L, path); + return 1; +} /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be @@ -1112,6 +1136,7 @@ int set_pm3_libraries(lua_State *L) { {"t55xx_detect", l_T55xx_detect}, {"ndefparse", l_ndefparse}, {"fast_push_mode", l_fast_push_mode}, + {"search_file", l_searchfile}, {NULL, NULL} }; @@ -1131,21 +1156,57 @@ int set_pm3_libraries(lua_State *L) { //-- remove the global environment table from the stack lua_pop(L, 1); - //--add to the LUA_PATH (package.path in lua) - // so we can load scripts from the ./scripts/ - directory - char scripts_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(scripts_path, get_my_executable_directory()); - strcat(scripts_path, LUA_SCRIPTS_DIRECTORY); - strcat(scripts_path, LUA_LIBRARIES_WILDCARD); - setLuaPath(L, scripts_path); + // so we can load scripts from various places: + const char *exec_path = get_my_executable_directory(); + if (exec_path != NULL) { + // from the ./luascripts/ directory + char scripts_path[strlen(exec_path) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, exec_path); + strcat(scripts_path, LUA_SCRIPTS_SUBDIR); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + // from the ./lualib/ directory + char libraries_path[strlen(exec_path) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, exec_path); + strcat(libraries_path, LUA_LIBRARIES_SUBDIR); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); + } + const char *user_path = get_my_user_directory(); + if (user_path != NULL) { + // from the $HOME/.proxmark3/luascripts/ directory + char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, user_path); + strcat(scripts_path, PM3_USER_DIRECTORY); + strcat(scripts_path, LUA_SCRIPTS_SUBDIR); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); - //-- Last but not least, add to the LUA_PATH (package.path in lua) - // so we can load libraries from the ./lualib/ - directory - char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; - strcpy(libraries_path, get_my_executable_directory()); - strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); - strcat(libraries_path, LUA_LIBRARIES_WILDCARD); - setLuaPath(L, libraries_path); + // from the $HOME/.proxmark3/lualib/ directory + char libraries_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, user_path); + strcat(libraries_path, PM3_USER_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_SUBDIR); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); + } + + if (exec_path != NULL) { + // from the $PREFIX/share/proxmark3/luascripts/ directory + char scripts_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(LUA_SCRIPTS_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(scripts_path, exec_path); + strcat(scripts_path, PM3_SHARE_RELPATH); + strcat(scripts_path, LUA_SCRIPTS_SUBDIR); + strcat(scripts_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, scripts_path); + // from the $PREFIX/share/proxmark3/lualib/ directory + char libraries_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(LUA_LIBRARIES_SUBDIR) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, exec_path); + strcat(libraries_path, PM3_SHARE_RELPATH); + strcat(libraries_path, LUA_LIBRARIES_SUBDIR); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); + } return 1; } diff --git a/client/scripting.h b/client/scripting.h index 07b07aa67..b23ce3a9a 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -14,8 +14,6 @@ //#include //#include -#define LUA_LIBRARIES_DIRECTORY "lualibs/" -#define LUA_SCRIPTS_DIRECTORY "scripts/" #define LUA_LIBRARIES_WILDCARD "?.lua" /** diff --git a/client/tinycbor/Makefile b/client/tinycbor/Makefile index af22846e9..6470246d4 100644 --- a/client/tinycbor/Makefile +++ b/client/tinycbor/Makefile @@ -1,11 +1,10 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -LIB_A = tinycbor.a -tinycbor_SOURCES = \ +MYSRCPATHS = +MYINCLUDES = +# Strange errors on Mingw when compiling with C99 +#MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYCFLAGS = +MYDEFS = +MYSRCS = \ cborencoder.c \ cborencoder_close_container_checked.c \ cborerrorstrings.c \ @@ -15,48 +14,9 @@ tinycbor_SOURCES = \ cbortojson.c \ cborvalidation.c \ -CFILES = $(filter %.c, $(tinycbor_SOURCES)) -CMDOBJS = $(CFILES:%.c=%.o) -CLEAN = $(CMDOBJS) +LIB_A = tinycbor.a -platform = $(shell uname) - -CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -LIBS= $(SYSLIBS) $(MYLIBS) -DEFAULT_INCLUDES = -I. -I.. -DEFS = -DHAVE_STDINT_H - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -TST= echo - -SYSLDFLAGS= -SYSLIBS= - -MYLIBS= -MYOBJS= - -$(LIB_A): $(CMDOBJS) - $(info [=] AR $@) - $(Q)$(AR) $(LIB_A) $(CMDOBJS) - $(Q)$(RANLIB) $(LIB_A) - -all: $(LIB_A) - -clean: - $(Q)$(RM) $(CLEAN) - $(Q)$(RM) $(LIB_A) - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS) - -.PHONY: all clean +# Strange errors on Mingw when compiling with -O3 +CFLAGS ?= -Wall -Werror -O2 +include ../../Makefile.host diff --git a/client/ui.c b/client/ui.c index 9927fd6d6..d12713b9b 100644 --- a/client/ui.c +++ b/client/ui.c @@ -24,7 +24,13 @@ #include #include #include "util.h" - +#include "proxmark3.h" // PROXLOG +#include "fileutils.h" +#include "pm3_cmd.h" +#ifdef _WIN32 +# include // _mkdir +#endif +#include session_arg_t session; double CursorScaleFactor = 1; @@ -36,9 +42,61 @@ bool GridLocked = false; bool showDemod = true; pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; -static const char *logfilename = "proxmark3.log"; + static void fPrintAndLog(FILE *stream, const char *fmt, ...); +// needed by flasher, so let's put it here instead of fileutils.c +int searchHomeFilePath(char **foundpath, const char *filename, bool create_home) { + if (foundpath == NULL) + return PM3_EINVARG; + const char *user_path = get_my_user_directory(); + if (user_path == NULL) { + fprintf(stderr, "Could not retrieve $HOME from the environment\n"); + return PM3_EFILE; + } + char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1, sizeof(char)); + if (path == NULL) + return PM3_EMALLOC; + strcpy(path, user_path); + strcat(path, PM3_USER_DIRECTORY); + + int result; +#ifdef _WIN32 + struct _stat st; + // Mingw _stat fails if path ends with /, so let's use a stripped path + if (path[strlen(path) - 1] == '/') { + path[strlen(path) - 1] = '\0'; + result = _stat(path, &st); + path[strlen(path)] = '/'; + } else { + result = _stat(path, &st); + } +#else + struct stat st; + result = stat(path, &st); +#endif + if ((result != 0) && create_home) { + +#ifdef _WIN32 + if (_mkdir(path)) { +#else + if (mkdir(path, 0700)) { +#endif + fprintf(stderr, "Could not create user directory %s\n", path); + free(path); + return PM3_EFILE; + } + } + if (filename == NULL) { + *foundpath = path; + return PM3_SUCCESS; + } + path = realloc(path, (strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(filename) + 1) * sizeof(char)); + strcat(path, filename); + *foundpath = path; + return PM3_SUCCESS; +} + void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) { char buff[2000] = "Options:\n"; char format[2000] = ""; @@ -165,11 +223,26 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { // lock this section to avoid interlacing prints from different threads pthread_mutex_lock(&print_lock); - if (logging && !logfile) { - logfile = fopen(logfilename, "a"); - if (!logfile) { - fprintf(stderr, "Can't open logfile, logging disabled!\n"); + if ((g_printAndLog & PRINTANDLOG_LOG) && logging && !logfile) { + char *my_logfile_path = NULL; + char filename[40]; + struct tm *timenow; + time_t now = time(NULL); + timenow = gmtime(&now); + strftime(filename, sizeof(filename), PROXLOG, timenow); + if (searchHomeFilePath(&my_logfile_path, filename, true) != PM3_SUCCESS) { + fprintf(stderr, "[-] Logging disabled!\n\n"); + my_logfile_path = NULL; logging = 0; + } else { + logfile = fopen(my_logfile_path, "a"); + if (logfile == NULL) { + fprintf(stderr, "[-] Can't open logfile %s, logging disabled!\n", my_logfile_path); + logging = 0; + } else { + printf("[=] Session log %s\n", my_logfile_path); + } + free(my_logfile_path); } } @@ -196,9 +269,11 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { bool filter_ansi = !session.supports_colors; memcpy_filter_ansi(buffer2, buffer, sizeof(buffer), filter_ansi); - fprintf(stream, "%s", buffer2); - fprintf(stream, " "); // cleaning prompt - fprintf(stream, "\n"); + if (g_printAndLog & PRINTANDLOG_PRINT) { + fprintf(stream, "%s", buffer2); + fprintf(stream, " "); // cleaning prompt + fprintf(stream, "\n"); + } #ifdef RL_STATE_READCMD // We are using GNU readline. libedit (OSX) doesn't support this flag. @@ -211,7 +286,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { } #endif - if (logging && logfile) { + if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) { if (filter_ansi) { // already done fprintf(logfile, "%s\n", buffer2); } else { @@ -228,10 +303,6 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) { pthread_mutex_unlock(&print_lock); } -void SetLogFilename(char *fn) { - logfilename = fn; -} - void SetFlushAfterWrite(bool value) { flushAfterWrite = value; } diff --git a/client/ui.h b/client/ui.h index 648dce4c4..7e00ab52b 100644 --- a/client/ui.h +++ b/client/ui.h @@ -39,7 +39,6 @@ void ShowGraphWindow(void); void RepaintGraphWindow(void); void PrintAndLogOptions(const char *str[][2], size_t size, size_t space); void PrintAndLogEx(logLevel_t level, const char *fmt, ...); -void SetLogFilename(char *fn); void SetFlushAfterWrite(bool value); void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter); @@ -49,6 +48,8 @@ extern uint32_t CursorCPos, CursorDPos; extern bool GridLocked; extern bool showDemod; +int searchHomeFilePath(char **foundpath, const char *filename, bool create_home); + extern pthread_mutex_t print_lock; void iceIIR_Butterworth(int *data, const size_t len); diff --git a/client/util.c b/client/util.c index 52321689b..1f5a29781 100644 --- a/client/util.c +++ b/client/util.c @@ -28,6 +28,8 @@ #define UTIL_BUFFER_SIZE_SPRINT 4097 // global client debug variable uint8_t g_debugMode = 0; +// global client disable logging variable +uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; #ifdef _WIN32 #include diff --git a/client/util.h b/client/util.h index 09aeeaecb..7cfea0f8b 100644 --- a/client/util.h +++ b/client/util.h @@ -22,6 +22,9 @@ #endif uint8_t g_debugMode; +uint8_t g_printAndLog; +#define PRINTANDLOG_PRINT 1 +#define PRINTANDLOG_LOG 2 int kbd_enter_pressed(void); void AddLogLine(const char *fn, const char *data, const char *c); diff --git a/common/mbedtls/Makefile b/common/mbedtls/Makefile index a16b2cfd9..52663d67e 100644 --- a/common/mbedtls/Makefile +++ b/common/mbedtls/Makefile @@ -1,11 +1,8 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - -LIB_A = libmbedtls.a -mbedtls_SOURCES = \ +MYSRCPATHS = +MYINCLUDES = -I. -I.. +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = +MYSRCS = \ aes.c \ asn1parse.c \ asn1write.c \ @@ -49,55 +46,7 @@ mbedtls_SOURCES = \ x509.c \ x509_crl.c \ x509_crt.c -mbedtls_LDFLAGS = \ - -no-undefined \ - -export-symbols-regex '^mbedtls_' \ - -version-info 15:0:11 +LIB_A = libmbedtls.a -CFILES = $(filter %.c, $(mbedtls_SOURCES)) -CMDOBJS = $(CFILES:%.c=%.o) -CLEAN = $(CMDOBJS) - -platform = $(shell uname) - -CC= gcc -CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function -LDFLAGS= $(SYSLDFLAGS) $(mbedtls_LDFLAGS) -LIBS= $(SYSLIBS) $(MYLIBS) -DEFAULT_INCLUDES = -I. -I.. -DEFS = -DHAVE_STDINT_H - -ifeq ($(platform),Darwin) -AR= /usr/bin/ar rcs -RANLIB= /usr/bin/ranlib -else -AR= ar rcs -RANLIB= ranlib -endif -RM= rm -f -TST= echo - -SYSLDFLAGS= -SYSLIBS= - -MYLIBS= -MYOBJS= - -$(LIB_A): $(CMDOBJS) - $(info [=] AR $@) - $(Q)$(AR) $(LIB_A) $(CMDOBJS) - $(Q)$(RANLIB) $(LIB_A) - -all: $(LIB_A) - -clean: - $(Q)$(RM) $(CLEAN) - $(Q)$(RM) $(LIB_A) - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS) - -.PHONY: all clean - +include ../../Makefile.host diff --git a/client/util_posix.c b/common/util_posix.c similarity index 100% rename from client/util_posix.c rename to common/util_posix.c diff --git a/client/util_posix.h b/common/util_posix.h similarity index 100% rename from client/util_posix.h rename to common/util_posix.h diff --git a/common/zlib/Makefile b/common/zlib/Makefile new file mode 100644 index 000000000..b62071d5d --- /dev/null +++ b/common/zlib/Makefile @@ -0,0 +1,10 @@ +MYSRCPATHS = ../../common/zlib +MYSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c +MYINCLUDES = -I../../common/zlib +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -DZ_SOLO -DNO_GZIP -DZLIB_PM3_TUNED +#-DDEBUG -Dverbose=1 + +LIB_A = libz.a + +include ../../Makefile.host diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index cf4405d6a..52ec2ebd2 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -6,63 +6,34 @@ # Common makefile functions for all platforms #----------------------------------------------------------------------------- -# This new makefile replaces the previous Makefile/Makefile.linux -# with as much common code for both environments as possible. -# Following is a short OS detection to set up variables, all the -# remaining Makefile should be portable and only depend on these -# variables -# - -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 - # Make sure that all is the default target # (The including Makefile still needs to define what 'all' is) -platform = $(shell uname) - all: -CROSS ?= arm-none-eabi- +# This Makefile might have been called from various subdirs, trying to find our Makefile.defs +ifeq ($(DEFSBEENHERE),) + -include Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + -include ../../Makefile.defs +endif +ifeq ($(DEFSBEENHERE),) + $(error Can't find Makefile.defs) +endif + CC = $(CROSS)gcc AS = $(CROSS)as LD = $(CROSS)ld OBJCOPY = $(CROSS)objcopy -GZIP=gzip -MV=mv OBJDIR = obj INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. -TAR=tar -TARFLAGS = -C .. -rvf - -# Windows' echo echos its input verbatim, on Posix there is some -# amount of shell command line parsing going on. echo "" on -# Windows yields literal "", on Linux yields an empty line -ifeq ($(shell echo ""),) -DELETE=rm -rf -MOVE=mv -COPY=cp -PATHSEP=/ -FLASH_TOOL=client/flasher -# This is probably a proper system, so we can use uname -DETECTED_OS=$(platform) -else - -# Assume that we are running on Windows. -DELETE=del /q -MOVE=ren -COPY=copy -PATHSEP=\\# -FLASH_TOOL=client\\flasher.exe -DETECTED_OS=Windows - -endif - # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index af80bc6ac..22ae385c3 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -14,37 +14,29 @@ define KNOWN_PLATFORM_DEFINITIONS Known definitions: -+==========================================================+ -| PLATFORM | DESCRIPTION | -+==========================================================+ -| PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3EVO | Proxmark3 EVO with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | -+----------------------------------------------------------+ -| PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | -+----------------------------------------------------------+ -| PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | -+----------------------------------------------------------+ -| PM3OLD512 | Proxmark3 V1 with AT91SAM7S512 | -+----------------------------------------------------------+ ++============================================+ +| PLATFORM | DESCRIPTION | ++============================================+ +| PM3RDV4 (def) | Proxmark3 rdv4 | ++--------------------------------------------+ +| PM3OTHER | Proxmark3 Generic target | ++--------------------------------------------+ -+==========================================================+ -| PLATFORM_EXTRAS | DESCRIPTION | -+==========================================================+ -| BTADDON | Proxmark3 rdv4 BT add-on | -+----------------------------------------------------------+ ++============================================+ +| PLATFORM_EXTRAS | DESCRIPTION | ++============================================+ +| BTADDON | Proxmark3 rdv4 BT add-on | ++--------------------------------------------+ endef define HELP_DEFINITIONS Options to define platform, platform extras and/or standalone mode: -(1) Run make with PLATFORM, PLATFORM_EXTRAS and/or STANDALONE as follows: -make PLATFORM=PM3EASY STANDALONE=$(HELP_EXAMPLE_STANDALONE) +(1) Run make with your PLATFORM, PLATFORM_EXTRAS and/or STANDALONE choices as follows: +make PLATFORM=PM3OTHER STANDALONE=$(HELP_EXAMPLE_STANDALONE) -(2) Save a file called Makefile.platform with contents: -PLATFORM=PM3EASY +(2) Save a file called Makefile.platform with contents, e.g.: +PLATFORM=PM3OTHER or if you have a Proxmark 3 RDV4 with the BT add-on: PLATFORM=PM3RDV4 @@ -64,24 +56,10 @@ endef PLTNAME = Unknown Platform ifeq ($(PLATFORM),PM3RDV4) - MCU = AT91SAM7S512 PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH PLTNAME = Proxmark3 rdv4 -else ifeq ($(PLATFORM),PM3EVO) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 EVO -else ifeq ($(PLATFORM),PM3EASY) - MCU = AT91SAM7S256 - PLTNAME = Proxmark3 rdv3 Easy -else ifeq ($(PLATFORM),PM3RDV2) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 rdv2 -else ifeq ($(PLATFORM),PM3OLD256) - MCU = AT91SAM7S256 - PLTNAME = Proxmark3 V1 with AT91SAM7S256 -else ifeq ($(PLATFORM),PM3OLD512) - MCU = AT91SAM7S512 - PLTNAME = Proxmark3 V1 with AT91SAM7S512 +else ifeq ($(PLATFORM),PM3OTHER) + PLTNAME = Proxmark3 Generic target else $(error Invalid or empty PLATFORM: $(PLATFORM). $(KNOWN_DEFINITIONS)) endif @@ -168,7 +146,6 @@ export PLATFORM export PLATFORM_EXTRAS export PLATFORM_EXTRAS_INFO export PLTNAME -export MCU export PLATFORM_DEFS export PLATFORM_DEFS_INFO export PLATFORM_DEFS_INFO_STANDALONE diff --git a/common_arm/default_version.c b/common_arm/default_version.c index e1e5dc64c..b4b8ae17d 100644 --- a/common_arm/default_version.c +++ b/common_arm/default_version.c @@ -1,5 +1,5 @@ #include "proxmark3_arm.h" -/* This is the default version.c file that Makefile.common falls back to if perl is not available */ +/* This is the default version.c file that Makefile.common falls back to if neither sh nor perl are available */ const struct version_information __attribute__((section(".version_information"))) version_information = { VERSION_INFORMATION_MAGIC, 1, /* version 1 */ diff --git a/doc/bt_manual_v10.md b/doc/bt_manual_v10.md index 5f140976f..38f5f0d3b 100644 --- a/doc/bt_manual_v10.md +++ b/doc/bt_manual_v10.md @@ -128,7 +128,7 @@ connection is successful. 4. Use Proxmark client on BT-serial port ```sh -./proxmark /dev/rfcomm0 +./proxmark3 /dev/rfcomm0 ``` The first time, your OS will ask you for pairing. The default PIN is 1234. If PIN is not typed in quickly, the client might timeout. Simply @@ -169,7 +169,7 @@ turn on solid. 4. a serial port `/dev/ttyUSB0` will be created, use Proxmark3 client on it ```sh -./proxmark /dev/ttyUSB0 +./proxmark3 /dev/ttyUSB0 ``` #### MacOS @@ -191,7 +191,7 @@ After reboot you can go ahead to pairing your Proxmark3 RDV4 Blue Shark: 8. A serial port like `/dev/tty.PM3_RDV40-DevB` will be created, use Proxmark3 client on it ```sh -./proxmark /dev/tty.PM3_RDV40-DevB +./proxmark3 /dev/tty.PM3_RDV40-DevB ``` #### Android diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 63c74d1a3..4a61ae7d2 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -1,4 +1,6 @@ # Command Cheat Sheet + + |Generic|Low Frequence 125 kHz|High Frequence 13.56 MHz| |---|---|---| |[Generic](#Generic)|[T55XX](#T55XX)|[Mifare](#Mifare)| @@ -10,6 +12,7 @@ ## Generic +^[Top](#top) Identify High Frequency cards ``` @@ -37,12 +40,13 @@ pm3 --> hw status ``` ## iClass +^[Top](#top) Reverse permute iClass master key ``` Options --- -r reverse permuted key +r reverse permuted key pm3 --> hf iclass permute r 3F90EBF0910F7B6F ``` @@ -162,10 +166,11 @@ p : EPURSE m : macs e : elite -pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f default_iclass_keys.dic e +pm3 --> hf iclass lookup u 010a0ffff7ff12e0 p feffffffffffffff m 66348979153c41b9 f iclass_default_keys e ``` ## Mifare +^[Top](#top) Check for default keys ``` @@ -176,14 +181,14 @@ Options card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K d : write keys to binary file -pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf chk *1 ? d mfc_default_keys ``` Check for default keys from local memory ``` Options --- -card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K +card memory : 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K m : use dictionary from flashmemory pm3 --> hf mf fchk 1 m @@ -240,7 +245,7 @@ pm3 --> hf mf eload 353C2AA6 pm3 --> hf mf eload 1 353C2AA6 ``` -Simulate Mifare +Simulate Mifare ``` u : (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used @@ -249,7 +254,7 @@ pm3 --> hf mf sim u 353c2aa6 Simulate Mifare Sequence ``` -pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf chk *1 ? d mfc_default_keys pm3 --> hf mf dump 1 pm3 --> script run dumptoemul -i dumpdata.bin pm3 --> hf mf eload 353C2AA6 @@ -258,12 +263,13 @@ pm3 --> hf mf sim u 353c2aa6 Clone Mifare 1K Sequence ``` -pm3 --> hf mf chk *1 ? d default_keys.dic +pm3 --> hf mf chk *1 ? d mfc_default_keys pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` ## HID Prox +^[Top](#top) Read HID Prox card ``` @@ -279,10 +285,10 @@ Convert Site & Facility code to Wiegand ``` Options --- - -OEM : OEM number / site code -FC : facility code -CN : card number + +OEM : OEM number / site code +FC : facility code +CN : card number pm3 --> lf hid wiegand 0 56 150 ``` @@ -313,6 +319,7 @@ pm3 --> lf hid brute v a 26 f 21 c 200 d 2000 ``` ## Indala +^[Top](#top) Read Indala card ``` @@ -343,6 +350,7 @@ pm3 --> lf indala clone a0000000c2c436c1 ``` ## Hitag +^[Top](#top) Read Hitag information ``` @@ -368,7 +376,7 @@ pm3 --> lf hitag 26 pm3 --> lf hitag 21 4D494B52 ``` -Sniff Hitag traffic +Sniff Hitag traffic ``` pm3 --> lf hitag sniff pm3 --> lf hitag list @@ -376,7 +384,7 @@ pm3 --> lf hitag list Simulate Hitag ``` -pm3 --> lf hitag sim c378181c_a8f7.ht2 +pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` Write to Hitag block @@ -397,10 +405,11 @@ pm3 --> lf hitag writer 24 499602D2 1 00000000 Simulate Hitag2 sequence ``` pm3 --> lf hitag reader 21 56713368 -pm3 --> lf hitag sim c378181c_a8f7.ht2 +pm3 --> lf hitag sim c378181c_a8f7.ht2 ``` ## T55XX +^[Top](#top) Detect T55XX card ``` @@ -423,16 +432,16 @@ Set timings to default ``` Options --- -p : persist to flashmemory -z : Set default t55x7 timings (use p to save if required) +p : persist to flashmemory +z : Set default t55x7 timings (use p to save if required) pm3 --> lf t55xx deviceconfig z p ``` Write to T55xx block ``` -b : block number to write. Between 0-7 -d : 4 bytes of data to write (8 hex characters) +b : block number to write. Between 0-7 +d : 4 bytes of data to write (8 hex characters) pm3 --> lf t55xx wr b 0 d 00081040 ``` @@ -443,6 +452,7 @@ pm3 --> lf t55xx wipe ``` ## Data +^[Top](#top) Get raw samples [512-40000] ``` @@ -460,6 +470,7 @@ pm3 --> data load ``` ## Lua Scripts +^[Top](#top) List Lua Scripts @@ -489,30 +500,33 @@ pm3 --> script run formatMifare -k FFFFFFFFFFFF -n FFFFFFFFFFFF -x ``` ## Memory +^[Top](#top) Load default keys into memory ``` Options --- -o : offset in memory -f : file name -m : upload 6 bytes keys (mifare key dictionary) -i : upload 8 bytes keys (iClass key dictionary) -t : upload 4 bytes keys (pwd dictionary) +o : offset in memory +f : file name +m : upload 6 bytes keys (mifare key dictionary) +i : upload 8 bytes keys (iClass key dictionary) +t : upload 4 bytes keys (pwd dictionary) -pm3 --> mem load f default_keys m -pm3 --> mem load f default_pwd t -pm3 --> mem load f default_iclass_keys i +pm3 --> mem load f mfc_default_keys m +pm3 --> mem load f t55xx_default_pwds t +pm3 --> mem load f iclass_default_keys i ``` ## Sim Module +^[Top](#top) Upgrade Sim Module firmware ``` -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +pm3 --> sc upgrade f ../tools/simmodule/sim011.bin ``` ## Smart Card +^[Top](#top) Get Smart Card Information ``` @@ -528,26 +542,26 @@ Set clock speed ``` Options --- -c : clockspeed (0 = 16MHz, 1=8MHz, 2=4MHz) - -pm3 --> sc setclock c 2 +c : clockspeed (0 = 16MHz, 1=8MHz, 2=4MHz) + +pm3 --> sc setclock c 2 ``` Send raw hex data ``` Options ---- -r : do not read response -a : active smartcard without select (reset sc module) -s : active smartcard with select (get ATR) -t : executes TLV decoder if it possible -0 : use protocol T=0 -d : bytes to send - -pm3 --> sc raw s 0 d 00a404000e315041592e5359532e4444463031 : 1PAY.SYS.DDF01 PPSE directory with get ATR -pm3 --> sc raw 0 d 00a404000e325041592e5359532e4444463031 : 2PAY.SYS.DDF01 PPSE directory -pm3 --> sc raw 0 t d 00a4040007a0000000041010 : Mastercard -pm3 --> sc raw 0 t d 00a4040007a0000000031010 : Visa +--- +r : do not read response +a : active smartcard without select (reset sc module) +s : active smartcard with select (get ATR) +t : executes TLV decoder if it possible +0 : use protocol T=0 +d : bytes to send + +pm3 --> sc raw s 0 d 00a404000e315041592e5359532e4444463031 : 1PAY.SYS.DDF01 PPSE directory with get ATR +pm3 --> sc raw 0 d 00a404000e325041592e5359532e4444463031 : 2PAY.SYS.DDF01 PPSE directory +pm3 --> sc raw 0 t d 00a4040007a0000000041010 : Mastercard +pm3 --> sc raw 0 t d 00a4040007a0000000031010 : Visa ```` Bruteforce SPI @@ -556,6 +570,6 @@ Options --- t : executes TLV decoder if it possible -pm3 --> sc brute +pm3 --> sc brute pm3 --> sc brute t ``` diff --git a/doc/emv_notes.md b/doc/emv_notes.md new file mode 100644 index 000000000..a289d8ea5 --- /dev/null +++ b/doc/emv_notes.md @@ -0,0 +1,141 @@ +# EMV commands + + +### EMV Implemented parts: + +- Get ATR|ATS +- Get AID by PSE (`emv pse`) +- Get AID by appliation list (`emv search`) +- Select application (`emv select`) +- Format PDOL (look at next part) +- Execute GPO (`emv gpo` this step and format PDOL) +- Get records from AFL (`emv readrec`) +- Make SDA (check records from GPO) +- Make DDA (`emv challenge` `emv intauth`) +- Check PIN (`not implemented`) +- Fill CDOL1 and CDOL2 (look at next part) +- Execute AC1 (with CDA support) (`emv genac`) +- Check ARQC (bank part) (`not implemented`) +- Make ARPC (bank part) (`not implemented`) +- Execute external authenticate (`not implemented`) +- Execute AC2 (with CDA support) (`not implemented`) +- Check ARQC cryptogram (`not implemented`) +- Issuer scripts processing (`not implemented`) + +### Working parts of qVSDC: +^[Top](#top) + +- Get ATR|ATS +- Get AID by PSE (`emv pse`) +- Get AID by appliation list (`emv search`) +- Select application (`emv select`) +- Format PDOL (look at next part) +- Execute GPO (`emv gpo` this step and format PDOL) +- Get records from AFL (`emv readrec`) +- Make fDDA (`emv challenge` `emv intauth`) +- External authenticate command (`not implemented`) +- Issuer scripts processing (`not implemented`) + +### `not implemented` parts of EMV +^[Top](#top) + +They can be implemented, but it needs to know issuer's card keys (usually 3DES) and now this parts can be tested only on special test cards. + +### Commands +^[Top](#top) + +All this commands are parts of command `emv exec`. +command `emv exec` executes EMV transaction. it have parameters: +``` + -j, -J, --jload Load transaction parameters from `emv/defparams.json` file. + -f, -F, --forceaid Force search AID. Search AID instead of execute PPSE. + By default: Transaction type - MSD + -v, -V, --qvsdc Transaction type - qVSDC or M/Chip. + -c, -C, --qvsdccda Transaction type - qVSDC or M/Chip plus CDA (SDAD generation). + -x, -X, --vsdc Transaction type - VSDC. + -g, -G, --acgpo VISA. generate AC from GPO. + -w, -W, --wired Send data via contact (iso7816) interface. Contactless interface set by default. +``` +It works for VISA(r) and Mastercard(r) transactions. It may work with other EMV payment system's card (and it works in general cases that is described in EMV). + +### VISA(r) transactions: +^[Top](#top) + +MSD - Magnetic Stripe mode +VSDC - contact transacion +qVSDC - contactless transaction + +### Mastercard(r) transactions +^[Top](#top) + +MSD - Magnetic Stripe mode +M/Chip - contact and contactless transaction + +Different cards have different modes on/of and different behavior in them. So needs to check card in all this modes. +MSD - compatibility mode. Now it work always. But it less secure and in near future it will be slowly) disabled. + +### all commands: +^[Top](#top) + +``` +exec Executes EMV contactless transaction. +pse Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory. +search Try to select all applets from applets list and print installed applets. +select Select applet. +gpo Execute GetProcessingOptions. +readrec Read files from card. +genac Generate ApplicationCryptogram. +challenge Generate challenge. +intauth Internal authentication. +scan Scan EMV card and save it contents to json file for emulator. +test Crypto logic test. +list List ISO7816 history +roca Extract public keys and run ROCA test +``` + +All main commands are parts of EMV specification. Commands than not described there: + +`emv scan` - scans card and saves all records to json file. Can be executed with or without tags disassembly. + +`emv roca` - extract public keys from cards (part of `emv scan`) + +`emv test` - test all crypto code from emv part of proxmark. + +### Useful links: +^[Top](#top) + +EMV specifications +http://www.emvco.com/specifications.aspx?id=155 + +Excelent explanation of EMV +http://www.openscdp.org/scripts/emv/index.html + +Fully working terminal written in Ruby. +https://code.google.com/p/ruby-pboc2-lib/source/browse/trunk/lib/pboc.rb + +EMV kernel written in C++ +https://github.com/ntufar/EMV/tree/master/EMV_Library + +C EMV library (part of this library uses proxmark) +https://github.com/lumag/emv-tools + +Resources (keys, country codes, etc): +https://github.com/binaryfoo/emv-bertlv/tree/master/src/main/resources + +### EMV kernels +^[Top](#top) + +POS terminal checks card and selects one of EMV kernels and launches it for EMV transaction. Different kernels have different rules to make EMV transaction. + +This list from: + +EMVco Architecture and General Requirement V2.4 volume A. +EMVco Entry Point specification V2.4 volume B + +- EMVco C-1 Kernel 1 V2.4 for some cards with JCB AIDs and some cards with Visa AIDs +- EMVco C-2 Kernel 2 V2.4 for MasterCards AIDs +- EMVco C-3 Kernel 3 V2.4 for Visa AIDs +- EMVco C-4 Kernel 4 V2.4 for American Express AIDs +- EMVco C-5 Kernel 5 V2.4 for JCB AIDs +- EMVco C-6 Kernel 6 V2.4 for Discover AIDs +- EMVco C-7 Kernel 7 V2.4 for UnionPay AIDs diff --git a/doc/extensions_notes.md b/doc/extensions_notes.md new file mode 100644 index 000000000..f8d4c75c1 --- /dev/null +++ b/doc/extensions_notes.md @@ -0,0 +1,17 @@ +# Notes on file extensions + +The Proxmark3 client uses a wide range of files. Here is a brief recap to get you up to speed. + +| extension | description| +|---|---| +| .exe | windows executable | +| .bin | binary file, can be firmware or memory dump of a tag | +| .eml | text file, with memory dump of a tag | +| .mfd | binary file, usually created with Mifare Classic Tool app (MCT), contains memory dump of tag. Very similar to .bin file | +| .json | JSON file, usually settings file or it can also be a memory dump of a tag | +| .dic | dictionary file. textual, with keys/passwords one line / key | +| .elf | binary proxmark3 device firmware file. | +| .cmd | text file, contains proxmark3 client commands used to call client with -s | +| .lua | text file, contains lua script to be run inside client. or called with -l | +| .pm3 | text file, with numbers ranging 0-255 or -127 - 128. Contains trace signal data for low frequency tags (data load) | +| .trace | binary file, contains trace log data usually from high frequency tags. (hw trace load) | diff --git a/doc/loclass_notes.md b/doc/loclass_notes.md new file mode 100644 index 000000000..2684ae433 --- /dev/null +++ b/doc/loclass_notes.md @@ -0,0 +1,26 @@ +# About LOCLASS attack + +This document is primarily intended for understanding `hf iclass loclass` and files used with it. + +LOCLASS aim is to recoved the used masterkey for that specific reader configued in Elite mode / High Security mode. + +LOCLASS, is a two part attack. First is the online part where you gather needed information from the reader by presenting a carefully selected CSN and save the responses to file. For the first part you run `hf iclass sim 2` and take notice of the saved filename. + +The second part is offline, where the information gathered from the first step is used in a series of DES operations to figure out the used +masterkey. + run `hf iclass loclass f abc.bin` + +If you don't have access to a iClass SE reader configured in Elite mode there is a test file which you can use. + `hf iclass loclass f iclass_dump.bin` + + +# Unit testing +In order to verify that loclass is actually working, there is a "unit" test mode. +run `hf iclass loclass t`. + +This test mode uses two files. + +- `iclass_dump.bin` + this is a sample file from `hf iclass sim 2`, with complete keytable recovery, using 128 carefully selected CSN and the file contains the MAC results from reader. +- `iclass_key.bin` + this is file shall contain the legacy masterkey, AA1 key. loclass uses it to verify that permution / reversing / generation of key is correct. \ No newline at end of file diff --git a/doc/md/Development/Maintainers.md b/doc/md/Development/Maintainers.md new file mode 100644 index 000000000..ff3525784 --- /dev/null +++ b/doc/md/Development/Maintainers.md @@ -0,0 +1,73 @@ +# Hi maintainers! + +Here are some tips how to integrate this repo in some nice package for your distro. +Feel free to contact us via Github issues for any question, suggestion or if you want to share useful tricks in this file for other maintainers. + +Makefile +======== + +`PREFIX` and `UDEV_PREFIX` can be provided by environment variable, else it defaults to `/usr/local/share` and `/etc/udev/rules.d`. + +`DESTDIR` can be provided by environment variable, it can be a relative path and it will be prepended to `PREFIX`, so you can use e.g.: + +``` +make -j +make install DESTDIR=build PREFIX=/usr UDEV_PREFIX=/lib/udev/rules.d +``` + +and it will be deployed as + +``` +./build/lib/udev/rules.d/77-pm3-usb-device-blacklist.rules +./build/usr/bin/proxmark3 ... +./build/usr/share/doc/proxmark3/... +./build/usr/share/proxmark3/firmware/fullimage.elf +etc. +``` + +That should be a good start for you to create your package :) + +If you need to tune some more paths, see their definition in `Makefile.defs`. +E.g. you might need to move the documentation elsewhere according to your distro policy: + +``` +make install PREFIX=/usr INSTALLDOCSRELPATH=share/doc/proxmark3-${version} +``` + +It's possible to add other firmwares as well with tagged names (`FWTAG=`), e.g. here we're compiling another image for non-RDV4 devices: + +``` +make -j fullimage PLATFORM=PM3OTHER PLATFORM_EXTRAS= +make fullimage/install PLATFORM=PM3OTHER PLATFORM_EXTRAS= DESTDIR=build PREFIX=/usr FWTAG=other +``` + +and it will be added along the other firmware as: + +``` +./build/usr/share/proxmark3/firmware/fullimage-other.elf +``` + +For verbose usage and see the actual commands being executed, add `V=1`. + +`CFLAGS` and `LDFLAGS` can be overriden by environment variables. + +Default compiler is gcc but you can use clang for the non-ARM parts with e.g. `make client CC=clang CXX=clang++ LD=clang++`. + +`make install` is actually triggering the following individual targets which can be accessed individually: + +* `make client/install` +* `make bootrom/install` +* `make fullimage/install` (alias of `make armsrc/install`) +* `make recovery/install` +* `make mfkey/install` +* `make nonce2key/install` +* `make fpga_compress/install` (dummy) +* `make common/install` (some shared content installation:) + * `pm3-*` scripts + * `tools/jtag_openocd`, `traces` + * `doc/md`, `doc/*.md` + * Tools scripts (`pm3_eml2lower.sh` etc) + * SIM firmware + * udev rule on Linux + +Same logic for `make all`, `make clean`, `make uninstall` diff --git a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md index fe23db001..70d102aa3 100644 --- a/doc/md/Installation_Instructions/Linux-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Linux-Installation-Instructions.md @@ -24,28 +24,32 @@ sudo apt-get update Install the requirements ```sh -sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev \ -libusb-0.1-4 libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libnewlib-dev libqt4-dev +sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` -If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. If you get some (non blocking) error at runtime such as _Gtk-Message: Failed to load module "canberra-gtk-module"_ you may have to install `libcanberra-gtk-module`. ## On ArchLinux ```sh -sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-gcc arm-none-eabi-newlib git --needed -``` -Additional AUR packages: -```sh -yaourt -S termcap +sudo pacman -Sy base-devel readline arm-none-eabi-gcc arm-none-eabi-newlib git --needed ``` If you want graphical output (such as in `hw tune`): ```sh sudo pacman -Su qt5-base ``` +## On Fedora + +```sh +sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel qt5-qtbase-devel libatomic +``` + +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qt5-qtbase-devel`. + # Clone the RRG/Iceman repository ```sh diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 34b9c3aa5..f78016df9 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -1,4 +1,7 @@ -# Homebrew (Mac OS X) +# Homebrew (Mac OS X), automatic installation + +## Install Proxmark3 tools + These instructions comes from @Chrisfu, where we got the proxmark3.rb scriptfile from. For further questions about Mac & Homebrew, contact @Chrisfu (https://github.com/chrisfu/) @@ -8,7 +11,9 @@ For further questions about Mac & Homebrew, contact @Chrisfu (https://github.c 3. Install Proxmark3: `brew install proxmark3` for stable release or `brew install --HEAD proxmark3` for latest non-stable from GitHub. -## Upgrading HomeBrew tap formula +For more info, go to https://github.com/RfidResearchGroup/homebrew-proxmark3 + +## Upgrade HomeBrew tap formula *This method is useful for those looking to run bleeding-edge versions of RRG/iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.* @@ -24,21 +29,33 @@ brew upgrade --fetch-HEAD proxmark3 ## Flash the BOOTROM & FULLIMAGE -With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. Continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!" +With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're un bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. + +In principle, the helper script `pm3-flash-all` should auto-detect your port, so you can just try: ```sh -sudo proxmark3-flasher /dev/tty.usbmodemiceman1 -b /usr/local/Cellar/proxmark3/HEAD-/share/firmware/bootrom.elf /usr/local/Cellar/proxmark3/HEAD-/share/firmware/fullimage.elf +pm3-flash-all ``` -> Replace \ with the HEAD-XXXX ID displayed by brew. -> Depending on the firmware version your Proxmark3 can also appear as `/dev/tty.usbmodem881` +If port detection failed, you'll have to call the flasher manually and specify the correct port: +```sh +proxmark3 /dev/tty.usbmodemiceman1 --flash --unlock-bootloader --image /usr/local/share/proxmark3/firmware/bootrom.elf --image /usr/local/share/proxmark3/firmware/fullimage.elf +``` + +> Depending on the firmware version your Proxmark3 can also appear as `/dev/tty.usbmodem881`. ## Run the client ```sh -sudo proxmark3 /dev/tty.usbmodemiceman1 +pm3 +``` + +or, if the port doesn't get properly detected: + +```sh +proxmark3 /dev/tty.usbmodemiceman1 ``` ## Next steps @@ -50,3 +67,31 @@ For the next steps, please read the following pages: * [Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)| + + +# Homebrew (Mac OS X), developer installation + +These instructions will show how to setup the environment on OSX to the point where you'll be able to clone and compile the repo by yourself, as on Linux, Windows, etc. + +1. Install homebrew if you haven't yet already done so: http://brew.sh/ + +2. Install dependencies: + +``` +brew install readline qt5 pkgconfig +brew install RfidResearchGroup/proxmark3/arm-none-eabi-gcc +``` + +## Compile and use the project + +To use the compiled client, the only difference is that the Proxmark3 port is `/dev/tty.usbmodemiceman1`, so commands become: + +```sh +proxmark3 /dev/ttyACM0 => proxmark3 /dev/tty.usbmodemiceman1 +``` + +Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). + +To flash on OS X, better to enter the bootloader mode manually, else you may experience errors. +With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're in bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've an old bootloader, start over and keep the button pressed during the whole flashing procedure. +From there, you can follow the original compilation instructions. diff --git a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md index 68b69ea7b..23ae480cc 100644 --- a/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md +++ b/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md @@ -121,7 +121,7 @@ In short: * unplug device * press button and keep it pressed (IMPORTANT) * plug in device -* run flash command `sudo client/flasher /dev/ttyACM0 armsrc/obj/fullimage.elf` +* run flash command `pm3-flash-fullimage` * wait until flash is finished * release button * un/plug device diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index b4ed877cb..e0cf7f7aa 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -4,13 +4,26 @@ Always use the latest repository commits from *master* branch. There are always many fixes done almost daily. -## `./proxmark.sh` or `./flash-*.sh` doesn't see my Proxmark +## Table of Contents -Try using directly the client or flasher: + * [pm3 or pm3-flash* doesn't see my Proxmark](#pm3-or-pm3-flash-doesnt-see-my-proxmark) + * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) + * [Maybe just a false alarm?](#maybe-just-a-false-alarm) + * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) + * [Determine if the bootloader was damaged or only the main OS image](#determine-if-the-bootloader-was-damaged-or-only-the-main-os-image) + * [Ok, my bootloader is definitively dead, now what?](#ok-my-bootloader-is-definitively-dead-now-what) + * [Slow to boot or difficulties to enumerate the device over USB](#slow-to-boot-or-difficulties-to-enumerate-the-device-over-usb) + * [Troubles with SIM card reader](#troubles-with-sim-card-reader) + * [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries) + * [File not found](#file-not-found) + * [pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + +## `pm3` or `pm3-flash*` doesn't see my Proxmark + +Try using directly the client: ``` -client/flasher ... -client/proxmark ... +client/proxmark3 ... ``` Refer to the installation guide specific to your OS for details about ports. @@ -30,13 +43,13 @@ Note that with the Bluetooth adapter, you *have to* use directly the client, and The flasher refused to flash your Proxmark3? Are there any messages in *red*? The most common reason is that the Proxmark3 RDV4 firmware recently got a new bootloader able to handle larger firmwares and... the image grew over 256k almost at the same time. So your old bootloader can't flash such new images. But it's easy, you just need to flash *first* the bootloader *only*, then the image. ``` -./flash-bootrom.sh -./flash-fullimage.sh +pm3-flash-bootrom +pm3-flash-fullimage ``` or ``` -client/flasher -b bootrom/obj/bootrom.elf -client/flasher armsrc/obj/fullimage.elf +proxmark3 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf +proxmark3 --flash --image armsrc/obj/fullimage.elf ``` ### Find out why it would be bricked @@ -53,21 +66,21 @@ On new bootloaders, you can release the button. If the pattern disappears, you'r Once in bootloader mode, flash the main image. ``` -./flash-fullimage.sh +pm3-flash-fullimage ``` or ``` -client/flasher armsrc/obj/fullimage.elf +proxmark3 --flash --image armsrc/obj/fullimage.elf ``` You should be back on tracks now. In case the flasher complains about bootloader version, you can follow the button procedure and flash first your bootloader. ``` -./flash-bootrom.sh +pm3-flash-bootrom ``` or ``` -client/flasher -b bootrom/obj/bootrom.elf +proxmark3 --flash --unlock-bootloader --image bootrom/obj/bootrom.elf ``` ### Ok, my bootloader is definitively dead, now what? @@ -76,7 +89,7 @@ At this point, only reflashing via JTAG can revive your Proxmark3. See [details here](/doc/jtag_notes.md). -## Slow to boot +## Slow to boot or difficulties to enumerate the device over USB You're using another Proxmark3 than a RDV4? The RDV4 firmware can run on other Proxmark3 as such but the booting procedure is a bit slower because of the absence of SIM and external flash. @@ -95,34 +108,52 @@ Instructions evolve over time so check if you're still up to date! ## File not found -Depending how you launch the client, your working directory might be the root of the repository: +If Proxmark3 has been installed with `make install` or packaged for your distro, the binaries should be in your path and you can call them directly: ``` -./proxmark.sh ... -client/proxmark ... +pm3 +proxmark3 +``` + +and you must adapt accordingly the file path of some commands, e.g. + +``` +proxmark3 --flash --image /usr/local/share/proxmark3/firmware/fullimage.elf +<> +proxmark3 --flash --image /usr/share/proxmark3/firmware/fullimage.elf + +pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin +<> +pm3 --> sc upgrade f /usr/share/proxmark3/firmware/sim011.bin +``` + +If you didn't install the PRoxmark but you're working from the sources directory and depending how you launch the client, your working directory might be the root of the repository: + +``` +./pm3 ... +client/proxmark3 ... ``` or the `client/` subdirectory: ``` -cd client; ./proxmark ... +cd client; ./proxmark3 ... ``` Therefore client commands referring to files of the repo must be adapted, e.g. ``` -pm3 --> sc upgrade f tools/simmodule/SIM011.BIN +client/proxmark3 --flash --image armsrc/obj/fullimage.elf <> -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN -``` +./proxmark3 --flash --image ../armsrc/obj/fullimage.elf -``` -pm3 --> mem load f default_keys m +pm3 --> sc upgrade f tools/simmodule/sim011.bin <> -pm3 --> mem load f client/default_keys m +pm3 --> sc upgrade f ../tools/simmodule/sim011.bin ``` etc. -This also affects where your history and logfile will be read from and written to. +## pixmap / pixbuf warnings +If you get warnings related to pixmap or pixbuf such as *Pixbuf theme: Cannot load pixmap file* or *Invalid borders specified for theme pixmap*, it's a problem of your Theme, try another one and the problem should vanish. See e.g. [#354](https://github.com/RfidResearchGroup/proxmark3/issues/354) (Yaru theme on Ubuntu) and [#386](https://github.com/RfidResearchGroup/proxmark3/issues/386) (Kali-X theme on Kali). diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index db9a9084f..9cd150a22 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -19,7 +19,7 @@ Step by step guides are online such as [RiscCorps](https://store.ryscc.com/blogs ## Download / clone ProxSpace repo -Download the Gator96100 ProxSpace package from https://github.com/Gator96100/ProxSpace/ +Download the Gator96100 ProxSpace package from https://github.com/Gator96100/ProxSpace/releases If you prefer, you can clone it, provided that you installed Github for Windows https://desktop.github.com/. @@ -52,34 +52,14 @@ pacman -S mingw-w64-x86_64-astyle ## Compile and use the project +To use the compiled client, the only differences are that executables end with `.exe` (e.g. `proxmark3.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows, so commands become: + +```sh +proxmark3 /dev/ttyACM0 => proxmark3.exe comX +``` + Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). -To use the compiled client and flasher, the only differences are that executables end with `.exe` (e.g. `client/flasher.exe`) and that the Proxmark3 port is one of your `comX` ports where "X" is the com port number assigned to proxmark3 under Windows. - -To flash: In principle, the helper script `flash-all.sh` should auto-detect your COM port, so you can just try: - -```sh -./flash-all.sh -``` - -If COM port detection failed, you'll have to call the flasher manually and specify the correct port: - -```sh -client/flasher.exe comX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf -``` - -Similarly, to run the client, you may try: - -```sh -./proxmark3.sh -``` - -Or, by specifying the COM port manually: - -```sh -client/proxmark3.exe comX -``` - # Installing on Windows with WSL It requires to run a Windows 10 version 1709 or above. Previous versions didn't have support for COM ports. @@ -98,12 +78,11 @@ Enter WSL prompt (`wsl`) and from there, follow the [Linux Installation Instruct ```sh sudo apt-get update -sudo apt-get install p7zip git ca-certificates build-essential libreadline5 libreadline-dev libusb-0.1-4 \ -libusb-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi libstdc++-arm-none-eabi-newlib \ -libqt4-dev +sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \ +libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev ``` -If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `libqt4-dev`. +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. ## Clone the RRG/Iceman repository @@ -113,9 +92,11 @@ git clone https://github.com/RfidResearchGroup/proxmark3.git ## Compile and use the project -Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). +To use the compiled client, the only difference is that the Proxmark3 port is translated from your `comX` port where "X" is the com port number assigned to proxmark3 under Windows, to a `/dev/ttySX`, so commands become: -To use the compiled client and flasher, the only difference is that the Proxmark3 port is translated from your `comX` port where "X" is the com port number assigned to proxmark3 under Windows, to a `/dev/ttySX`. +```sh +proxmark3 /dev/ttyACM0 => proxmark3 /dev/ttySX +``` Depending on the Windows version, you might need to give permission to the current user to access `/dev/ttySX`: (change X to your port number) @@ -142,28 +123,6 @@ and add it to your Bash profile for the next times: echo "export DISPLAY=:0" >> ~/.bashrc ``` -To flash: In principle, the helper script `flash-all.sh` should auto-detect your COMX==/dev/ttySX port, so you can just try: - -```sh -./flash-all.sh -``` - -If port detection failed, you'll have to call the flasher manually and specify the correct port: - -```sh -client/flasher /dev/ttySX -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf -``` - -Similarly, to run the client, you may try: - -```sh -./proxmark3.sh -``` - -Or, by specifying the COM port manually: - -```sh -client/proxmark3 /dev/ttySX -``` - Note that it may take a quite long time for a freshly plugged Proxmark3 to be visible on a WSL /dev/ttySX port. + +Now you're ready to follow the [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md). diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index 7493fba1a..e423752ab 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -24,27 +24,62 @@ git pull make clean && make all ``` -## Flash the BOOTROM & FULLIMAGE +## Install -In most cases, you can run the script `flash-all.sh` which try to auto-detect the port to use, on several OS. - -For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: +This is an optional step. If you do ```sh -client/flasher /dev/ttyACM0 -b bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf +sudo make install +``` + +Then the required files will be installed on your system, by default in `/usr/local/bin` and `/usr/local/share/proxmark3`. +Maintainers can read [this doc](../Development/Maintainers.md) to learn how to modify installation paths via `DESTDIR` and `PREFIX` Makefile variables. + +The commands given in the documentation assume you did the installation step. If you didn't, you've to adjust the commands paths and files paths accordingly, +e.g. calling `./pm3` or `client/proxmark3` instead of just `pm3` or `proxmark3`. + +## Flash the BOOTROM & FULLIMAGE + +In most cases, you can run the following script which try to auto-detect the port to use, on several OS: + +```sh +pm3-flash-all +``` + +For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux (adjust the port for your OS): + +```sh +proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image bootrom.elf --image fullimage.elf +``` + +The firmware files will be searched in the expected locations (installed files, working repo files, user folder, etc.). You can also specify their location: + +```sh +pm3-flash -b /tmp/my-bootrom.elf /tmp/my-fullimage.elf +``` + +or + +```sh +proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image /tmp/my-bootrom.elf --image /tmp/my-fullimage.elf ``` ## Run the client -In most cases, you can run the script `proxmark3.sh` which try to auto-detect the port to use, on several OS. +In most cases, you can run the script `pm3` which try to auto-detect the port to use, on several OS. For the other cases, specify the port by yourself. For example, for a Proxmark3 connected via USB under Linux: -Here, for example, for a Proxmark3 connected via USB under Linux: +Here, for example, for a Proxmark3 connected via USB under Linux (adjust the port for your OS): ```sh -cd client -./proxmark3 /dev/ttyACM0 +proxmark3 /dev/ttyACM0 +``` + +or from the local repo + +```sh +client/proxmark3 /dev/ttyACM0 ``` ## Next steps diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 0d3665f37..8b88115c6 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -1,9 +1,9 @@ ### First things on your RDV40 You will need to run these commands to make sure your rdv4 is prepared ``` -pm3 --> mem load f default_keys m -pm3 --> mem load f default_pwd t -pm3 --> mem load f default_iclass_keys i +pm3 --> mem load f mfc_default_keys m +pm3 --> mem load f t55xx_default_pwds t +pm3 --> mem load f iclass_default_keys i pm3 --> lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 p pm3 --> lf t55xx deviceconfig r 1 a 31 b 20 c 18 d 50 e 15 p pm3 --> lf t55xx deviceconfig r 2 a 31 b 20 c 18 d 40 e 15 p @@ -30,11 +30,25 @@ Find version in the long output, look for these two lines #db# version.................v2.06 ``` -This version is obsolete. The following command upgrades your device sim module firmware. -Don't not turn off your device during the execution of this command!! +This version is obsolete. + +If you didn't download sim011.bin from the RRG Repo be aware that it might be corrupted or faulty. +You find a hash text file in this folder. It was generated with the following linux command. ``` -pm3 --> sc upgrade f ../tools/simmodule/SIM011.BIN +sha512sum -b sim011.bin > sim011.sha512.txt +``` + +You should validate the sim011.bin file against this hash file in order to be sure the file is not corrupted or faulty. + +The following command upgrades your device sim module firmware. +Don't not turn off your device during the execution of this command!! +Even its a quite fast command you should be warned. You may brick it if you interrupt it. + +``` +pm3 --> sc upgrade f /usr/local/share/proxmark3/firmware/sim011.bin +# or if from local repo +pm3 --> sc upgrade f tools/simmodule/sim011.bin ``` You get the following output if the execution was successful: @@ -54,6 +68,12 @@ You get the following output if the execution was successful: [+] Smartcard socket firmware upgraded successful ``` +Run hw status command to verify that the upgrade went well. + +``` +pm3 --> hw status +``` + ## Next steps For the next steps, please read the following page: diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index aea5b5e30..b4fb4384a 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -19,7 +19,7 @@ These features make it very different from all other devices, there is non other **Recommendation**: if you don't have a RDV4, we strongly recommend your device to have at least a 512kb arm chip, since this repo is on the very edge of 256kb limit. -A firmware built for the RDV4 can still run on the other platforms as it will auto-detect during boot that external SPI and Sim are not present, still it will boot faster if it's tuned to the platform. +A firmware built for the RDV4 can still run on the other platforms as it will auto-detect during boot that external SPI and Sim are not present, still it will boot faster if it's tuned to the platform, which solves USB enumeration issues on some OSes. If you need to tune things and save the configuration, create a file `Makefile.platform` in the root directory of the repository, see `Makefile.platform.sample`. For an up-to-date exhaustive list of options, you can run `make PLATFORM=`. @@ -28,17 +28,15 @@ For an up-to-date exhaustive list of options, you can run `make PLATFORM=`. Here are the supported values you can assign to `PLATFORM` in `Makefile.platform`: -| PLATFORM | DESCRIPTION | -|-----------------|----------------------------------------| -| PM3RDV4 (def) | Proxmark3 rdv4 with AT91SAM7S512 | -| PM3EVO | Proxmark3 EVO with AT91SAM7S512 | -| PM3EASY | Proxmark3 rdv3 Easy with AT91SAM7S256 | -| PM3RDV2 | Proxmark3 rdv2 with AT91SAM7S512 | -| PM3OLD256 | Proxmark3 V1 with AT91SAM7S256 | -| PM3OLD512 | Proxmark3 V1 with AT91SAM7S512 | +| PLATFORM | DESCRIPTION | +|-----------------|--------------------------| +| PM3RDV4 (def) | Proxmark3 rdv4 | +| PM3OTHER | Proxmark3 generic target | By default `PLATFORM=PM3RDV4`. +The MCU version (256 or 512) will be detected automatically during flashing. + Known issues: * 256kb Arm chip devices: The compiled firmware image from this repo may/will be too large for your device. diff --git a/doc/path_notes.md b/doc/path_notes.md new file mode 100644 index 000000000..556780f54 --- /dev/null +++ b/doc/path_notes.md @@ -0,0 +1,235 @@ +# Notes on paths. + + +With the recent (2019-09-01) changes and creation of `make install` command it is easy to get lost. + +If you install the Proxmark tools with `make install`, they will go under the prefix `/usr/local/` but if you install the tools from your distro, there are chances the path is `/usr` so you'll have to adapt the paths presented here. + +# Installed elements + +## Binaries + +The main Proxmark3 executables / shellscripts will be copied to + +``` +/usr/local/bin/ +``` + +* executables: `proxmark3` +* scripts: `pm3`, `pm3-flash`, `pm3-flash-all`, `pm3-flash-bootloader`, `pm3-flash-fullimage` + +Some more executable / scripts will be copied to + +``` +/usr/local/share/proxmark3/tools +``` + +* executables: `mfkey32`, `mfkey32v2`, `mfkey64`, `nonce2key` +* scripts: `pm3_eml2lower.sh`, `pm3_eml2upper.sh`, `pm3_mfdread.py`, `pm3_mfd2eml.py`, `pm3_eml2mfd.py`, `findbits.py`, `rfidtest.pl`, `xorcheck.py` + + +## Firmwares + +The recovery / firmware files will be copied to + +``` +/usr/local/share/proxmark3/firmware +``` + +* Proxmark3 firmware: `bootrom.elf`, `fullimage.elf`, `proxmark3_recovery.bin` (used for JTAG) +* SIM firmware: `sim011.bin`, `sim011.sha512.txt` + + +## Traces + +Proxmark3 client has a lot of sample trace files for many different low frequency tags. They will be copied to + +``` +/usr/local/share/proxmark3/traces +``` + + +## JTAG-related stuff + +JTAG configurations and helper scripts for OpenOCD will be copied to + +`/usr/local/share/proxmark3/jtag_openocd` + + +## Proxmark3 client files: dictionaries + +Dictionaries used by the client will be copied to + +``` +/usr/local/share/proxmark3/dictionaries +``` + +Here you find the default dictionaries used for commands like `hf mf chk`, `hf mf fchk`, `lf t55xx chk` +A dictionary file is a text based file with one key per line in hexdecimal form. +The length of the key is decided by the Proxmark3 client for the different commands. All chars afterwards on line is ignored. +if key isn't a hex number, the key is igonored. + +- t55xx, Mifare Ultralight/NTAG - uses 4 hexbytes (11223344) +- Mifare classic uses 6 hexbytes (112233445566) +- iClass uses 8 hexbytes (1122334455667788) + +See [here](#proxmark3-client-files-and-traces) how to add your own dictionaries. + +## Proxmark3 client files: cmd scripts + +Cmd scripts used by the client will be copied to + +``` +/usr/local/share/proxmark3/cmdscripts +``` + +See [here](#proxmark3-client-files-and-traces) how to add your own cmd scripts. + +## Proxmark3 client files: Lua libraries and scripts + +Lua libraries and scripts used by the client will be copied to + +``` +/usr/local/share/proxmark3/lualibs +/usr/local/share/proxmark3/luascripts +``` + +`lualibs` contains the supporting lua libraries used for lua scripts. Basically reused functions in a lua file like converting string to hex etc. + +See [here](#proxmark3-client-files-and-traces) how to add your own Lua scripts. + +## Proxmark3 client files: various resources + +Various resources used by the client will be copied to + +``` +/usr/local/share/proxmark3/resources +``` + +It comprises the needed files for commands like hardnested, fido, EMV, iClass. + +See [here](#proxmark3-client-files-and-traces) how to add your own resources. + +## Documentation + +Documentation will be copied to + +``` +/usr/local/share/doc/proxmark3 +``` + +# User files + +The client will make use of a personal directory `~/.proxmark3` (or more precisely `$HOME/.proxmark3`) + +## .history / log files + +We have now a rolling log file, created new per day. All these logfiles and the history file are now located at + +``` +~/.proxmark3/history.txt +~/.proxmark3/log_YYYYMMDD.txt +``` + +## Proxmark3 client files and traces + +If you wants to add scripts, dictionaries or other resources, you can use the same structure as the installed directory structure and add your own files there, e.g. + +``` +~/.proxmark3/cmdscripts/mycmdscript.cmd +~/.proxmark3/dictionaries/mydict.dic +~/.proxmark3/luascripts/myluascript.lua +~/.proxmark3/resources/oids.json +~/.proxmark3/traces/mylftrace.pm3 +``` + +If you add a file with the same name as the file provided with the Proxmark3 installation, it will take precedence. + +See also [Scripts](#scripts) on how to write your own scripts. + +# Searching files + +With the directory structure explained above, the client applies some heuristics to find its files or the files you specified in command line. + +## TL;DR + +It adds the expected suffix if you didn't provide it yet, then it looks (by order of precedence): + +1. in the current directory, or in the path if you provided also a path, so it works with autocompletion +2. in the `~/.proxmark3` directory structure as seen above, so it works with your stuffs +3. in the repo directory structure, so it works as usual if used from the Git repo +4. in the installed directory structure, so it works when installed + +## Gory details + +The client is using _searchFile_ (in _client/fileutils.c_) when calling a Proxmark3 command with a filename or when the client needs to find its files. +_searchFile_ takes as argument a relative path *pm3dir*, a file to search and possibly a *suffix*. + +So for example when using _searchFile_ over a filename supposed to be a dictionary file, it's called with *pm3dir=dictionaries/* and *suffix=.dic*. +When a user provides a filename (including possibly a path), _searchFile_ will search different locations and return as soon as a file is found: + +* Add the suffix if the suffix is not yet present, so: *foo* -> *foo.dic* and *foo.dic* -> *foo.dic* +* If the filename is an absolute path (*/tmp/foo.dic*), take it as it is, try to access the file and return. +* If the filename is an explicit relative path (*./foo.dic*), take it as it is, try to access the file from the current directory and return. +* Try to find the filename as relative path (*foo.dic* -> *./foo.dic*), so filenames provided by CLI autocompletion work as expected. +* Try to find the filename in the *pm3dir* relative to the user directory *$HOME/.proxmark3* (*foo.dic* -> *~/.proxmark3/dictionaries/foo.dic*) +* Try to find the filename in the *pm3dir* relative to where the client binary is when in the repo configuration (*foo.dic* -> *$(path_to_dir_of_proxmark3_bin)/dictionaries/foo.dic*), so when the client is executed from a repo workdir, filenames are searched in the expected location. +* Try to find the filename in the *pm3dir* relative to where the client binary is when in the installed configuration (*foo.dic* -> *$(path_to_dir_of_proxmark3_bin)/../share/proxmark3/dictionaries/foo.dic* which resolves to e.g. */usr/share/proxmark3/dictionaries/foo.dic* or */usr/local/share/proxmark3/dictionaries/foo.dic*), so when the client is executed from a repo workdir, filenames are searched in the expected location. + +# Scripts + +You can provide your own lua or cmd scripts. +Look at existing scripts for ideas how to create your own scripts. + +### Proxmark command script (.cmd) +For cmd scripts, the command line scripts, the client can run a text file containing Proxmark3 commands. + +A samplefile could be like this. +``` +$> cat myscript.cmd + +rem running some HF-based info commands +hf 14a info +hf mfu info +rem done +``` + +You call it with: + +`$> pm3 -s myscript.cmd` + +The client will execute each one of the commands in order and then exit. There is also a possibility to remain in the client afterwards with the -i parameter: + +`$> pm3 -s myscript.cmd -i` + +You can place it in `~/.proxmark3/cmdscripts/` and it will be found automatically. + +You can skip the script file extension, it works equally well with. + +`pm3 -s myscript` + + +### Shebangs (on *nix) + +You can also use the magic of shebangs to make an executable script, e.g. taking the example above, we can write: + +``` +$> cat myscript.cmd + +#!/usr/bin/env -S pm3 -s +hf 14a info +hf mfu info + +$> chmod +x myscript.cmd +$> ./myscript.cmd +``` + +And it will be executed invoking the `pm3` script. + +Use the following if your script is intended to work offline. + +``` +#!/usr/bin/env -S proxmark3 -s +``` + +Beware the shebang trick is not available on all the platforms, it requires your `env` to accept the `-S` switch. diff --git a/doc/trace_wireshark_notes.md b/doc/trace_wireshark_notes.md new file mode 100644 index 000000000..50dd9d082 --- /dev/null +++ b/doc/trace_wireshark_notes.md @@ -0,0 +1,60 @@ +# Trace command notes + +The `trace` command lists the data exchange by the proxmark3 and a tag or a reader in human readable form. + +With `trace list` a table is shown which gives timing information, the src of the data bytes, the transmitted/received bytes itself, a check if the CRC was correct and some decoding of the command. + +To get a more detailed explanation of the transmitted data for ISO14443A traces the output can be converted to a pcapng file to read it with [Wireshark](https://www.wireshark.org/). + +To do so + +* use `trace list 14a x` +* copy the output (starting with the timestamp) into a textfile +* run `text2pcap -t "%S." -l 264 -n ` +* now open your pcapng file in Wireshark or read it with the CLI version `tshark` + +An example frame + +with `trace list 14a`: + +``` +19072 | 29536 | Rdr |93 70 88 04 cf ff bc 7f bb | ok | SELECT_UID +``` + +the same data with `tshark -r foo.pcapng -V -x`: + +``` +Frame 5: 13 bytes on wire (104 bits), 13 bytes captured (104 bits) on interface 0 + Interface id: 0 (unknown) + Interface name: unknown + Encapsulation type: ISO 14443 contactless smartcard standards (177) + Arrival Time: Aug 17, 2019 23:17:00.000002606 CEST + [Time shift for this packet: 0.000000000 seconds] + Epoch Time: 1566076620.000002606 seconds + [Time delta from previous captured frame: 0.000000840 seconds] + [Time delta from previous displayed frame: 0.000000840 seconds] + [Time since reference or first frame: 0.000001907 seconds] + Frame Number: 5 + Frame Length: 13 bytes (104 bits) + Capture Length: 13 bytes (104 bits) + [Frame is marked: False] + [Frame is ignored: False] + [Protocols in frame: iso14443] +ISO 14443 + Pseudo header + Version: 0x00 + Event: Data transfer PCD -> PICC (0xfe) + Length field: 9 + Message: Select + SEL: 0x93 + NVB: 0x70 + CT: 0x88 + UID_CLn: 04cfff + BCC: 0xbc + CRC: 0xbb7f [correct] + [CRC Status: Good] + +0000 00 fe 00 09 93 70 88 04 cf ff bc 7f bb .....p....... +``` + +If the Wireshark ISO14443a dissector is missing some commands or needs some other rework please [file a bug](https://bugs.wireshark.org/bugzilla/). diff --git a/flash-all.sh b/flash-all.sh deleted file mode 100755 index d4fcdc975..000000000 --- a/flash-all.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 -. proxmark3.sh diff --git a/flash-bootrom.sh b/flash-bootrom.sh deleted file mode 100755 index d4fcdc975..000000000 --- a/flash-bootrom.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 -. proxmark3.sh diff --git a/flash-fullimage.sh b/flash-fullimage.sh deleted file mode 100755 index d4fcdc975..000000000 --- a/flash-fullimage.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 -. proxmark3.sh diff --git a/fpga/Makefile b/fpga/Makefile index b28c27db9..06cdec2ee 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -1,36 +1,36 @@ all: fpga_lf.bit fpga_hf.bit clean: - $(Q)$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp - $(Q)$(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst + $(Q)$(RM) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp + $(Q)$(RM) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_flite.v - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] XST $@) $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr fpga_lf.ngc: fpga_lf.v fpga.ucf xst_lf.scr util.v clk_divider.v lo_edge_detect.v lo_read.v lo_passthru.v lp20khz_1MSa_iir_filter.v min_max_tracker.v lf_edge_detect.v - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] XST $@) $(Q)$(XILINX_TOOLS_PREFIX)xst -ifn xst_lf.scr %.ngd: %.ngc - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] NGD $@) $(Q)$(XILINX_TOOLS_PREFIX)ngdbuild -aul -p xc2s30-5-vq100 -nt timestamp -uc fpga.ucf $< $@ %.ncd: %.ngd - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] MAP $@) $(Q)$(XILINX_TOOLS_PREFIX)map -p xc2s30-5-vq100 $< %-placed.ncd: %.ncd - $(Q)$(DELETE) $@ + $(Q)$(RM) $@ $(info [-] PAR $@) $(Q)$(XILINX_TOOLS_PREFIX)par $< $@ %.bit: %-placed.ncd - $(Q)$(DELETE) $@ $*.drc $*.rbt + $(Q)$(RM) $@ $*.drc $*.rbt $(info [=] BITGEN $@) $(Q)$(XILINX_TOOLS_PREFIX)bitgen $< $@ diff --git a/fpga/tests/Makefile b/fpga/tests/Makefile index 79ed20816..f2ae6d729 100644 --- a/fpga/tests/Makefile +++ b/fpga/tests/Makefile @@ -5,7 +5,7 @@ # at your option, any later version. See the LICENSE.txt file for the text of # the license. #----------------------------------------------------------------------------- - +MKDIR = mkdir -p TEST_OUTDIR = tb_tmp TB_SOURCES = \ @@ -62,7 +62,7 @@ tb_lf_edge_detect: tb_lf_edge_detect.vvp | test_dir rm -f $(TEST_OUTDIR)/data.* test_dir: - @if [ ! -d $(TEST_OUTDIR) ] ; then mkdir $(TEST_OUTDIR) ; fi + @if [ ! -d $(TEST_OUTDIR) ] ; then $(MKDIR) $(TEST_OUTDIR) ; fi .PHONY: all clean diff --git a/include/ansi.h b/include/ansi.h index 29df618a1..49bd46039 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -1,11 +1,14 @@ #ifndef __ANSI_H #define __ANSI_H -#define _BLUE_(s) "\x1b[34m" s "\x1b[0m " -#define _RED_(s) "\x1b[31m" s "\x1b[0m " -#define _GREEN_(s) "\x1b[32m" s "\x1b[0m " -#define _YELLOW_(s) "\x1b[33m" s "\x1b[0m " -#define _MAGENTA_(s) "\x1b[35m" s "\x1b[0m " -#define _CYAN_(s) "\x1b[36m" s "\x1b[0m " +#define AEND "\x1b[0m " + +#define _BLUE_(s) "\x1b[34m" s AEND +#define _RED_(s) "\x1b[31m" s AEND +#define _GREEN_(s) "\x1b[32m" s AEND +#define _YELLOW_(s) "\x1b[33m" s AEND +#define _MAGENTA_(s) "\x1b[35m" s AEND +#define _CYAN_(s) "\x1b[36m" s AEND +#define _WHITE_(s) "\x1b[37m" s AEND #endif diff --git a/include/common.h b/include/common.h index f427cb221..627846ff2 100644 --- a/include/common.h +++ b/include/common.h @@ -16,6 +16,24 @@ #include #include +#define PATHSEP "/" +// PM3 share path relative to executable when installed +#define PM3_SHARE_RELPATH ".." PATHSEP "share" PATHSEP "proxmark3" PATHSEP + +// PM3_USER_DIRECTORY will be expanded from $HOME, e.g. ~/.proxmark3/ +#define PM3_USER_DIRECTORY PATHSEP ".proxmark3" PATHSEP + +// PM3 subdirectories: +#define CMD_SCRIPTS_SUBDIR "cmdscripts" PATHSEP +#define DICTIONARIES_SUBDIR "dictionaries" PATHSEP +#define LUA_LIBRARIES_SUBDIR "lualibs" PATHSEP +#define LUA_SCRIPTS_SUBDIR "luascripts" PATHSEP +#define RESOURCES_SUBDIR "resources" PATHSEP +#define TRACES_SUBDIR "traces" PATHSEP +#define FIRMWARES_SUBDIR "firmware" PATHSEP +#define BOOTROM_SUBDIR "bootrom/obj" PATHSEP +#define FULLIMAGE_SUBDIR "armsrc/obj" PATHSEP + #define PACKED __attribute__((packed)) // debug diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 035e85405..e87e8bc33 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -229,6 +229,10 @@ typedef struct { uint8_t key[6]; } PACKED mf_readblock_t; +typedef struct { + uint8_t sectorcnt; + uint8_t keytype; +} PACKED mfc_eload_t; // For the bootloader #define CMD_DEVICE_INFO 0x0000 diff --git a/include/protocols.h b/include/protocols.h index 5a1e56f4e..9b47266c3 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -120,22 +120,21 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. // for instance ICLASS_CMD_SELECT 0x81 tells if ISO14443b/BPSK coding/106 kbits/s // for instance ICLASS_CMD_SELECT 0x41 tells if ISO14443b/BPSK coding/423 kbits/s // -#define ICLASS_CMD_HALT 0x00 -#define ICLASS_CMD_SELECT_15 0x01 -#define ICLASS_CMD_ACTALL 0x0A -#define ICLASS_CMD_DETECT 0x0F +#define ICLASS_CMD_HALT 0x0 +#define ICLASS_CMD_SELECT 0x1 +#define ICLASS_CMD_ACTALL 0xA +#define ICLASS_CMD_DETECT 0xF -#define ICLASS_CMD_CHECK 0x05 -#define ICLASS_CMD_READ4 0x06 -#define ICLASS_CMD_READ_OR_IDENTIFY 0x0C - -#define ICLASS_CMD_SELECT 0x81 -#define ICLASS_CMD_PAGESEL 0x84 -#define ICLASS_CMD_UPDATE 0x87 -#define ICLASS_CMD_READCHECK_KC 0x18 -#define ICLASS_CMD_READCHECK_KD 0x88 -#define ICLASS_CMD_ACT 0x8E +#define ICLASS_CMD_PAGESEL 0x4 +#define ICLASS_CMD_CHECK 0x5 +#define ICLASS_CMD_READ4 0x6 +#define ICLASS_CMD_UPDATE 0x7 +#define ICLASS_CMD_READCHECK 0x8 +#define ICLASS_CMD_READ_OR_IDENTIFY 0xC +#define ICLASS_CMD_ACT 0xE +#define ICLASS_CREDIT(x) (((x) & 0x5) == 1) +#define ICLASS_DEBIT(x) (((x) & 0x5) == 0) #define ISO14443A_CMD_REQA 0x26 @@ -542,5 +541,26 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define CALYPSO_SAM_SV_DEBIT 0x54 #define CALYPSO_SAM_SV_RELOAD 0x56 +// HITAG1 commands +#define HITAG1_SET_CCNEW 0xC2 // left 5 bits only +#define HITAG1_READ_ID 0x00 // not a real command, consists of 5 bits length, bits partial SN, 8 bits CRC +#define HITAG1_SELECT 0x00 // left 5 bits only, followed by 32 bits SN and 8 bits CRC +#define HITAG1_WRPPAGE 0x80 // left 4 bits only, followed by 8 bits page and 8 bits CRC +#define HITAG1_WRPBLK 0x90 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_WRCPAGE 0xA0 // left 4 bits only, followed by 8 bits page or key information and 8 bits CRC +#define HITAG1_WRCBLK 0xB0 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_RDPPAGE 0xC0 // left 4 bits only, followed by 8 bits page and 8 bits CRC +#define HITAG1_RDPBLK 0xD0 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_RDCPAGE 0xE0 // left 4 bits only, followed by 8 bits page and 8 bits CRC +#define HITAG1_RDCBLK 0xF0 // left 4 bits only, followed by 8 bits block and 8 bits CRC +#define HITAG1_HALT 0x70 // left 4 bits only, followed by 8 bits (dummy) page and 8 bits CRC + +// HITAG2 commands +#define HITAG2_START_AUTH 0xC0 // left 5 bits only +#define HITAG2_READ_PAGE 0xC0 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_READ_PAGE_INVERTED 0x44 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_WRITE_PAGE 0x82 // page number in bits 5 to 3, page number inverted in bit 0 and following 2 bits +#define HITAG2_HALT 0x00 // left 5 bits only + #endif // PROTOCOLS_H diff --git a/include/proxmark3_arm.h b/include/proxmark3_arm.h index a2f76e93d..3ea80da9d 100644 --- a/include/proxmark3_arm.h +++ b/include/proxmark3_arm.h @@ -90,6 +90,7 @@ #define LED_D_OFF() LOW(GPIO_LED_D) #define LED_D_INV() INVBIT(GPIO_LED_D) + // SPI #define SCK_LOW LOW(GPIO_SPCK) #define SCK_HIGH HIGH(GPIO_SPCK) @@ -107,7 +108,9 @@ #define RELAY_ON() HIGH(GPIO_RELAY) #define RELAY_OFF() LOW(GPIO_RELAY) -#define BUTTON_PRESS() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) == GPIO_BUTTON) + +#define BUTTON_PRESS() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) == GPIO_BUTTON) +#define WAIT_BUTTON_RELEASED() { while ( BUTTON_PRESS() ) { WDT_HIT(); }; } //NVDD goes LOW when USB is attached. #define USB_ATTACHED() !((AT91C_BASE_PIOA->PIO_PDSR & GPIO_NVDD_ON) == GPIO_NVDD_ON) diff --git a/include/usart_defs.h b/include/usart_defs.h index 232e80276..cf6630e83 100644 --- a/include/usart_defs.h +++ b/include/usart_defs.h @@ -18,7 +18,7 @@ #if defined (_WIN32) #define SERIAL_PORT_EXAMPLE_H "com3" #elif defined(__APPLE__) -#define SERIAL_PORT_EXAMPLE_H "/dev/cu.usbmodem" +#define SERIAL_PORT_EXAMPLE_H "/dev/tty.usbmodemiceman1" #else #define SERIAL_PORT_EXAMPLE_H "/dev/ttyACM0" #endif diff --git a/install.sh b/install.sh deleted file mode 100755 index 8dc3e5317..000000000 --- a/install.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -set -x -# This is for linux ppl and it works on Ubuntu distros. Don't know about Kali. -function installProxmark_Linux { - # install dependencies for Proxmark3 source code. - sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev gcc-arm-none-eabi - sudo apt-get install libusb-0.1-4 libusb-dev libqt4-dev libncurses5-dev perl pkg-config wget - #cleaning up - sudo apt-get install -f -y - sudo apt-get autoremove -y - sudo apt-get autoclean -y - sudo apt-get clean -y - sudo apt-get update - - # Install libcanberragtk in Ubuntu 18.04 - if [[ $(cat /etc/issue | awk '{print $2}') = *"18.04"* ]]; then - apt-get install libcanberra-gtk-module - fi - -# install RDV40 - proxmark3 - git clone https://github.com/RfidResearchGroup/proxmark3.git . - ( - cd proxmark3 || exit 1 - git reset --hard - git clean -dfx - make clean - make -j$(nproc) all - # Copy blacklist rules into /etc/udev/rules.d - # check the Makefile for details - sudo make udev - ) -} -function installProxmark_macOS { - # Install dependencies for Proxmark3 source code. - brew tap nitsky/stm32 - brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig arm-none-eabi-gcc - brew link --force readline - # add moc_location in Qt5Core.pc file. -local qtDir=$(ls /usr/local/Cellar/qt/ 2>/dev/null | head -1) -local qt5Core=$(find /usr -name Qt5Core.pc 2>/dev/null) - ( - export PKG_CONFIG_PATH=/usr/local/Cellar/qt/$qtDir/lib/pkgconfig/ - export QT_PKG_CONFIG_QT5CORE=$qt5Core - chmod 666 $QT_PKG_CONFIG_QT5CORE - echo "moc_location=\${prefix}/bin/moc" >> $QT_PKG_CONFIG_QT5CORE - chmod 444 $QT_PKG_CONFIG_QT5CORE - ) - # install RDV40 - proxmark3 - git clone https://github.com/RfidResearchGroup/proxmark3.git - ( - cd proxmark3 || exit 1 - git reset --hard - git clean -dfx - make clean - make -j$(sysctl -n hw.physicalcpu) - ) - } -# Where is my device? -#dmesg | tail -10 -# Detect OS and install libraries and proxmark3 client -if [[ $(uname | awk '{print toupper($0)}') == "LINUX" ]]; then - echo >&2 "Linux Detected - Updating your system..." - $(installProxmark_Linux) -elif [[ $(uname | awk '{print toupper($0)}') == "DARWIN" ]]; then - echo >&2 "MAC OS X Detected - Updating your system..." - $(installProxmark_macOS) 2>/dev/null -fi -echo >&2 "Done." diff --git a/pm3 b/pm3 new file mode 100755 index 000000000..a740beb12 --- /dev/null +++ b/pm3 @@ -0,0 +1,197 @@ +#!/bin/bash + +# Usage: run option -h to get help + +PM3PATH=$(dirname "$0") +FULLIMAGE="fullimage.elf" +BOOTIMAGE="bootrom.elf" +# try pm3 dirs in current repo workdir +if [ -d "$PM3PATH/client/" ]; then + CLIENT="$PM3PATH/client/proxmark3" +# try install dir +elif [ -x "$PM3PATH/proxmark3" ]; then + CLIENT="$PM3PATH/proxmark3" +else +# hope it's installed somehow, still not sure where fw images are... + CLIENT="proxmark3" +fi + +function wait4proxmark_Linux { + echo >&2 "[=] Waiting for Proxmark3 to appear..." + while true; do + PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1) + if [[ $PM3 != "" ]]; then + break + fi + sleep .1 + done + echo "$PM3" +} + +function wait4proxmark_macOS { + echo >&2 "[=] Waiting for Proxmark3 to appear..." + while true; do + PM3=$(find /dev/pm3-* /dev/tty.usbmodem* 2>/dev/null | head -1) + if [[ $PM3 != "" ]]; then + break + fi + sleep .1 + done + echo "$PM3" +} + +function wait4proxmark_Windows { + echo >&2 "[=] Waiting for Proxmark3 to appear..." + while true; do + device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') + if [[ $device != "" ]]; then + PM3=${device/ */} + break + fi + sleep .1 + done + echo "$PM3" +} + +function wait4proxmark_WSL { + echo >&2 "[=] Waiting for Proxmark3 to appear..." + while true; do + device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') + if [[ $device != "" ]]; then + PM3=${device/ */} + PM3="/dev/ttyS${PM3#COM}" + break + fi + sleep .1 + done + if [ -e "$PM3" ] && [ ! -w "$PM3" ]; then + echo "[!!] We need to give current user read/write access to $PM3" + sudo chmod 666 "$PM3" + fi + echo "$PM3" +} + +SCRIPT=$(basename -- "$0") + +if [ "$SCRIPT" = "pm3" ]; then + CMD() { $CLIENT "$@"; } + HELP() { + cat << EOF +Quick helper script for proxmark3 client when working with a Proxmark device connected via USB + +Description: + The usage is the same as for the proxmark3 client, with the following differences: + * the correct port name will be automatically guessed; + * the script will wait for a Proxmark to be connected (same as option -w of the client). + Don't use this script if you want to work offline or with the BT addon. + +Usage: + $SCRIPT [-f] [-c ]|[-l ]|[-s ] [-i] + +See "$CLIENT -h" for more details on options. +EOF + } +elif [ "$SCRIPT" = "pm3-flash" ]; then + CMD() { + ARGS=("$1" "--flash") + shift; + while [ "$1" != "" ]; do + if [ "$1" == "-b" ]; then + ARGS+=("--unlock-bootloader") + else + ARGS+=("--image" "$1") + fi + shift; + done + $CLIENT ${ARGS[@]}; + } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT [-b] image.elf [image.elf...] + +Options: + -b Enable flashing of bootloader area (DANGEROUS) + +Example: + $SCRIPT -b bootrom.elf fullimage.elf +EOF + } +elif [ "$SCRIPT" = "pm3-flash-all" ]; then + CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT +EOF + } +elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then + CMD() { $CLIENT "$1" "--flash" "--image" "$FULLIMAGE"; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The correct port name will be automatically guessed and the stock firmware image will be flashed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT +EOF + } +elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then + CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; } + HELP() { + cat << EOF +Quick helper script for flashing a Proxmark device via USB + +Description: + The correct port name will be automatically guessed and the stock bootloader will be flashed. + If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h". + +Usage: + $SCRIPT +EOF + } +else + echo "[!!] Script ran under unknown name, abort: $SCRIPT" + exit 1 +fi +if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + HELP + exit 0 +fi +HOSTOS=$(uname | awk '{print toupper($0)}') +if [ "$HOSTOS" = "LINUX" ]; then + if uname -a|grep -q Microsoft; then + PORT=$(wait4proxmark_WSL) + else + PORT=$(wait4proxmark_Linux) + fi +elif [ "$HOSTOS" = "DARWIN" ]; then + PORT=$(wait4proxmark_macOS) +elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then + PORT=$(wait4proxmark_Windows) +else + echo "[!!] Host OS not recognized, abort: $HOSTOS" + exit 1 +fi +if [ "$PORT" = "" ]; then + echo "[!!] No port, abort" + exit 1 +fi + +CMD "$PORT" "$@" +exit $? diff --git a/pm3-flash b/pm3-flash new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" diff --git a/pm3-flash-all b/pm3-flash-all new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash-all @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" diff --git a/pm3-flash-bootrom b/pm3-flash-bootrom new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash-bootrom @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" diff --git a/pm3-flash-fullimage b/pm3-flash-fullimage new file mode 100755 index 000000000..e5cd5479d --- /dev/null +++ b/pm3-flash-fullimage @@ -0,0 +1,4 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +. "$PM3PATH/pm3" diff --git a/pm3test.sh b/pm3test.sh new file mode 100755 index 000000000..8785bf8df --- /dev/null +++ b/pm3test.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +PM3PATH=$(dirname "$0") +cd "$PM3PATH" || exit 1 + +C_RED='\033[0;31m' +C_GREEN='\033[0;32m' +C_YELLOW='\033[0;33m' +C_BLUE='\033[0;34m' +C_NC='\033[0m' # No Color + +# title, file name or file wildcard to check +function CheckFileExist() { + + if [ -f "$2" ]; then + echo -e "$1 ${C_GREEN}[OK]${C_NC}" + return 0 + fi + + if ls $2 1> /dev/null 2>&1; then + echo -e "$1 ${C_GREEN}[OK]${C_NC}" + return 0 + fi + + echo -e "$1 ${C_RED}[Fail]${C_NC}" + return 1 +} + +# title, command line, check result, repeat several times if failed, ignore if fail +function CheckExecute() { + + if [ $4 ]; then + local RETRY="1 2 3 e" + else + local RETRY="e" + fi + + for I in $RETRY + do + RES=$(eval "$2") + if echo "$RES" | grep -q "$3"; then + echo -e "$1 ${C_GREEN}[OK]${C_NC}" + return 0 + fi + if [ ! $I == "e" ]; then echo "retry $I"; fi + done + + + if [ $5 ]; then + echo -e "$1 ${C_YELLOW}[Ignored]${C_NC}" + return 0 + fi + + echo -e "$1 ${C_RED}[Fail]${C_NC}" + echo -e "Execution trace:\n$RES" + return 1 +} + +printf "\n${C_BLUE}RRG/Iceman Proxmark3 test tool ${C_NC}\n\n" + +printf "work directory: " +pwd + +if [ "$TRAVIS_COMMIT" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + echo "Travis branch: $TRAVIS_BRANCH slug: $TRAVIS_REPO_SLUG commit: $TRAVIS_COMMIT" + else + echo "Travis pull request: $TRAVIS_PULL_REQUEST branch: $TRAVIS_BRANCH slug: $TRAVIS_PULL_REQUEST_SLUG commit: $TRAVIS_COMMIT" + fi +fi + +printf "git branch: " +git describe --all +printf "git sha: " +git rev-parse HEAD +echo "" + +while true; do + printf "\n${C_BLUE}Testing files:${C_NC}\n" + if ! CheckFileExist "proxmark3 exists" "./client/proxmark3"; then break; fi + if ! CheckFileExist "arm image exists" "./armsrc/obj/fullimage.elf"; then break; fi + if ! CheckFileExist "bootrom exists" "./bootrom/obj/bootrom.elf"; then break; fi + if ! CheckFileExist "hardnested tables exists" "./client/resources/hardnested_tables/*.z"; then break; fi + + printf "\n${C_BLUE}Testing basic help:${C_NC}\n" + if ! CheckExecute "proxmark help" "./client/proxmark3 -h" "wait"; then break; fi + if ! CheckExecute "proxmark help text ISO7816" "./client/proxmark3 -t 2>&1" "ISO7816"; then break; fi + if ! CheckExecute "proxmark help text hardnested" "./client/proxmark3 -t 2>&1" "hardnested"; then break; fi + + printf "\n${C_BLUE}Testing data manipulation:${C_NC}\n" + if ! CheckExecute "reveng test" "./client/proxmark3 -c 'reveng -w 8 -s 01020304e3 010204039d'" "CRC-8/SMBUS"; then break; fi + + printf "\n${C_BLUE}Testing LF:${C_NC}\n" + if ! CheckExecute "lf em4x05 test" "./client/proxmark3 -c 'data load traces/em4x05.pm3;lf search'" "FDX-B ID found"; then break; fi + + printf "\n${C_BLUE}Testing HF:${C_NC}\n" + if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi + if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi + if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi + if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi + + printf "\n${C_BLUE}Testing tools:${C_NC}\n" + # Need a decent example for mfkey32... + if ! CheckExecute "mfkey32v2 test" "tools/mfkey/mfkey32v2 12345678 1AD8DF2B 1D316024 620EF048 30D6CB07 C52077E2 837AC61A" "Found Key: \[a0a1a2a3a4a5\]"; then break; fi + if ! CheckExecute "mfkey64 test" "tools/mfkey/mfkey64 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439" "Found Key: \[ffffffffffff\]"; then break; fi + if ! CheckExecute "mfkey64 long trace test" "tools/mfkey/./mfkey64 14579f69 ce844261 f8049ccb 0525c84f 9431cc40 7093df99 9972428ce2e8523f456b99c831e769dced09 8ca6827b ab797fd369e8b93a86776b40dae3ef686efd c3c381ba 49e2c9def4868d1777670e584c27230286f4 fbdcd7c1 4abd964b07d3563aa066ed0a2eac7f6312bf 9f9149ea" "Found Key: \[091e639cb715\]"; then break; fi + if ! CheckExecute "nonce2key test" "tools/nonce2key/nonce2key e9cadd9c a8bf4a12 a020a8285858b090 050f010607060e07 5693be6c00000000" "key recovered: fc00018778f7"; then break; fi + printf "\n${C_GREEN}Tests [OK]${C_NC}\n\n" + exit 0 +done + +printf "\n${C_RED}Tests [FAIL]${C_NC}\n\n" +exit 1 diff --git a/proxmark3.sh b/proxmark3.sh deleted file mode 100755 index 07d2a27d5..000000000 --- a/proxmark3.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash - -FULLIMAGE="armsrc/obj/fullimage.elf" -BOOTIMAGE="bootrom/obj/bootrom.elf" - -PM3PATH=$(dirname "$0") -cd "$PM3PATH" || exit 1 - -function wait4proxmark_Linux { - echo >&2 "[=] Waiting for Proxmark to appear..." - while true; do - PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1) - if [[ $PM3 != "" ]]; then - break - fi - sleep .1 - done - echo "$PM3" -} - -function wait4proxmark_macOS { - echo >&2 "[=] Waiting for Proxmark to appear..." - while true; do - PM3=$(find /dev/pm3-* /dev/cu.usbmodem* 2>/dev/null | head -1) - if [[ $PM3 != "" ]]; then - break - fi - sleep .1 - done - echo "$PM3" -} - -function wait4proxmark_Windows { - echo >&2 "[=] Waiting for Proxmark to appear..." - while true; do - device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') - if [[ $device != "" ]]; then - PM3=${device/ */} - break - fi - sleep .1 - done - echo "$PM3" -} - -function wait4proxmark_WSL { - echo >&2 "[=] Waiting for Proxmark to appear..." - while true; do - device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2') - if [[ $device != "" ]]; then - PM3=${device/ */} - PM3="/dev/ttyS${PM3#COM}" - break - fi - sleep .1 - done - if [ -e "$PM3" ] && [ ! -w "$PM3" ]; then - echo "[!!] We need to give current user read/write access to $PM3" - sudo chmod 666 "$PM3" - fi - echo "$PM3" -} - -SCRIPT=$(basename -- "$0") - -if [ "$SCRIPT" = "proxmark3.sh" ]; then - CMD() { client/proxmark3 "$@"; } -elif [ "$SCRIPT" = "flash-all.sh" ]; then - CMD() { client/flasher "$1" -b "$BOOTIMAGE" "$FULLIMAGE"; } -elif [ "$SCRIPT" = "flash-fullimage.sh" ]; then - CMD() { client/flasher "$1" "$FULLIMAGE"; } -elif [ "$SCRIPT" = "flash-bootrom.sh" ]; then - CMD() { client/flasher "$1" -b "$BOOTIMAGE"; } -else - echo "[!!] Script ran under unknown name, abort: $SCRIPT" - exit 1 -fi -HOSTOS=$(uname | awk '{print toupper($0)}') -if [ "$HOSTOS" = "LINUX" ]; then - if uname -a|grep -q Microsoft; then - PORT=$(wait4proxmark_WSL) - else - PORT=$(wait4proxmark_Linux) - fi -elif [ "$HOSTOS" = "DARWIN" ]; then - PORT=$(wait4proxmark_macOS) -elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then - PORT=$(wait4proxmark_Windows) -else - echo "[!!] Host OS not recognized, abort: $HOSTOS" - exit 1 -fi -if [ "$PORT" = "" ]; then - echo "[!!] No port, abort" - exit 1 -fi - -CMD "$PORT" "$@" -exit $? diff --git a/recovery/Makefile b/recovery/Makefile index 59f7f37c8..2bfd1475f 100644 --- a/recovery/Makefile +++ b/recovery/Makefile @@ -1,6 +1,13 @@ include ../common_arm/Makefile.common -BINS = bootrom.bin fullimage.bin proxmark3_recovery.bin +INSTALLFW = proxmark3_recovery.bin +ifneq (,$(FWTAG)) + INSTALLFWTAG = $(notdir $(INSTALLFW:%.bin=%-$(FWTAG).bin)) +else + INSTALLFWTAG = $(notdir $(INSTALLFW)) +endif + +BINS = bootrom.bin fullimage.bin $(INSTALLFW) all: $(BINS) @@ -17,5 +24,15 @@ proxmark3_recovery.bin: bootrom.bin fullimage.bin $(Q)cat bootrom.bin fullimage.bin > $@ clean: - $(Q)rm -f $(BINS) + $(Q)$(RM) $(BINS) +install: all + $(info [@] Installing recovery to $(DESTDIR)$(PREFIX)...) + $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) + +uninstall: + $(info [@] Uninstalling recovery from $(DESTDIR)$(PREFIX)...) + $(Q)$(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) + +.PHONY: all clean install uninstall diff --git a/tools/Makefile b/tools/Makefile index 3b1dc1b0f..5f2355f20 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,18 +1,23 @@ +MKDIR = mkdir -p +WGET = wget -N +TAR = tar Jxvf +GIT = git clone + get_craptev1: - wget -N http://crapto1.netgarage.org/craptev1-v1.1.tar.xz - tar Jxvf craptev1-v1.1.tar.xz -C craptev1-v1.1 + $(WGET) http://crapto1.netgarage.org/craptev1-v1.1.tar.xz + $(TAR) craptev1-v1.1.tar.xz -C craptev1-v1.1 get_crapto1: - wget -N http://crapto1.netgarage.org/crapto1-v3.3.tar.xz - tar Jxvf crapto1-v3.3.tar.xz -C crapto1-v3.3 + $(WGET) http://crapto1.netgarage.org/crapto1-v3.3.tar.xz + $(TAR) Jxvf crapto1-v3.3.tar.xz -C crapto1-v3.3 get_nonce_bf: -# git clone https://github.com/J-Run/mf_key_brute.git mf_key_brute - git clone https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute +# $(GIT) https://github.com/J-Run/mf_key_brute.git mf_key_brute + $(GIT) https://github.com/iceman1001/mf_nonce_brute mf_nonce_brute get_xorsearch: - mkdir xorsearch - wget -N https://didierstevens.com/files/software/XORSearch_V1_11_2.zip + $(MKDIR) xorsearch + $(WGET) https://didierstevens.com/files/software/XORSearch_V1_11_2.zip # Mingw # unzzip-big XORSearch_V1_11_2.zip # linux diff --git a/tools/analyzesize.py b/tools/analyzesize.py index 4a5211c67..889222c01 100755 --- a/tools/analyzesize.py +++ b/tools/analyzesize.py @@ -16,7 +16,7 @@ except FileNotFoundError: db = dict() if len(sys.argv) < 3: - print("Usage: analazysize.py ") + print("Usage: analyzesize.py ") exit(-1) action, name = sys.argv[1:3] currentdata = subprocess.run(["arm-none-eabi-size","armsrc/obj/fullimage.stage1.elf"], stdout=subprocess.PIPE).stdout diff --git a/tools/deprecated-hid-flasher/flasher/Makefile b/tools/deprecated-hid-flasher/flasher/Makefile index bff511459..52b1229fe 100644 --- a/tools/deprecated-hid-flasher/flasher/Makefile +++ b/tools/deprecated-hid-flasher/flasher/Makefile @@ -5,30 +5,27 @@ #----------------------------------------------------------------------------- CC=gcc -CXX=g++ -#COMMON_FLAGS = -m32 +LD=gcc OBJDIR = obj -LDLIBS = -lreadline -lpthread -CFLAGS = -std=gnu99 -Wall -Wno-unused-function $(COMMON_FLAGS) -g -O3 +LDLIBS = +CFLAGS ?= -Wall -Werror -g -O3 +CFLAGS += -std=gnu99 ifeq ($(platform),Darwin) LDLIBS += -lusb-1.0 else LDLIBS += -lusb endif -LDFLAGS = $(COMMON_FLAGS) -CXXFLAGS = - RM = rm -f -BINS = flasher -CLEAN = flasher flasher.exe $(OBJDIR)/*.o *.o +BINS = pm3-hid-flasher +CLEAN = pm3-hid-flasher pm3-hid-flasher.exe $(OBJDIR)/*.o all: $(BINS) -flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/proxusb.o - $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@ +pm3-hid-flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/proxusb.o + $(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(OBJDIR)/%.o: %.c $(CC) $(CFLAGS) -c -o $@ $< diff --git a/tools/deprecated-hid-flasher/flasher/README.md b/tools/deprecated-hid-flasher/flasher/README.md new file mode 100644 index 000000000..c5ddfed62 --- /dev/null +++ b/tools/deprecated-hid-flasher/flasher/README.md @@ -0,0 +1,10 @@ +Compilation notes +================= + +Besides the global Proxmark3 requirements, this flasher compatible with very old firmwares requires the libusb 0.1 to work. +So you'll need to install the libusb 0.1 package first. + +* OSX: libusb-compat +* Debian-alike: libusb-0.1-4 libusb-dev +* Arch: libusb +* Fedora: libusb-devel diff --git a/tools/fpga_compress/Makefile b/tools/fpga_compress/Makefile index 8798ace1e..86c995924 100644 --- a/tools/fpga_compress/Makefile +++ b/tools/fpga_compress/Makefile @@ -1,80 +1,21 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +MYSRCPATHS = +MYINCLUDES = -I../../common_fpga +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = +MYSRCS = +MYLIBS = -CC = gcc -CXX = g++ -LD = g++ -RM = rm -f -MV = mv -CP = cp -a - -platform = $(shell uname) - -VPATH = ../../common/zlib -OBJDIR = obj - -# RPi Zero gcc requires -latomic -# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld -# doesn't recognize option --as-needed -ifneq ($(platform),Darwin) - LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed -endif - -LIBS = -I../../common/zlib -INCLUDES_CLIENT = -I../../common_fpga $(LIBS) - -CFLAGS += -std=c99 -D_ISOC99_SOURCE -DPRESETS $(INCLUDES_CLIENT) -Wall -Werror -g -O3 - -# Flags to generate temporary dependency files -DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td -# make temporary to final dependency files after successful compilation -POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d - -ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c -ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED -#-DDEBUG -Dverbose=1 - -ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o) +ZLIBPATH = ../../common/zlib +MYINCLUDES += -I$(ZLIBPATH) +MYLIBS += $(OBJDIR)/libz.a BINS = fpga_compress -CLEAN = $(BINS) $(DEPENDENCY_FILES) $(ZLIBOBJS) $(OBJDIR)/*.o -# OSX Brew is expecting fpga_compress in client folder, some workaround for now: -ifeq ($(platform),Darwin) -CLEAN += $(foreach bin,$(BINS),../../client/$(bin)) -endif -# need to assign dependancies to build these first... -all: $(BINS) +ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) -all-static: LDLIBS:=-static $(LDLIBS) -all-static: $(BINS) - -fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS) - $(info [=] LD $@) - $(Q)$(LD) $(LDFLAGS) $(ZLIBFLAGS) $^ $(LDLIBS) -o $@ -# OSX Brew is expecting fpga_compress in client folder, some workaround for now: -ifeq ($(platform),Darwin) - $(Q)$(CP) $@ ../../client/ -endif - -clean: - $(Q)$(RM) $(CLEAN) - -.PHONY: all clean - -%.o: %.c -$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d - $(info [-] CC $<) - $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $< - $(Q)$(POSTCOMPILE) - -DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(ZLIBSRCS)) $(OBJDIR)/fpga_compress.d - -$(DEPENDENCY_FILES): ; -.PRECIOUS: $(DEPENDENCY_FILES) - --include $(DEPENDENCY_FILES) +include ../../Makefile.host +fpga_compress: $(OBJDIR)/fpga_compress.o $(MYOBJS) +$(OBJDIR)/libz.a: + $(info [*] MAKE zlib) + $(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all diff --git a/tools/fpga_compress/fpga_compress.c b/tools/fpga_compress/fpga_compress.c index 7777b6d51..54d2438d2 100644 --- a/tools/fpga_compress/fpga_compress.c +++ b/tools/fpga_compress/fpga_compress.c @@ -337,6 +337,8 @@ static int FpgaGatherVersion(FILE *infile, char *infile_name, char *dst, int len for (uint16_t i = 0; i < fpga_info_len; i++) { char c = (char)fgetc(infile); if (i < sizeof(tempstr)) { + if (c == '/') c = '-'; + if (c == ' ') c = '0'; tempstr[i] = c; } } diff --git a/tools/fpga_compress/obj/.dummy b/tools/fpga_compress/obj/.dummy deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/install-gnuarm4.sh b/tools/install-gnuarm4.sh deleted file mode 100755 index a5d92c5d5..000000000 --- a/tools/install-gnuarm4.sh +++ /dev/null @@ -1,277 +0,0 @@ -#!/bin/bash - -# Some things for you to configure -BINUTILS_VER="2.19.1a" -GCC_VER="4.3.3" -GDB_VER="6.8a" -NEWLIB_VER="1.17.0" -GMP_VER="4.2.4" -MPFR_VER="2.4.2" -INSIGHT_VER="6.8a" - -# Where you want to install the tools -if [ "${1}" = "" ]; then - echo "Syntax: ${0} [download & build directory (default ${PWD})]" - exit 1 -else - DESTDIR="${1}" -fi - -# Where do you want to build the tools. This is where the log files -# will be written (which you can monitor with 'tail' during compilation). -# You can delete this directory after everything is done. -if [ ! "${2}" = "" ]; then - SRCDIR="${2}" -else - SRCDIR="${PWD}" -fi -BUILDDIR=${SRCDIR}/build-gnuarm4 - -# Where to get each of the toolchain components -BINUTILS=http://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VER}.tar.bz2 -BINUTILS_TAR=binutils-${BINUTILS_VER}.tar.bz2 -GCCCORE=http://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/gcc-core-${GCC_VER}.tar.bz2 -GCCCORE_TAR=gcc-core-${GCC_VER}.tar.bz2 -GPP=http://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/gcc-g++-${GCC_VER}.tar.bz2 -GPP_TAR=gcc-g++-${GCC_VER}.tar.bz2 -NEWLIB=ftp://sources.redhat.com/pub/newlib/newlib-${NEWLIB_VER}.tar.gz -NEWLIB_TAR=newlib-${NEWLIB_VER}.tar.gz -#INSIGHT=ftp://sourceware.org/pub/insight/releases/insight-${INSIGHT_VER}.tar.bz2 -INSIGHT=http://mirrors.kernel.org/sources.redhat.com/insight/releases/insight-${INSIGHT_VER}.tar.bz2 -INSIGHT_TAR=insight-${INSIGHT_VER}.tar.bz2 -#INSIGHT=http://www.mirrorservice.org/sites/sources.redhat.com/pub/insight/releases/insight-${INSIGHT_VER}.tar.bz2 -GDB=http://ftp.gnu.org/gnu/gdb/gdb-${GDB_VER}.tar.bz2 -GDB_TAR=gdb-${GDB_VER}.tar.bz2 -GMP=http://ftp.sunet.se/pub/gnu/gmp/gmp-${GMP_VER}.tar.bz2 -GMP_TAR=gmp-${GMP_VER}.tar.bz2 -MPFR=http://ftp.gnu.org/gnu/mpfr/mpfr-${MPFR_VER}.tar.bz2 -MPFR_TAR=mpfr-${MPFR_VER}.tar.bz2 -GNU_KEYRING_GPG=gnu-keyring.gpg -GNU_KEYRING=ftp://ftp.gnu.org/gnu/${GNU_KEYRING_GPG} - -# Common configuration options (i.e., things to pass to 'configure') -COMMON_CFG="--enable-interwork --target=arm-eabi --program-prefix=arm-none-eabi- --prefix=${DESTDIR} --disable-werror --enable-languages=c,c++ --enable-multilib --disable-shared" - -# Extra configuration options for each toolchain component -BINUTILS_CFG= -GCCCORE_CFG="--disable-nls --disable-threads --with-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --with-newlib --with-headers=${BUILDDIR}/newlib-${NEWLIB_VER}/newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp -v" -NEWLIB_CFG= -INSIGHT_CFG= -GDB_CFG= - -# Make flags -MAKEFLAGS="-j 4" - -# wget options -# -nv: non-verbose but not too quiet (still print errors/warnings) -# -nc: no-clobber, do not download a file that already exists -# -t 0: retry indefinitely -# -a wget.log: append errors/warnings to wget.log file -# -c continue -#WGET_OPTS="-nv -nc -t 0 -a wget.log" -WGET_OPTS="-c -t 0" - -# Compiler flags for compiling Newlib (-O2 is already hard-coded) -NEWLIB_FLAGS="-march=armv4t -mcpu=arm7tdmi -g" - -# GPG options to avoid polluting the user's keyring -GPG_OPTS="--keyring ${GNU_KEYRING_GPG} --no-default-keyring --homedir ." - -############################################################################ -# End of configuration section. You shouldn't have to modify anything below. -############################################################################ - -if [[ "$USER" != "root" ]]; then - echo "*** Warning! Not running as root!" - echo "Installation may fail if you do not have appropriate permissions!" -fi - -mkdir -p ${BUILDDIR} -cd ${SRCDIR} - -if [[ -f all.downloaded ]]; then - echo Looks like all downloads are complete, skipping downloads -else - wget ${WGET_OPTS} ${GNU_KEYRING} - - # TODO: guess it's better to have a function that "downloads, checks file-presence and signature, and returns true/false" whether the file is ok - # Function will check if file exists (otherwise try to download the file - if failed and file still doesn't exist, complain and exit the script) - # Check if signature file exists (otherwise download the signature file as well - if download fail, warn the user and return function) - # Check the signature. If failed, backup-by-renaming current files, redownload both file & signature, run the function body one more time - if still no success, warn and return from function - - function download_lib { - echo Now downloading $1 - wget ${WGET_OPTS} $2 - } - - function download_signed_lib { - download_lib $1 $2 - wget -N ${WGET_OPTS} $2.sig - gpg $GPG_OPTS --verify $3.sig 2> /dev/null - if [[ $? != 0 ]]; then - echo "Failed signature check for:" $3.sig - exit 1 - fi - } - - # NOTE: If new downloads are added here, please see the IMPORTANT note below - download_signed_lib BINUTILS ${BINUTILS} ${BINUTILS_TAR} || exit 1 - download_signed_lib GCC ${GCCCORE} ${GCCCORE_TAR} || exit 1 - download_signed_lib G++ ${GPP} ${GPP_TAR} || exit 1 - download_lib NEWLIB ${NEWLIB} - # TODO: signature/hash check - download_lib INSIGHT ${INSIGHT} - # TODO: signature/hash check - download_signed_lib GDB ${GDB} ${GDB_TAR} || exit 1 - download_signed_lib GMP ${GMP} ${GMP_TAR} || exit 1 - download_signed_lib MPFR ${MPFR} ${MPFR_TAR} || exit 1 - - # IMPORTANT: Here is the number of .tar. archives downloaded above. Please update if new .tar. are added to download list. - if [[ `ls -1 *.tar.bz2 *.tar.gz | wc -l` != 8 ]]; then - echo "Seems like not all prerequisite files downloaded... Exiting." - exit 1 - else - touch all.downloaded - fi -fi - -cd ${BUILDDIR} -if [[ -f binutils.built ]]; then - echo Looks like BINUTILS was already built. -else - echo Building BINUTILS... - tar -xjf ../`basename ${BINUTILS}` - echo ___________________ > make.log - echo Building binutils... >> make.log - cd `find . -maxdepth 1 -type d -name 'binutils*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${BINUTILS_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} MAKEINFO=`which makeinfo` >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch binutils.built -fi - - echo ___________________ >> make.log - echo Adding ${DESTDIR}/bin to PATH >> make.log -export PATH; PATH=${DESTDIR}/bin:$PATH - echo ___________________ >> make.log - -if [[ -f gcc.built ]]; then - echo Looks like GCC was already built. -else - echo Building GCC... - tar -xjf ../`basename ${GCCCORE}` - tar -xjf ../`basename ${GPP}` - tar -xjf ../`basename ${GMP}` - ln -s "${BUILDDIR}/gmp-${GMP_VER}" "${BUILDDIR}/gcc-${GCC_VER}/gmp" - tar -xjf ../`basename ${MPFR}` - ln -s "${BUILDDIR}/mpfr-${MPFR_VER}" "${BUILDDIR}/gcc-${GCC_VER}/mpfr" - tar -xzf ../`basename ${NEWLIB}` - - echo ___________________ >> make.log - -cat << EOF > gcc.patch ---- gcc-4.3.3.orig/gcc/config/arm/t-arm-elf -+++ gcc-4.3.3.mod/gcc/config/arm/t-arm-elf -@@ -33,8 +33,8 @@ - # MULTILIB_DIRNAMES += fpu soft - # MULTILIB_EXCEPTIONS += *mthumb/*mhard-float* - # --# MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork --# MULTILIB_DIRNAMES += normal interwork -+MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork -+MULTILIB_DIRNAMES += normal interwork - # - # MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore - # MULTILIB_DIRNAMES += elf under -EOF - - echo Patching GCC >> make.log - cd `find . -maxdepth 1 -type d -name 'gcc*'` - patch -p1 < ../gcc.patch - echo Building gcc... >> make.log - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${GCCCORE_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} all-gcc >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch gcc.built -fi - -if [[ -f newlib.built ]]; then - echo Looks like NEWLIB was already built. -else - echo Building NEWLIB... - echo ___________________ >> make.log - echo Building newlib... >> make.log - cd `find . -maxdepth 1 -type d -name 'newlib*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${NEWLIB_CFG} >> ../../make.log 2>&1 - - # This line adds our NEWLIB_CFLAGS to the configure.host file in the - # newlib subdirectory. This is the only way I could find to tell Newlib to - # compile itself with the -mmarch=armv4t and -mcpu=arm7tdmi flags. -# sed -i "/^newlib_cflags=/s/=.*\$/=\"${NEWLIB_FLAGS}\"/" ../newlib/configure.host - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch newlib.built -fi - - echo ___________________ >> make.log - echo "Now that newlib is built, second pass for GCC..." >> make.log - cd `find . -maxdepth 1 -type d -name 'gcc*'` - cd gnuarm - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - - -if [[ -f insight.built ]]; then - echo Looks like INSIGHT was already built. -else - echo Building INSIGHT... - tar -xjf ../`basename ${INSIGHT}` - echo ___________________ >> make.log - echo Building insight... >> make.log - cd `find . -maxdepth 1 -type d -name 'insight*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${INSIGHT_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch insight.built -fi - -if [[ -f gdb.built ]]; then - echo Looks like GDB was already built. -else - echo Building GDB... - tar -xjf ../`basename ${GDB}` - echo ___________________ >> make.log - echo Building insight... >> make.log - cd `find . -maxdepth 1 -type d -name 'gdb*'` - mkdir gnuarm - cd gnuarm - ../configure ${COMMON_CFG} ${GDB_CFG} >> ../../make.log 2>&1 - make ${MAKEFLAGS} >> ../../make.log 2>&1 - make install >> ../../make.log 2>&1 - cd ../.. - touch gdb.built -fi - -echo ___________________ >> make.log -echo Build complete. >> make.log - -cd ${DESTDIR} -chmod -R a+rX . - -echo Downloaded archives are in ${SRCDIR} -echo build driectory: ${BUILDDIR} -echo set environment variable ARMLIB to ${DESTDIR}/lib/gcc/arm-eabi/4.3.3/interwork for Makefile.linux -exit 0 diff --git a/tools/mfkey/Makefile b/tools/mfkey/Makefile index 24508265a..a7b006f6e 100644 --- a/tools/mfkey/Makefile +++ b/tools/mfkey/Makefile @@ -1,27 +1,14 @@ -# Hide full compilation line: -ifneq ($(V),1) - Q?=@ -endif -# To see full command lines, use make V=1 +MYSRCPATHS = ../../common ../../common/crapto1 +MYSRCS = crypto1.c crapto1.c bucketsort.c +MYINCLUDES = -I../../include -I../../common +MYCFLAGS = -std=c99 -D_ISOC99_SOURCE +MYDEFS = -VPATH = ../../common ../../common/crapto1 ../../client -CC = gcc -LD = gcc -CFLAGS += -std=c99 -D_ISOC99_SOURCE -I../../include -I../../common -I../../client -Wall -O3 -LDFLAGS += +BINS = mfkey32 mfkey32v2 mfkey64 +INSTALLTOOLS = $(BINS) -OBJS = crypto1.o crapto1.o parity.o util_posix.o bucketsort.o -EXES = mfkey32 mfkey32v2 mfkey64 +include ../../Makefile.host -all: $(OBJS) $(EXES) - -%.o : %.c - $(info [-] CC $<) - $(Q)$(CC) $(CFLAGS) -c -o $@ $< - -% : %.c $(OBJS) - $(info [=] LD $@) - $(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $< - -clean: - $(Q)rm -f $(OBJS) $(EXES) +mfkey32 : $(OBJDIR)/mfkey32.o $(MYOBJS) +mfkey32v2 : $(OBJDIR)/mfkey32v2.o $(MYOBJS) +mfkey64 : $(OBJDIR)/mfkey64.o $(MYOBJS) diff --git a/tools/mkversion.sh b/tools/mkversion.sh new file mode 100755 index 000000000..f839f6e18 --- /dev/null +++ b/tools/mkversion.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# Output a version.c file that includes information about the current build +# From mkversion.pl +# pure sh POSIX as now even on Windows we use WSL or ProxSpace with sh available + +# Clear environment locale so that git will not use localized strings +export LC_ALL="C" +export LANG="C" + +# if you are making your own fork, change this line to reflect your fork-name +fullgitinfo="RRG/Iceman" +# GIT status 0 = dirty, 1 = clean , 2 = undecided +clean=2 + +# Do we have acces to git command? +commandGIT=$(env git) + +if [ "$commandGIT" != "" ]; then + + # now avoiding the "fatal: No names found, cannot describe anything." error by fallbacking to abbrev hash in such case + gitversion=$(git describe --dirty --always) + gitbranch=$(git rev-parse --abbrev-ref HEAD) + if [ "$gitversion" != "${gitversion%-dirty}" ]; then + clean=0 + else + clean=1 + fi + if [ "$gitbranch" != "" ] && [ "$gitversion" != "" ]; then + fullgitinfo="${fullgitinfo}/${gitbranch}/${gitversion}" + ctime="$(date '+%Y-%m-%d %H:%M:%S')" + else + fullgitinfo="${fullgitinfo}/master/release (git)" + fi +else + fullgitinfo="${fullgitinfo}/master/release (no_git)" + dl_time=$(stat --printf="%y" ../README.md) + # POSIX way... + ctime=${dl_time%.*} +fi + +# Crop so it fits within 50 characters C string, so max 49 chars +# POSIX way +fullgitinfoextra="${fullgitinfo#??????????????????????????????????????????????}" +if [ "$fullgitinfoextra" != "$fullgitinfo" ]; then + fullgitinfo46="${fullgitinfo%"${fullgitinfoextra}"}" + fullgitinfo="${fullgitinfo46}..." +fi +cat < $@ - -%.o: %.c - $(info [-] CC $<) - $(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< +nonce2key : $(OBJDIR)/nonce2key.o $(MYOBJS) diff --git a/tools/nonce2key/crapto1.c b/tools/nonce2key/crapto1.c deleted file mode 100644 index 3be92c0f2..000000000 --- a/tools/nonce2key/crapto1.c +++ /dev/null @@ -1,549 +0,0 @@ -/* crapto1.c - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, US$ - - Copyright (C) 2008-2014 bla -*/ -#include "crapto1.h" -#include - -#if !defined LOWMEM && defined __GNUC__ -static uint8_t filterlut[1 << 20]; -static void __attribute__((constructor)) fill_lut() { - uint32_t i; - for (i = 0; i < 1 << 20; ++i) - filterlut[i] = filter(i); -} -#define filter(x) (filterlut[(x) & 0xfffff]) -#endif - - - -typedef struct bucket { - uint32_t *head; - uint32_t *bp; -} bucket_t; - -typedef bucket_t bucket_array_t[2][0x100]; - -typedef struct bucket_info { - struct { - uint32_t *head, *tail; - } bucket_info[2][0x100]; - uint32_t numbuckets; -} bucket_info_t; - - -static void bucket_sort_intersect(uint32_t *const estart, uint32_t *const estop, - uint32_t *const ostart, uint32_t *const ostop, - bucket_info_t *bucket_info, bucket_array_t bucket) { - uint32_t *p1, *p2; - uint32_t *start[2]; - uint32_t *stop[2]; - - start[0] = estart; - stop[0] = estop; - start[1] = ostart; - stop[1] = ostop; - - // init buckets to be empty - for (uint32_t i = 0; i < 2; i++) { - for (uint32_t j = 0x00; j <= 0xff; j++) { - bucket[i][j].bp = bucket[i][j].head; - } - } - - // sort the lists into the buckets based on the MSB (contribution bits) - for (uint32_t i = 0; i < 2; i++) { - for (p1 = start[i]; p1 <= stop[i]; p1++) { - uint32_t bucket_index = (*p1 & 0xff000000) >> 24; - *(bucket[i][bucket_index].bp++) = *p1; - } - } - - - // write back intersecting buckets as sorted list. - // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets. - for (uint32_t i = 0; i < 2; i++) { - p1 = start[i]; - uint32_t nonempty_bucket = 0; - for (uint32_t j = 0x00; j <= 0xff; j++) { - if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only - bucket_info->bucket_info[i][nonempty_bucket].head = p1; - for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++); - bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1; - nonempty_bucket++; - } - } - bucket_info->numbuckets = nonempty_bucket; - } -} - -/** update_contribution - * helper, calculates the partial linear feedback contributions and puts in MSB - */ -static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2) { - uint32_t p = *item >> 25; - - p = p << 1 | parity(*item & mask1); - p = p << 1 | parity(*item & mask2); - *item = p << 24 | (*item & 0xffffff); -} - -/** extend_table - * using a bit of the keystream extend the table of possible lfsr states - */ -static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in) { - in <<= 24; - for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1) - if (filter(*tbl) ^ filter(*tbl | 1)) { - *tbl |= filter(*tbl) ^ bit; - update_contribution(tbl, m1, m2); - *tbl ^= in; - } else if (filter(*tbl) == bit) { - *++*end = tbl[1]; - tbl[1] = tbl[0] | 1; - update_contribution(tbl, m1, m2); - *tbl++ ^= in; - update_contribution(tbl, m1, m2); - *tbl ^= in; - } else - *tbl-- = *(*end)--; -} -/** extend_table_simple - * using a bit of the keystream extend the table of possible lfsr states - */ -static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit) { - for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1) { - if (filter(*tbl) ^ filter(*tbl | 1)) { // replace - *tbl |= filter(*tbl) ^ bit; - } else if (filter(*tbl) == bit) { // insert - *++*end = *++tbl; - *tbl = tbl[-1] | 1; - } else { // drop - *tbl-- = *(*end)--; - } - } -} -/** recover - * recursively narrow down the search space, 4 bits of keystream at a time - */ -static struct Crypto1State * -recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks, - uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem, - struct Crypto1State *sl, uint32_t in, bucket_array_t bucket) { - bucket_info_t bucket_info; - - if (rem == -1) { - for (uint32_t *e = e_head; e <= e_tail; ++e) { - *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ (!!(in & 4)); - for (uint32_t *o = o_head; o <= o_tail; ++o, ++sl) { - sl->even = *o; - sl->odd = *e ^ parity(*o & LF_POLY_ODD); - sl[1].odd = sl[1].even = 0; - } - } - return sl; - } - - for (uint32_t i = 0; i < 4 && rem--; i++) { - oks >>= 1; - eks >>= 1; - in >>= 2; - extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0); - if (o_head > o_tail) - return sl; - - extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3); - if (e_head > e_tail) - return sl; - } - - bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket); - - for (int i = bucket_info.numbuckets - 1; i >= 0; i--) { - sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks, - bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks, - rem, sl, in, bucket); - } - - return sl; -} -/** lfsr_recovery - * recover the state of the lfsr given 32 bits of the keystream - * additionally you can use the in parameter to specify the value - * that was fed into the lfsr at the time the keystream was generated - */ -struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in) { - struct Crypto1State *statelist; - uint32_t *odd_head = 0, *odd_tail = 0, oks = 0; - uint32_t *even_head = 0, *even_tail = 0, eks = 0; - - // split the keystream into an odd and even part - for (int i = 31; i >= 0; i -= 2) - oks = oks << 1 | BEBIT(ks2, i); - for (int i = 30; i >= 0; i -= 2) - eks = eks << 1 | BEBIT(ks2, i); - - odd_head = odd_tail = malloc(sizeof(uint32_t) << 21); - even_head = even_tail = malloc(sizeof(uint32_t) << 21); - statelist = malloc(sizeof(struct Crypto1State) << 18); - if (!odd_tail-- || !even_tail-- || !statelist) { - free(statelist); - statelist = 0; - goto out; - } - - statelist->odd = statelist->even = 0; - - // allocate memory for out of place bucket_sort - bucket_array_t bucket; - - for (uint32_t i = 0; i < 2; i++) { - for (uint32_t j = 0; j <= 0xff; j++) { - bucket[i][j].head = malloc(sizeof(uint32_t) << 14); - if (!bucket[i][j].head) { - goto out; - } - } - } - - // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream - for (int i = 1 << 20; i >= 0; --i) { - if (filter(i) == (oks & 1)) - *++odd_tail = i; - if (filter(i) == (eks & 1)) - *++even_tail = i; - } - - // extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even): - for (uint8_t i = 0; i < 4; i++) { - extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1); - extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1); - } - - // the statelists now contain all states which could have generated the last 10 Bits of the keystream. - // 22 bits to go to recover 32 bits in total. From now on, we need to take the "in" - // parameter into account. - in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping - recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket); - -out: - for (uint32_t i = 0; i < 2; i++) - for (uint32_t j = 0; j <= 0xff; j++) - free(bucket[i][j].head); - free(odd_head); - free(even_head); - return statelist; -} - -static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214, - 0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83, - 0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA - }; -static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60, - 0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8, - 0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20, - 0x7EC7EE90, 0x7F63F748, 0x79117020 - }; -static const uint32_t T1[] = { - 0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66, - 0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B, - 0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615, - 0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C -}; -static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0, - 0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268, - 0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0, - 0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0, - 0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950, - 0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0 - }; -static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD}; -static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0}; -/** Reverse 64 bits of keystream into possible cipher states - * Variation mentioned in the paper. Somewhat optimized version - */ -struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3) { - struct Crypto1State *statelist, *sl; - uint8_t oks[32], eks[32], hi[32]; - uint32_t low = 0, win = 0; - uint32_t *tail, table[1 << 16]; - int i, j; - - sl = statelist = malloc(sizeof(struct Crypto1State) << 4); - if (!sl) - return 0; - sl->odd = sl->even = 0; - - for (i = 30; i >= 0; i -= 2) { - oks[i >> 1] = BEBIT(ks2, i); - oks[16 + (i >> 1)] = BEBIT(ks3, i); - } - for (i = 31; i >= 0; i -= 2) { - eks[i >> 1] = BEBIT(ks2, i); - eks[16 + (i >> 1)] = BEBIT(ks3, i); - } - - for (i = 0xfffff; i >= 0; --i) { - if (filter(i) != oks[0]) - continue; - - *(tail = table) = i; - for (j = 1; tail >= table && j < 29; ++j) - extend_table_simple(table, &tail, oks[j]); - - if (tail < table) - continue; - - for (j = 0; j < 19; ++j) - low = low << 1 | parity(i & S1[j]); - for (j = 0; j < 32; ++j) - hi[j] = parity(i & T1[j]); - - for (; tail >= table; --tail) { - for (j = 0; j < 3; ++j) { - *tail = *tail << 1; - *tail |= parity((i & C1[j]) ^ (*tail & C2[j])); - if (filter(*tail) != oks[29 + j]) - goto continue2; - } - - for (j = 0; j < 19; ++j) - win = win << 1 | parity(*tail & S2[j]); - - win ^= low; - for (j = 0; j < 32; ++j) { - win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]); - if (filter(win) != eks[j]) - goto continue2; - } - - *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail); - sl->odd = *tail ^ parity(LF_POLY_ODD & win); - sl->even = win; - ++sl; - sl->odd = sl->even = 0; -continue2: - ; - } - } - return statelist; -} - -/** lfsr_rollback_bit - * Rollback the shift register in order to get previous states - */ -uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) { - int out; - uint8_t ret; - uint32_t t; - - s->odd &= 0xffffff; - t = s->odd, s->odd = s->even, s->even = t; - - out = s->even & 1; - out ^= LF_POLY_EVEN & (s->even >>= 1); - out ^= LF_POLY_ODD & s->odd; - out ^= !!in; - out ^= (ret = filter(s->odd)) & (!!fb); - - s->even |= parity(out) << 23; - return ret; -} -/** lfsr_rollback_byte - * Rollback the shift register in order to get previous states - */ -uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) { - uint8_t ret = 0; - ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7; - ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6; - ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5; - ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4; - ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3; - ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2; - ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1; - ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0; - return ret; -} -/** lfsr_rollback_word - * Rollback the shift register in order to get previous states - */ -uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) { - - uint32_t ret = 0; - ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (29 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (28 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (27 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (26 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24); - - ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (23 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (22 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (21 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (20 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (19 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24); - - ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (12 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (11 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24); - - ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (4 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (3 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (2 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24); - ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24); - return ret; -} - -/** nonce_distance - * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y - */ -static uint16_t *dist = 0; -int nonce_distance(uint32_t from, uint32_t to) { - if (!dist) { - dist = calloc(2 << 16, sizeof(uint8_t)); - if (!dist) - return -1; - uint16_t x = 1; - for (uint16_t i = 1; i; ++i) { - dist[(x & 0xff) << 8 | x >> 8] = i; - x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15; - } - } - return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535; -} - - -static uint32_t fastfwd[2][8] = { - { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB}, - { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980} -}; - - -/** lfsr_prefix_ks - * - * Is an exported helper function from the common prefix attack - * Described in the "dark side" paper. It returns an -1 terminated array - * of possible partial(21 bit) secret state. - * The required keystream(ks) needs to contain the keystream that was used to - * encrypt the NACK which is observed when varying only the 3 last bits of Nr - * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3 - */ -uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) { - uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t)); - if (!candidates) return 0; - - uint32_t c, entry; - int size = 0, i, good; - - for (i = 0; i < 1 << 21; ++i) { - for (c = 0, good = 1; good && c < 8; ++c) { - entry = i ^ fastfwd[isodd][c]; - good &= (BIT(ks[c], isodd) == filter(entry >> 1)); - good &= (BIT(ks[c], isodd + 2) == filter(entry)); - } - if (good) - candidates[size++] = i; - } - - candidates[size] = -1; - - return candidates; -} - -/** check_pfx_parity - * helper function which eliminates possible secret states using parity bits - */ -static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State *sl) { - uint32_t good = 1; - - for (uint32_t c = 0; good && c < 8; ++c) { - sl->odd = odd ^ fastfwd[1][c]; - sl->even = even ^ fastfwd[0][c]; - - lfsr_rollback_bit(sl, 0, 0); - lfsr_rollback_bit(sl, 0, 0); - - uint32_t ks3 = lfsr_rollback_bit(sl, 0, 0); - uint32_t ks2 = lfsr_rollback_word(sl, 0, 0); - uint32_t ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1); - - uint32_t nr = ks1 ^ (prefix | c << 5); - uint32_t rr = ks2 ^ rresp; - - good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24); - good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16); - good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8); - good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0); - good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3; - } - - return sl + good; -} - -/** lfsr_common_prefix - * Implentation of the common prefix attack. - * Requires the 28 bit constant prefix used as reader nonce (pfx) - * The reader response used (rr) - * The keystream used to encrypt the observed NACK's (ks) - * The parity bits (par) - * It returns a zero terminated list of possible cipher states after the - * tag nonce was fed in - */ - -struct Crypto1State *lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]) { - struct Crypto1State *statelist, *s; - uint32_t *odd, *even, *o, *e, top; - - odd = lfsr_prefix_ks(ks, 1); - even = lfsr_prefix_ks(ks, 0); - - s = statelist = malloc((sizeof * statelist) << 24); // was << 20. Need more for no_par special attack. Enough??? - if (!s || !odd || !even) { - free(statelist); - statelist = 0; - goto out; - } - - for (o = odd; *o + 1; ++o) - for (e = even; *e + 1; ++e) - for (top = 0; top < 64; ++top) { - *o += 1 << 21; - *e += (!(top & 7) + 1) << 21; - s = check_pfx_parity(pfx, rr, par, *o, *e, s); - } - - s->odd = s->even = 0; -out: - free(odd); - free(even); - return statelist; -} diff --git a/tools/nonce2key/crapto1.h b/tools/nonce2key/crapto1.h deleted file mode 100644 index e1f9c7570..000000000 --- a/tools/nonce2key/crapto1.h +++ /dev/null @@ -1,87 +0,0 @@ -/* crapto1.h - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, US$ - - Copyright (C) 2008-2014 bla -*/ -#ifndef CRAPTO1_H__ -#define CRAPTO1_H__ -#include - -struct Crypto1State {uint32_t odd, even;}; -struct Crypto1State *crypto1_create(uint64_t); -void crypto1_destroy(struct Crypto1State *); -void crypto1_get_lfsr(struct Crypto1State *, uint64_t *); -uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int); -uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int); -uint32_t crypto1_word(struct Crypto1State *, uint32_t, int); -uint32_t prng_successor(uint32_t x, uint32_t n); - -struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in); -struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3); -uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd); -struct Crypto1State *lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]); - -uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb); -uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb); -uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb); -int nonce_distance(uint32_t from, uint32_t to); -#define SWAPENDIAN(x)\ - (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) - -#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\ - uint32_t __n = 0,__M = 0, N = 0;\ - int __i;\ - for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\ - for(__i = FSIZE - 1; __i >= 0; __i--)\ - if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\ - break;\ - else if(__i)\ - __M = prng_successor(__M, (__i == 7) ? 48 : 8);\ - else - -#define LF_POLY_ODD (0x29CE5C) -#define LF_POLY_EVEN (0x870804) -#define BIT(x, n) ((x) >> (n) & 1) -#define BEBIT(x, n) BIT(x, (n) ^ 24) -static inline int parity(uint32_t x) { -#if !defined __i386__ || !defined __GNUC__ - x ^= x >> 16; - x ^= x >> 8; - x ^= x >> 4; - return BIT(0x6996, x & 0xf); -#else - __asm__("movl %1, %%eax\n" - "mov %%ax, %%cx\n" - "shrl $0x10, %%eax\n" - "xor %%ax, %%cx\n" - "xor %%ch, %%cl\n" - "setpo %%al\n" - "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax", "ecx"); - return x; -#endif -} -static inline int filter(uint32_t const x) { - uint32_t f; - - f = 0xf22c0 >> (x & 0xf) & 16; - f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; - f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; - f |= 0x1e458 >> (x >> 12 & 0xf) & 2; - f |= 0x0d938 >> (x >> 16 & 0xf) & 1; - return BIT(0xEC57E80A, f); -} -#endif diff --git a/tools/nonce2key/crypto1.c b/tools/nonce2key/crypto1.c deleted file mode 100644 index f6f4642e2..000000000 --- a/tools/nonce2key/crypto1.c +++ /dev/null @@ -1,125 +0,0 @@ -/* crypto1.c - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, US - - Copyright (C) 2008-2008 bla -*/ -#include "crapto1.h" -#include - -struct Crypto1State *crypto1_create(uint64_t key) { - struct Crypto1State *s = malloc(sizeof(*s)); - if (!s) return NULL; - - s->odd = s->even = 0; - - int i; - //for(i = 47;s && i > 0; i -= 2) { - for (i = 47; i > 0; i -= 2) { - s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7); - s->even = s->even << 1 | BIT(key, i ^ 7); - } - return s; -} -void crypto1_destroy(struct Crypto1State *state) { - free(state); -} -void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) { - int i; - for (*lfsr = 0, i = 23; i >= 0; --i) { - *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3); - *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3); - } -} -uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) { - uint32_t feedin; - uint32_t tmp; - uint8_t ret = filter(s->odd); - - feedin = ret & (!!is_encrypted); - feedin ^= !!in; - feedin ^= LF_POLY_ODD & s->odd; - feedin ^= LF_POLY_EVEN & s->even; - s->even = s->even << 1 | parity(feedin); - - tmp = s->odd; - s->odd = s->even; - s->even = tmp; - - return ret; -} -uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) { - uint8_t ret = 0; - ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0; - ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1; - ret |= crypto1_bit(s, BIT(in, 2), is_encrypted) << 2; - ret |= crypto1_bit(s, BIT(in, 3), is_encrypted) << 3; - ret |= crypto1_bit(s, BIT(in, 4), is_encrypted) << 4; - ret |= crypto1_bit(s, BIT(in, 5), is_encrypted) << 5; - ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6; - ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7; - return ret; -} -uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) { - uint32_t ret = 0; - ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (0 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (1 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 2), is_encrypted) << (2 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 3), is_encrypted) << (3 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 4), is_encrypted) << (4 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (5 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24); - - ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (8 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (9 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (10 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 11), is_encrypted) << (11 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 12), is_encrypted) << (12 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 13), is_encrypted) << (13 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 14), is_encrypted) << (14 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (15 ^ 24); - - ret |= crypto1_bit(s, BEBIT(in, 16), is_encrypted) << (16 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 17), is_encrypted) << (17 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 18), is_encrypted) << (18 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 19), is_encrypted) << (19 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 20), is_encrypted) << (20 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 21), is_encrypted) << (21 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 22), is_encrypted) << (22 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (23 ^ 24); - - ret |= crypto1_bit(s, BEBIT(in, 24), is_encrypted) << (24 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 25), is_encrypted) << (25 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 26), is_encrypted) << (26 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 27), is_encrypted) << (27 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 28), is_encrypted) << (28 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 29), is_encrypted) << (29 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (30 ^ 24); - ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24); - return ret; -} - -/* prng_successor - * helper used to obscure the keystream during authentication - */ -uint32_t prng_successor(uint32_t x, uint32_t n) { - SWAPENDIAN(x); - while (n--) - x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; - - return SWAPENDIAN(x); -} diff --git a/tools/nonce2key/nonce2key.c b/tools/nonce2key/nonce2key.c index f4cb10e62..d7ccec0bb 100644 --- a/tools/nonce2key/nonce2key.c +++ b/tools/nonce2key/nonce2key.c @@ -1,4 +1,4 @@ -#include "crapto1.h" +#include "crapto1/crapto1.h" #define __STDC_FORMAT_MACROS #include #include @@ -48,7 +48,7 @@ int main(const int argc, const char *argv[]) { } printf("+----+--------+---+-----+---------------+\n"); - state = lfsr_common_prefix(nr, rr, ks3x, par); + state = lfsr_common_prefix(nr, rr, ks3x, par, false); lfsr_rollback_word(state, uid ^ nt, 0); crypto1_get_lfsr(state, &key_recovered); printf("\nkey recovered: %012" PRIx64 "\n\n", key_recovered); diff --git a/client/eml2lower.sh b/tools/pm3_eml2lower.sh old mode 100644 new mode 100755 similarity index 97% rename from client/eml2lower.sh rename to tools/pm3_eml2lower.sh index ddb3354db..086439c3c --- a/client/eml2lower.sh +++ b/tools/pm3_eml2lower.sh @@ -1,7 +1,7 @@ #!/bin/bash # Andrei Costin , 2011 -# eml2lower.sh +# pm3_eml2lower.sh # Converts PM3 Mifare Classic emulator EML file to lower case (for easier comparison in some text-comparison tools) # http://www.linuxquestions.org/questions/programming-9/bash-script-parsing-optional-parameters-621728/ diff --git a/client/pm3_eml2mfd.py b/tools/pm3_eml2mfd.py similarity index 100% rename from client/pm3_eml2mfd.py rename to tools/pm3_eml2mfd.py diff --git a/client/eml2UPPER.sh b/tools/pm3_eml2upper.sh old mode 100644 new mode 100755 similarity index 97% rename from client/eml2UPPER.sh rename to tools/pm3_eml2upper.sh index a28ae22a0..73b8646b7 --- a/client/eml2UPPER.sh +++ b/tools/pm3_eml2upper.sh @@ -1,7 +1,7 @@ #!/bin/bash # Andrei Costin , 2011 -# eml2UPPER.sh +# pm3_eml2upper.sh # Converts PM3 Mifare Classic emulator EML file to UPPER case (for easier comparison in some text-comparison tools) # http://www.linuxquestions.org/questions/programming-9/bash-script-parsing-optional-parameters-621728/ diff --git a/client/pm3_eml_mfd_test.py b/tools/pm3_eml_mfd_test.py similarity index 100% rename from client/pm3_eml_mfd_test.py rename to tools/pm3_eml_mfd_test.py diff --git a/client/pm3_mfd2eml.py b/tools/pm3_mfd2eml.py similarity index 100% rename from client/pm3_mfd2eml.py rename to tools/pm3_mfd2eml.py diff --git a/client/pm3_mfdread.py b/tools/pm3_mfdread.py old mode 100644 new mode 100755 similarity index 100% rename from client/pm3_mfdread.py rename to tools/pm3_mfdread.py diff --git a/tools/simmodule/SIM010.BIN b/tools/simmodule/SIM010.BIN deleted file mode 100644 index dea57a7d8..000000000 Binary files a/tools/simmodule/SIM010.BIN and /dev/null differ diff --git a/tools/simmodule/SIM010.md5.txt b/tools/simmodule/SIM010.md5.txt deleted file mode 100644 index c790101f7..000000000 --- a/tools/simmodule/SIM010.md5.txt +++ /dev/null @@ -1 +0,0 @@ -136e157364609e5c395540dc8dadbfd6 *SIM010.BIN diff --git a/tools/simmodule/SIM010.sha512.txt b/tools/simmodule/SIM010.sha512.txt deleted file mode 100644 index b7bab7246..000000000 --- a/tools/simmodule/SIM010.sha512.txt +++ /dev/null @@ -1 +0,0 @@ -e6ac5e6f1d7cc86d56f2128f2a495f1395fe044bf6ff3b6ca24ce90d1e361ae835fe273a206f2fc90e4344a13b37b180dd017a2c7f23312f1ed163f10c01ea5a *SIM010.BIN diff --git a/tools/simmodule/SIM011.md5.txt b/tools/simmodule/SIM011.md5.txt deleted file mode 100644 index 2a564eeb6..000000000 --- a/tools/simmodule/SIM011.md5.txt +++ /dev/null @@ -1 +0,0 @@ -e0be612fd3e68681ef0ee4706b4f28e2 *SIM011.BIN diff --git a/tools/simmodule/readme.txt b/tools/simmodule/readme.txt deleted file mode 100644 index 5dad9cd85..000000000 --- a/tools/simmodule/readme.txt +++ /dev/null @@ -1,32 +0,0 @@ - -2018-12-20 Iceman -2019-03-11 Iceman chg -======================================= - -The latest firmware for the SIM MODULE is : SIM011.bin - -You can use it to upgrade you sim module via the pm3 client. - -pm3 --> sc upgrade -h -pm3 --> sc upgrade f ../tools/simmodule/SIM011.bin - - -Even its a quite fast command you should be warned. You may brick it if you interrupt it. - - -Run hw status command to verify that the upgrade went well. - -pm3 --> hw status - - - -If you didn't download this file from the RRG Repo be aware that it might be corrupt or faulty. - -You find to hash text files in this folder. They were generated with the following linux commands. - - -md5sum -b SIM011.bin > SIM011.md5.txt -sha512sum -b SIM011.bin > SIM011.sha512.txt - - -You should validate the SIM011.bin file against these hash files in order to be sure the file is not corrupt or faulty. \ No newline at end of file diff --git a/tools/simmodule/sim011.asm b/tools/simmodule/sim011.asm new file mode 100644 index 000000000..178b1c484 --- /dev/null +++ b/tools/simmodule/sim011.asm @@ -0,0 +1,713 @@ +; --------------------------------------------------------------------------- +; Proxmark3 RDV4 SIM module firmware +; +; Copyright (C) 2019 Sentinel +; +; This program is free software: you can redistribute it and/or modify it +; under the terms of the GNU Lesser General Public License as published by the +; Free Software Foundation, either version 3 of the License, or (at your +; option) any later version. +; +; This program 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 Lesser General Public License +; along with this program. If not, see +; --------------------------------------------------------------------------- + VERS_HI equ 3 + VERS_LO equ 11 +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + SCON_0 equ 098h + FE_0 equ 098h.7 + + SCON_1 equ 0F8h + RI_1 equ 0F8h.0 + TI_1 equ 0F8h.1 + FE_1 equ 0F8h.7 + SBUF_1 equ 09Ah + T3CON equ 0C4h + RL3 equ 0C5h + RH3 equ 0C6h + + P0M1 equ 0B1h + P0M2 equ 0B2h + P1M1 equ 0B3h + P1M2 equ 0B4h + P3M1 equ 0ACh; + P3M2 equ 0ADh; + + EIE equ 09Bh + EIE1 equ 09Ch + + TA equ 0C7h + + RCTRIM0 equ 084h +; --------------------------------------------------------------------------- + CKCON equ 08Eh + CKDIV equ 095h +; --------------------------------------------------------------------------- + P1S equ 0B3h ;Page1 + SFRS equ 091h ;TA Protection +; --------------------------------------------------------------------------- + AUXR1 equ 0A2h +; --------------------------------------------------------------------------- + I2DAT equ 0BCh; + I2STAT equ 0BDh; + I2CLK equ 0BEh; + I2TOC equ 0BFh; + I2CON equ 0C0h; + ; equ I2CON.7;8 + I2CEN equ I2CON.6;4 + STA equ I2CON.5;2 + STO equ I2CON.4;1 + SI equ I2CON.3;8 + AA equ I2CON.2;4 + ; equ I2CON.1;2 + I2CPX equ I2CON.0;1 + + + I2ADDR equ 0C1h; + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + pin_TX1 equ P1.6 + + pin_TX0 equ P0.6 + pin_RX0 equ P0.7 + + pin_SCL equ P1.3 + pin_SDA equ P1.4 + + pin_RST equ P1.0 + pin_CLC equ P1.1 + pin_led equ P1.2 + +; --------------------------------------------------------------------------- +; =========================================================================== + + + CMD_GENERATE_ATR equ 01h + CMD_WRITE_DATA_SIM equ 02h + CMD_READ_DATA_SIM equ 03h + + CMD_SET_BAUD_RATE equ 04h + CMD_SET_SIM_CLC equ 05h + CMD_GET_VERS equ 06h + CMD_WRITE_CONFIRM equ 07h + + + +; --------------------------------------------------------------------------- +; =========================================================================== + + bit_RX0 equ 32.0 + bit_command_receive equ 32.1 + bit_generate_ATR equ 32.2 + i2c_write_mode equ 32.3 + i2c_write_done equ 32.4 + bit_data_sim_wr equ 32.5 + bit_length_answer equ 32.6 + bit_TX0 equ 32.7 + + bit_command_buff equ 33.0 + i2c_write_command equ 33.1 + i2c_command_done equ 33.2 + bit_wait_confirm equ 33.3 + bit_first_ATR equ 33.4 ;11/03/2019 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + bit_32 equ 32 + bit_33 equ 33 + pointer_RX1 equ 34 ;save SBUF(SIM) to XRAM + pointer_RX2 equ 35 ;read XRAM to I2C + pointer_TX equ 36 + + length_send_to_sim equ 37 + length_answer_sim equ 38 + length_command equ 39 + time_data_read equ 40 + time_confirm equ 41 + + buff_command equ 42 + cmd_command equ 42 + data_command equ 43 + + STACKKKKK equ 200 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; Beginning of the main program + cseg at 00 + Ljmp main_start + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 +; --------------------------------------------------------------------------- + jb time_confirm.7, $+3+2 ;3 + dec time_confirm ;2 +; --------------------------------------------------------------------------- + jb time_data_read.7,reti_timer0 + djnz time_data_read, reti_timer0 + setb pin_scl +reti_timer0: + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 35 ;UART0 + ajmp jmp_UART0_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 51 ;I2C + ajmp jmp_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 123 ;UART1 + clr RI_1 + clr TI_1 + reti + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_UART0_interrupt: + jbc RI,jmp_byte_RI + jbc TI,jmp_byte_TI + reti +; --------------------------------------------------------------------------- +jmp_byte_RI: + jnb bit_first_ATR, jmp_not_collect ;11/03/2019 + + setb bit_RX0 + jb i2c_write_done,jmp_not_collect + PUSH ACC + inc AUXR1 ;DPTR2 + mov a,SBUF ;DPTR2 + ;mov SBUF_1,DPL ;DPTR2 + mov DPL,pointer_RX1 ;DPTR2 + mov DPH,#1 ;DPTR2 + movx @DPTR,a ;DPTR2 + inc pointer_RX1 ;DPTR2 + inc AUXR1 ;DPTR2 + POP ACC + ;09/08/2018 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_sim +jmp_not_collect: + reti +; --------------------------------------------------------------------------- +jmp_byte_TI: + setb bit_TX0 + reti + + +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_i2c_interrupt: + PUSH ACC + PUSH PSW + mov PSW,#24 + mov R7,I2STAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#000h,nextttt00000 + setb STO + clr SI + jb STO,$ + ajmp pop_i2c_psw +nextttt00000: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#060h,nextttt00001 ;START+MY ADRESS + clr pin_led ;LED ON + + clr bit_command_receive + clr i2c_write_mode + clr bit_data_sim_wr + clr bit_length_answer + clr bit_command_buff + clr i2c_write_command + + ajmp end_i2c_interrupt +nextttt00001: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#080h,nextttt00002 ;RAM ADRESS + + jb bit_command_receive,jmp_data_receive + setb bit_command_receive + + mov a,I2DAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_CONFIRM,next_comm001a + + setb bit_wait_confirm + + sjmp jmp_WRITEDATASIM +next_comm001a: +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_DATA_SIM,next_comm001b + clr bit_wait_confirm +jmp_WRITEDATASIM: + mov length_send_to_sim,#0 + setb bit_data_sim_wr + mov pointer_TX,#0 + ajmp end_i2c_interrupt +next_comm001b: +; --------------------------------------------------------------------------- + cjne a,#CMD_GENERATE_ATR,next_comm002 + setb bit_generate_ATR + ;Prepare to answer + mov length_answer_sim,#0 + mov pointer_RX1,#0 + mov pointer_RX2,#0 + ajmp end_i2c_interrupt +next_comm002: +; --------------------------------------------------------------------------- + cjne a,#CMD_GET_VERS,next_comm003 + ajmp ANSWER_VERS +next_comm003: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_BAUD_RATE,next_comm004 + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_BAUD_RATE + setb i2c_write_command + ajmp end_i2c_interrupt +next_comm004: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC,next_comm005 + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_SIM_CLC + setb i2c_write_command + ajmp end_i2c_interrupt +next_comm005: +; --------------------------------------------------------------------------- + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +jmp_data_receive: + ;What receive ? Data to SIM/Command to bridge + jb bit_data_sim_wr, jmp_data_sim_receive + jb i2c_write_command,jmp_comm_bridge_receive + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_comm_bridge_receive: + mov @R0,I2DAT + inc R0 + inc length_command + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_data_sim_receive: + + setb i2c_write_mode + + inc AUXR1 ;DPTR2 + mov a,I2DAT ;DPTR2 + mov DPL,pointer_TX ;DPTR2 + mov DPH,#0 ;DPTR2 + movx @DPTR,a ;DPTR2 + inc pointer_TX ;DPTR2 + inc AUXR1 ;DPTR2 + + inc length_send_to_sim + ajmp end_i2c_interrupt +nextttt00002: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A0h,nextttt00003 ;STOP + setb pin_led ;LED OFF + + ;Command finish ? + jnb i2c_write_command,jmp_not_command + clr i2c_write_command + setb i2c_command_done +jmp_not_command: + + ;data to SIM finish ? + jnb i2c_write_mode,end_i2c_interrupt + clr i2c_write_mode + + setb i2c_write_done + ;Prepare to answer + mov length_answer_sim,#0 + mov pointer_RX1,#0 + mov pointer_RX2,#0 + + ajmp end_i2c_interrupt +nextttt00003: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A8h,nextttt00004 + sjmp read_byte_I2C +nextttt00004: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0B8h,nextttt00005 +read_byte_I2C: + jnb bit_command_buff,jmp_not_comm_buff2 + mov I2DAT,@R0 + inc R0 + ajmp end_i2c_interrupt + +jmp_not_comm_buff2: + jb bit_length_answer,read_byte_APROM + setb bit_length_answer + + mov I2DAT,length_answer_sim + ajmp end_i2c_interrupt +read_byte_APROM: + inc AUXR1 ;DPTR2 + mov DPL,pointer_RX2 ;DPTR2 + mov DPH,#1 ;DPTR2 + movx a,@DPTR ;DPTR2 + mov I2DAT,a ;DPTR2 + inc pointer_RX2 ;DPTR2 + inc AUXR1 ;DPTR2 +nextttt00005: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +end_i2c_interrupt: + clr STA + clr STO + setb AA +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +pop_i2c_psw: + POP PSW + POP ACC + clr SI + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +ANSWER_VERS: + mov R0,#data_command + mov cmd_command,#CMD_GET_VERS + mov (data_command+0),#2 + mov (data_command+1),#VERS_HI + mov (data_command+2),#VERS_LO + setb bit_command_buff + ajmp end_i2c_interrupt + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +main_start: + mov SP,#STACKKKKK +; --------------------------------------------------------------------------- + ;0-bidirect 1-push pull 0-input only 1-open drain + ;0 0 1 1 +; --------------------------------------------------------------------------- + mov P0M2,#01000000b ;Р0 + mov P0M1,#11111111b ;P1.6-Tx0 SIM; + ; + mov P1M2,#01011111b ;Р1 + mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; + + mov P3M2,#00000000b ;P3 + mov P3M1,#11111111b ; +; --------------------------------------------------------------------------- + mov TMOD, #22h + mov TH0, #0 ;14400hz + mov TH1, #0E9h ;UART0 10800 Bit/sec + mov TCON, #55h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov TA,#0AAh + mov TA,#055h + orl SFRS,#00000001b + + mov P1S, #00010000b ;P1.4 trigger schmiddt + + mov TA,#0AAh + mov TA,#055h + anl SFRS,#11111110b +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;------- CONFIG I2C --------- + mov I2CON, #44h ;set AA, set I2C enable + setb pin_sda + setb pin_scl + mov I2ADDR,#0C0h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;mov SCON, #050h ;UART0 8bit + mov SCON, #0D0h ;UART0 9bit + ;mov PCON, #11000000b;FE_0 enable + mov PCON, #10000000b;FE_0 disable +; --------------------------------------------------------------------------- + mov SCON_1,#050h ;UART1 + ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD + ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD + mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD + ;mov RL3,#0E9h ;10800/21600 + ;mov RH3,#0FFh +; --------------------------------------------------------------------------- + ;UART1 + mov RL3,#0F7h ;27777/55556 + mov RH3,#0FFh +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov CKDIV,#2 ;Fsys=4.00MHZ + ;mov CKDIV,#1 ;Fsys=8.00MHZ +; --------------------------------------------------------------------------- + mov bit_32,#0 + mov bit_33,#0 + setb time_data_read.7 +; --------------------------------------------------------------------------- + ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 + orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys +; --------------------------------------------------------------------------- + ;mov a,RCTRIM0 + ;add a,#31 + ;mov TA,#0AAh + ;mov TA,#055h + ;mov RCTRIM0,a +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + acall clr_buffer +; --------------------------------------------------------------------------- + mov EIE, #00000001b ;I2C Interrupt + ;mov IE, #10010000b ;EA, SERIAL0 + mov IE, #10010010b ;EA, SERIAL0, TIMER0 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +main_loop: + acall control_ATR + acall control_send_to_sim + acall control_command + sjmp main_loop + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_command: + jbc i2c_command_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;Control Length command=1 + mov a,length_command + cjne a,#1,next_commandEND ;error length_command != 1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov a,cmd_command + cjne a,#CMD_SET_BAUD_RATE,next_command001 + mov TH1,data_command ;Timer1 HIGH byte + ret +next_command001: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC, next_command002 + mov CKDIV,data_command ;Fsys DIV + ret +next_command002: +; --------------------------------------------------------------------------- +next_commandEND: + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_send_to_sim: + jb i2c_write_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jbc bit_wait_confirm,jmp_wait_confirm +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov DPTR,#0000 +looop_send: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz length_send_to_sim,looop_send +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr i2c_write_done + ret + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_wait_confirm: + mov DPTR,#0001 + movx a,@DPTR + mov R3,a + mov R4,#5 +; --------------------------------------------------------------------------- + mov DPTR,#0000 +looop_seend: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz R4,jmp_not_5byte + + jnb bit_RX0,$ + clr bit_RX0 + ;18/12/2018 + mov time_confirm,#65 ;New timeout 50mS +looop_waitconf: + jb time_confirm.7,jmp_no_answer + jnb bit_RX0,looop_waitconf + + ;clr pin_scl ;TEST PULSE! + mov a,SBUF + xrl a,R3 + ;setb pin_scl ;TEST PULSE! + + jnz jmp_no_correct_answer ;18/12/2018 + + ;pause for next byte 17/12/2018 + mov R7,#0 + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + +jmp_not_5byte: + djnz length_send_to_sim,looop_seend +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr bit_RX0 +jmp_no_answer: + clr i2c_write_done + ret + +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +;18/12/2018 +jmp_no_correct_answer: + clr EA + clr i2c_write_done + mov a,SBUF + mov DPL,pointer_RX1 + mov DPH,#1 + movx @DPTR,a + inc pointer_RX1 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + inc length_answer_sim + setb EA + ret + + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_ATR: + jbc bit_generate_ATR,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- + clr pin_RST + ;acall clr_buffer + ; Add rezet pause 17/12/2018 + + mov R6,#200 +looop_pause50mS: + djnz R7,$ ;~260mkSec + djnz R6,looop_pause50mS + + ;Prepare to answer 11/03/2019 + acall clr_buffer + mov length_answer_sim,#0 + mov pointer_RX1,#0 + mov pointer_RX2,#0 + setb bit_first_ATR + setb pin_RST + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +for_coooooom0: + clr bit_RX0 + mov c,P + mov TB8,c ;9bit parity + mov SBUF,a + jnb bit_TX0,$ + clr bit_TX0 + mov R7,#100 + djnz R7,$ + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +clr_buffer: + mov DPTR,#0256 ;Receive SIM buffer + mov R7,#255 + clr a +looop_clr_bufff: + movx @DPTR,a + inc DPTR + djnz R7,looop_clr_bufff + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +;for_coooooom1: +; mov SBUF_1,a +; jnb TI_1,$ +; clr TI_1 +; ret +; +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + +end. diff --git a/tools/simmodule/SIM011.BIN b/tools/simmodule/sim011.bin similarity index 100% rename from tools/simmodule/SIM011.BIN rename to tools/simmodule/sim011.bin diff --git a/tools/simmodule/SIM011.sha512.txt b/tools/simmodule/sim011.sha512.txt similarity index 90% rename from tools/simmodule/SIM011.sha512.txt rename to tools/simmodule/sim011.sha512.txt index 54a8bfd09..23ee6875f 100644 --- a/tools/simmodule/SIM011.sha512.txt +++ b/tools/simmodule/sim011.sha512.txt @@ -1 +1 @@ -752f9d8af3db214a797bacb7362a0b53eff4dd3793853e467047b7d36ddae9d1b4a050d9136225a48830d9c70bbad791f89d05553b0453f004b7bbcdc337e658 *SIM011.BIN +752f9d8af3db214a797bacb7362a0b53eff4dd3793853e467047b7d36ddae9d1b4a050d9136225a48830d9c70bbad791f89d05553b0453f004b7bbcdc337e658 *sim011.bin diff --git a/tools/srecswap.pl b/tools/srecswap.pl deleted file mode 100644 index 47db8e687..000000000 --- a/tools/srecswap.pl +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/perl - -# endian-swap S records; we need this because the JTAG tools we're using -# expect the memory image in byte-swapped format -# -# Jonathan Westhues, April 2004 - -if(@ARGV == 0) { - die "usage: $0 file-to-endian-swap.s19 > out.s19\n"; -} - -while(<>) { - chomp; - - if(/^S0/) { - next; - } - if(/^S7/) { - print "$_\n"; - next; - } - - if(not /^S3(..)(........)(.*)(..)$/) { - die "bad S record at line $.\n"; - } - - $data = $3; - $checksum = $4; - - print "S3$1$2"; - while($data =~ m#(..)(..)(..)(..)#g) { - print "$4$3$2$1"; - } - print "$checksum\n"; -}