This commit is contained in:
Bjoern Kerler 2020-06-13 15:11:10 +02:00
commit 631be7af32
1097 changed files with 50849 additions and 20982 deletions

12
.gitignore vendored
View file

@ -40,6 +40,7 @@ Makefile.platform
# cmake # cmake
client/build/ client/build/
client/android/build/
# Coverity # Coverity
cov-int/ cov-int/
@ -60,9 +61,9 @@ flasher
!flasher/ !flasher/
lua lua
luac luac
fpga_compress tools/fpga_compress/fpga_compress
mfkey32 tools/mfkey/mfkey32
mfkey64 tools/mfkey/mfkey64
tools/nonce2key/nonce2key tools/nonce2key/nonce2key
fpga/* fpga/*
@ -87,7 +88,7 @@ client/dumps/*
*.ice *.ice
*.new *.new
armsrc/TEMP EMV/* armsrc/TEMP EMV/*
tools/mf_nonce_brute/* tools/mf_nonce_brute/mf_nonce_brute
tools/andrew/* tools/andrew/*
tools/jtag_openocd/openocd_configuration tools/jtag_openocd/openocd_configuration
ppls patches/* ppls patches/*
@ -99,3 +100,6 @@ client/lualibs/pm3_cmd.lua
fpga_version_info.c fpga_version_info.c
.proxmark3/* .proxmark3/*
# .tmp files are created during compilation
*.tmp

View file

@ -8,7 +8,7 @@ os:
- linux - linux
- osx - osx
dist: xenial dist: bionic
osx_image: xcode11 osx_image: xcode11
@ -27,11 +27,12 @@ addons:
packages: packages:
- gcc-arm-none-eabi - gcc-arm-none-eabi
- libnewlib-dev - libnewlib-dev
- libsndfile1-dev - libbluetooth-dev
- python3-dev
- libbz2-dev
homebrew: homebrew:
packages: packages:
- readline - readline
- libsndfile
- qt5 - qt5
- RfidResearchGroup/proxmark3/arm-none-eabi-gcc - RfidResearchGroup/proxmark3/arm-none-eabi-gcc
taps: RfidResearchGroup/proxmark3 taps: RfidResearchGroup/proxmark3
@ -55,9 +56,9 @@ install:
script: script:
- if [ "$TO_TEST" = "MAKEFILE" ]; then - if [ "$TO_TEST" = "MAKEFILE" ]; then
make clean && make V=1 "$MAKE_PARAMS"; make clean && make V=1 "$MAKE_PARAMS";
./pm3test.sh; make check;
fi fi
- if [ "$TO_TEST" = "CMAKE" ]; then - if [ "$TO_TEST" = "CMAKE" ]; then
mkdir -p client/build && ( cd client/build && cmake .. && make VERBOSE=1 ); mkdir -p client/build && ( cd client/build && cmake .. && make VERBOSE=1 );
PM3BIN=./client/build/proxmark3 ./pm3test.sh client; make client/check CHECKARGS="--clientbin ./client/build/proxmark3";
fi fi

View file

@ -3,12 +3,146 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Add Android cross-compilation to client cmake (@dxl, @doegox)
- Fix `emv scan` - now saves in current folder and uses unique names (@iceman1001)
- Fix pm3.sh - parse COM ports larger than one digit (@doegox)
- Fix stack size and automatically use available space for BigBuf. Stack is now 5K (@slurdge)
- Added Mifare MAD Card Holder Information decoding (@lukaskuzmiak)
- Change Better precision for HF and LF voltage measurements and Add theremin.py script (@rosco)
- Added Mifare MAD Info Byte decoding. Easier to identify Card Publisher (@lukaskuzmiak)
- Change use system Bzip2 library instead of Zlib for hardnested tables, tables are now 7x smaller (@doegox)
- Change pushed some ARM source to compile with THUMB. Saves a lot of space of ARM flash memory (@slurdge)
- Change from using ZLIB compression of FPGA images in ARM to LZ4. 15%+ speedups when swapping between HF & LF now (@slurdge)
- Fix `emv scan -w` - hash mismatch, solution similar to below (@iceman1001)
- Fix 'emv roca' - hash mismatch, merged from offical repo (@pwpiwi)
- Fix 'lf ti demod' - now calculates correct crc (@iceman1001)
- Add Python3 as possible script engine (@iceman1001, @doegox)
- Add doc/mfu_binary_format_notes.md (@iceman1001)
- Fix `hf mfu dump` - now reads Ulev1 3counter vs NTAG 1 counters (@iceman1001)
- Fix `hf mfu info` - now print correct cfg1 - nfc protection (@iceman1001)
- Fix `hf mfu eload` - now detects and converts between plain/old/new mfu binary format (@iceman1001)
- Change, hitag2crack now integrated into main Makefile, tests added (@doegox)
- Add `make check` mechanics (@doegox)
- Change, log files moved to subfolders (@doegox)
- Change, use system Lua library if available (@doegox)
- Change, use system Jansson library if available (@doegox)
- Change, use system Whereami library if available (@doegox)
- Change, use system Zlib library if available (@doegox)
- Fix release version information (@doegox)
## [ice coffee.4.9237][2020-05-21]
- Updated documentation (@doegox, @iceman1001)
- Change `pm3test.sh` - more regression tests to (@doegox, @iceman1001)
- Change `hf 15 dump` - now supports basic json format (@iceman1001)
- Change Test and fix many `-Wxxxxxx` warnings [compiler trials] (@doegox)
- Fix COVERITY warnings [compiler trials] (@doegox, @iceman1001)
- Fix CPPCHECKER warnings [compiler trials] (@doegox, @iceman1001)
- Fix CLANG warnings [compiler trials] (@doegox)
- Change, stricter warnings [compiler trials] (@doegox)
- Change, remove section version_information for client (@doegox)
- Change, Add RELEASE_NAME (@doegox)
- Change, version info also for client (@doegox)
- Added `make release` (@doegox)
- Change `trace load` - err if offline mode (@doegox)
- Fix `standalone mode matty_run` eloadcard (@iceman1001)
- Added, HF 15 traces (@FlUxIUS)
- Fix, follow naming conventions [android] (@dxl)
- Change, work directory supported [android] (@dxl)
- Added `lf fdx demod` - decoding of Bio-Thermo lf tag. Thanks to Rosco! (@iceman1001)
- Fix, 32-bit time_t compilation error on [WIN64] (@grspy)
- Change, LogTrace error msg (@doegox)
- Change, remove inline [compiler trials] (@iceman1001)
- Change, adding execute/home/current working directory functions to lua (<@iceman1001)
- Change, fix max duration in LogTrace (@doegox)
- Change, first attempt for trace log header (@iceman1001)
- Change, pm3.sh, attempt to detect BT dongle when udevadm is not available (@doegox)
- Change, pm3.sh, test access to /dev/ttyXXX files as prerequisite for [linux] (@doegox)
- iclass bf: avoid slowdown (@doegox)
- Change, pm3tests.sh, shellcheck (@doegox)
- Change, pm3.sh, shellcheck (@doegox)
- Change, pm3.sh, err msgs on stderr (@doegox)
- Change, pm3.sh, textual and --list with no device, exit 1 (@doegox)
- Change, pm3.sh, without udev: change detection routine (@doegox)
- Change, pm3.sh, alternative if udevadm is not available [termux] (@doegox)
- Change `makefiles` - allow to skip pthread [termux] (@doegox)
- Change `script run test_t55x7` - enabled param to swap modulation to test (@iceman1001)
- Add mf_nonce_brute from https://github.com/@iceman1001/mf_nonce_brute and merge to pm3 Makefile (@doegox)
- Change `lf indala demod` - more lenient size check (@iceman1001)
- Change clarify BUTTON macro usages (@doegox)
- Change fix REV macros & hitagS (@doegox)
- Change, `hf iclass loclass` -removed printvar function (@iceman1001)
- Change, clock can be negative (@iceman1001)
- Change `data tune` (@doegox)
- fancy timers (@doegox)
- Change, copied from pm3 repo (@iceman1001)
- Change psk demodualtion, keep starting samples to easily find the zero init bit (@iceman1001)
- Change use machine/endian.h with osx (Jamie Fiedler)
- Fix 2 issues in proxendian.h (@doegox)
- Fix issue #729. Avoid stalling on non-rdv4 when polling for FeliCa without card in proximity (@doegox)
- Change `lf nexwatch demod` - lenient demod sizes (@iceman1001)
- Change `lf nexwath sim/clone` - now supports 88bit format direct. (@iceman1001)
- Rewrited `standalone mode lf_em4100rwc `, added card bruteforce mode. (Dmitriy Loginoov)
- Change `data load` - color (@iceman1001)
- Change appveyor verbose (@doegox)
- Change `lf nexwatch demod` - now detects type, and show parity /chksum (@iceman1001)
- Change `lfsampling` - interruptible only when logging not yet triggered (@doegox)
- Change `lf keri demod - more leanient when it comes to bits (@iceman1001)
- fix, proper filtering of RL markers (@doegox)
- Change, clean deps [compiler trials] (@doegox)
- Change, remove c99 restrictions [compiler trials] (@doegox)
- Added tracelog file for hf mfu sniff or a ntag (@iceman1001)
- Change `trace list` - different alloc (@iceman1001)
- Change, convert OLD -> MIX (@iceman1001)
- Change `trace list` - adjust messages (@iceman1001)
- Fix a mem corruption in `trace load/list` (@doegox)
- Change, rework banners (@doegox)
- Change, Let's see if the prompt suffixed spaces are still needed.(@doegox)
- Fix colored readline prompt bug (@doegox)
- Change, simpler ul_print_type (@doegox)
- Fix cmake for reveng [compiler trials] (@doegox)
- Change, hook reveng outputs to pm3 machinery, add regression test (@doegox)
- Change, cmake android: add backslashes for host compatibility [compiler trials](@doegox)
- Change, Translation some comments from Chinese to English. [android] (@dxl)
- Change, cmake android: use common cmake files for deps [android] (@doegox)
- Fix, proper way to fix reveng getopt bug(@doegox)
- Change, cmake deps: add prefix pm3rrg_rdv4_ [compiler trials] (@doegox)
- Change, cmake deps: add -fPIC so they can be integrated in a pm3 shared lib [compiler trials] (@doegox)
- Change, platform adaptation [android] (@dxl)
- Change, don't mix ifdef and defined [android] (@dxl)
- fix `trace list`- too short array for explanation (@iceman1001)
- Change, check for sim module fw file (@iceman1001)
- Change, rpi aling warning [compiler trials] (@iceman1001)
- Change, more LF demodulation tests (@iceman1001)
- Change, update whereami and avoid compiling unnneded troublesome parts [compiler trials] (@doegox)
- Change, rework C includes in C++ [compiler trials] (@doegox)
- Change, leanient parsing of tcp:/bt:/socket: vars (@iceman1001)
- Change, add bluetooth group to `make accessrights` (@iceman1001)
- Change, `Makefile` - fix PKG_CONFIG_ENV (@uli)
- Change, `f sim` - now only fills until bigbuffer is full (@iceman1001)
- Change, `hf mf hardnested` - don't drop field when in test mode (@doegox)
- Change, `lf sim` - better to return err on faulty offset, thanks @iceman (@doegox)
- Change, `lf sim` - fix offset of last packet (@doegox)
- Change, `client Makefile` - make sure to rebuild deps when needed [compiler trials](@doegox)
- Change, silent err if dbus absent [linux] (@doegox)
- Change, `pm3.sh` - for direct bt devices (@doegox)
- Change, `pm3.sh` - moved WSL/PS3.x bt native to be tested first. Since call to Win32_serialport crashes it. (@iceman1001)
- Change, `pm3.sh` - Bt dongle, bt direct listing of serial ports on WSL and PS3.x, now using powershell.exe since wmic is deprecated (@iceman1001)
- Change, remove libsndfile (@doegox)
- Change, enforce PACKED structs [compiler trials] (@iceman1001)
- Change, adjust number of threads according to cpu (@iceman1001)
- Change, `hitag2crack` compile flags(@doegox)
- Change, msdsal fix bug after var de-shadowing (@doegox)
- Change, lighter msg for loading prefs, json will anyway always tell the filename (@doegox)
- Change, make sure colors and emoji are disabled when not on TTY (@doegox)
- Added `pref` command. PM3 client now support user preferences saved to a json file. (@mwalker33)
- Added native support for Bluetooth in client [linux] (@doegox)
- Added `LF_EM4100RSWB` (based on `LF_EM4100RWC`) standalone mode to read/sim/clone/brute EM4100 cards (@Monster1024)
- Added `HF_MSDSAL` standalone mode which read and emulate Visa EMV cards (@Netxing) - Added `HF_MSDSAL` standalone mode which read and emulate Visa EMV cards (@Netxing)
- Added Mifare Ultralight tear off experiment (@cintainfinita and @fukmar) - Added `hf mfu tear` - Mifare Ultralight tear off experiment (@cintainfinitam, @fukmar)
- Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler) - Added Mifare Desfire Read/Write/Create files/records/values functionality and several fixes to `hf mfdes` (@bkerler)
- Added CreateStdFile command to Mifare `hf mfdes` (@bkerler) - Added CreateStdFile command to Mifare `hf mfdes` (@bkerler)
- Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler) - Rework des/3des/3k3des/aes auth. Port to mbedtls crypto library on device (@bkerler)
- Port 'hf mfdes' Authentification to CommandNG structure, fix auth session key (@bkerler) - Port `hf mfdes` Authentification to CommandNG structure, fix auth session key (@bkerler)
- Updates `hf mfdes` functions, improved logging and added new commands (@bkerler) - Updates `hf mfdes` functions, improved logging and added new commands (@bkerler)
- Updated 'legic.lua' and 'legic_clone.lua' script - works with current command set (@Pizza_4u) - Updated 'legic.lua' and 'legic_clone.lua' script - works with current command set (@Pizza_4u)
- Rewrote `hf mfdes` functions and added apdu debugging (@bkerler) - Rewrote `hf mfdes` functions and added apdu debugging (@bkerler)
@ -17,10 +151,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Improved `hf 14a info` - card detection handling (@bkerler) - Improved `hf 14a info` - card detection handling (@bkerler)
- Updated helptext layout in all luascripts (@iceman1001) - Updated helptext layout in all luascripts (@iceman1001)
- Change `hf mfdes info` - output and logging (@bkerler) - Change `hf mfdes info` - output and logging (@bkerler)
- Updated texts in legic commands (@ikarus23) - Updated texts in `hf legic` commands (@ikarus23)
- Fix timing bug inside 40x5 (@mwalker33) - Fix timing bug inside 40x5 (@mwalker33)
- Refactored all Hitag2 attacks (@doegox) - Refactored all Hitag2 attacks (@doegox)
- Added two new Hitag2 attacks (@doegox) - Added two new Hitag2 attacks (@doegox)
- Change `hf iclass decrypt` - limit amount of data to read if wrong app limit (@iceman1001)
- Change `hf search` - now continue to search in case of dual tech cards (@iceman1001) Thanks to @ikarus23 for the suggestion! - Change `hf search` - now continue to search in case of dual tech cards (@iceman1001) Thanks to @ikarus23 for the suggestion!
- Added `hf topas info` - old reader command, now also prints NDEF (@iceman1001) - Added `hf topas info` - old reader command, now also prints NDEF (@iceman1001)
- Change `hf topaz reader` - now only prints lighter info, like UID. (@iceman1001) - Change `hf topaz reader` - now only prints lighter info, like UID. (@iceman1001)
@ -39,14 +174,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Change - NDEF supports more signatures now (@iceman1001) - Change - NDEF supports more signatures now (@iceman1001)
- OSX Makefile now supports `make style` and `make checks` (@Pizza_4u) - OSX Makefile now supports `make style` and `make checks` (@Pizza_4u)
- Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u) - Added `HF_LEGIC` standalone mode to read and simulate a Legic prime tag (@Pizza_4u)
- Added keri MS decode/encode and update 'lf keri clone' to support MS fc/cid cloning. (@mwalker33) - Added keri MS decode/encode and update `lf keri clone` to support MS fc/cid cloning. (@mwalker33)
- Fix 'hf mfdes enum' - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001) - Fix `hf mfdes enum` - now actually manages to enumerate files under all AID's. :smiley: (@iceman1001)
- Fix 'hf mfdes info' - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001) - Fix `hf mfdes info` - now detects DESFire light and work properly Wrapped commands :+1: (@iceman1001)
- :smiling_imp: support (@doegox) - :smiling_imp: support (@doegox)
- Additional colour changes as recommended by @iceman (@dunderhay) - Additional colour changes as recommended by @iceman (@dunderhay)
- Change type colour for `hf 14a` card types (@dunderhay) - Change type colour for `hf 14a` card types (@dunderhay)
- Add colour to `hf mfdes` command (@dunderhay) - Add colour to `hf mfdes` command (@dunderhay)
- Add 'HINTS' command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001) - Add `HINTS` command. Will turn off / on hint messages. Default mode is OFF. (@iceman1001)
- Add colour to `hf 14a` and `hf mfu` commands (@dunderhay) - Add colour to `hf 14a` and `hf mfu` commands (@dunderhay)
- Add colour to `lf hid` commands (@dunderhay) - Add colour to `lf hid` commands (@dunderhay)
- Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay) - Change `script run hf_bruteforce -s start_id -e end_id -t timeout -x mifare_card_type` - The hf_bruteforce card script now requires Mifare type (mfc or mfu) (@dunderhay)

View file

@ -14,7 +14,9 @@ ifneq (,$(DESTDIR))
endif endif
endif endif
all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/% all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% mf_nonce_brute/% fpga_compress/%
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
#all clean install uninstall check: %: hitag2crack/%
INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py 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 INSTALLSIMFW=sim011.bin sim011.sha512.txt
@ -78,12 +80,49 @@ ifeq ($(platform),Linux)
endif endif
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) $(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
# tests
mfkey/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
nonce2key/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
mf_nonce_brute/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
fpga_compress/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
bootrom/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
armsrc/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
client/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
recovery/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
hitag2crack/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
common/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
check: common/check
$(info [*] ALL CHECKS DONE)
mfkey/%: FORCE mfkey/%: FORCE
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR) $(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR)
nonce2key/%: FORCE nonce2key/%: FORCE
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR) $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR)
mf_nonce_brute/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/mf_nonce_brute $(patsubst mf_nonce_brute/%,%,$@) DESTDIR=$(MYDESTDIR)
fpga_compress/%: FORCE fpga_compress/%: FORCE
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR) $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR)
@ -101,9 +140,12 @@ recovery/install: bootrom/all armsrc/all
recovery/%: FORCE cleanifplatformchanged recovery/%: FORCE cleanifplatformchanged
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR) $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
hitag2crack/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/hitag2crack $(patsubst hitag2crack/%,%,$@) DESTDIR=$(MYDESTDIR)
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged .PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key mf_nonce_brute hitag2crack style miscchecks release FORCE udev accessrights cleanifplatformchanged
help: help:
@echo "Multi-OS Makefile" @echo "Multi-OS Makefile"
@ -122,10 +164,14 @@ help:
@echo "+ client - Make only the OS-specific host client" @echo "+ client - Make only the OS-specific host client"
@echo "+ mfkey - Make tools/mfkey" @echo "+ mfkey - Make tools/mfkey"
@echo "+ nonce2key - Make tools/nonce2key" @echo "+ nonce2key - Make tools/nonce2key"
@echo "+ mf_nonce_brute - Make tools/mf_nonce_brute"
@echo "+ hitag2crack - Make tools/hitag2crack"
@echo "+ fpga_compress - Make tools/fpga_compress" @echo "+ fpga_compress - Make tools/fpga_compress"
@echo @echo
@echo "+ style - Apply some automated source code formatting rules" @echo "+ style - Apply some automated source code formatting rules"
@echo "+ checks - Detect various encoding issues in source code" @echo "+ check - Run offline tests. Set CHECKARGS to pass arguments to the test script"
@echo "+ .../check - Run offline tests against specific target. See above."
@echo "+ miscchecks - Detect various encoding issues in source code"
@echo @echo
@echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4" @echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4"
@echo "To activate verbose mode, use make V=1" @echo "To activate verbose mode, use make V=1"
@ -152,8 +198,12 @@ mfkey: mfkey/all
nonce2key: nonce2key/all nonce2key: nonce2key/all
mf_nonce_brute: mf_nonce_brute/all
fpga_compress: fpga_compress/all fpga_compress: fpga_compress/all
hitag2crack: hitag2crack/all
newtarbin: newtarbin:
$(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz $(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
@touch proxmark3-$(platform)-bin.tar @touch proxmark3-$(platform)-bin.tar
@ -186,8 +236,10 @@ udev:
accessrights: accessrights:
ifneq ($(wildcard /etc/arch-release),) #If user is running ArchLinux ifneq ($(wildcard /etc/arch-release),) #If user is running ArchLinux
sudo usermod -aG uucp $(USER) #Use specific command and group sudo usermod -aG uucp $(USER) #Use specific command and group
sudo usermod -aG bluetooth $(USER) #Use specific command and group
else else
sudo adduser $(USER) dialout sudo adduser $(USER) dialout
sudo adduser $(USER) bluetooth
endif endif
# easy printing of MAKE VARIABLES # easy printing of MAKE VARIABLES
@ -209,7 +261,7 @@ style:
--align-pointer=name {} \; --align-pointer=name {} \;
# Detecting weird codepages and tabs. # Detecting weird codepages and tabs.
checks: miscchecks:
# Make sure recode is installed # Make sure recode is installed
@which recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 ) @which recode >/dev/null || ( echo "Please install 'recode' package first" ; exit 1 )
@echo "Files with suspicious chars:" @echo "Files with suspicious chars:"
@ -228,5 +280,39 @@ endif
# @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \ # @find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \
# -exec grep -lP '\\t' {} \; # -exec grep -lP '\\t' {} \;
release: VERSION="v4.$(shell git log --oneline master | wc -l)"
release:
$(if $(findstring master,$(shell git rev-parse --abbrev-ref HEAD)),,$(error "!!! you are not on master branch, aborting"))
$(if $(findstring dirty,$(shell git describe --dirty --always)),$(error "!!! you have pending changes, aborting"))
$(if $(RELEASE_NAME),,$(error "!!! missing RELEASE_NAME, aborting"))
# Preparing a commit for release tagging, to be reverted after tagging.
@echo "# - Release Tag: $(VERSION)"
@echo "# - Release Name: $(RELEASE_NAME)"
# - Removing -Werror...
@find . \( -path "./Makefile.defs" -or -path "./client/Makefile" -or -path "./common_arm/Makefile.common" -or -path "./tools/hitag2crack/*/Makefile" \) -exec sed -i 's/ -Werror//' {} \;
@find . \( -path "./client/deps/*.cmake" -or -path "./client/CMakeLists.txt" \) -exec sed -i 's/ -Werror//' {} \;
# - Changing banner...
@sed -i "s/^#define BANNERMSG3 .*/#define BANNERMSG3 \"Release $(VERSION) - $(RELEASE_NAME)\"/" client/src/proxmark3.c
@echo -n "# ";grep "^#define BANNERMSG3" client/src/proxmark3.c
# - Committing temporarily...
@git commit -a -m "Release $(VERSION) - $(RELEASE_NAME)"
# - Tagging temporarily...
@git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION)
# - Changing default version information based on new tag
@$(SH) tools/mkversion.sh > common/default_version.c.tmp && $(MV) common/default_version.c.tmp common/default_version.c
# - Removing mkversion calls
@sed -i 's#^.*\.\./tools/mkversion.sh.*|| #\t$$(Q)#' client/Makefile bootrom/Makefile armsrc/Makefile
@sed -i '/COMMAND/s/sh .*|| //' client/CMakeLists.txt
# - Deleting tag...
@git tag -d $(VERSION)
# - Amending commit...
@git commit -a --amend -m "Release $(VERSION) - $(RELEASE_NAME)"
# - Tagging again...
@git tag -a -m "Release $(VERSION) - $(RELEASE_NAME)" $(VERSION)
# - Reverting tagged commit...
@git revert --no-edit HEAD
@echo "==================================================================="
@echo "Done! You can now execute 'git push && git push origin $(VERSION)'"
# Dummy target to test for GNU make availability # Dummy target to test for GNU make availability
_test: _test:

View file

@ -24,6 +24,9 @@ CROSS ?= arm-none-eabi-
CC = gcc CC = gcc
CXX = g++ CXX = g++
LD = g++ LD = g++
SH = sh
BASH = bash
PERL = perl
PATHSEP=/ PATHSEP=/
PREFIX ?= /usr/local PREFIX ?= /usr/local
@ -44,3 +47,57 @@ else
AR= ar rcs AR= ar rcs
RANLIB= ranlib RANLIB= ranlib
endif endif
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
# Some more warnings we want as errors:
DEFCFLAGS += -Wbad-function-cast -Wredundant-decls -Wmissing-prototypes -Wchar-subscripts -Wshadow -Wundef -Wwrite-strings -Wunused -Wuninitialized -Wpointer-arith -Winline -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wmissing-declarations -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits -Wold-style-definition
# Some more warnings we need first to eliminate, so temporarely tolerated:
DEFCFLAGS += -Wcast-align -Wno-error=cast-align
DEFCFLAGS += -Wswitch-enum -Wno-error=switch-enum
ifeq ($(platform),Darwin)
# their readline has strict-prototype issues
DEFCFLAGS += -Wno-strict-prototypes
else
DEFCFLAGS += -Wstrict-prototypes
endif
# Next ones are activated only if GCCEXTRA=1 or CLANGEXTRA=1
EXTRACFLAGS =
EXTRACFLAGS += -Wunused-parameter -Wno-error=unused-parameter
EXTRACFLAGS += -Wsign-compare -Wno-error=sign-compare
EXTRACFLAGS += -Wconversion -Wno-error=conversion -Wno-error=sign-conversion -Wno-error=float-conversion
# unknown to clang or old gcc:
# First we activate Wextra then we explicitly list those we know about
# Those without -Wno-error are supposed to be completely solved
GCCEXTRACFLAGS = -Wextra
GCCEXTRACFLAGS += -Wclobbered -Wno-error=clobbered
GCCEXTRACFLAGS += -Wcast-function-type
GCCEXTRACFLAGS += -Wimplicit-fallthrough=3 -Wno-error=implicit-fallthrough
GCCEXTRACFLAGS += -Wmissing-parameter-type
GCCEXTRACFLAGS += -Wold-style-declaration -Wno-error=old-style-declaration
GCCEXTRACFLAGS += -Woverride-init
GCCEXTRACFLAGS += -Wshift-negative-value
GCCEXTRACFLAGS += -Wunused-but-set-parameter -Wno-error=unused-but-set-parameter
ifeq ($(GCCEXTRA),1)
DEFCFLAGS += $(GCCEXTRACFLAGS) $(EXTRACFLAGS)
endif
# unknown to gcc or old clang:
# First we activate Wextra then we explicitly list those we know about
# Those without -Wno-error are supposed to be completely solved
CLANGEXTRACFLAGS = -Wextra
CLANGEXTRACFLAGS += -Wtautological-type-limit-compare
CLANGEXTRACFLAGS += -Wnull-pointer-arithmetic
CLANGEXTRACFLAGS += -Woverride-init
CLANGEXTRACFLAGS += -Wshift-negative-value
CLANGEXTRACFLAGS += -Wimplicit-fallthrough
ifeq ($(CLANGEXTRA),1)
DEFCFLAGS += $(CLANGEXTRACFLAGS) $(EXTRACFLAGS)
endif
ifeq ($(CLANGEVERYTHING),1)
DEFCFLAGS += -Weverything -Wno-error
endif
ifeq ($(NOERROR),1)
DEFCFLAGS += -Wno-error
endif

View file

@ -15,8 +15,10 @@ ifeq ($(DEFSBEENHERE),)
$(error Can't find Makefile.defs) $(error Can't find Makefile.defs)
endif endif
CFLAGS ?= -Wall -Werror -O3 CFLAGS ?= $(DEFCFLAGS)
CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES)
LDFLAGS += $(MYLDFLAGS)
LDLIBS += $(MYLDLIBS)
vpath %.c $(MYSRCPATHS) vpath %.c $(MYSRCPATHS)
@ -66,7 +68,7 @@ $(BINDIR)/$(LIB_A): $(MYOBJS)
$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS) $(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS)
$(info [=] LD $(notdir $@)) $(info [=] LD $(notdir $@))
$(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS)
$(OBJDIR)/%.o : %.c | $(OBJDIR) $(OBJDIR)/%.o : %.c | $(OBJDIR)
$(info [-] CC $<) $(info [-] CC $<)

View file

@ -2,7 +2,7 @@
# Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file. # Run 'make PLATFORM=' to get an exhaustive list of possible parameters for this file.
PLATFORM=PM3RDV4 PLATFORM=PM3RDV4
#PLATFORM=PM3OTHER
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces: # If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
#PLATFORM_EXTRAS=BTADDON #PLATFORM_EXTRAS=BTADDON
#STANDALONE=LF_SAMYRUN #STANDALONE=HF_MSDSAL
STANDALONE=LF_ICEHID

View file

@ -1,9 +1,11 @@
# RRG / Iceman repo - Proxmark3 # RRG / Iceman repo - Proxmark3
| Releases | Linux & OSX CI | Windows CI | Coverity | | Releases | Linux & OSX CI | Windows CI | Coverity |
| ------------------- |:-------------------:| -------------------:| -------------------:| | ------------------- |:-------------------:| -------------------:| -------------------:|
| [![Latest release](https://img.shields.io/github/release/RfidResearchGroup/proxmark3.svg)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| | [![Latest release](https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://api.travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)|
@ -16,15 +18,22 @@
|[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)| |[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)| |[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) || |[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) ||
|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)| |[Donations](#Donations)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)|
|[Notes on frame format](/doc/new_frame_format.md)|[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)| ||[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.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)| ||**[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)**|[Complete client command set](/doc/commands.md)|
|[Notes on Termux / Android](/doc/termux_notes.md)|**[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)**|[Complete client command set](/doc/commands.md)| ||**[JTAG](/doc/jtag_notes.md)**||
|[Notes on tracedata / wireshark](/doc/trace_notes.md)|**[JTAG](/doc/jtag_notes.md)**||
|[Notes on loclass](/doc/loclass_notes.md)|||
|[Notes on paths](/doc/path_notes.md)||| ## Notes / helpful documents
| Notes |||
| ------------------- |:-------------------:| -------------------:|
|[Notes on UART](/doc/uart_notes.md)|[Notes on Termux / Android](/doc/termux_notes.md)|[Notes on paths](/doc/path_notes.md)|
|[Notes on frame format](/doc/new_frame_format.md)|[Notes on tracelog / wireshark](/doc/trace_notes.md)|[Notes on EMV](/doc/emv_notes.md)|
|[Notes on external flash](/doc/ext_flash_notes.md)|[Notes on loclass](/doc/loclass_notes.md)|[Notes on Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md)|
|[Notes on file formats used with Proxmark3](/doc/extensions_notes.md)|[Notes on MFU binary format](/doc/mfu_binary_format_notes.md)|[Notes on FPGA & ARM](/doc/fpga_arm_notes.md)|
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)|| |[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)||
|[Donations](#Donations)|||
## Build for non-RDV4 Proxmark3 platforms ## Build for non-RDV4 Proxmark3 platforms
@ -48,30 +57,63 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
This repo compiles nicely on This repo compiles nicely on
- Proxspace v3.x - Proxspace v3.x
- Windows/mingw environment with Qt5.6.1 & GCC 4.8 - [latest release v3.4](https://github.com/Gator96100/ProxSpace/releases)
- Ubuntu 1604, 1804, 1904 - Windows/mingw environment with Qt5.6.1 & GCC 4.9
- Ubuntu 1604 -> 2004
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora, Debian
- Rasbian
- Android / Termux
- Mac OS X / Homebrew - Mac OS X / Homebrew
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora
- WSL, WSL2 (Windows subsystem linux) on Windows 10 - WSL, WSL2 (Windows subsystem linux) on Windows 10
- Docker container - Docker container
- [ RRG / Iceman repo based ubuntu 18.04 container ](https://hub.docker.com/r/secopsconsult/proxmark3)
- [ Iceman fork based container v1.7 ](https://hub.docker.com/r/iceman1001/proxmark3/)
Hardware to run client on
- PC
- Android
- Raspberry Pi & Raspberry Pi Zero
- Jetson Nano
## Precompiled binaries
We don't maintain any precompiled binaries in this repo. There is community effort over at the Proxmark3 forum where @gator96100 has set up a google drive with many mingw binaries which is up-to-date. We link to these files here as to make it easier for users.
If you are having troubles with these files, contact the package maintainer @gator96100 and read the [sticky thread at forum](http://www.proxmark.org/forum/viewtopic.php?pid=24763#p24763) where known issues has been documented.
Ref:
- [Precompiled builds for RDV40 dedicated x86](https://drive.google.com/open?id=13zUs-aiQkYaSl5KWrBtuW5IWCoHJPsue)
- [Precompiled builds for RDV40 dedicated x64](https://drive.google.com/open?id=1SyPB8t5Vo8O0Lh7PjNm3Kv-mO4BNbxjX)
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x86](https://drive.google.com/open?id=1TqWYctkRvkLshQ1ZRBHPLDzYHR-asuMO)
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x64](https://drive.google.com/open?id=17ful7u2QyYmMQzQzc5fAf8nJvyoDJfSL)
Generice Proxmark3 devices (non RDV4)
- [Precompiled builds for RRG / Iceman repository x86](https://drive.google.com/open?id=1PI3Xr1mussPBPnYGu4ZjWzGPARK4N7JR)
- [Precompiled builds for RRG / Iceman repository x64](https://drive.google.com/open?id=1uX9RtYGinuFrpHybu4xq_BE3HrobI20e)
## Roadmap
The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing. The [public roadmap](https://github.com/RfidResearchGroup/proxmark3/wiki/Public-Roadmap) is an excellent start to read if you are interesting in contributing.
> 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first. > 👉 **Remember!** If you intend to contribute to the code, please read the [coding style notes](HACKING.md) first.
We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards.
## Notes / helpful documents
- notes on [Coverity Scan Config & Run](/doc/md/Development/Coverity-Scan-Config-%26-Run.md). ## Issues & Troubleshooting
- notes on [UART](/doc/uart_notes.md) Please search the [issues](https://github.com/rfidresearchgroup/proxmark3/issues) page here and see if your issue is listed in the first instance. Next place to visit is the [Proxmark Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :) You will find many blogposts, youtube videos, tweets, reddit
- notes on [Frame format](/doc/new_frame_format.md)
- notes on [external flash](/doc/ext_flash_notes.md) Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
- notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)
- notes on [Termux / Android](/doc/termux_notes.md) Offical channels
- notes on [tracedata / Wireshark](/doc/trace_notes.md) - [Proxmark3 IRC channel](http://webchat.freenode.net/?channels=#proxmark3)
- notes on [loclass](/doc/loclass_notes.md) - [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/)
- notes on [EMV](/doc/emv_notes.md) - [Twitter](https://twitter.com/proxmark3/)
- notes on [Paths](/doc/path_notes.md)
- notes on [file formats used with Proxmark3](/doc/extensions_notes.md) _no discord or slack channel_
Iceman has quite a few videos on his [youtube channel](https://www.youtube.com/c/ChrisHerrmann1001)
## Cheat sheet ## Cheat sheet
Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md) Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md)
@ -90,13 +132,6 @@ The separation from official Proxmark3 repo gives us a lot of freedom to create
The official PM3-GUI from Gaucho will not work. 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. 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.
## Issues
Please see the [Proxmark Forum](http://www.proxmark.org/forum/index.php) and see if your issue is listed in the first instance Google is your friend :) Questions will be answered via the forum by Iceman and the team.
Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
## The end ## The end
- July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001) - July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001)

View file

@ -187,7 +187,7 @@ build_script:
#make #make
bash -c -i 'pwd;make clean;make all' bash -c -i 'pwd;make clean;make V=1'
#some checks #some checks
@ -204,7 +204,7 @@ build_script:
} }
if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){ if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.bz2)){
throw "Files in client\resources\hardnested_tables is not exists." throw "Files in client\resources\hardnested_tables is not exists."
@ -371,7 +371,7 @@ test_script:
ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin} 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 "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.bz2}
ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip} ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip}

View file

@ -12,35 +12,50 @@
#include "string.h" #include "string.h"
#include "dbprint.h" #include "dbprint.h"
#include "pm3_cmd.h"
extern uint8_t _stack_start, __bss_end__;
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces. // BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
// Also used to hold various smaller buffers and the Mifare Emulator Memory. // Also used to hold various smaller buffers and the Mifare Emulator Memory.
// declare it as uint32_t to achieve alignment to 4 Byte boundary // We know that bss is aligned to 4 bytes.
static uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)]; static uint8_t* BigBuf = &__bss_end__;
/* BigBuf memory layout: /* BigBuf memory layout:
Pointer to highest available memory: BigBuf_hi Pointer to highest available memory: BigBuf_hi
high BigBuf_size
high BIGBUF_SIZE
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi, reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
low 0x00 low 0x00
*/ */
static uint32_t BigBuf_size = 0;
// High memory mark // High memory mark
static uint16_t BigBuf_hi = BIGBUF_SIZE; static uint32_t BigBuf_hi = 0;
// pointer to the emulator memory. // pointer to the emulator memory.
static uint8_t *emulator_memory = NULL; static uint8_t *emulator_memory = NULL;
// trace related variables // trace related variables
static uint32_t traceLen = 0; static uint32_t traceLen = 0;
static bool tracing = true; //todo static? static bool tracing = true;
// compute the available size for BigBuf
void BigBuf_initialize(void) {
BigBuf_size = (uint32_t)&_stack_start - (uint32_t)&__bss_end__;
BigBuf_hi = BigBuf_size;
traceLen = 0;
}
// get the address of BigBuf // get the address of BigBuf
uint8_t *BigBuf_get_addr(void) { uint8_t *BigBuf_get_addr(void) {
return (uint8_t *)BigBuf; return (uint8_t *)BigBuf;
} }
uint32_t BigBuf_get_size(void) {
return BigBuf_size;
}
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
uint8_t *BigBuf_get_EM_addr(void) { uint8_t *BigBuf_get_EM_addr(void) {
// not yet allocated // not yet allocated
@ -57,9 +72,9 @@ void BigBuf_Clear(void) {
// clear ALL of BigBuf // clear ALL of BigBuf
void BigBuf_Clear_ext(bool verbose) { void BigBuf_Clear_ext(bool verbose) {
memset(BigBuf, 0, BIGBUF_SIZE); memset(BigBuf, 0, BigBuf_size);
if (verbose) if (verbose)
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE); Dbprintf("Buffer cleared (%i bytes)", BigBuf_size);
} }
void BigBuf_Clear_EM(void) { void BigBuf_Clear_EM(void) {
@ -73,7 +88,7 @@ void BigBuf_Clear_keep_EM(void) {
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory // allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
// at the beginning of BigBuf is always for traces/samples // at the beginning of BigBuf is always for traces/samples
uint8_t *BigBuf_malloc(uint16_t chunksize) { uint8_t *BigBuf_malloc(uint16_t chunksize) {
if (BigBuf_hi - chunksize < 0) if (BigBuf_hi < chunksize)
return NULL; // no memory left return NULL; // no memory left
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4 chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
@ -83,7 +98,7 @@ uint8_t *BigBuf_malloc(uint16_t chunksize) {
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again. // free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
void BigBuf_free(void) { void BigBuf_free(void) {
BigBuf_hi = BIGBUF_SIZE; BigBuf_hi = BigBuf_size;
emulator_memory = NULL; emulator_memory = NULL;
// shouldn't this empty BigBuf also? // shouldn't this empty BigBuf also?
} }
@ -93,16 +108,16 @@ void BigBuf_free_keep_EM(void) {
if (emulator_memory != NULL) if (emulator_memory != NULL)
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
else else
BigBuf_hi = BIGBUF_SIZE; BigBuf_hi = BigBuf_size;
// shouldn't this empty BigBuf also? // shouldn't this empty BigBuf also?
} }
void BigBuf_print_status(void) { void BigBuf_print_status(void) {
DbpString(_BLUE_("Memory")); DbpString(_CYAN_("Memory"));
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); Dbprintf(" BigBuf_size.............%d", BigBuf_size);
Dbprintf(" Available memory........%d", BigBuf_hi); Dbprintf(" Available memory........%d", BigBuf_hi);
DbpString(_BLUE_("Tracing")); DbpString(_CYAN_("Tracing"));
Dbprintf(" tracing ................%d", tracing); Dbprintf(" tracing ................%d", tracing);
Dbprintf(" traceLen ...............%d", traceLen); Dbprintf(" traceLen ...............%d", traceLen);
} }
@ -146,41 +161,37 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
if (!tracing) return false; if (!tracing) return false;
uint8_t *trace = BigBuf_get_addr(); uint8_t *trace = BigBuf_get_addr();
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + traceLen);
uint32_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity uint32_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity
uint32_t duration = timestamp_end - timestamp_start;
// Return when trace is full // Return when trace is full
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) { if (TRACELOG_HDR_LEN + iLen + num_paritybytes >= BigBuf_max_traceLen() - traceLen) {
tracing = false; // don't trace any more tracing = false; // don't trace any more
return false; return false;
} }
// Traceformat:
// 32 bits timestamp (little endian)
// 16 bits duration (little endian)
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
// y Bytes data
// x Bytes parity (one byte per 8 bytes data)
// timestamp (start) uint32_t duration;
trace[traceLen++] = ((timestamp_start >> 0) & 0xff); if (timestamp_end > timestamp_start) {
trace[traceLen++] = ((timestamp_start >> 8) & 0xff); duration = timestamp_end - timestamp_start;
trace[traceLen++] = ((timestamp_start >> 16) & 0xff); } else {
trace[traceLen++] = ((timestamp_start >> 24) & 0xff); duration = (UINT32_MAX - timestamp_start) + timestamp_end;
// duration
trace[traceLen++] = ((duration >> 0) & 0xff);
trace[traceLen++] = ((duration >> 8) & 0xff);
// data length
trace[traceLen++] = ((iLen >> 0) & 0xff);
trace[traceLen++] = ((iLen >> 8) & 0xff);
// readerToTag flag
if (!readerToTag) {
trace[traceLen - 1] |= 0x80;
} }
if (duration > 0x7FFF) {
if (DBGLEVEL >= DBG_DEBUG) {
Dbprintf("Error in LogTrace: duration too long for 15 bits encoding: 0x%08x start:0x%08x end:0x%08x", duration, timestamp_start, timestamp_end);
Dbprintf("Forcing duration = 0");
}
duration = 0;
}
hdr->timestamp = timestamp_start;
hdr->duration = duration;
hdr->data_len = iLen;
hdr->isResponse = !readerToTag;
traceLen += TRACELOG_HDR_LEN;
// data bytes // data bytes
if (btBytes != NULL && iLen != 0) { if (btBytes != NULL && iLen != 0) {
memcpy(trace + traceLen, btBytes, iLen); memcpy(trace + traceLen, btBytes, iLen);

View file

@ -14,7 +14,6 @@
#include "common.h" #include "common.h"
#define BIGBUF_SIZE 40000
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) #define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
@ -23,8 +22,10 @@
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!? #define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
uint8_t *BigBuf_get_addr(void); uint8_t *BigBuf_get_addr(void);
uint32_t BigBuf_get_size(void);
uint8_t *BigBuf_get_EM_addr(void); uint8_t *BigBuf_get_EM_addr(void);
uint16_t BigBuf_max_traceLen(void); uint16_t BigBuf_max_traceLen(void);
void BigBuf_initialize(void);
void BigBuf_Clear(void); void BigBuf_Clear(void);
void BigBuf_Clear_ext(bool verbose); void BigBuf_Clear_ext(bool verbose);
void BigBuf_Clear_keep_EM(void); void BigBuf_Clear_keep_EM(void);

View file

@ -20,8 +20,7 @@ endif
#in the next section to remove that particular feature from compilation. #in the next section to remove that particular feature from compilation.
# NO space,TABs after the "\" sign. # NO space,TABs after the "\" sign.
APP_CFLAGS = $(PLATFORM_DEFS) \ APP_CFLAGS = $(PLATFORM_DEFS) \
-DON_DEVICE \ -ffunction-sections -fdata-sections
-fno-strict-aliasing -ffunction-sections -fdata-sections
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c
SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO15693 = iso15693.c iso15693tools.c
@ -76,13 +75,13 @@ include Standalone/Makefile.inc
#the FPGA bitstream files. Note: order matters! #the FPGA bitstream files. Note: order matters!
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
#the zlib source files required for decompressing the fpga config at run time #the lz4 source files required for decompressing the fpga config at run time
SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c SRC_LZ4 = lz4.c
#additional defines required to compile zlib #additional defines required to compile lz4
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED LZ4_CFLAGS = -DLZ4_MEMORY_USAGE=8
APP_CFLAGS += $(ZLIB_CFLAGS) APP_CFLAGS += $(LZ4_CFLAGS)
# zlib includes: # lz4 includes:
APP_CFLAGS += -I../common/zlib APP_CFLAGS += -I../common/lz4
# stdint.h provided locally until GCC 4.5 becomes C99 compliant, # stdint.h provided locally until GCC 4.5 becomes C99 compliant,
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
@ -94,13 +93,21 @@ THUMBSRC = start.c \
$(SRC_ISO15693) \ $(SRC_ISO15693) \
$(SRC_NFCBARCODE) \ $(SRC_NFCBARCODE) \
$(SRC_LF) \ $(SRC_LF) \
$(SRC_ZLIB) \ $(SRC_LZ4) \
$(SRC_LEGIC) \ $(SRC_LEGIC) \
$(SRC_FLASH) \ $(SRC_FLASH) \
$(SRC_SMARTCARD) \ $(SRC_SMARTCARD) \
$(SRC_FPC) \ $(SRC_FPC) \
$(SRC_HITAG) \ $(SRC_HITAG) \
$(SRC_SPIFFS) \ $(SRC_SPIFFS) \
$(SRC_ISO14443a) \
$(SRC_ISO14443b) \
$(SRC_CRAPTO1) \
$(SRC_ICLASS) \
$(SRC_EMV) \
$(SRC_CRC) \
$(SRC_FELICA) \
$(SRC_STANDALONE) \
appmain.c \ appmain.c \
printf.c \ printf.c \
dbprint.c \ dbprint.c \
@ -115,14 +122,6 @@ THUMBSRC = start.c \
# These are to be compiled in ARM mode # These are to be compiled in ARM mode
ARMSRC = fpgaloader.c \ ARMSRC = fpgaloader.c \
$(SRC_ISO14443a) \
$(SRC_ISO14443b) \
$(SRC_CRAPTO1) \
$(SRC_ICLASS) \
$(SRC_EMV) \
$(SRC_CRC) \
$(SRC_FELICA) \
$(SRC_STANDALONE) \
parity.c \ parity.c \
usb_cdc.c \ usb_cdc.c \
cmd.c cmd.c
@ -133,8 +132,6 @@ VERSIONSRC = version.c \
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
include ../common_arm/Makefile.common include ../common_arm/Makefile.common
COMMON_FLAGS = -Os
INSTALLFW = $(OBJDIR)/fullimage.elf INSTALLFW = $(OBJDIR)/fullimage.elf
ifneq (,$(FWTAG)) ifneq (,$(FWTAG))
INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf)) INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf))
@ -145,16 +142,19 @@ endif
OBJS = $(OBJDIR)/fullimage.s19 OBJS = $(OBJDIR)/fullimage.s19
FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress
all: $(OBJS) all: showinfo $(OBJS)
showinfo:
$(info compiler version: $(shell $(CC) --version|head -n 1))
.DELETE_ON_ERROR: .DELETE_ON_ERROR:
# version.c should be remade on every time fullimage.stage1.elf should be remade # 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) version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
$(info [-] GEN $@) $(info [-] GEN $@)
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@
fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR) fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(info [-] GEN $@) $(info [-] GEN $@)
$(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@ $(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@
@ -176,7 +176,7 @@ $(FPGA_COMPRESSOR):
$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
$(info [=] LD $@) $(info [=] LD $@)
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) $(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
$(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf $(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf
$(info [-] GEN $@) $(info [-] GEN $@)
@ -204,7 +204,7 @@ $(OBJDIR)/fullimage.data.o: $(OBJDIR)/fullimage.data.bin.z
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o $(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o
$(info [=] LD $@) $(info [=] LD $@)
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^
tarbin: $(OBJS) tarbin: $(OBJS)
$(info TAR $@) $(info TAR $@)

View file

@ -17,6 +17,9 @@ define KNOWN_STANDALONE_DEFINITIONS
| LF_EM4100EMUL | Simulate predefined em4100 tags only | | LF_EM4100EMUL | Simulate predefined em4100 tags only |
| | | | | |
+----------------------------------------------------------+ +----------------------------------------------------------+
| LF_EM4100RSWB | Read/simulate/brute em4100 tags & |
| | clone it to T555x tags |
+----------------------------------------------------------+
| LF_EM4100RWC | Read/simulate em4100 tags & clone it | | LF_EM4100RWC | Read/simulate em4100 tags & clone it |
| | to T555x tags | | | to T555x tags |
+----------------------------------------------------------+ +----------------------------------------------------------+
@ -55,7 +58,7 @@ define KNOWN_STANDALONE_DEFINITIONS
+----------------------------------------------------------+ +----------------------------------------------------------+
endef endef
STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN
STANDALONE_MODES += HF_14ASNIFF HF_BOG HF_COLIN HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_YOUNG STANDALONE_MODES += HF_14ASNIFF HF_BOG HF_COLIN HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_YOUNG
STANDALONE_MODES_REQ_SMARTCARD := STANDALONE_MODES_REQ_SMARTCARD :=
STANDALONE_MODES_REQ_FLASH := LF_ICEHID HF_14ASNIFF HF_BOG HF_COLIN STANDALONE_MODES_REQ_FLASH := LF_ICEHID HF_14ASNIFF HF_BOG HF_COLIN

View file

@ -45,6 +45,10 @@ endif
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS))) ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS)))
SRC_STANDALONE = lf_em4100emul.c SRC_STANDALONE = lf_em4100emul.c
endif endif
# WITH_STANDALONE_LF_EM4100RSWB
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWB,$(APP_CFLAGS)))
SRC_STANDALONE = lf_em4100rswb.c
endif
# WITH_STANDALONE_LF_EM4100RWC # WITH_STANDALONE_LF_EM4100RWC
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS))) ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS)))
SRC_STANDALONE = lf_em4100rwc.c SRC_STANDALONE = lf_em4100rwc.c

View file

@ -68,7 +68,7 @@
#define HF_14ASNIFF_LOGFILE "hf_14asniff.trc" #define HF_14ASNIFF_LOGFILE "hf_14asniff.trc"
void DownloadTraceInstructions() { static void DownloadTraceInstructions(void) {
Dbprintf(""); Dbprintf("");
Dbprintf("To get the trace from flash and display it:"); Dbprintf("To get the trace from flash and display it:");
Dbprintf("1. mem spiffs dump o "HF_14ASNIFF_LOGFILE" f trace.trc"); Dbprintf("1. mem spiffs dump o "HF_14ASNIFF_LOGFILE" f trace.trc");
@ -81,7 +81,7 @@ void ModInfo(void) {
DownloadTraceInstructions(); DownloadTraceInstructions();
} }
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
Dbprintf("Starting standalone mode: hf_14asniff"); Dbprintf("Starting standalone mode: hf_14asniff");

View file

@ -41,7 +41,7 @@ from the client to view the stored quadlets.
#define HF_BOG_LOGFILE "hf_bog.log" #define HF_BOG_LOGFILE "hf_bog.log"
// This is actually copied from SniffIso14443a // This is actually copied from SniffIso14443a
void RAMFUNC SniffAndStore(uint8_t param) { static void RAMFUNC SniffAndStore(uint8_t param) {
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
@ -235,7 +235,7 @@ void ModInfo(void) {
DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)");
} }
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();

View file

@ -81,12 +81,12 @@
*/ */
uint8_t cjuid[10]; static uint8_t cjuid[10];
uint32_t cjcuid; static uint32_t cjcuid;
iso14a_card_select_t p_card; static iso14a_card_select_t p_card;
int currline; static int currline;
int currfline; static int currfline;
int curlline; static int curlline;
// TODO : Implement fast read of KEYS like in RFIdea // TODO : Implement fast read of KEYS like in RFIdea
// also http://ext.delaat.net/rp/2015-2016/p04/report.pdf // also http://ext.delaat.net/rp/2015-2016/p04/report.pdf
@ -104,7 +104,7 @@ static const uint8_t is_hex[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
static inline uint64_t hex2i(const char *s) { static uint64_t hex2i(const char *s) {
uint64_t val = 0; uint64_t val = 0;
if (s == NULL || s[0] == 0) if (s == NULL || s[0] == 0)
return 0; return 0;
@ -162,7 +162,7 @@ static void scan_keys(const char *str, int len, uint64_t *user_data) {
} }
} }
MFC1KSchema Schemas[MAX_SCHEMAS]; static MFC1KSchema Schemas[MAX_SCHEMAS];
/*MFC1KSchema Noralsy = { /*MFC1KSchema Noralsy = {
.name = "Noralsy", .name = "Noralsy",
@ -196,16 +196,16 @@ MFC1KSchema InfiHexact = {.name = "Infineon/Hexact",
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}}; 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}};
*/ */
int total_schemas = 0; static int total_schemas = 0;
void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) { static void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) {
if (*schemas_counter < MAX_SCHEMAS) { if (*schemas_counter < MAX_SCHEMAS) {
p[*schemas_counter] = a; p[*schemas_counter] = a;
*schemas_counter += 1; *schemas_counter += 1;
} }
} }
/*
void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) { static void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) {
if (*schemas_counter > 0 && index < *schemas_counter && index > -1) { if (*schemas_counter > 0 && index < *schemas_counter && index > -1) {
int last_index = *schemas_counter - 1; int last_index = *schemas_counter - 1;
for (int i = index; i < last_index; i++) { for (int i = index; i < last_index; i++) {
@ -214,33 +214,25 @@ void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) {
*schemas_counter -= 1; *schemas_counter -= 1;
} }
} }
*/
void cjSetCursFRight() { static void cjSetCursFRight(void) {
vtsend_cursor_position(NULL, 98, (currfline)); vtsend_cursor_position(NULL, 98, (currfline));
currfline++; currfline++;
} }
void cjSetCursRight() { static void cjSetCursRight(void) {
vtsend_cursor_position(NULL, 59, (currline)); vtsend_cursor_position(NULL, 59, (currline));
currline++; currline++;
} }
void cjSetCursLeft() { static void cjSetCursLeft(void) {
vtsend_cursor_position(NULL, 0, (curlline)); vtsend_cursor_position(NULL, 0, (curlline));
curlline++; curlline++;
} }
void cjTabulize() { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); } static void cjTabulize(void) { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); }
/* static char *ReadSchemasFromSPIFFS(char *filename) {
void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) {
char tosendkey[13];
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4],
foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type);
}
*/
char *ReadSchemasFromSPIFFS(char *filename) {
SpinOff(0); SpinOff(0);
int changed = rdv40_spiffs_lazy_mount(); int changed = rdv40_spiffs_lazy_mount();
@ -255,7 +247,7 @@ char *ReadSchemasFromSPIFFS(char *filename) {
return (char *)mem; return (char *)mem;
} }
void add_schemas_from_json_in_spiffs(char *filename) { static void add_schemas_from_json_in_spiffs(char *filename) {
char *jsonfile = ReadSchemasFromSPIFFS((char *)filename); char *jsonfile = ReadSchemasFromSPIFFS((char *)filename);
@ -275,7 +267,7 @@ void add_schemas_from_json_in_spiffs(char *filename) {
} }
} }
void ReadLastTagFromFlash() { static void ReadLastTagFromFlash(void) {
SpinOff(0); SpinOff(0);
LED_A_ON(); LED_A_ON();
LED_B_ON(); LED_B_ON();
@ -292,6 +284,7 @@ void ReadLastTagFromFlash() {
// this one will handle filetype (symlink or not) and resolving by itself // this one will handle filetype (symlink or not) and resolving by itself
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE); rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
// copy 64blocks (16bytes) starting w block0, to emulator mem.
emlSetMem(mem, 0, 64); emlSetMem(mem, 0, 64);
DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator"); DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator");
@ -330,16 +323,22 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
return; return;
} }
void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); } void ModInfo(void) {
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
}
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
Dbprintf(">> HF Mifare ultra fast sniff/sim/clone a.k.a VIGIKPWN Started <<");
// turn off all debugging.
DBGLEVEL = DBG_NONE;
// add_schema(Schemas, Noralsy, &total_schemas); // add_schema(Schemas, Noralsy, &total_schemas);
// add_schema(Schemas, InfiHexact, &total_schemas); // add_schema(Schemas, InfiHexact, &total_schemas);
// add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON); // add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON);
// add_schema(Schemas, UrmetCaptive, &total_schemas); // add_schema(Schemas, UrmetCaptive, &total_schemas);
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
currline = 20; currline = 20;
curlline = 20; curlline = 20;
@ -459,7 +458,6 @@ void RunMod() {
bool err = 0; bool err = 0;
bool trapped = 0; bool trapped = 0;
bool allKeysFound = true; bool allKeysFound = true;
uint32_t size = mfKeysCnt; uint32_t size = mfKeysCnt;
// banner: // banner:
@ -487,7 +485,7 @@ failtag:
SpinOff(50); SpinOff(50);
LED_A_ON(); LED_A_ON();
uint8_t ticker = 0; uint8_t ticker = 0;
// while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
WDT_HIT(); WDT_HIT();
@ -496,7 +494,7 @@ failtag:
LED_A_INV(); LED_A_INV();
} }
if (BUTTON_HELD(10) > 0) { if (BUTTON_HELD(10) == BUTTON_HOLD) {
WDT_HIT(); WDT_HIT();
DbprintfEx(FLAG_NEWLINE, "\t\t\t[ READING FLASH ]"); DbprintfEx(FLAG_NEWLINE, "\t\t\t[ READING FLASH ]");
ReadLastTagFromFlash(); ReadLastTagFromFlash();
@ -505,8 +503,8 @@ failtag:
} }
SpinOff(50); SpinOff(50);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
vtsend_cursor_position_restore(NULL); vtsend_cursor_position_restore(NULL);
DbprintfEx(FLAG_NEWLINE, "\t\t\t%s[ GOT a Tag ! ]%s", _XGREEN_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "\t\t\t%s[ GOT a Tag ! ]%s", _XGREEN_, _XWHITE_);
cjSetCursLeft(); cjSetCursLeft();
@ -625,7 +623,6 @@ failtag:
break; break;
} }
} }
/* etc etc for testing schemes quick schemes */ /* etc etc for testing schemes quick schemes */
} }
} }
@ -641,7 +638,7 @@ failtag:
return; return;
} }
/* Settings keys to emulator */ // Settings keys to emulator
emlClearMem(); emlClearMem();
uint8_t mblock[16]; uint8_t mblock[16];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
@ -655,7 +652,7 @@ failtag:
DbprintfEx(FLAG_NEWLINE, "%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _XYELLOW_, _XWHITE_, _XGREEN_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _XYELLOW_, _XWHITE_, _XGREEN_, _XWHITE_);
/* filling TAG to emulator */ // filling TAG to emulator
int filled; int filled;
cjSetCursLeft(); cjSetCursLeft();
@ -666,11 +663,10 @@ failtag:
DbprintfEx(FLAG_NEWLINE, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _XRED_, _XORANGE_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _XRED_, _XORANGE_, _XWHITE_);
/* no trace, no dbg */ // no trace, no dbg
filled = e_MifareECardLoad(sectorsCnt, 1); filled = e_MifareECardLoad(sectorsCnt, 1);
if (filled != PM3_SUCCESS) { if (filled != PM3_SUCCESS) {
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B"); DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
SpinErr(LED_C, 100, 8); SpinErr(LED_C, 100, 8);
SpinOff(100); SpinOff(100);
@ -717,10 +713,9 @@ readysim:
SpinOff(100); SpinOff(100);
LED_C_ON(); LED_C_ON();
DBGLEVEL = DBG_NONE; /*
uint16_t flags = 0;
//uint16_t flags=0; switch (p_card.uidlen) {
/*switch (p_card.uidlen) {
case 10: case 10:
flags = FLAG_10B_UID_IN_DATA; flags = FLAG_10B_UID_IN_DATA;
break; break;
@ -733,19 +728,18 @@ readysim:
default: default:
flags = FLAG_UID_IN_EMUL; flags = FLAG_UID_IN_EMUL;
break; break;
}*/ }
// Use UID, SAK, ATQA from EMUL, if uid not defined // Use UID, SAK, ATQA from EMUL, if uid not defined
// if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
//flags |= FLAG_UID_IN_EMUL; flags |= FLAG_UID_IN_EMUL;
//} }
//flags |= FLAG_MF_1K; flags |= FLAG_MF_1K;
//if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
// flags |= FLAG_UID_IN_EMUL; flags |= FLAG_UID_IN_EMUL;
//} }
//flags = 0x10; flags = 0x10;
uint16_t flags = 0; */
flags = 16; uint16_t flags = FLAG_UID_IN_EMUL;
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags); DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
cjSetCursLeft(); cjSetCursLeft();
SpinOff(1000); SpinOff(1000);
@ -789,8 +783,6 @@ readysim:
* - tracing is falsed * - tracing is falsed
*/ */
int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) { int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
DBGLEVEL = DBG_NONE;
uint8_t numSectors = numofsectors; uint8_t numSectors = numofsectors;
uint8_t keyType = keytype; uint8_t keyType = keytype;
@ -802,7 +794,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
uint8_t dataoutbuf2[16]; uint8_t dataoutbuf2[16];
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace(); clear_trace();
set_tracing(false); set_tracing(false);
@ -810,24 +801,17 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
isOK = false; isOK = false;
if (DBGLEVEL >= 1)
DbprintfEx(FLAG_RAWPRINT, "Can't select card");
} }
for (uint8_t s = 0; isOK && s < numSectors; s++) { for (uint8_t s = 0; isOK && s < numSectors; s++) {
uint64_t ui64Key = emlGetKey(s, keyType); uint64_t ui64Key = emlGetKey(s, keyType);
if (s == 0) { if (s == 0) {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) { if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
if (DBGLEVEL >= 1)
DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth error", s);
break; break;
} }
} else { } else {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) { if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
isOK = false; isOK = false;
if (DBGLEVEL >= 1)
DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth nested error", s);
break; break;
} }
} }
@ -835,8 +819,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) { for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) {
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) { if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
isOK = false; isOK = false;
if (DBGLEVEL >= 1)
DbprintfEx(FLAG_NEWLINE, "Error reading sector %2d block %2d", s, blockNo);
break; break;
}; };
if (isOK) { if (isOK) {
@ -852,23 +834,18 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
} }
} }
if (mifare_classic_halt(pcs, cjcuid)) { int res = mifare_classic_halt(pcs, cjcuid);
if (DBGLEVEL >= 1) (void)res;
DbprintfEx(FLAG_NEWLINE, "Halt error");
};
crypto1_deinit(pcs); crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return (isOK) ? PM3_SUCCESS : PM3_EUNDEF; return (isOK) ? PM3_SUCCESS : PM3_EUNDEF;
} }
/* the chk function is a piwi'ed(tm) check that will try all keys for /* the chk function is a piwi'ed(tm) check that will try all keys for
a particular sector. also no tracing no dbg */ a particular sector. also no tracing no dbg */
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
uint64_t *key) { uint8_t keyCount, uint8_t *datain, uint64_t *key) {
DBGLEVEL = DBG_NONE;
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(false); set_tracing(false);
@ -876,14 +853,16 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
struct Crypto1State *pcs; struct Crypto1State *pcs;
pcs = &mpcs; pcs = &mpcs;
for (int i = 0; i < keyCount; ++i) { int retval = -1;
for (uint8_t i = 0; i < keyCount; i++) {
/* no need for anticollision. just verify tag is still here */ /* no need for anticollision. just verify tag is still here */
// if (!iso14443a_fast_select_card(cjuid, 0)) { // if (!iso14443a_fast_select_card(cjuid, 0)) {
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) { if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
return -1; break;
} }
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
@ -894,15 +873,13 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
SpinDelayUs(AUTHENTICATION_TIMEOUT); SpinDelayUs(AUTHENTICATION_TIMEOUT);
continue; continue;
} }
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
*key = ui64Key; *key = ui64Key;
return i; retval = i;
break;
} }
crypto1_deinit(pcs); crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return retval;
return -1;
} }
void saMifareMakeTag(void) { void saMifareMakeTag(void) {
@ -920,7 +897,6 @@ void saMifareMakeTag(void) {
int flags = 0; int flags = 0;
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) { for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
uint8_t mblock[16]; uint8_t mblock[16];
// cnt = 0;
emlGetMem(mblock, blockNum, 1); emlGetMem(mblock, blockNum, 1);
// switch on field and send magic sequence // switch on field and send magic sequence
if (blockNum == 0) if (blockNum == 0)
@ -935,21 +911,15 @@ void saMifareMakeTag(void) {
flags = 0x04 + 0x10; flags = 0x04 + 0x10;
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) { if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) {
//&& cnt <= retry) {
// cnt++;
cjSetCursFRight(); cjSetCursFRight();
if (currfline > 53) { if (currfline > 53) {
currfline = 54; currfline = 54;
} }
DbprintfEx(FLAG_NEWLINE, "Block :%02x %sOK%s", blockNum, _XGREEN_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "Block :%02x %sOK%s", blockNum, _XGREEN_, _XWHITE_);
// DbprintfEx(FLAG_RAWPRINT,"FATAL:E_MF_CHINESECOOK_NORICE");
// cfail=1;
// return;
continue; continue;
} else { } else {
cjSetCursLeft(); cjSetCursLeft();
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _XRED_, _XWHITE_, blockNum); DbprintfEx(FLAG_NEWLINE, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _XRED_, _XWHITE_, blockNum);
cjSetCursFRight(); cjSetCursFRight();
DbprintfEx(FLAG_NEWLINE, "%s>>>>%s STOP AT %02x", _XRED_, _XWHITE_, blockNum); DbprintfEx(FLAG_NEWLINE, "%s>>>>%s STOP AT %02x", _XRED_, _XWHITE_, blockNum);
@ -957,14 +927,9 @@ void saMifareMakeTag(void) {
break; break;
} }
cjSetCursFRight(); cjSetCursFRight();
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>> END <<<<<<<<%s", _XYELLOW_, _XWHITE_); DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>> END <<<<<<<<%s", _XYELLOW_, _XWHITE_);
// break;
/*if (cfail == 1) {
DbprintfEx(FLAG_RAWPRINT,"FATAL: E_MF_HARA_KIRI_\r\n");
break;
} */
} }
if (cfail == 0) { if (cfail == 0) {
SpinUp(50); SpinUp(50);
SpinUp(50); SpinUp(50);

View file

@ -44,7 +44,8 @@
* *
*/ */
void DownloadLogInstructions() { #ifdef WITH_FLASH
static void DownloadLogInstructions(void) {
Dbprintf(""); Dbprintf("");
Dbprintf("[=] List all dumps from flash:"); Dbprintf("[=] List all dumps from flash:");
Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree"); Dbprintf("[=] " _YELLOW_("-") " mem spiffs tree");
@ -52,8 +53,9 @@ void DownloadLogInstructions() {
Dbprintf("[=] To save a dump file from flash to client:"); Dbprintf("[=] To save a dump file from flash to client:");
Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin"); Dbprintf("[=] " _YELLOW_("-") " mem spiffs dump o hf-legic-UID-dump.bin f hf-legic-UID-dump.bin");
} }
#endif
void save_dump_to_file(legic_card_select_t *p_card) { static void save_dump_to_file(legic_card_select_t *p_card) {
#ifdef WITH_FLASH #ifdef WITH_FLASH
@ -99,7 +101,7 @@ void ModInfo(void) {
// A, B, C = Reading // A, B, C = Reading
// A, D = Simulating // A, D = Simulating
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
Dbprintf("[=] >> HF Legic Prime Read/Simulate Started <<"); Dbprintf("[=] >> HF Legic Prime Read/Simulate Started <<");

View file

@ -49,9 +49,16 @@ on a blank card.
#include "mifaresim.h" // mifare1ksim #include "mifaresim.h" // mifare1ksim
#include "mifareutil.h" #include "mifareutil.h"
uint8_t uid[10]; static uint8_t uid[10];
uint32_t cuid; static uint32_t cuid;
iso14a_card_select_t p_card; static iso14a_card_select_t p_card;
// Pseudo-configuration block.
static bool printKeys = false; // Prints keys
static bool transferToEml = true; // Transfer keys to emulator memory
static bool ecfill = true; // Fill emulator memory with cards content.
static bool simulation = true; // Simulates an exact copy of the target tag
static bool fillFromEmulator = false; // Dump emulator memory.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Matt's StandAlone mod. // Matt's StandAlone mod.
@ -169,7 +176,8 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
/* the chk function is a piwied(tm) check that will try all keys for /* the chk function is a piwied(tm) check that will try all keys for
a particular sector. also no tracing no dbg */ a particular sector. also no tracing no dbg */
static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) { static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
uint8_t keyCount, uint8_t *datain, uint64_t *key) {
DBGLEVEL = DBG_NONE; DBGLEVEL = DBG_NONE;
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(false); set_tracing(false);
@ -178,13 +186,15 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
struct Crypto1State *pcs; struct Crypto1State *pcs;
pcs = &mpcs; pcs = &mpcs;
for (int i = 0; i < keyCount; ++i) { int retval = -1;
for (uint8_t i = 0; i < keyCount; i++) {
/* no need for anticollision. just verify tag is still here */ /* no need for anticollision. just verify tag is still here */
// if (!iso14443a_fast_select_card(cjuid, 0)) { // if (!iso14443a_fast_select_card(cjuid, 0)) {
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) { if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
DbprintfEx(FLAG_NEWLINE, "FATAL : E_MF_LOSTTAG"); DbprintfEx(FLAG_NEWLINE, "FATAL : E_MF_LOSTTAG");
return -1; break;
} }
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
@ -195,26 +205,90 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
SpinDelayUs(AUTHENTICATION_TIMEOUT); SpinDelayUs(AUTHENTICATION_TIMEOUT);
continue; continue;
} }
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
*key = ui64Key; *key = ui64Key;
return i; retval = i;
break;
} }
crypto1_deinit(pcs); crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return retval;
return -1;
} }
/* Abusive microgain on original MifareECardLoad :
* - *datain used as error return
* - tracing is falsed
*/
static int saMifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
DBGLEVEL = DBG_NONE;
uint8_t numSectors = numofsectors;
uint8_t keyType = keytype;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
uint8_t dataoutbuf[16];
uint8_t dataoutbuf2[16];
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
set_tracing(false);
int retval = PM3_SUCCESS;
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
retval = PM3_ESOFT;
DbprintfEx(FLAG_RAWPRINT, "Can't select card");
goto out;
}
for (uint8_t s = 0; s < numSectors; s++) {
uint64_t ui64Key = emlGetKey(s, keyType);
if (s == 0) {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
retval = PM3_ESOFT;
break;
}
} else {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
retval = PM3_ESOFT;
break;
}
}
// failure to read one block, skips to next sector.
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(s); blockNo++) {
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
retval = PM3_ESOFT;
break;
};
if (blockNo < NumBlocksPerSector(s) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1);
} else {
// sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
}
}
}
int res = mifare_classic_halt(pcs, cuid);
(void)res;
out:
crypto1_deinit(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return retval;
}
void ModInfo(void) { void ModInfo(void) {
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)"); DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)");
} }
void RunMod() {
StandAloneMode();
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
/* /*
It will check if the keys from the attacked tag are a subset from It will check if the keys from the attacked tag are a subset from
the hardcoded set of keys inside of the ARM. If this is the case the hardcoded set of keys inside of the ARM. If this is the case
@ -228,33 +302,23 @@ void RunMod() {
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
messages, you MUST uncomment usb_disable(). messages, you MUST uncomment usb_disable().
*/ */
void RunMod(void) {
StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
// Comment this line below if you want to see debug messages. // Comment this line below if you want to see debug messages.
// usb_disable(); // usb_disable();
/*
Pseudo-configuration block.
*/
bool printKeys = false; // Prints keys
bool transferToEml = true; // Transfer keys to emulator memory
bool ecfill = true; // Fill emulator memory with cards content.
bool simulation = true; // Simulates an exact copy of the target tag
bool fillFromEmulator = false; // Dump emulator memory.
uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now) uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now)
uint8_t sectorSize = 64; // 1k's sector size is 64 bytes. uint8_t sectorSize = 64; // 1k's sector size is 64 bytes.
uint8_t blockNo = 3; // Security block is number 3 for each sector. uint8_t blockNo = 3; // Security block is number 3 for each sector.
uint8_t sectorsCnt = (mifare_size / sectorSize); uint8_t sectorsCnt = (mifare_size / sectorSize);
uint8_t keyType = 2; // Keytype buffer
uint64_t key64; // Defines current key uint64_t key64; // Defines current key
uint8_t *keyBlock; // Where the keys will be held in memory. uint8_t *keyBlock; // Where the keys will be held in memory.
uint8_t stKeyBlock = 20; // Set the quantity of keys in the block.
bool keyFound = false; bool keyFound = false;
/* // Set of keys to be used.
Set of keys to be used.
*/
uint64_t mfKeys[] = { uint64_t mfKeys[] = {
0xffffffffffff, // Default key 0xffffffffffff, // Default key
0x000000000000, // Blank key 0x000000000000, // Blank key
@ -269,22 +333,73 @@ void RunMod() {
0xa0478cc39091, 0xa0478cc39091,
0x533cb6c723f6, 0x533cb6c723f6,
0x8fd0a4f256e9, 0x8fd0a4f256e9,
0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT...
0x414c41524f4e, // ALARON NORALSY
0x424c41524f4e, // BLARON NORALSY
0x4a6352684677, // COMELIT A General Key / 08 [2] 004
0x536653644c65, // COMELIT B General Key / 08 [2] 004
0x8829da9daf76, // URMET CAPTIV IF A => ALL A/B / BTICINO
0x314B49474956, // "1KIGIV" VIGIK'S SERVICE BADGE A KEY
0x021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
0x010203040506, // VIGIK's B Derivative
0xa22ae129c013, // INFINEON B 00
0x49fae4e3849f, // INFINEON B 01
0x38fcf33072e0, // INFINEON B 02
0x8ad5517b4b18, // INFINEON B 03
0x509359f131b1, // INFINEON B 04
0x6c78928e1317, // INFINEON B 05
0xaa0720018738, // INFINEON B 06
0xa6cac2886412, // INFINEON B 07
0x62d0c424ed8e, // INFINEON B 08
0xe64a986a5d94, // INFINEON B 09
0x8fa1d601d0a2, // INFINEON B 0A
0x89347350bd36, // INFINEON B 0B
0x66d2b7dc39ef, // INFINEON B 0C
0x6bc1e1ae547d, // INFINEON B 0D
0x22729a9bd40f, // INFINEON B 0E
0xd2ece8b9395e, // lib / Nat Bieb
0x1494E81663D7, // # NSCP default key
0x569369c5a0e5, // # kiev
0x632193be1c3c, // # kiev
0x644672bd4afe, // # kiev
0x8fe644038790, // # kiev
0x9de89e070277, // # kiev
0xb5ff67cba951, // # kiev / ov-chipkaart
0xeff603e1efe9, // # kiev
0xf14ee7cae863, // # kiev
0xfc00018778f7, // # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA
0x0297927c0f77, // # Västtrafiken KeyA
0x54726176656c, // # Västtrafiken KeyA
0x00000ffe2488, // # Västtrafiken KeyB
0x776974687573, // # Västtrafiken KeyB
0xee0042f88840, // # Västtrafiken KeyB
0x26940b21ff5d, // # RKF SLKeyA
0xa64598a77478, // # RKF SLKeyA
0x5c598c9c58b5, // # RKF SLKeyB
0xe4d2770a89be, // # RKF SLKeyB
0x722bfcc5375f, // # RKF RejskortDanmark KeyA
0xf1d83f964314, // # RKF RejskortDanmark KeyB
0x505249564141, // # RKF JOJOPRIVAKeyA
0x505249564142, // # RKF JOJOPRIVAKeyB
0x47524f555041, // # RKF JOJOGROUPKeyA
0x47524f555042, // # RKF JOJOGROUPKeyB
0x434f4d4d4f41, // # RKF JOJOGROUPKeyA
0x434f4d4d4f42, // # RKF JOJOGROUPKeyB
0x4b0b20107ccb, // # TNP3xxx
}; };
/* /*
This part allocates the byte representation of the This part allocates the byte representation of the
keys in keyBlock's memory space . keys in keyBlock's memory space .
*/ */
keyBlock = BigBuf_malloc(stKeyBlock * 6); keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
int mfKeysCnt = ARRAYLEN(mfKeys); int mfKeysCnt = ARRAYLEN(mfKeys);
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
} }
/* // Pretty print of the keys to be checked.
Pretty print of the keys to be checked.
*/
if (printKeys) { if (printKeys) {
Dbprintf("[+] Printing mf keys"); Dbprintf("[+] Printing mf keys");
for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++) for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++)
@ -301,30 +416,31 @@ void RunMod() {
*/ */
bool validKey[2][40]; bool validKey[2][40];
uint8_t foundKey[2][40][6]; uint8_t foundKey[2][40][6];
for (uint16_t t = 0; t < 2; t++) { for (uint8_t i = 0; i < 2; i++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
validKey[t][sectorNo] = false; validKey[i][sectorNo] = false;
for (uint16_t i = 0; i < 6; i++) { foundKey[i][sectorNo][0] = 0xFF;
foundKey[t][sectorNo][i] = 0xff; foundKey[i][sectorNo][1] = 0xFF;
} foundKey[i][sectorNo][2] = 0xFF;
foundKey[i][sectorNo][3] = 0xFF;
foundKey[i][sectorNo][4] = 0xFF;
foundKey[i][sectorNo][5] = 0xFF;
} }
} }
/* // Iterates through each sector checking if there is a correct key.
Iterates through each sector checking if there is a correct key.
*/
bool err = 0; bool err = 0;
bool allKeysFound = true; bool allKeysFound = true;
uint32_t size = mfKeysCnt; uint32_t size = mfKeysCnt;
for (int type = !keyType; type < 2 && !err; keyType == 2 ? (type++) : (type = 2)) { for (int type = 0; type < 2 && !err; type++) {
int block = blockNo; int block = blockNo;
for (int sec = 0; sec < sectorsCnt && !err; ++sec) { for (int sec = 0; sec < sectorsCnt && !err; ++sec) {
Dbprintf("\tCurrent sector:%3d, block:%3d, key type: %c, key count: %i ", sec, block, type ? 'B' : 'A', mfKeysCnt); Dbprintf("\tCurrent sector:%3d, block:%3d, key type: %c, key count: %i ", sec, block, type ? 'B' : 'A', mfKeysCnt);
int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64); int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64);
if (key == -1) { if (key == -1) {
LED(LED_RED, 50); LED(LED_RED, 50);
Dbprintf("\t Key not found for this sector!"); Dbprintf("\t [✕] Key not found for this sector!");
allKeysFound = false; allKeysFound = false;
// break; // break;
} else if (key == -2) { } else if (key == -2) {
@ -334,7 +450,7 @@ void RunMod() {
num_to_bytes(key64, 6, foundKey[type][sec]); num_to_bytes(key64, 6, foundKey[type][sec]);
validKey[type][sec] = true; validKey[type][sec] = true;
keyFound = true; keyFound = true;
Dbprintf("\t Found valid key: [%02x%02x%02x%02x%02x%02x]\n", Dbprintf("\t [✓] Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
(keyBlock + 6 * key)[0], (keyBlock + 6 * key)[1], (keyBlock + 6 * key)[2], (keyBlock + 6 * key)[0], (keyBlock + 6 * key)[1], (keyBlock + 6 * key)[2],
(keyBlock + 6 * key)[3], (keyBlock + 6 * key)[4], (keyBlock + 6 * key)[5] (keyBlock + 6 * key)[3], (keyBlock + 6 * key)[4], (keyBlock + 6 * key)[5]
); );
@ -371,8 +487,9 @@ void RunMod() {
emlClearMem(); emlClearMem();
uint8_t mblock[16]; uint8_t mblock[16];
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
if (validKey[0][sectorNo] || validKey[1][sectorNo]) { if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4) emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4)
for (uint16_t t = 0; t < 2; t++) { for (uint16_t t = 0; t < 2; t++) {
if (validKey[t][sectorNo]) { if (validKey[t][sectorNo]) {
@ -382,47 +499,40 @@ void RunMod() {
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
} }
} }
Dbprintf("\t✓ Found keys have been transferred to the emulator memory.");
Dbprintf("\t [✓] Found keys have been transferred to the emulator memory.");
if (ecfill) { if (ecfill) {
int filled; int filled;
Dbprintf("\tFilling in with key A."); Dbprintf("\tFilling in with key A.");
filled = MifareECardLoad(sectorsCnt, 0);
if (filled != PM3_SUCCESS) {
Dbprintf("\t✕ Failed filling with A.");
}
Dbprintf("\tFilling in with key B."); filled = saMifareECardLoad(sectorsCnt, 0);
filled = MifareECardLoad(sectorsCnt, 1);
if (filled != PM3_SUCCESS) { if (filled != PM3_SUCCESS) {
Dbprintf("\t✕ Failed filling with B.");
Dbprintf("\t [✕] Failed filling with A.");
Dbprintf("\tFilling in with key B.");
filled = saMifareECardLoad(sectorsCnt, 1);
if (filled != PM3_SUCCESS) {
Dbprintf("\t [✕] Failed filling with B.");
}
} }
if ((filled == PM3_SUCCESS) && simulation) { if ((filled == PM3_SUCCESS) && simulation) {
Dbprintf("\t✓ Emulator memory filled, simulation started."); Dbprintf("\t [✓] Emulator memory filled, simulation started.");
// This will tell the fpga to emulate using previous keys and current target tag content. // This will tell the fpga to emulate using previous keys and current target tag content.
Dbprintf("\t Press button to abort simulation at anytime."); Dbprintf("\t Press button to abort simulation at anytime.");
LED_B_ON(); // green LED_B_ON(); // green
// assuming arg0==0, use hardcoded uid 0xdeadbeaf
uint16_t simflags;
switch (p_card.uidlen) {
case 10:
simflags = FLAG_10B_UID_IN_DATA;
break;
case 7:
simflags = FLAG_7B_UID_IN_DATA;
break;
default:
simflags = FLAG_4B_UID_IN_DATA;
break;
}
Mifare1ksim(simflags | FLAG_MF_1K, 0, uid, 0, 0);
LED_B_OFF();
/* uint16_t simflags = FLAG_UID_IN_EMUL | FLAG_MF_1K;
Needs further testing.
*/ SpinOff(1000);
Mifare1ksim(simflags, 0, uid, 0, 0);
LED_B_OFF();
Dbprintf("\t [✓] Simulation ended");
// Needs further testing.
if (fillFromEmulator) { if (fillFromEmulator) {
uint8_t retry = 5; uint8_t retry = 5;
Dbprintf("\t Trying to dump into blank card."); Dbprintf("\t Trying to dump into blank card.");
@ -457,8 +567,10 @@ void RunMod() {
} }
} }
} else if (filled != PM3_SUCCESS) { }
Dbprintf("\t✕ Emulator memory could not be filled due to errors.");
if (filled != PM3_SUCCESS) {
Dbprintf("\t [✕] Emulator memory could not be filled due to errors.");
LED_C_ON(); LED_C_ON();
} }
} }

View file

@ -52,9 +52,9 @@ void ModInfo(void) {
* technologies. Be brave enough to share your knowledge & inspire others. Salvador Mendoza. * technologies. Be brave enough to share your knowledge & inspire others. Salvador Mendoza.
*/ */
uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING static uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING
uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING
uint8_t plen = 7; uint8_t plen = 7;
//PDOL Format: 80 A8 00 00 + (PDOL Length+2) + 83 + PDOL Length + PDOL + 00 //PDOL Format: 80 A8 00 00 + (PDOL Length+2) + 83 + PDOL Length + PDOL + 00
for (uint8_t i = 1; i <= apdu[0]; i++) { //Magic stuff, the generation order is important for (uint8_t i = 1; i <= apdu[0]; i++) { //Magic stuff, the generation order is important
@ -117,9 +117,9 @@ uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING
return plen; return plen;
} }
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
Dbprintf(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started<<"); DbpString(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started " _YELLOW_("<<"));
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
//For reading process //For reading process
@ -183,8 +183,8 @@ void RunMod() {
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 }; uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 }; uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 };
uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE]; uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0};
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE]; uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0};
// to know the transaction status // to know the transaction status
uint8_t prevCmd = 0; uint8_t prevCmd = 0;
@ -206,7 +206,7 @@ void RunMod() {
//Checking if the user wants to go directly to emulation mode using a hardcoded track 2 //Checking if the user wants to go directly to emulation mode using a hardcoded track 2
if (chktoken == true && token[0] != 0x00) { if (chktoken == true && token[0] != 0x00) {
state = STATE_EMU; state = STATE_EMU;
Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]")); DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]"));
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
} else { } else {
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
@ -222,18 +222,18 @@ void RunMod() {
// Was our button held down or pressed? // Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000); int button_pressed = BUTTON_HELD(1000);
if (button_pressed == 1) //Holding down the button if (button_pressed == BUTTON_HOLD) //Holding down the button
break; break;
else if (button_pressed == -1) { //Pressing one time change between reading & emulation else if (button_pressed == BUTTON_SINGLE_CLICK) { //Pressing one time change between reading & emulation
if (state == STATE_READ) { if (state == STATE_READ) {
if (chktoken == true && token[0] != 0x00) { //Only change to emulation if it saved a track 2 in memory if (chktoken == true && token[0] != 0x00) { //Only change to emulation if it saved a track 2 in memory
state = STATE_EMU; state = STATE_EMU;
Dbprintf(_YELLOW_("[") "In emulation mode " _YELLOW_("]")); DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
} else } else
Dbprintf(_YELLOW_("!!") "Nothing in memory to emulate"); DbpString(_YELLOW_("!!") "Nothing in memory to emulate");
} else { } else {
state = STATE_READ; state = STATE_READ;
Dbprintf(_YELLOW_("[") "In reading mode " _YELLOW_("]")); DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]"));
} }
} }
@ -248,7 +248,7 @@ void RunMod() {
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) { if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
Dbprintf(_YELLOW_("+") "Found ISO 14443 Type A!"); DbpString(_YELLOW_("+") "Found ISO 14443 Type A!");
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {
chktoken = false; chktoken = false;
@ -257,11 +257,11 @@ void RunMod() {
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL); uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL);
if (apdulen > 0) { if (apdulen > 0) {
Dbprintf(_YELLOW_("[") "Proxmark command " _YELLOW_("]")); DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]"));
Dbhexdump(apdusLen[i], apdus[i], false); Dbhexdump(apdusLen[i], apdus[i], false);
Dbprintf(_GREEN_("[") "Card answer " _GREEN_("]")); DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]"));
Dbhexdump(apdulen - 2, apdubuffer, false); Dbhexdump(apdulen - 2, apdubuffer, false);
Dbprintf("----"); DbpString("----");
for (uint8_t u = 0; u < apdulen; u++) { for (uint8_t u = 0; u < apdulen; u++) {
if (i == 1) { if (i == 1) {
@ -284,24 +284,24 @@ void RunMod() {
} }
if (i == 1) { if (i == 1) {
Dbprintf(_GREEN_("[") "Challenge generated " _GREEN_("]")); DbpString(_GREEN_("[ ") "Challenge generated" _GREEN_(" ]"));
Dbhexdump(plen, existpdol ? ppdol : processing, false); Dbhexdump(plen, existpdol ? ppdol : processing, false);
} }
} else { } else {
Dbprintf(_YELLOW_("!!") "Error reading the card"); DbpString(_YELLOW_("!!") "Error reading the card");
} }
LED_B_OFF(); LED_B_OFF();
} }
if (chktoken) { if (chktoken) {
Dbprintf(_RED_("[") "Track 2 " _RED_("]")); DbpString(_RED_("[ ") "Track 2" _RED_(" ]"));
Dbhexdump(19, (uint8_t *)token, false); Dbhexdump(19, (uint8_t *)token, false);
Dbprintf(_YELLOW_("!!") "Card number"); DbpString(_YELLOW_("!!") "Card number");
Dbhexdump(8, (uint8_t *)token, false); Dbhexdump(8, (uint8_t *)token, false);
DbpString("---"); DbpString("---");
LED_C_ON(); LED_C_ON();
state = STATE_EMU; state = STATE_EMU;
Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]")); DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]"));
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
} }
} }
@ -336,7 +336,7 @@ void RunMod() {
LED_B_OFF(); LED_B_OFF();
// Clean receive command buffer // Clean receive command buffer
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
Dbprintf(_YELLOW_("!!") "Emulator stopped"); DbpString(_YELLOW_("!!") "Emulator stopped");
retval = PM3_EOPABORTED; retval = PM3_EOPABORTED;
break; break;
} }
@ -367,7 +367,7 @@ void RunMod() {
DbpString(_YELLOW_("+") "Request for RATS"); DbpString(_YELLOW_("+") "Request for RATS");
p_response = &responses[RATS]; p_response = &responses[RATS];
} else { } else {
Dbprintf(_YELLOW_("[") "Card reader command " _YELLOW_("]")); DbpString(_YELLOW_("[ ") "Card reader command" _YELLOW_(" ]"));
Dbhexdump(len, receivedCmd, false); Dbhexdump(len, receivedCmd, false);
if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { //Emulate a Visa MSD(Magnetic stripe data) card if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { //Emulate a Visa MSD(Magnetic stripe data) card
@ -408,7 +408,7 @@ void RunMod() {
} }
} }
} else { } else {
Dbprintf(_YELLOW_("!!") "Received unknown command!"); DbpString(_YELLOW_("!!") "Received unknown command!");
if (prevCmd < 4) { if (prevCmd < 4) {
memcpy(dynamic_response_info.response, receivedCmd, len); memcpy(dynamic_response_info.response, receivedCmd, len);
dynamic_response_info.response_n = len; dynamic_response_info.response_n = len;
@ -418,9 +418,9 @@ void RunMod() {
} }
} }
if (dynamic_response_info.response_n > 0) { if (dynamic_response_info.response_n > 0) {
Dbprintf(_GREEN_("[") "Proxmark3 answer " _GREEN_("]")); DbpString(_GREEN_("[ ") "Proxmark3 answer" _GREEN_(" ]"));
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false); Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
Dbprintf("----"); DbpString("----");
// Add CRC bytes, always used in ISO 14443A-4 compliant cards // Add CRC bytes, always used in ISO 14443A-4 compliant cards
AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n); AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n);

View file

@ -37,7 +37,7 @@ void ModInfo(void) {
DbpString(" HF Mifare sniff/simulation - (Craig Young)"); DbpString(" HF Mifare sniff/simulation - (Craig Young)");
} }
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<"); Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -151,10 +151,10 @@ void RunMod() {
SpinDelay(500); SpinDelay(500);
// Begin clone function here: // Begin clone function here:
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards: /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
SendCommandOLD(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16); SendCommandMIX(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16);
Block read is similar: Block read is similar:
SendCommandOLD(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...}; SendCommandMIX(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...};
We need to imitate that call with blockNo 0 to set a uid. We need to imitate that call with blockNo 0 to set a uid.
The get and set commands are handled in this file: The get and set commands are handled in this file:
@ -222,8 +222,8 @@ void RunMod() {
// exit from Standalone Mode, send a usbcommand. // exit from Standalone Mode, send a usbcommand.
if (data_available()) return; if (data_available()) return;
int button_action = BUTTON_HELD(1000); int button_pressed = BUTTON_HELD(1000);
if (button_action == 0) { // No button action, proceed with sim if (button_pressed == BUTTON_NO_CLICK) { // No button action, proceed with sim
uint8_t flags = FLAG_4B_UID_IN_DATA; uint8_t flags = FLAG_4B_UID_IN_DATA;
uint8_t data[PM3_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break uint8_t data[PM3_CMD_DATA_SIZE] = {0}; // in case there is a read command received we shouldn't break
@ -259,12 +259,12 @@ void RunMod() {
SimulateIso14443aTag(1, flags, data); SimulateIso14443aTag(1, flags, data);
} }
} else if (button_action == BUTTON_SINGLE_CLICK) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {
selected = (selected + 1) % OPTS; selected = (selected + 1) % OPTS;
Dbprintf("Done playing. Switching to record mode on bank %d", selected); Dbprintf("Done playing. Switching to record mode on bank %d", selected);
iGotoRecord = 1; iGotoRecord = 1;
break; break;
} else if (button_action == BUTTON_HOLD) { } else if (button_pressed == BUTTON_HOLD) {
Dbprintf("Playtime over. Begin cloning..."); Dbprintf("Playtime over. Begin cloning...");
iGotoClone = 1; iGotoClone = 1;
break; break;

View file

@ -18,23 +18,22 @@
#include "ticks.h" #include "ticks.h"
#include "string.h" #include "string.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "commonutil.h"
#define MAX_IND 16 // 4 LEDs - 2^4 combinations #define MAX_IND 16 // 4 LEDs - 2^4 combinations
#define CLOCK 64 //for 125kHz #define CLOCK 64 //for 125kHz
// low & high - array for storage IDs. Its length must be equal. // low & high - array for storage IDs. Its length must be equal.
// Predefined IDs must be stored in low[]. // Predefined IDs must be stored in low[].
// In high[] must be nulls static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF}; static uint8_t *bba, slots_count;
uint32_t high[] = {0, 0, 0, 0}; static int buflen;
uint8_t *bba, slots_count;
int buflen;
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF EM4100 simulator standalone mode"); DbpString(" LF EM4100 simulator standalone mode");
} }
uint64_t ReversQuads(uint64_t bits) { static uint64_t ReversQuads(uint64_t bits) {
uint64_t result = 0; uint64_t result = 0;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
@ -42,14 +41,14 @@ uint64_t ReversQuads(uint64_t bits) {
return result >> 24; return result >> 24;
} }
void FillBuff(uint8_t bit) { static void FillBuff(uint8_t bit) {
memset(bba + buflen, bit, CLOCK / 2); memset(bba + buflen, bit, CLOCK / 2);
buflen += (CLOCK / 2); buflen += (CLOCK / 2);
memset(bba + buflen, bit ^ 1, CLOCK / 2); memset(bba + buflen, bit ^ 1, CLOCK / 2);
buflen += (CLOCK / 2); buflen += (CLOCK / 2);
} }
void ConstructEM410xEmulBuf(uint64_t id) { static void ConstructEM410xEmulBuf(uint64_t id) {
int i, j, binary[4], parity[4]; int i, j, binary[4], parity[4];
buflen = 0; buflen = 0;
@ -70,7 +69,7 @@ void ConstructEM410xEmulBuf(uint64_t id) {
FillBuff(0); FillBuff(0);
} }
void LED_Slot(int i) { static void LED_Slot(int i) {
LEDsoff(); LEDsoff();
if (slots_count > 4) { if (slots_count > 4) {
LED(i % MAX_IND, 0); //binary indication for slots_count > 4 LED(i % MAX_IND, 0); //binary indication for slots_count > 4
@ -79,7 +78,7 @@ void LED_Slot(int i) {
} }
} }
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
Dbprintf("[=] >> LF EM4100 simulator started <<"); Dbprintf("[=] >> LF EM4100 simulator started <<");

View file

@ -0,0 +1,340 @@
//-----------------------------------------------------------------------------
// Monster1024
// based on code by: Artyom Gnatyuk, 2020
//
// 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.
//-----------------------------------------------------------------------------
// LF rswb - This mode can simulate ID from selected slot, read ID to
// selected slot, write from selected slot to T5555/T55x7 tag and store
// readed ID to flash (only RDV4).
// Predefined its is not recomended because you can incedently rewrite your MANDATORY tag data.
//
// To recall stored ID from flash execute:
// mem spifss dump o emdump p
// or:
// mem spifss dump o emdump f emdump
// then from shell:
// hexdump emdump -e '5/1 "%02X" /0 "\n"'
//
// Mode list (switched by single click):
//
// 0 - READ Read source card ID and store it to current slot
// Will switch to SIM mode automatically.
//
// 1 - SIM Simulate readed ID
//
// 2 - WRITE(CLONE) Write readed ID to T55x7 card
// !!! Warning, card id WILL BE OVERRWRITED
//
// 3 - BRUTE Brute upper or down from readed card)
// You can PRESS SINGLE to exit brute mode OR
// PRESS DOUBLE to save bruted ID to current slot (will automatically switch to SIM mode) AND
// Also You can HOLD button to change brute speeds.
//
// Slots are switched by HOLD (LONG PRESS)
//-----------------------------------------------------------------------------
#include "standalone.h"
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "lfops.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#include "string.h"
#include "BigBuf.h"
#include "spiffs.h"
#include "inttypes.h"
#include "parity.h"
#ifdef WITH_FLASH
#include "flashmem.h"
#endif
#define LF_CLOCK 64 //for 125kHz
#define LF_RWSB_T55XX_TYPE 1 //Tag type: 0 - T5555, 1-T55x7
#define LF_RWSB_UNKNOWN_RESULT 0
#define LF_RWSB_BRUTE_STOPED 1
#define LF_RWSB_BRUTE_SAVED 2
//modes
#define LF_RWSB_MODE_READ 0
#define LF_RWSB_MODE_SIM 1
#define LF_RWSB_MODE_WRITE 2
#define LF_RWSB_MODE_BRUTE 3
// Predefined bruteforce speed
// avg: 1s, 1.2s, 1.5s, 2s
static int bruteforceSpeedCurrent = 1;
static int bruteforceSpeed[] = {10, 12, 14, 16};
// low & high - array for storage IDs. Its length must be equal.
// Predefined IDs must be stored in low[].
// In high[] must be nulls
static uint64_t low[] = {0, 0, 0, 0};
static uint32_t high[] = {0, 0, 0, 0};
static uint8_t *bba;
static int buflen;
void ModInfo(void) {
DbpString(" LF EM4100 read/sim/write/brute mode");
}
static uint64_t ReversQuads(uint64_t bits) {
uint64_t result = 0;
for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
}
return result >> 24;
}
static void FillBuff(uint8_t bit) {
memset(bba + buflen, bit, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
}
static void ConstructEM410xEmulBuf(uint64_t id) {
bba = BigBuf_get_addr();
int i, j, binary[4], parity[4];
buflen = 0;
for (i = 0; i < 9; i++)
FillBuff(1);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2;
for (j = 0; j < 4; j++)
FillBuff(binary[j]);
FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++)
parity[j] ^= binary[j];
}
for (j = 0; j < 4; j++)
FillBuff(parity[j]);
FillBuff(0);
}
static void LED_Update(int mode, int slot) {
LEDsoff();
switch (mode) {
case 0:
break;
case 1:
LED_A_ON();
break;
case 2:
LED_B_ON();
break;
case 3:
LED_A_ON();
LED_B_ON();
break;
}
switch (slot) {
case 0:
break;
case 1:
LED_C_ON();
break;
case 2:
LED_D_ON();
break;
case 3:
LED_C_ON();
LED_D_ON();
break;
}
}
static void FlashLEDs(uint32_t speed, uint8_t times) {
for (int i = 0; i < times * 2; i++) {
LED_A_INV();
LED_B_INV();
LED_C_INV();
LED_D_INV();
SpinDelay(speed);
}
}
#ifdef WITH_FLASH
static void SaveIDtoFlash(int addr, uint64_t id) {
uint8_t bt[5];
char *filename = "emdump";
rdv40_spiffs_mount();
for (int i = 0; i < 5; i++) {
bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff);
}
if (exists_in_spiffs(filename) == false) {
rdv40_spiffs_write(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL);
} else {
rdv40_spiffs_append(filename, &bt[0], 5, RDV40_SPIFFS_SAFETY_NORMAL);
}
}
#endif
static uint64_t PackEmID(uint64_t original, int newCardNum) {
uint64_t buf = original;
//clear pairity bits
buf &= ~(1 << 0);
buf &= ~(1 << 25);
//clear card number
for (int i = 1; i <= 16; i++) {
buf &= ~(1 << i);
}
buf |= (newCardNum & 0xFFFF) << 1;
buf |= oddparity32((buf >> 1) & 0xFFF) & 1;
buf |= (evenparity32((buf >> 13) & 0xFFF) & 1) << 25;
uint32_t cardnumNew = (buf >> 1) & 0xFFFF;
uint32_t fcNew = (buf >> 17) & 0xFF;
Dbprintf("[=] RECONSTRUCT TAG ID: %"PRIx64" - FC: %u - Card: %u\n", buf, fcNew, cardnumNew);
return buf;
}
static void PrintFcAndCardNum(uint64_t lowData) {
// Calculate Facility Code and Card Number from high and low
uint32_t fc = (lowData >> 17) & 0xFF;
uint32_t cardnum = (lowData >> 1) & 0xFFFF;
Dbprintf("[=] READ TAG ID: %"PRIx64" - FC: %u - Card: %u", lowData, fc, cardnum);
}
static int ButeEMTag(uint64_t originalCard, int slot) {
int speed_count = 4;
int direction = 1;
uint32_t cardnum = (originalCard >> 1) & 0xFFFF;
if (cardnum > 32767) {
direction = -1;
}
while (cardnum > 1 && cardnum < 65535) {
WDT_HIT();
if (data_available()) break;
cardnum = cardnum + direction;
uint64_t currentCard = PackEmID(originalCard, cardnum);
Dbprintf("[=] >> Simulating card id %"PRIx64" <<", currentCard);
ConstructEM410xEmulBuf(ReversQuads(currentCard));
SimulateTagLowFrequencyEx(buflen, 0, 1, bruteforceSpeed[bruteforceSpeedCurrent] * 10000);
int button_pressed = BUTTON_CLICKED(1000);
if (button_pressed == BUTTON_SINGLE_CLICK) {
Dbprintf("[=] >> Exit bruteforce mode without saving. <<");
return LF_RWSB_BRUTE_STOPED;
} else if (button_pressed == BUTTON_DOUBLE_CLICK) {
FlashLEDs(100, 10);
Dbprintf("[=] >> Saving bruteforced card to current slot <<");
low[slot] = currentCard;
#ifdef WITH_FLASH
SaveIDtoFlash(slot, low[slot]);
#endif
return LF_RWSB_BRUTE_SAVED;
} else if (button_pressed == BUTTON_HOLD) {
FlashLEDs(100, 1);
WAIT_BUTTON_RELEASED();
bruteforceSpeedCurrent = (bruteforceSpeedCurrent + 1) % speed_count;
FlashLEDs(100, bruteforceSpeedCurrent + 1);
Dbprintf("[=] >> Setting speed to %d (%d) <<", bruteforceSpeedCurrent, bruteforceSpeed[bruteforceSpeedCurrent]);
}
}
return LF_RWSB_BRUTE_STOPED;
}
static int ExecuteMode(int mode, int slot) {
LED_Update(mode, slot);
WDT_HIT();
switch (mode) {
//default first mode is simulate
case LF_RWSB_MODE_READ:
Dbprintf("[=] >> Read mode started <<");
CmdEM410xdemod(1, &high[slot], &low[slot], 0);
LED_Update(mode, slot);
Dbprintf("[=] >> Tag found. Saving. <<");
FlashLEDs(100, 5);
PrintFcAndCardNum(low[slot]);
#ifdef WITH_FLASH
SaveIDtoFlash(slot, low[slot]);
#endif
return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_SIM:
Dbprintf("[=] >> Sim mode started <<");
ConstructEM410xEmulBuf(ReversQuads(low[slot]));
SimulateTagLowFrequency(buflen, 0, 1);
return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_WRITE:
Dbprintf("[!!] >> Write mode started <<");
WriteEM410x(LF_RWSB_T55XX_TYPE, (uint32_t)(low[slot] >> 32), (uint32_t)(low[slot] & 0xffffffff));
return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_BRUTE:
Dbprintf("[=] >> Bruteforce mode started <<");
return ButeEMTag(low[slot], slot);
}
return LF_RWSB_UNKNOWN_RESULT;
}
static int SwitchMode(int mode, int slot) {
WDT_HIT();
ExecuteMode(mode, slot);
if (mode == LF_RWSB_MODE_READ) {
//After read mode we need to switch to sim mode automatically
Dbprintf("[=] >> automatically switch to sim mode after read <<");
return SwitchMode(LF_RWSB_MODE_SIM, slot);
} else if (mode == LF_RWSB_MODE_BRUTE) {
//We have already have a click inside brute mode. Lets switch next mode
Dbprintf("[=] >> automatically switch to read mode after brute <<");
return SwitchMode(LF_RWSB_MODE_READ, slot);
}
return mode;
}
void RunMod() {
StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
Dbprintf("[=] >> LF EM4100 read/write/clone/brute started <<");
int slots_count = 4;
int mode_count = 4;
int mode = 0;
int slot = 0;
mode = SwitchMode(mode, slot);
bba = BigBuf_get_addr();
for (;;) {
WDT_HIT();
if (data_available()) break;
int button_pressed = BUTTON_CLICKED(1000);
LED_Update(mode, slot);
//press button - switch mode
//hold button - switch slot
if (button_pressed == BUTTON_SINGLE_CLICK) {
Dbprintf("[=] >> Single click <<");
mode = (mode + 1) % mode_count;
SpinDown(100);
mode = SwitchMode(mode, slot);
} else if (button_pressed == BUTTON_HOLD) {
Dbprintf("[=] >> Button hold <<");
slot = (slot + 1) % slots_count;
SpinUp(100);
SpinDelay(300);
//automatically switch to SIM mode on slot selection
mode = LF_RWSB_MODE_SIM;
mode = SwitchMode(mode, slot);
}
}
}

View file

@ -27,6 +27,7 @@
#include "string.h" #include "string.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "spiffs.h" #include "spiffs.h"
#include "commonutil.h"
#ifdef WITH_FLASH #ifdef WITH_FLASH
#include "flashmem.h" #include "flashmem.h"
@ -38,16 +39,16 @@
// low & high - array for storage IDs. Its length must be equal. // low & high - array for storage IDs. Its length must be equal.
// Predefined IDs must be stored in low[]. // Predefined IDs must be stored in low[].
// In high[] must be nulls // In high[] must be nulls
uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t *bba, slots_count; static uint8_t *bba, slots_count;
int buflen; static int buflen;
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF EM4100 read/write/clone mode"); DbpString(" LF EM4100 read/write/clone mode");
} }
uint64_t ReversQuads(uint64_t bits) { static uint64_t ReversQuads(uint64_t bits) {
uint64_t result = 0; uint64_t result = 0;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i); result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
@ -55,14 +56,14 @@ uint64_t ReversQuads(uint64_t bits) {
return result >> 24; return result >> 24;
} }
void FillBuff(uint8_t bit) { static void FillBuff(uint8_t bit) {
memset(bba + buflen, bit, CLOCK / 2); memset(bba + buflen, bit, CLOCK / 2);
buflen += (CLOCK / 2); buflen += (CLOCK / 2);
memset(bba + buflen, bit ^ 1, CLOCK / 2); memset(bba + buflen, bit ^ 1, CLOCK / 2);
buflen += (CLOCK / 2); buflen += (CLOCK / 2);
} }
void ConstructEM410xEmulBuf(uint64_t id) { static void ConstructEM410xEmulBuf(uint64_t id) {
int i, j, binary[4], parity[4]; int i, j, binary[4], parity[4];
buflen = 0; buflen = 0;
@ -83,7 +84,7 @@ void ConstructEM410xEmulBuf(uint64_t id) {
FillBuff(0); FillBuff(0);
} }
void LED_Slot(int i) { static void LED_Slot(int i) {
LEDsoff(); LEDsoff();
if (slots_count > 4) { if (slots_count > 4) {
LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4 LED(i % MAX_IND, 0); //binary indication, usefully for slots_count > 4
@ -92,7 +93,7 @@ void LED_Slot(int i) {
} }
} }
void FlashLEDs(uint32_t speed, uint8_t times) { static void FlashLEDs(uint32_t speed, uint8_t times) {
for (int i = 0; i < times * 2; i++) { for (int i = 0; i < times * 2; i++) {
LED_A_INV(); LED_A_INV();
LED_B_INV(); LED_B_INV();
@ -103,9 +104,9 @@ void FlashLEDs(uint32_t speed, uint8_t times) {
} }
#ifdef WITH_FLASH #ifdef WITH_FLASH
void SaveIDtoFlash(int addr, uint64_t id) { static void SaveIDtoFlash(int addr, uint64_t id) {
uint8_t bt[5]; uint8_t bt[5];
char *filename = "emdump"; const char *filename = "emdump";
rdv40_spiffs_mount(); rdv40_spiffs_mount();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff); bt[4 - i] = (uint8_t)(id >> 8 * i & 0xff);
@ -118,7 +119,7 @@ void SaveIDtoFlash(int addr, uint64_t id) {
} }
#endif #endif
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
Dbprintf("[=] >> LF EM4100 read/write/clone started <<"); Dbprintf("[=] >> LF EM4100 read/write/clone started <<");
@ -140,12 +141,12 @@ void RunMod() {
switch (state) { switch (state) {
case 0: case 0:
// Select mode // Select mode
if (button_pressed == 1) { if (button_pressed == BUTTON_HOLD) {
// Long press - switch to simulate mode // Long press - switch to simulate mode
SpinUp(100); SpinUp(100);
LED_Slot(selected); LED_Slot(selected);
state = 2; state = 2;
} else if (button_pressed < 0) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {
// Click - switch to next slot // Click - switch to next slot
selected = (selected + 1) % slots_count; selected = (selected + 1) % slots_count;
LED_Slot(selected); LED_Slot(selected);
@ -153,12 +154,12 @@ void RunMod() {
break; break;
case 1: case 1:
// Read mode. // Read mode.
if (button_pressed > 0) { if (button_pressed == BUTTON_HOLD) {
// Long press - switch to read mode // Long press - switch to read mode
SpinUp(100); SpinUp(100);
LED_Slot(selected); LED_Slot(selected);
state = 3; state = 3;
} else if (button_pressed < 0) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {
// Click - exit to select mode // Click - exit to select mode
CmdEM410xdemod(1, &high[selected], &low[selected], 0); CmdEM410xdemod(1, &high[selected], &low[selected], 0);
FlashLEDs(100, 5); FlashLEDs(100, 5);
@ -170,12 +171,12 @@ void RunMod() {
break; break;
case 2: case 2:
// Simulate mode // Simulate mode
if (button_pressed > 0) { if (button_pressed == BUTTON_HOLD) {
// Long press - switch to read mode // Long press - switch to read mode
SpinDown(100); SpinDown(100);
LED_Slot(selected); LED_Slot(selected);
state = 1; state = 1;
} else if (button_pressed < 0) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {
// Click - start simulating. Click again to exit from simulate mode // Click - start simulating. Click again to exit from simulate mode
LED_Slot(selected); LED_Slot(selected);
ConstructEM410xEmulBuf(ReversQuads(low[selected])); ConstructEM410xEmulBuf(ReversQuads(low[selected]));
@ -187,12 +188,12 @@ void RunMod() {
break; break;
case 3: case 3:
// Write tag mode // Write tag mode
if (button_pressed > 0) { if (button_pressed == BUTTON_HOLD) {
// Long press - switch to select mode // Long press - switch to select mode
SpinDown(100); SpinDown(100);
LED_Slot(selected); LED_Slot(selected);
state = 0; state = 0;
} else if (button_pressed < 0) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {
// Click - write ID to tag // Click - write ID to tag
WriteEM410x(0, (uint32_t)(low[selected] >> 32), (uint32_t)(low[selected] & 0xffffffff)); WriteEM410x(0, (uint32_t)(low[selected] >> 32), (uint32_t)(low[selected] & 0xffffffff));
LED_Slot(selected); LED_Slot(selected);

View file

@ -42,7 +42,7 @@ void ModInfo(void) {
} }
// samy's sniff and repeat routine for LF // samy's sniff and repeat routine for LF
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<"); Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -85,7 +85,7 @@ void RunMod() {
// so next button push begins playing what we recorded // so next button push begins playing what we recorded
playing = 0; playing = 0;
cardRead = 1; cardRead = 1;
} else if (button_pressed > 0 && cardRead == 1) { } else if (button_pressed == BUTTON_HOLD && cardRead == 1) {
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
LED(LED_A, 0); LED(LED_A, 0);
@ -109,7 +109,7 @@ void RunMod() {
} }
// Change where to record (or begin playing) // Change where to record (or begin playing)
else if (button_pressed) { else if (button_pressed != BUTTON_NO_CLICK) {
// Next option if we were previously playing // Next option if we were previously playing
if (playing) if (playing)
selected = (selected + 1) % OPTS; selected = (selected + 1) % OPTS;
@ -131,7 +131,7 @@ void RunMod() {
CmdHIDsimTAG(0, high[selected], low[selected], 0, 0); CmdHIDsimTAG(0, high[selected], low[selected], 0, 0);
DbpString("[=] done playing"); DbpString("[=] done playing");
if (BUTTON_HELD(1000) > 0) if (BUTTON_HELD(1000) == BUTTON_HOLD)
goto out; goto out;
/* We pressed a button so ignore it here with a delay */ /* We pressed a button so ignore it here with a delay */
@ -169,7 +169,7 @@ void RunMod() {
// Needed for exiting from proxbrute when button is pressed // Needed for exiting from proxbrute when button is pressed
if (BUTTON_PRESS()) { if (BUTTON_PRESS()) {
if (BUTTON_HELD(1000) > 0) { if (BUTTON_HELD(1000) == BUTTON_HOLD) {
goto out; goto out;
} else { } else {
while (BUTTON_PRESS()) { while (BUTTON_PRESS()) {
@ -199,7 +199,7 @@ void RunMod() {
// Needed for exiting from proxbrute when button is pressed // Needed for exiting from proxbrute when button is pressed
if (BUTTON_PRESS()) { if (BUTTON_PRESS()) {
if (BUTTON_HELD(1000) > 0) { if (BUTTON_HELD(1000) == BUTTON_HOLD) {
goto out; goto out;
} else { } else {
while (BUTTON_PRESS()) { WDT_HIT(); } while (BUTTON_PRESS()) { WDT_HIT(); }
@ -220,7 +220,7 @@ void RunMod() {
} }
DbpString("[=] done bruteforcing"); DbpString("[=] done bruteforcing");
if (BUTTON_HELD(1000) > 0) if (BUTTON_HELD(1000) == BUTTON_HOLD)
goto out; goto out;
/* We pressed a button so ignore it here with a delay */ /* We pressed a button so ignore it here with a delay */

View file

@ -54,7 +54,7 @@
#define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log" #define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log"
void DownloadLogInstructions() { static void DownloadLogInstructions(void) {
Dbprintf(""); Dbprintf("");
Dbprintf("[=] To get the logfile from flash and display it:"); Dbprintf("[=] To get the logfile from flash and display it:");
Dbprintf("[=] " _YELLOW_("1.") " mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE); Dbprintf("[=] " _YELLOW_("1.") " mem spiffs dump o "LF_HIDCOLLECT_LOGFILE" f "LF_HIDCOLLECT_LOGFILE);
@ -64,7 +64,7 @@ void DownloadLogInstructions() {
bool log_exists; bool log_exists;
void append(uint8_t *entry, size_t entry_len) { static void append(uint8_t *entry, size_t entry_len) {
LED_B_ON(); LED_B_ON();
if (log_exists == false) { if (log_exists == false) {
@ -76,7 +76,7 @@ void append(uint8_t *entry, size_t entry_len) {
LED_B_OFF(); LED_B_OFF();
} }
uint32_t IceEM410xdemod() { static uint32_t IceEM410xdemod(void) {
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
size_t idx = 0; size_t idx = 0;
@ -128,7 +128,7 @@ uint32_t IceEM410xdemod() {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
uint32_t IceAWIDdemod() { static uint32_t IceAWIDdemod(void) {
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
size_t size = MIN(12800, BigBuf_max_traceLen()); size_t size = MIN(12800, BigBuf_max_traceLen());
@ -180,7 +180,7 @@ uint32_t IceAWIDdemod() {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
uint32_t IceIOdemod() { static uint32_t IceIOdemod(void) {
int dummyIdx = 0; int dummyIdx = 0;
uint8_t version = 0, facilitycode = 0; uint8_t version = 0, facilitycode = 0;
@ -224,7 +224,7 @@ uint32_t IceIOdemod() {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
uint32_t IceHIDDemod() { static uint32_t IceHIDDemod(void) {
int dummyIdx = 0; int dummyIdx = 0;
@ -320,7 +320,7 @@ void ModInfo(void) {
DbpString(_YELLOW_(" LF HID / IOprox / AWID / EM4100 collector mode") " - a.k.a IceHID (Iceman)"); DbpString(_YELLOW_(" LF HID / IOprox / AWID / EM4100 collector mode") " - a.k.a IceHID (Iceman)");
} }
void RunMod() { void RunMod(void) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
LFSetupFPGAForADC(LF_DIVISOR_125, true); LFSetupFPGAForADC(LF_DIVISOR_125, true);

View file

@ -23,7 +23,7 @@ void ModInfo(void) {
} }
// samy's sniff and repeat routine for LF // samy's sniff and repeat routine for LF
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<"); Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);

View file

@ -31,7 +31,7 @@ void ModInfo(void) {
// C = playing bank A // C = playing bank A
// D = playing bank B // D = playing bank B
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
@ -56,11 +56,6 @@ void RunMod() {
int button_pressed = BUTTON_HELD(280); int button_pressed = BUTTON_HELD(280);
if (button_pressed != BUTTON_HOLD) if (button_pressed != BUTTON_HOLD)
continue; continue;
/*
#define BUTTON_NO_CLICK 0
#define BUTTON_SINGLE_CLICK -1
#define BUTTON_DOUBLE_CLICK -2
*/
if (state == STATE_READ) { if (state == STATE_READ) {

View file

@ -18,7 +18,7 @@ void ModInfo(void) {
DbpString(" LF skeleton mode - aka Skeleton (iceman)"); DbpString(" LF skeleton mode - aka Skeleton (iceman)");
} }
void RunMod() { void RunMod(void) {
StandAloneMode(); StandAloneMode();
Dbprintf("[=] LF skeleton code a.k.a Skeleton started"); Dbprintf("[=] LF skeleton code a.k.a Skeleton started");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -35,7 +35,7 @@ void RunMod() {
Dbprintf("button %d", button_pressed); Dbprintf("button %d", button_pressed);
if (button_pressed) if (button_pressed != BUTTON_NO_CLICK)
break; break;
} }

View file

@ -6,5 +6,5 @@ void ModInfo(void) {
DbpString(" No standalone mode present"); DbpString(" No standalone mode present");
} }
void RunMod() { void RunMod(void) {
} }

View file

@ -131,7 +131,7 @@ Remember only one can be selected at a time for now.
The final steps is to The final steps is to
- force recompilation of all code. ```make clean``` - force recompilation of all code. ```make clean```
- compile ```make -j8``` - compile ```make -j```
- flash your device - flash your device
- connect to your device - connect to your device
- press button long time to trigger ledshow and enter your new standalone mode - press button long time to trigger ledshow and enter your new standalone mode

View file

@ -11,7 +11,7 @@
#ifndef __STANDALONE_H #ifndef __STANDALONE_H
#define __STANDALONE_H #define __STANDALONE_H
void RunMod(); void RunMod(void);
void ModInfo(); void ModInfo(void);
#endif /* __STANDALONE_H */ #endif /* __STANDALONE_H */

View file

@ -70,10 +70,14 @@
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits #define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
uint8_t ToSend[TOSEND_BUFFER_SIZE]; uint8_t ToSend[TOSEND_BUFFER_SIZE];
int ToSendMax = -1; int ToSendMax = -1;
extern uint32_t _stack_start, _stack_end;
static int ToSendBit; static int ToSendBit;
struct common_area common_area __attribute__((section(".commonarea"))); struct common_area common_area __attribute__((section(".commonarea")));
int button_status = BUTTON_NO_CLICK; static int button_status = BUTTON_NO_CLICK;
bool allow_send_wtx = false; static bool allow_send_wtx = false;
inline void send_wtx(uint16_t wtx) { inline void send_wtx(uint16_t wtx) {
if (allow_send_wtx) { if (allow_send_wtx) {
@ -106,7 +110,7 @@ void ToSendStuffBit(int b) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Read an ADC channel and block till it completes, then return the result // Read an ADC channel and block till it completes, then return the result
// in ADC units (0 to 1023). Also a routine to average 32 samples and // in ADC units (0 to 1023). Also a routine to sum up a number of samples and
// return that. // return that.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static uint16_t ReadAdc(int ch) { static uint16_t ReadAdc(int ch) {
@ -136,15 +140,17 @@ static uint16_t ReadAdc(int ch) {
// was static - merlok // was static - merlok
uint16_t AvgAdc(int ch) { uint16_t AvgAdc(int ch) {
uint16_t a = 0; return SumAdc(ch, 32) >> 5;
for (uint8_t i = 0; i < 32; i++)
a += ReadAdc(ch);
//division by 32
return (a + 15) >> 5;
} }
void MeasureAntennaTuning(void) { uint16_t SumAdc(int ch, int NbSamples) {
uint16_t a = 0;
for (uint8_t i = 0; i < NbSamples; i++)
a += ReadAdc(ch);
return (a + (NbSamples >> 1) - 1);
}
static void MeasureAntennaTuning(void) {
uint32_t peak = 0; uint32_t peak = 0;
@ -184,7 +190,7 @@ void MeasureAntennaTuning(void) {
WDT_HIT(); WDT_HIT();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
SpinDelay(20); SpinDelay(20);
uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14);
if (i == LF_DIVISOR_125) if (i == LF_DIVISOR_125)
payload.v_lf125 = adcval; // voltage at 125kHz payload.v_lf125 = adcval; // voltage at 125kHz
@ -210,9 +216,9 @@ void MeasureAntennaTuning(void) {
SpinDelay(50); SpinDelay(50);
#if defined RDV4 #if defined RDV4
payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
#else #else
payload.v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; payload.v_hf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
#endif #endif
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -221,19 +227,19 @@ void MeasureAntennaTuning(void) {
} }
// Measure HF in milliVolt // Measure HF in milliVolt
uint16_t MeasureAntennaTuningHfData(void) { static uint16_t MeasureAntennaTuningHfData(void) {
#if defined RDV4 #if defined RDV4
return (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; return (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
#else #else
return (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; return (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
#endif #endif
} }
// Measure LF in milliVolt // Measure LF in milliVolt
uint32_t MeasureAntennaTuningLfData(void) { static uint32_t MeasureAntennaTuningLfData(void) {
return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; return (MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14;
} }
void ReadMem(int addr) { void ReadMem(int addr) {
@ -242,11 +248,10 @@ void ReadMem(int addr) {
Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
} }
/* osimage version information is linked in */ /* osimage version information is linked in, cf commonutil.h */
extern struct version_information version_information;
/* bootrom version information is pointed to from _bootphase1_version_pointer */ /* bootrom version information is pointed to from _bootphase1_version_pointer */
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__; extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__;
void SendVersion(void) { static void SendVersion(void) {
char temp[PM3_CMD_DATA_SIZE - 12]; /* Limited data payload in USB packets */ char temp[PM3_CMD_DATA_SIZE - 12]; /* Limited data payload in USB packets */
char VersionString[PM3_CMD_DATA_SIZE - 12] = { '\0' }; char VersionString[PM3_CMD_DATA_SIZE - 12] = { '\0' };
@ -256,17 +261,19 @@ void SendVersion(void) {
*/ */
char *bootrom_version = *(char **)&_bootphase1_version_pointer; char *bootrom_version = *(char **)&_bootphase1_version_pointer;
strncat(VersionString, " [ ARM ]\n", sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, " "_YELLOW_("[ ARM ]")"\n", sizeof(VersionString) - strlen(VersionString) - 1);
if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) { if (bootrom_version < &_flash_start || bootrom_version >= &_flash_end) {
strcat(VersionString, "bootrom version information appears invalid\n"); strcat(VersionString, "bootrom version information appears invalid\n");
} else { } else {
FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version); FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version);
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
} }
FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information);
strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
#if defined(__clang__) #if defined(__clang__)
strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, " compiled with Clang/LLVM "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
@ -274,11 +281,11 @@ void SendVersion(void) {
strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, " compiled with GCC "__VERSION__"\n", sizeof(VersionString) - strlen(VersionString) - 1);
#endif #endif
strncat(VersionString, "\n [ FPGA ]\n ", sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, "\n "_YELLOW_("[ FPGA ]")"\n ", sizeof(VersionString) - strlen(VersionString) - 1);
for (int i = 0; i < fpga_bitstream_num; i++) { for (int i = 0; i < g_fpga_bitstream_num; i++) {
strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, g_fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
if (i < fpga_bitstream_num - 1) { if (i < g_fpga_bitstream_num - 1) {
strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1); strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1);
} }
} }
@ -302,7 +309,7 @@ void SendVersion(void) {
reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len); reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len);
} }
void TimingIntervalAcquisition(void) { static void TimingIntervalAcquisition(void) {
// trigger new acquisition by turning main oscillator off and on // trigger new acquisition by turning main oscillator off and on
mck_from_pll_to_slck(); mck_from_pll_to_slck();
mck_from_slck_to_pll(); mck_from_slck_to_pll();
@ -312,8 +319,8 @@ void TimingIntervalAcquisition(void) {
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included.
void printConnSpeed(void) { static void printConnSpeed(void) {
DbpString(_BLUE_("Transfer Speed")); DbpString(_CYAN_("Transfer Speed"));
Dbprintf(" Sending packets to client..."); Dbprintf(" Sending packets to client...");
#define CONN_SPEED_TEST_MIN_TIME 500 // in milliseconds #define CONN_SPEED_TEST_MIN_TIME 500 // in milliseconds
@ -339,7 +346,7 @@ void printConnSpeed(void) {
/** /**
* Prints runtime information about the PM3. * Prints runtime information about the PM3.
**/ **/
void SendStatus(void) { static void SendStatus(void) {
BigBuf_print_status(); BigBuf_print_status();
Fpga_print_status(); Fpga_print_status();
#ifdef WITH_FLASH #ifdef WITH_FLASH
@ -353,7 +360,13 @@ void SendStatus(void) {
printT55xxConfig(); // LF T55XX Config printT55xxConfig(); // LF T55XX Config
#endif #endif
printConnSpeed(); printConnSpeed();
DbpString(_BLUE_("Various")); DbpString(_CYAN_("Various"));
for (uint32_t *p = &_stack_start; ; ++p) {
if (*p != 0xdeadbeef) {
Dbprintf(" Max stack usage so far..%d", (&_stack_end - p)*4);
break;
}
}
Dbprintf(" DBGLEVEL................%d", DBGLEVEL); Dbprintf(" DBGLEVEL................%d", DBGLEVEL);
Dbprintf(" ToSendMax...............%d", ToSendMax); Dbprintf(" ToSendMax...............%d", ToSendMax);
Dbprintf(" ToSendBit...............%d", ToSendBit); Dbprintf(" ToSendBit...............%d", ToSendBit);
@ -372,7 +385,7 @@ void SendStatus(void) {
Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"),
(16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS);
} }
DbpString(_BLUE_("Installed StandAlone Mode")); DbpString(_CYAN_("Installed StandAlone Mode"));
ModInfo(); ModInfo();
#ifdef WITH_FLASH #ifdef WITH_FLASH
@ -382,15 +395,16 @@ void SendStatus(void) {
reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0); reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0);
} }
void SendCapabilities(void) { static void SendCapabilities(void) {
capabilities_t capabilities; capabilities_t capabilities;
capabilities.version = CAPABILITIES_VERSION; capabilities.version = CAPABILITIES_VERSION;
capabilities.via_fpc = reply_via_fpc; capabilities.via_fpc = g_reply_via_fpc;
capabilities.via_usb = reply_via_usb; capabilities.via_usb = g_reply_via_usb;
capabilities.bigbuf_size = BigBuf_get_size();
capabilities.baudrate = 0; // no real baudrate for USB-CDC capabilities.baudrate = 0; // no real baudrate for USB-CDC
#ifdef WITH_FPC_USART #ifdef WITH_FPC_USART
if (reply_via_fpc) if (g_reply_via_fpc)
capabilities.baudrate = usart_baudrate; capabilities.baudrate = g_usart_baudrate;
#endif #endif
#ifdef WITH_FLASH #ifdef WITH_FLASH
@ -524,7 +538,7 @@ at the same place! :-)
void ListenReaderField(uint8_t limit) { void ListenReaderField(uint8_t limit) {
#define LF_ONLY 1 #define LF_ONLY 1
#define HF_ONLY 2 #define HF_ONLY 2
#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE #define REPORT_CHANGE 1000 // report new values only if they have changed at least by REPORT_CHANGE mV
uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0; uint16_t lf_av = 0, lf_av_new, lf_baseline = 0, lf_max = 0;
uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0; uint16_t hf_av = 0, hf_av_new, hf_baseline = 0, hf_max = 0;
@ -538,8 +552,8 @@ void ListenReaderField(uint8_t limit) {
LEDsoff(); LEDsoff();
if (limit == LF_ONLY) { if (limit == LF_ONLY) {
lf_av = lf_max = AvgAdc(ADC_CHAN_LF); lf_av = lf_max = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15;
Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av);
lf_baseline = lf_av; lf_baseline = lf_av;
} }
@ -547,11 +561,11 @@ void ListenReaderField(uint8_t limit) {
#if defined RDV4 #if defined RDV4
// iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader.
hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); hf_av = hf_max = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
#else #else
hf_av = hf_max = AvgAdc(ADC_CHAN_HF); hf_av = hf_max = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
#endif #endif
Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av);
hf_baseline = hf_av; hf_baseline = hf_av;
} }
@ -583,10 +597,10 @@ void ListenReaderField(uint8_t limit) {
LED_D_OFF(); LED_D_OFF();
} }
lf_av_new = AvgAdc(ADC_CHAN_LF); lf_av_new = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15;
// see if there's a significant change // see if there's a significant change
if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) { if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) {
Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new);
lf_av = lf_av_new; lf_av = lf_av_new;
if (lf_av > lf_max) if (lf_av > lf_max)
lf_max = lf_av; lf_max = lf_av;
@ -602,13 +616,13 @@ void ListenReaderField(uint8_t limit) {
} }
#if defined RDV4 #if defined RDV4
hf_av_new = AvgAdc(ADC_CHAN_HF_RDV40); hf_av_new = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
#else #else
hf_av_new = AvgAdc(ADC_CHAN_HF); hf_av_new = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
#endif #endif
// see if there's a significant change // see if there's a significant change
if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) { if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) {
Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new);
hf_av = hf_av_new; hf_av = hf_av_new;
if (hf_av > hf_max) if (hf_av > hf_max)
hf_max = hf_av; hf_max = hf_av;
@ -701,8 +715,8 @@ static void PacketReceived(PacketCommandNG *packet) {
case CMD_BREAK_LOOP: case CMD_BREAK_LOOP:
break; break;
case CMD_QUIT_SESSION: { case CMD_QUIT_SESSION: {
reply_via_fpc = false; g_reply_via_fpc = false;
reply_via_usb = false; g_reply_via_usb = false;
break; break;
} }
// emulator // emulator
@ -1428,7 +1442,7 @@ static void PacketReceived(PacketCommandNG *packet) {
// upload file from client // upload file from client
uint8_t *mem = BigBuf_get_addr(); uint8_t *mem = BigBuf_get_addr();
memcpy(mem + packet->oldarg[0], packet->data.asBytes, PM3_CMD_DATA_SIZE); memcpy(mem + packet->oldarg[0], packet->data.asBytes, PM3_CMD_DATA_SIZE);
reply_old(CMD_ACK, 1, 0, 0, 0, 0); reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
break; break;
} }
case CMD_SMART_UPGRADE: { case CMD_SMART_UPGRADE: {
@ -1628,7 +1642,7 @@ static void PacketReceived(PacketCommandNG *packet) {
// arg1 = RFU // arg1 = RFU
// arg2 = tracelen? // arg2 = tracelen?
// asbytes = samplingconfig array // asbytes = samplingconfig array
reply_old(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config)); reply_mix(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config));
LED_B_OFF(); LED_B_OFF();
break; break;
} }
@ -1642,7 +1656,7 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p { struct p {
uint8_t flag; uint8_t flag;
uint16_t offset; uint16_t offset;
uint8_t *data; uint8_t data[PM3_CMD_DATA_SIZE - sizeof(uint8_t) - sizeof(uint16_t)];
} PACKED; } PACKED;
struct p *payload = (struct p *)packet->data.asBytes; struct p *payload = (struct p *)packet->data.asBytes;
@ -1653,18 +1667,17 @@ static void PacketReceived(PacketCommandNG *packet) {
BigBuf_free(); BigBuf_free();
} }
// 40 000 - (512-3) 509 = 39491 // offset should not be over buffer
uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset); if (payload->offset >= BigBuf_get_size()) {
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_EOVFLOW, NULL, 0);
// need to copy len bytes of data, not PM3_CMD_DATA_SIZE - 3 - offset break;
}
// ensure len bytes copied wont go past end of bigbuf // ensure len bytes copied wont go past end of bigbuf
uint16_t len = MIN(BIGBUF_SIZE - offset, PM3_CMD_DATA_SIZE - 3); uint16_t len = MIN(BigBuf_get_size() - payload->offset, sizeof(payload->data));
uint8_t *mem = BigBuf_get_addr(); uint8_t *mem = BigBuf_get_addr();
// x + 394 memcpy(mem + payload->offset, &payload->data, len);
memcpy(mem + offset, &payload->data, len);
// memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset);
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0);
break; break;
} }
@ -1760,7 +1773,7 @@ static void PacketReceived(PacketCommandNG *packet) {
int changed = rdv40_spiffs_lazy_mount(); int changed = rdv40_spiffs_lazy_mount();
uint32_t size = size_in_spiffs((char *)filename); uint32_t size = size_in_spiffs((char *)filename);
if (changed) rdv40_spiffs_lazy_unmount(); if (changed) rdv40_spiffs_lazy_unmount();
reply_old(CMD_ACK, size, 0, 0, 0, 0); reply_mix(CMD_ACK, size, 0, 0, 0, 0);
LED_B_OFF(); LED_B_OFF();
break; break;
} }
@ -1936,7 +1949,7 @@ static void PacketReceived(PacketCommandNG *packet) {
Flash_UniqueID(info->flashid); Flash_UniqueID(info->flashid);
FlashStop(); FlashStop();
} }
reply_old(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t)); reply_mix(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t));
BigBuf_free(); BigBuf_free();
LED_B_OFF(); LED_B_OFF();
@ -2050,7 +2063,11 @@ static void PacketReceived(PacketCommandNG *packet) {
void __attribute__((noreturn)) AppMain(void) { void __attribute__((noreturn)) AppMain(void) {
SpinDelay(100); SpinDelay(100);
clear_trace(); BigBuf_initialize();
for (uint32_t * p = &_stack_start; p < (uint32_t *)((uintptr_t)&_stack_end - 0x200); ++p) {
*p = 0xdeadbeef;
}
if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { if (common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
/* Initialize common area */ /* Initialize common area */
@ -2117,6 +2134,10 @@ void __attribute__((noreturn)) AppMain(void) {
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
if (_stack_start != 0xdeadbeef) {
Dbprintf("Stack overflow detected! Please increase stack size.");
}
// Check if there is a packet available // Check if there is a packet available
PacketCommandNG rx; PacketCommandNG rx;
memset(&rx.data, 0, sizeof(rx.data)); memset(&rx.data, 0, sizeof(rx.data));

View file

@ -13,10 +13,8 @@
#include "common.h" #include "common.h"
extern const uint8_t OddByteParity[256]; extern int g_rsamples; // = 0;
extern int rsamples; // = 0; extern uint8_t g_trigger;
extern uint8_t trigger;
extern bool allow_send_wtx;
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV // ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
#define MAX_ADC_HF_VOLTAGE 36300 #define MAX_ADC_HF_VOLTAGE 36300
@ -33,6 +31,7 @@ void ReadMem(int addr);
void __attribute__((noreturn)) AppMain(void); void __attribute__((noreturn)) AppMain(void);
uint16_t AvgAdc(int ch); uint16_t AvgAdc(int ch);
uint16_t SumAdc(int ch, int NbSamples);
//void PrintToSendBuffer(void); //void PrintToSendBuffer(void);
void ToSendStuffBit(int b); void ToSendStuffBit(int b);

View file

@ -36,11 +36,11 @@
#include "string.h" #include "string.h"
// Flags to tell where to add CRC on sent replies // Flags to tell where to add CRC on sent replies
bool reply_with_crc_on_usb = false; bool g_reply_with_crc_on_usb = false;
bool reply_with_crc_on_fpc = true; bool g_reply_with_crc_on_fpc = true;
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART // "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
bool reply_via_fpc = false; bool g_reply_via_fpc = false;
bool reply_via_usb = false; bool g_reply_via_usb = false;
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) {
PacketResponseOLD txcmd = {CMD_UNKNOWN, {0, 0, 0}, {{0}}}; PacketResponseOLD txcmd = {CMD_UNKNOWN, {0, 0, 0}, {{0}}};
@ -62,15 +62,17 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *d
} }
} }
#ifdef WITH_FPC_USART_HOST
int resultfpc = PM3_EUNDEF; int resultfpc = PM3_EUNDEF;
#endif
int resultusb = PM3_EUNDEF; int resultusb = PM3_EUNDEF;
// Send frame and make sure all bytes are transmitted // Send frame and make sure all bytes are transmitted
if (reply_via_usb) { if (g_reply_via_usb) {
resultusb = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); resultusb = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
} }
if (reply_via_fpc) { if (g_reply_via_fpc) {
#ifdef WITH_FPC_USART_HOST #ifdef WITH_FPC_USART_HOST
resultfpc = usart_writebuffer_sync((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); resultfpc = usart_writebuffer_sync((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
#else #else
@ -78,8 +80,10 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *d
#endif #endif
} }
// we got two results, let's prioritize the faulty one and USB over FPC. // we got two results, let's prioritize the faulty one and USB over FPC.
if (reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb; if (g_reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb;
if (reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc; #ifdef WITH_FPC_USART_HOST
if (g_reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc;
#endif
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -108,7 +112,7 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t
PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len); PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len);
// Note: if we send to both FPC & USB, we'll set CRC for both if any of them require CRC // Note: if we send to both FPC & USB, we'll set CRC for both if any of them require CRC
if ((reply_via_fpc && reply_with_crc_on_fpc) || ((reply_via_usb) && reply_with_crc_on_usb)) { if ((g_reply_via_fpc && g_reply_with_crc_on_fpc) || ((g_reply_via_usb) && g_reply_with_crc_on_usb)) {
uint8_t first, second; uint8_t first, second;
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second); compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second);
tx_post->crc = (first << 8) + second; tx_post->crc = (first << 8) + second;
@ -117,14 +121,16 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t
} }
txBufferNGLen = sizeof(PacketResponseNGPreamble) + len + sizeof(PacketResponseNGPostamble); txBufferNGLen = sizeof(PacketResponseNGPreamble) + len + sizeof(PacketResponseNGPostamble);
#ifdef WITH_FPC_USART_HOST
int resultfpc = PM3_EUNDEF; int resultfpc = PM3_EUNDEF;
#endif
int resultusb = PM3_EUNDEF; int resultusb = PM3_EUNDEF;
// Send frame and make sure all bytes are transmitted // Send frame and make sure all bytes are transmitted
if (reply_via_usb) { if (g_reply_via_usb) {
resultusb = usb_write((uint8_t *)&txBufferNG, txBufferNGLen); resultusb = usb_write((uint8_t *)&txBufferNG, txBufferNGLen);
} }
if (reply_via_fpc) { if (g_reply_via_fpc) {
#ifdef WITH_FPC_USART_HOST #ifdef WITH_FPC_USART_HOST
resultfpc = usart_writebuffer_sync((uint8_t *)&txBufferNG, txBufferNGLen); resultfpc = usart_writebuffer_sync((uint8_t *)&txBufferNG, txBufferNGLen);
#else #else
@ -132,8 +138,10 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, uint8_t *data, size_t
#endif #endif
} }
// we got two results, let's prioritize the faulty one and USB over FPC. // we got two results, let's prioritize the faulty one and USB over FPC.
if (reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb; if (g_reply_via_usb && (resultusb != PM3_SUCCESS)) return resultusb;
if (reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc; #ifdef WITH_FPC_USART_HOST
if (g_reply_via_fpc && (resultfpc != PM3_SUCCESS)) return resultfpc;
#endif
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -208,8 +216,8 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da
if ((first << 8) + second != rx->crc) if ((first << 8) + second != rx->crc)
return PM3_EIO; return PM3_EIO;
} }
reply_via_usb = usb; g_reply_via_usb = usb;
reply_via_fpc = fpc; g_reply_via_fpc = fpc;
} else { // Old style command } else { // Old style command
PacketCommandOLD rx_old; PacketCommandOLD rx_old;
memcpy(&rx_old, &rx_raw.pre, sizeof(PacketCommandNGPreamble)); memcpy(&rx_old, &rx_raw.pre, sizeof(PacketCommandNGPreamble));
@ -217,8 +225,8 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da
if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble)) if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble))
return PM3_EIO; return PM3_EIO;
reply_via_usb = usb; g_reply_via_usb = usb;
reply_via_fpc = fpc; g_reply_via_fpc = fpc;
rx->ng = false; rx->ng = false;
rx->magic = 0; rx->magic = 0;
rx->crc = 0; rx->crc = 0;

View file

@ -37,11 +37,11 @@
#include "pm3_cmd.h" #include "pm3_cmd.h"
// Flags to tell where to add CRC on sent replies // Flags to tell where to add CRC on sent replies
extern bool reply_with_crc_on_usb; extern bool g_reply_with_crc_on_usb;
extern bool reply_with_crc_on_fpc; extern bool g_reply_with_crc_on_fpc;
// "Session" flag, to tell via which interface next msgs should be sent: USB and/or FPC USART // "Session" flag, to tell via which interface next msgs should be sent: USB and/or FPC USART
extern bool reply_via_fpc; extern bool g_reply_via_fpc;
extern bool reply_via_usb; extern bool g_reply_via_usb;
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);

View file

@ -22,7 +22,7 @@
// Debug print functions, to go out over USB, to the usual PC-side client. // Debug print functions, to go out over USB, to the usual PC-side client.
//============================================================================= //=============================================================================
void DbpStringEx(uint32_t flags, char *src, size_t srclen) { void DbpStringEx(uint32_t flags, const char *src, size_t srclen) {
#if DEBUG #if DEBUG
struct { struct {
uint16_t flag; uint16_t flag;
@ -35,7 +35,7 @@ void DbpStringEx(uint32_t flags, char *src, size_t srclen) {
#endif #endif
} }
void DbpString(char *str) { void DbpString(const char *str) {
#if DEBUG #if DEBUG
DbpStringEx(FLAG_LOG, str, strlen(str)); DbpStringEx(FLAG_LOG, str, strlen(str));
#endif #endif
@ -98,7 +98,7 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) {
#endif #endif
} }
void print_result(char *name, uint8_t *buf, size_t len) { void print_result(const char *name, uint8_t *buf, size_t len) {
uint8_t *p = buf; uint8_t *p = buf;
uint16_t tmp = len & 0xFFF0; uint16_t tmp = len & 0xFFF0;

View file

@ -15,39 +15,39 @@
#include "ansi.h" #include "ansi.h"
#define Dbprintf_usb(...) {\ #define Dbprintf_usb(...) {\
bool tmpfpc = reply_via_fpc;\ bool tmpfpc = g_reply_via_fpc;\
bool tmpusb = reply_via_usb;\ bool tmpusb = g_reply_via_usb;\
reply_via_fpc = false;\ g_reply_via_fpc = false;\
reply_via_usb = true;\ g_reply_via_usb = true;\
Dbprintf(__VA_ARGS__);\ Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\ g_reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;} g_reply_via_usb = tmpusb;}
#define Dbprintf_fpc(...) {\ #define Dbprintf_fpc(...) {\
bool tmpfpc = reply_via_fpc;\ bool tmpfpc = g_reply_via_fpc;\
bool tmpusb = reply_via_usb;\ bool tmpusb = g_reply_via_usb;\
reply_via_fpc = true;\ g_reply_via_fpc = true;\
reply_via_usb = false;\ g_reply_via_usb = false;\
Dbprintf(__VA_ARGS__);\ Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\ g_reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;} g_reply_via_usb = tmpusb;}
#define Dbprintf_all(...) {\ #define Dbprintf_all(...) {\
bool tmpfpc = reply_via_fpc;\ bool tmpfpc = g_reply_via_fpc;\
bool tmpusb = reply_via_usb;\ bool tmpusb = g_reply_via_usb;\
reply_via_fpc = true;\ g_reply_via_fpc = true;\
reply_via_usb = true;\ g_reply_via_usb = true;\
Dbprintf(__VA_ARGS__);\ Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\ g_reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;} g_reply_via_usb = tmpusb;}
void DbpString(char *str); void DbpString(const char *str);
void DbpStringEx(uint32_t flags, char *src, size_t srclen); void DbpStringEx(uint32_t flags, const char *src, size_t srclen);
void Dbprintf(const char *fmt, ...); void Dbprintf(const char *fmt, ...);
void DbprintfEx(uint32_t flags, const char *fmt, ...); void DbprintfEx(uint32_t flags, const char *fmt, ...);
void Dbhexdump(int len, uint8_t *d, bool bAsci); void Dbhexdump(int len, uint8_t *d, bool bAsci);
void print_result(char *name, uint8_t *buf, size_t len); void print_result(const char *name, uint8_t *buf, size_t len);
//void PrintToSendBuffer(void); //void PrintToSendBuffer(void);
#endif #endif

View file

@ -36,6 +36,7 @@
#include "printf.h" #include "printf.h"
#include "iso14443a.h" #include "iso14443a.h"
#include "dbprint.h" #include "dbprint.h"
#include "BigBuf.h"
#ifndef AddCrc14A #ifndef AddCrc14A
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
@ -45,9 +46,9 @@ static mbedtls_des_context ctx;
static mbedtls_des3_context ctx3; static mbedtls_des3_context ctx3;
static mbedtls_aes_context actx; static mbedtls_aes_context actx;
static inline void update_key_schedules(desfirekey_t key); static void update_key_schedules(desfirekey_t key);
static inline void update_key_schedules(desfirekey_t key) { static void update_key_schedules(desfirekey_t key) {
// DES_set_key ((DES_cblock *)key->data, &(key->ks1)); // DES_set_key ((DES_cblock *)key->data, &(key->ks1));
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2)); // DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
// if (T_3K3DES == key->type) { // if (T_3K3DES == key->type) {
@ -282,7 +283,10 @@ void cmac_generate_subkeys(desfirekey_t key) {
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) { void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) {
int kbs = key_block_size(key); int kbs = key_block_size(key);
uint8_t *buffer = malloc(padded_data_length(len, kbs)); if (kbs == 0)
return;
uint8_t *buffer = BigBuf_malloc(padded_data_length(len, kbs));
memcpy(buffer, data, len); memcpy(buffer, data, len);
@ -299,7 +303,7 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le
mifare_cypher_blocks_chained(NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER); mifare_cypher_blocks_chained(NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
memcpy(cmac, ivect, kbs); memcpy(cmac, ivect, kbs);
free(buffer); //free(buffer);
} }
size_t key_block_size(const desfirekey_t key) { size_t key_block_size(const desfirekey_t key) {
@ -538,7 +542,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
} }
size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings); size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings);
edata = malloc(edl); edata = BigBuf_malloc(edl);
memcpy(edata, data, *nbytes - 1); memcpy(edata, data, *nbytes - 1);
memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1); memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);

View file

@ -99,8 +99,6 @@ struct desfire_tag {
uint32_t selected_application; uint32_t selected_application;
}; };
typedef struct desfire_tag *desfiretag_t; typedef struct desfire_tag *desfiretag_t;
void crc32_ex(const uint8_t *data, const size_t len, uint8_t *crc);
void crc32_append(uint8_t *data, const size_t len);
void des_encrypt(void *out, const void *in, const void *key); void des_encrypt(void *out, const void *in, const void *key);
void des_decrypt(void *out, const void *in, const void *key); void des_decrypt(void *out, const void *in, const void *key);
void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode); void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode);

View file

@ -113,7 +113,7 @@ static char iso_type = 0;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Wrapper for sending APDUs to type A and B cards // Wrapper for sending APDUs to type A and B cards
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) { static int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) {
switch (iso_type) { switch (iso_type) {
case 'a': case 'a':
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
@ -130,7 +130,7 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Closes the communication channel and turns off the field // Closes the communication channel and turns off the field
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void EPA_Finish() { void EPA_Finish(void) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
iso_type = 0; iso_type = 0;
@ -501,7 +501,7 @@ void EPA_PACE_Replay(PacketCommandNG *c) {
// Set up a communication channel (Card Select, PPS) // Set up a communication channel (Card Select, PPS)
// Returns 0 on success or a non-zero error code on failure // Returns 0 on success or a non-zero error code on failure
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int EPA_Setup() { int EPA_Setup(void) {
// first, look for type A cards // first, look for type A cards
// power up the field // power up the field

View file

@ -23,12 +23,12 @@ typedef struct {
} pace_version_info_t; } pace_version_info_t;
// general functions // general functions
void EPA_Finish(); void EPA_Finish(void);
size_t EPA_Parse_CardAccess(uint8_t *data, size_t EPA_Parse_CardAccess(uint8_t *data,
size_t length, size_t length,
pace_version_info_t *pace_info); pace_version_info_t *pace_info);
int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length); int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length);
int EPA_Setup(); int EPA_Setup(void);
// PACE related functions // PACE related functions
int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password); int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password);

View file

@ -35,13 +35,13 @@ static uint32_t felica_lasttime_prox2air_start;
static void iso18092_setup(uint8_t fpga_minor_mode); static void iso18092_setup(uint8_t fpga_minor_mode);
static uint8_t felica_select_card(felica_card_select_t *card); static uint8_t felica_select_card(felica_card_select_t *card);
static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed); static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed);
bool WaitForFelicaReply(uint16_t maxbytes); static bool WaitForFelicaReply(uint16_t maxbytes);
void iso18092_set_timeout(uint32_t timeout) { static void iso18092_set_timeout(uint32_t timeout) {
felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2; felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2;
} }
uint32_t iso18092_get_timeout(void) { static uint32_t iso18092_get_timeout(void) {
return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2; return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2;
} }
@ -80,7 +80,7 @@ static struct {
# define SYNC_16BIT 0xB24D # define SYNC_16BIT 0xB24D
#endif #endif
static void FelicaFrameReset() { static void FelicaFrameReset(void) {
FelicaFrame.state = STATE_UNSYNCD; FelicaFrame.state = STATE_UNSYNCD;
FelicaFrame.posCnt = 0; FelicaFrame.posCnt = 0;
FelicaFrame.crc_ok = false; FelicaFrame.crc_ok = false;
@ -431,7 +431,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
); );
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL"); if (DBGLEVEL >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL");
return true; return true;
} else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { } else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) {
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD"); if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD");
return false; return false;
} }
@ -481,7 +481,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
LED_D_ON(); LED_D_ON();
} }
void felica_reset_frame_mode() { static void felica_reset_frame_mode(void) {
switch_off(); switch_off();
//Resetting Frame mode (First set in fpgaloader.c) //Resetting Frame mode (First set in fpgaloader.c)
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
@ -738,7 +738,7 @@ void felica_sim_lite(uint64_t uid) {
#define RES_SVC_LEN 11 + 3 #define RES_SVC_LEN 11 + 3
void felica_dump_lite_s() { void felica_dump_lite_s(void) {
uint8_t ndef[8]; uint8_t ndef[8];
uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21};
uint16_t liteblks[28] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x90, 0x91, 0x92, 0xa0}; uint16_t liteblks[28] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x90, 0x91, 0x92, 0xa0};

View file

@ -17,6 +17,6 @@
void felica_sendraw(PacketCommandNG *c); void felica_sendraw(PacketCommandNG *c);
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip); void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip);
void felica_sim_lite(uint64_t uid); void felica_sim_lite(uint64_t uid);
void felica_dump_lite_s(); void felica_dump_lite_s(void);
#endif #endif

View file

@ -16,8 +16,8 @@
/// Calculates the value of the CSR DLYBCT field given the desired delay (in ns) /// Calculates the value of the CSR DLYBCT field given the desired delay (in ns)
#define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24) #define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24)
static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; #define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
void FlashmemSetSpiBaudrate(uint32_t baudrate) { void FlashmemSetSpiBaudrate(uint32_t baudrate) {
FLASHMEM_SPIBAUDRATE = baudrate; FLASHMEM_SPIBAUDRATE = baudrate;
@ -25,7 +25,7 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate) {
} }
// initialize // initialize
bool FlashInit() { bool FlashInit(void) {
FlashSetup(FLASHMEM_SPIBAUDRATE); FlashSetup(FLASHMEM_SPIBAUDRATE);
StartTicks(); StartTicks();
@ -435,7 +435,7 @@ bool Flash_WipeMemoryPage(uint8_t page) {
return true; return true;
} }
// Wipes flash memory completely, fills with 0xFF // Wipes flash memory completely, fills with 0xFF
bool Flash_WipeMemory() { bool Flash_WipeMemory(void) {
if (!FlashInit()) { if (!FlashInit()) {
if (DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail"); if (DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail");
return false; return false;
@ -462,7 +462,7 @@ bool Flash_WipeMemory() {
} }
// enable the flash write // enable the flash write
void Flash_WriteEnable() { void Flash_WriteEnable(void) {
FlashSendLastByte(WRITEENABLE); FlashSendLastByte(WRITEENABLE);
if (DBGLEVEL > 3) Dbprintf("Flash Write enabled"); if (DBGLEVEL > 3) Dbprintf("Flash Write enabled");
} }
@ -523,7 +523,7 @@ void Flash_EraseChip(void) {
*/ */
void Flashmem_print_status(void) { void Flashmem_print_status(void) {
DbpString(_BLUE_("Flash memory")); DbpString(_CYAN_("Flash memory"));
Dbprintf(" Baudrate................" _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000); Dbprintf(" Baudrate................" _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
if (!FlashInit()) { if (!FlashInit()) {
@ -562,7 +562,7 @@ void Flashmem_print_info(void) {
if (!FlashInit()) return; if (!FlashInit()) return;
DbpString(_BLUE_("Flash memory dictionary loaded")); DbpString(_CYAN_("Flash memory dictionary loaded"));
// load dictionary offsets. // load dictionary offsets.
uint8_t keysum[2]; uint8_t keysum[2];

View file

@ -106,12 +106,10 @@
#define FLASH_FASTBAUD MCK #define FLASH_FASTBAUD MCK
#define FLASH_MINBAUD FLASH_FASTBAUD #define FLASH_MINBAUD FLASH_FASTBAUD
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void FlashmemSetSpiBaudrate(uint32_t baudrate); void FlashmemSetSpiBaudrate(uint32_t baudrate);
bool FlashInit(); bool FlashInit(void);
void FlashSetup(uint32_t baudrate); void FlashSetup(uint32_t baudrate);
void FlashStop(void); void FlashStop(void);
bool Flash_WaitIdle(void); bool Flash_WaitIdle(void);
@ -122,9 +120,9 @@ void Flash_TransferAdresse(uint32_t address);
bool Flash_CheckBusy(uint32_t timeout); bool Flash_CheckBusy(uint32_t timeout);
void Flash_WriteEnable(); void Flash_WriteEnable(void);
bool Flash_WipeMemoryPage(uint8_t page); bool Flash_WipeMemoryPage(uint8_t page);
bool Flash_WipeMemory(); bool Flash_WipeMemory(void);
bool Flash_Erase4k(uint8_t block, uint8_t sector); bool Flash_Erase4k(uint8_t block, uint8_t sector);
//bool Flash_Erase32k(uint32_t address); //bool Flash_Erase32k(uint32_t address);
bool Flash_Erase64k(uint8_t block); bool Flash_Erase64k(uint8_t block);

View file

@ -17,10 +17,19 @@
#include "ticks.h" #include "ticks.h"
#include "dbprint.h" #include "dbprint.h"
#include "util.h" #include "util.h"
#include "zlib.h"
#include "fpga.h" #include "fpga.h"
#include "string.h" #include "string.h"
#include "lz4.h" // uncompress
typedef struct lz4_stream_s {
LZ4_streamDecode_t *lz4StreamDecode;
char *next_in;
int avail_in;
} lz4_stream;
typedef lz4_stream *lz4_streamp;
// remember which version of the bitstream we have already downloaded to the FPGA // remember which version of the bitstream we have already downloaded to the FPGA
static int downloaded_bitstream = 0; static int downloaded_bitstream = 0;
@ -30,8 +39,6 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end;
static uint8_t *fpga_image_ptr = NULL; static uint8_t *fpga_image_ptr = NULL;
static uint32_t uncompressed_bytes_cnt; static uint32_t uncompressed_bytes_cnt;
#define OUTPUT_BUFFER_LEN 80
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Set up the Serial Peripheral Interface as master // Set up the Serial Peripheral Interface as master
// Used to write the FPGA config word // Used to write the FPGA config word
@ -180,19 +187,24 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with // Uncompress (inflate) the FPGA data. Returns one decompressed byte with
// each call. // each call.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int get_from_fpga_combined_stream(lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data
compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
fpga_image_ptr = output_buffer; fpga_image_ptr = output_buffer;
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH); int cmp_bytes;
memcpy(&cmp_bytes, compressed_fpga_stream->next_in, sizeof(int));
if (res != Z_OK) compressed_fpga_stream->next_in += 4;
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg); compressed_fpga_stream->avail_in -= cmp_bytes + 4;
int res = LZ4_decompress_safe_continue(compressed_fpga_stream->lz4StreamDecode,
if (res < 0) compressed_fpga_stream->next_in,
(char *)output_buffer,
cmp_bytes,
FPGA_RING_BUFFER_BYTES);
if (res <= 0) {
Dbprintf("inflate returned: %d", res);
return res; return res;
} }
compressed_fpga_stream->next_in += cmp_bytes;
}
uncompressed_bytes_cnt++; uncompressed_bytes_cnt++;
return *fpga_image_ptr++; return *fpga_image_ptr++;
} }
@ -202,8 +214,8 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
// are combined into one big file: // are combined into one big file:
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int get_from_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) { while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) {
// skip undesired data belonging to other bitstream_versions // skip undesired data belonging to other bitstream_versions
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
} }
@ -211,37 +223,23 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
} }
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) {
return BigBuf_malloc(items * size);
}
// free eventually allocated BigBuf memory
static void fpga_inflate_free(voidpf opaque, voidpf address) {
BigBuf_free();
BigBuf_Clear_ext(false);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Initialize decompression of the respective (HF or LF) FPGA stream // Initialize decompression of the respective (HF or LF) FPGA stream
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static bool reset_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
uncompressed_bytes_cnt = 0; uncompressed_bytes_cnt = 0;
// initialize z_stream structure for inflate: // initialize z_stream structure for inflate:
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start; compressed_fpga_stream->next_in = (char *)&_binary_obj_fpga_all_bit_z_start;
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start; compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
compressed_fpga_stream->zfree = &fpga_inflate_free;
int res = inflateInit2(compressed_fpga_stream, 0); int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0);
if (res < 0) if (res == 0)
return false; return false;
fpga_image_ptr = output_buffer; fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES;
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
@ -266,7 +264,7 @@ static void DownloadFPGA_byte(uint8_t w) {
} }
// Download the fpga image starting at current stream position with length FpgaImageLen bytes // Download the fpga image starting at current stream position with length FpgaImageLen bytes
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
int i = 0; int i = 0;
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
@ -348,7 +346,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes * (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
* length. * length.
*/ */
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
int result = 0; int result = 0;
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
uint16_t numbytes = 0; uint16_t numbytes = 0;
@ -407,8 +405,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
// Send waiting time extension request as this will take a while // Send waiting time extension request as this will take a while
send_wtx(1500); send_wtx(1500);
z_stream compressed_fpga_stream;
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
bool verbose = (DBGLEVEL > 3); bool verbose = (DBGLEVEL > 3);
@ -416,6 +412,11 @@ void FpgaDownloadAndGo(int bitstream_version) {
BigBuf_free(); BigBuf_free();
BigBuf_Clear_ext(verbose); BigBuf_Clear_ext(verbose);
lz4_stream compressed_fpga_stream;
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
return; return;
@ -425,8 +426,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
downloaded_bitstream = bitstream_version; downloaded_bitstream = bitstream_version;
} }
inflateEnd(&compressed_fpga_stream);
// turn off antenna // turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -508,8 +507,8 @@ void SetAdcMuxFor(uint32_t whichGpio) {
} }
void Fpga_print_status(void) { void Fpga_print_status(void) {
DbpString(_BLUE_("Currently loaded FPGA image")); DbpString(_CYAN_("Current FPGA image"));
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream - 1]); Dbprintf(" mode....................%s", g_fpga_version_information[downloaded_bitstream - 1]);
} }
int FpgaGetCurrent(void) { int FpgaGetCurrent(void) {

View file

@ -1471,10 +1471,9 @@ char *json_vasprintf(const char *fmt, va_list ap) {
char *json_asprintf(const char *fmt, ...) WEAK; char *json_asprintf(const char *fmt, ...) WEAK;
char *json_asprintf(const char *fmt, ...) { char *json_asprintf(const char *fmt, ...) {
char *result = NULL;
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
result = json_vasprintf(fmt, ap); char *result = json_vasprintf(fmt, ap);
va_end(ap); va_end(ap);
return result; return result;
} }

View file

@ -48,8 +48,8 @@ static bool bCrypto;
// Is in auth stage // Is in auth stage
static bool bAuthenticating; static bool bAuthenticating;
// Successful password auth // Successful password auth
bool bSelecting; static bool bSelecting;
bool bCollision; static bool bCollision;
static bool bPwd; static bool bPwd;
static bool bSuccessful; static bool bSuccessful;
@ -89,14 +89,14 @@ static uint8_t password[4];
static uint8_t NrAr[8]; static uint8_t NrAr[8];
static uint8_t key[8]; static uint8_t key[8];
static uint8_t writedata[4]; static uint8_t writedata[4];
uint8_t logdata_0[4], logdata_1[4]; static uint8_t logdata_0[4], logdata_1[4];
uint8_t nonce[4]; static uint8_t nonce[4];
bool key_no; static bool key_no;
static uint64_t cipher_state; static uint64_t cipher_state;
int16_t blocknr; static int16_t blocknr;
size_t flipped_bit = 0; static size_t flipped_bit = 0;
uint32_t byte_value = 0; static uint32_t byte_value = 0;
static int hitag2_reset(void) { static int hitag2_reset(void) {
tag.state = TAG_STATE_RESET; tag.state = TAG_STATE_RESET;
@ -373,7 +373,7 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len)
return wait; return wait;
} }
uint8_t hitag_crc(uint8_t *data, size_t length) { static uint8_t hitag_crc(uint8_t *data, size_t length) {
uint8_t crc = 0xff; uint8_t crc = 0xff;
unsigned int byte, bit; unsigned int byte, bit;
for (byte = 0; byte < ((length + 7) / 8); byte++) { for (byte = 0; byte < ((length + 7) / 8); byte++) {
@ -411,7 +411,7 @@ void fix_ac_decoding(uint8_t *input, size_t len) {
// looks at number of received bits. // looks at number of received bits.
// 0 = collision? // 0 = collision?
// 32 = good response // 32 = good response
bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) {
uint8_t crc; uint8_t crc;
*txlen = 0; *txlen = 0;
switch (rxlen) { switch (rxlen) {
@ -480,7 +480,7 @@ bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bo
} }
bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) { static bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
uint8_t crc; uint8_t crc;
*txlen = 0; *txlen = 0;
switch (rxlen) { switch (rxlen) {
@ -997,7 +997,7 @@ void SniffHitag2(void) {
lf_init(false, false); lf_init(false, false);
logging = false; g_logging = false;
size_t periods = 0; size_t periods = 0;
uint8_t periods_bytes[4]; uint8_t periods_bytes[4];
@ -1031,8 +1031,8 @@ void SniffHitag2(void) {
// Test if we detected the first reader modulation edge // Test if we detected the first reader modulation edge
if (periods != 0) { if (periods != 0) {
if (logging == false) { if (g_logging == false) {
logging = true; g_logging = true;
LED_D_ON(); LED_D_ON();
} }
} }
@ -1062,7 +1062,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
lf_init(false, true); lf_init(false, true);
int response = 0; int response = 0;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN] = {0};
size_t rxlen = 0; size_t rxlen = 0;
uint8_t tx[HITAG_FRAME_LEN]; uint8_t tx[HITAG_FRAME_LEN];
size_t txlen = 0; size_t txlen = 0;
@ -1238,7 +1238,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) {
// Check if frame was captured // Check if frame was captured
if (rxlen > 4) { if (rxlen > 4) {
LogTrace(rx, nbytes(rxlen), response, 0, NULL, true); LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
// Process the incoming frame (rx) and prepare the outgoing frame (tx) // Process the incoming frame (rx) and prepare the outgoing frame (tx)
hitag2_handle_reader_command(rx, rxlen, tx, &txlen); hitag2_handle_reader_command(rx, rxlen, tx, &txlen);
@ -1397,21 +1397,23 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
uint8_t attempt_count = 0; uint8_t attempt_count = 0;
// Tag specific configuration settings (sof, timings, etc.) // Tag specific configuration settings (sof, timings, etc.)
if (htf < 10) { // TODO HTS
/* if (htf <= HTS_LAST_CMD) {
// hitagS settings // hitagS settings
t_wait_1 = 204; t_wait_1 = 204;
t_wait_2 = 128; t_wait_2 = 128;
flipped_bit = 0; flipped_bit = 0;
tag_size = 8; tag_size = 8;
DBG DbpString("Configured for hitagS reader"); DBG DbpString("Configured for hitagS reader");
} else if (htf < 20) { } else */
if (htf <= HT1_LAST_CMD) {
// hitag1 settings // hitag1 settings
t_wait_1 = 204; t_wait_1 = 204;
t_wait_2 = 128; t_wait_2 = 128;
tag_size = 256; tag_size = 256;
flipped_bit = 0; flipped_bit = 0;
DBG DbpString("Configured for hitag1 reader"); DBG DbpString("Configured for hitag1 reader");
} else if (htf < 30) { } else if (htf <= HT2_LAST_CMD) {
// hitag2 settings // hitag2 settings
t_wait_1 = HITAG_T_WAIT_1_MIN; t_wait_1 = HITAG_T_WAIT_1_MIN;
t_wait_2 = HITAG_T_WAIT_2_MIN; t_wait_2 = HITAG_T_WAIT_2_MIN;
@ -1721,28 +1723,32 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
lf_init(true, false); lf_init(true, false);
// Tag specific configuration settings (sof, timings, etc.) // Tag specific configuration settings (sof, timings, etc.)
if (htf < 10) { // TODO HTS
/* if (htf <= HTS_LAST_CMD) {
// hitagS settings // hitagS settings
t_wait_1 = 204; t_wait_1 = 204;
t_wait_2 = 128; t_wait_2 = 128;
/*tag_size = 256;*/ //tag_size = 256;
flipped_bit = 0; flipped_bit = 0;
tag_size = 8; tag_size = 8;
DbpString("Configured for hitagS writer"); DbpString("Configured for hitagS writer");
} else if (htf < 20) { } else */
// TODO HT1
/* if (htf <= HT1_LAST_CMD) {
// hitag1 settings // hitag1 settings
t_wait_1 = 204; t_wait_1 = 204;
t_wait_2 = 128; t_wait_2 = 128;
tag_size = 256; tag_size = 256;
flipped_bit = 0; flipped_bit = 0;
DbpString("Configured for hitag1 writer"); DbpString("Configured for hitag1 writer");
} else if (htf < 30) { } else */
// if (htf <= HT2_LAST_CMD) {
// hitag2 settings // hitag2 settings
t_wait_1 = HITAG_T_WAIT_1_MIN; t_wait_1 = HITAG_T_WAIT_1_MIN;
t_wait_2 = HITAG_T_WAIT_2_MIN; t_wait_2 = HITAG_T_WAIT_2_MIN;
tag_size = 48; tag_size = 48;
DbpString("Configured for hitag2 writer"); DbpString("Configured for hitag2 writer");
} // }
uint8_t tag_modulation; uint8_t tag_modulation;
size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit

View file

@ -17,9 +17,9 @@
#define READP0CMD "1100000111" #define READP0CMD "1100000111"
#define ERROR_RESPONSE "F402889C" #define ERROR_RESPONSE "F402889C"
extern const uint8_t Hitag2Sync[5]; static const uint8_t Hitag2Sync[5];
extern bool CryptoActive; static bool CryptoActive;
extern Hitag_State Hitag_Crypto_State; static Hitag_State Hitag_Crypto_State;
// hitag2_crack implements the first crack algorithm described in the paper, // hitag2_crack implements the first crack algorithm described in the paper,
// Gone In 360 Seconds by Verdult, Garcia and Balasch. // Gone In 360 Seconds by Verdult, Garcia and Balasch.

View file

@ -48,8 +48,7 @@ static int temp2 = 0;
static int sof_bits; // number of start-of-frame bits static int sof_bits; // number of start-of-frame bits
static uint8_t pwdh0, pwdl0, pwdl1; // password bytes static uint8_t pwdh0, pwdl0, pwdl1; // password bytes
static uint32_t rnd = 0x74124485; // randomnumber static uint32_t rnd = 0x74124485; // randomnumber
size_t blocknr; static bool end = false;
bool end = false;
//#define SENDBIT_TEST //#define SENDBIT_TEST
/* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3 /* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3
@ -110,7 +109,7 @@ bool end = false;
* Implementation of the crc8 calculation from Hitag S * Implementation of the crc8 calculation from Hitag S
* from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf * from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf
*/ */
void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitcount) { static void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitcount) {
*crc ^= data; // crc = crc (exor) data *crc ^= data; // crc = crc (exor) data
do { do {
if (*crc & 0x80) { // if (MSB-CRC == 1) if (*crc & 0x80) { // if (MSB-CRC == 1)
@ -333,7 +332,7 @@ static int check_select(uint8_t *rx, uint32_t uid) {
return 0; return 0;
} }
void hitagS_set_frame_modulation() { static void hitagS_set_frame_modulation(void) {
switch (tag.mode) { switch (tag.mode) {
case HT_STANDARD: case HT_STANDARD:
sof_bits = 1; sof_bits = 1;
@ -434,8 +433,8 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
temp2++; temp2++;
*txlen = 32; *txlen = 32;
state = _hitag2_init(REV64(tag.key), state = _hitag2_init(REV64(tag.key),
REV32(tag.pages[0][0]), REV32((tag.pages[0][3] << 24) + (tag.pages[0][2] << 16) + (tag.pages[0][1] << 8) + tag.pages[0][0]),
REV32(((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0])) REV32((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0])
); );
Dbprintf(",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", Dbprintf(",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}",
rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]);
@ -446,7 +445,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
_hitag2_byte(&state); _hitag2_byte(&state);
//send con2, pwdh0, pwdl0, pwdl1 encrypted as a response //send con2, pwdh0, pwdl0, pwdl1 encrypted as a response
tx[0] = _hitag2_byte(&state) ^ ((tag.pages[0][1] >> 16) & 0xff); tx[0] = _hitag2_byte(&state) ^ tag.pages[1][2];
tx[1] = _hitag2_byte(&state) ^ tag.pwdh0; tx[1] = _hitag2_byte(&state) ^ tag.pwdh0;
tx[2] = _hitag2_byte(&state) ^ tag.pwdl0; tx[2] = _hitag2_byte(&state) ^ tag.pwdl0;
tx[3] = _hitag2_byte(&state) ^ tag.pwdl1; tx[3] = _hitag2_byte(&state) ^ tag.pwdl1;
@ -454,7 +453,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
//add crc8 //add crc8
*txlen = 40; *txlen = 40;
crc = CRC_PRESET; crc = CRC_PRESET;
calc_crc(&crc, ((tag.pages[0][1] >> 16) & 0xff), 8); calc_crc(&crc, tag.pages[1][2], 8);
calc_crc(&crc, tag.pwdh0, 8); calc_crc(&crc, tag.pwdh0, 8);
calc_crc(&crc, tag.pwdl0, 8); calc_crc(&crc, tag.pwdl0, 8);
calc_crc(&crc, tag.pwdl1, 8); calc_crc(&crc, tag.pwdl1, 8);
@ -466,10 +465,16 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
if (temp2 % 2 == 0) { if (temp2 % 2 == 0) {
tag.uid = 0x11223344; tag.uid = 0x11223344;
tag.pages[0][0] = 0x44332211; tag.pages[0][0] = 0x11;
tag.pages[0][1] = 0x22;
tag.pages[0][2] = 0x33;
tag.pages[0][3] = 0x44;
} else { } else {
tag.uid = 0x55667788; tag.uid = 0x55667788;
tag.pages[0][0] = 0x88776655; tag.pages[0][0] = 0x55;
tag.pages[0][1] = 0x66;
tag.pages[0][2] = 0x77;
tag.pages[0][3] = 0x88;
} }
*/ */
} }
@ -480,16 +485,20 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen,
//data received to be written //data received to be written
if (tag.tstate == HT_WRITING_PAGE_DATA) { if (tag.tstate == HT_WRITING_PAGE_DATA) {
tag.tstate = HT_NO_OP; tag.tstate = HT_NO_OP;
tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] tag.pages[page_to_be_written][0] = rx[0];
<< 0) + (rx[1] << 8) + (rx[2] << 16) + (rx[3] << 24); tag.pages[page_to_be_written][1] = rx[1];
tag.pages[page_to_be_written][2] = rx[2];
tag.pages[page_to_be_written][3] = rx[3];
//send ack //send ack
*txlen = 2; *txlen = 2;
tx[0] = 0x40; tx[0] = 0x40;
page_to_be_written = 0; page_to_be_written = 0;
hitagS_set_frame_modulation(); hitagS_set_frame_modulation();
} else if (tag.tstate == HT_WRITING_BLOCK_DATA) { } else if (tag.tstate == HT_WRITING_BLOCK_DATA) {
tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] tag.pages[page_to_be_written][0] = rx[0];
<< 24) + (rx[1] << 16) + (rx[2] << 8) + rx[3]; tag.pages[page_to_be_written][1] = rx[1];
tag.pages[page_to_be_written][2] = rx[2];
tag.pages[page_to_be_written][3] = rx[3];
//send ack //send ack
*txlen = 2; *txlen = 2;
tx[0] = 0x40; tx[0] = 0x40;
@ -889,9 +898,12 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) {
} }
tag.uid = ((tag.pages[0][3]) << 24) | ((tag.pages[0][2]) << 16) | ((tag.pages[0][1]) << 8) | tag.pages[0][0]; tag.uid = ((tag.pages[0][3]) << 24) | ((tag.pages[0][2]) << 16) | ((tag.pages[0][1]) << 8) | tag.pages[0][0];
tag.key = ((tag.pages[3][3]) << 24) | ((tag.pages[3][2]) << 16) | ((tag.pages[3][1]) << 8) | tag.pages[3][0]; tag.key = (((uint64_t)tag.pages[3][3]) << 40) |
tag.key <<= 16; (((uint64_t)tag.pages[3][2]) << 32) |
tag.key += ((tag.pages[2][3]) << 8) + tag.pages[2][2]; (((uint64_t)tag.pages[3][1]) << 24) |
(((uint64_t)tag.pages[3][0]) << 16) |
(((uint64_t)tag.pages[2][3]) << 8) |
(((uint64_t)tag.pages[2][2]));
tag.pwdl0 = tag.pages[2][0]; tag.pwdl0 = tag.pages[2][0];
tag.pwdl1 = tag.pages[2][1]; tag.pwdl1 = tag.pages[2][1];
tag.pwdh0 = tag.pages[1][3]; tag.pwdh0 = tag.pages[1][3];
@ -1027,7 +1039,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) {
// Check if frame was captured // Check if frame was captured
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, 0, NULL, true); LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
// Disable timer 1 with external trigger to avoid triggers during our own modulation // Disable timer 1 with external trigger to avoid triggers during our own modulation
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
@ -1075,7 +1087,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) {
DbpString("Sim Stopped"); DbpString("Sim Stopped");
} }
void hitagS_receive_frame(uint8_t *rx, size_t *rxlen, int *response) { static void hitagS_receive_frame(uint8_t *rx, size_t *rxlen, int *response) {
// Reset values for receiving frames // Reset values for receiving frames
memset(rx, 0x00, HITAG_FRAME_LEN * sizeof(uint8_t)); memset(rx, 0x00, HITAG_FRAME_LEN * sizeof(uint8_t));
@ -1269,7 +1281,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
// Check if frame was captured and store it // Check if frame was captured and store it
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
} }
// By default reset the transmission buffer // By default reset the transmission buffer
@ -1398,7 +1410,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
// Add transmitted frame to total count // Add transmitted frame to total count
if (txlen > 0) { if (txlen > 0) {
// frame_count++; // frame_count++;
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
} }
hitagS_receive_frame(rx, &rxlen, &response); hitagS_receive_frame(rx, &rxlen, &response);
@ -1526,7 +1538,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
// Check if frame was captured and store it // Check if frame was captured and store it
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
} }
//check for valid input //check for valid input
@ -1613,7 +1625,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
// Add transmitted frame to total count // Add transmitted frame to total count
if (txlen > 0) { if (txlen > 0) {
// frame_count++; // frame_count++;
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
} }
hitagS_receive_frame(rx, &rxlen, &response); hitagS_receive_frame(rx, &rxlen, &response);
@ -1645,7 +1657,7 @@ void check_challenges(bool file_given, uint8_t *data) {
size_t rxlen = 0; size_t rxlen = 0;
uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t txbuf[HITAG_FRAME_LEN];
int t_wait = HITAG_T_WAIT_MAX; int t_wait = HITAG_T_WAIT_MAX;
int lastbit, STATE = 0;; int lastbit, STATE = 0;
bool bStop; bool bStop;
int response_bit[200]; int response_bit[200];
unsigned char mask = 1; unsigned char mask = 1;
@ -1720,7 +1732,7 @@ void check_challenges(bool file_given, uint8_t *data) {
// Check if frame was captured and store it // Check if frame was captured and store it
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
} }
uint8_t *tx = txbuf; uint8_t *tx = txbuf;
@ -1852,7 +1864,7 @@ void check_challenges(bool file_given, uint8_t *data) {
// Add transmitted frame to total count // Add transmitted frame to total count
if (txlen > 0) { if (txlen > 0) {
// frame_count++; // frame_count++;
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
} }
hitagS_receive_frame(rx, &rxlen, &response); hitagS_receive_frame(rx, &rxlen, &response);

View file

@ -27,19 +27,19 @@
#define SDA_H HIGH(GPIO_SDA) #define SDA_H HIGH(GPIO_SDA)
#define SDA_L LOW(GPIO_SDA) #define SDA_L LOW(GPIO_SDA)
#define SCL_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) #define SCL_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) == GPIO_SCL)
#define SDA_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) #define SDA_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) == GPIO_SDA)
#define I2C_ERROR "I2C_WaitAck Error" #define I2C_ERROR "I2C_WaitAck Error"
volatile unsigned long c; static volatile uint32_t c;
// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz, // Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
// delay=1 is about 200kbps // delay=1 is about 200kbps
// timer. // timer.
// I2CSpinDelayClk(4) = 12.31us // I2CSpinDelayClk(4) = 12.31us
// I2CSpinDelayClk(1) = 3.07us // I2CSpinDelayClk(1) = 3.07us
void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
for (c = delay * 2; c; c--) {}; for (c = delay * 2; c; c--) {};
} }
@ -47,6 +47,12 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
#define I2C_DELAY_2CLK I2CSpinDelayClk(2) #define I2C_DELAY_2CLK I2CSpinDelayClk(2)
#define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
#define I2C_DELAY_100us I2CSpinDelayClk( 100 / 3)
#define I2C_DELAY_600us I2CSpinDelayClk( 600 / 3)
#define I2C_DELAY_10ms I2CSpinDelayClk( 10 * 1000 / 3 )
#define I2C_DELAY_30ms I2CSpinDelayClk( 30 * 1000 / 3 )
#define I2C_DELAY_100ms I2CSpinDelayClk( 100 * 1000 / 3)
#define ISO7618_MAX_FRAME 255 #define ISO7618_MAX_FRAME 255
// try i2c bus recovery at 100kHz = 5us high, 5us low // try i2c bus recovery at 100kHz = 5us high, 5us low
@ -69,6 +75,7 @@ void I2C_recovery(void) {
//a STOP signal (SDA from low to high while CLK is high) //a STOP signal (SDA from low to high while CLK is high)
SDA_L; SDA_L;
WaitUS(5); WaitUS(5);
SCL_H; SCL_H;
WaitUS(2); WaitUS(2);
SDA_H; SDA_H;
@ -127,11 +134,11 @@ void I2C_Reset_EnterMainProgram(void) {
StartTicks(); StartTicks();
I2C_init(); I2C_init();
I2C_SetResetStatus(0, 0, 0); I2C_SetResetStatus(0, 0, 0);
WaitMS(30); I2C_DELAY_30ms;
I2C_SetResetStatus(1, 0, 0); I2C_SetResetStatus(1, 0, 0);
WaitMS(30); I2C_DELAY_30ms;
I2C_SetResetStatus(1, 1, 1); I2C_SetResetStatus(1, 1, 1);
WaitMS(10); I2C_DELAY_10ms;
} }
// Reset the SIM_Adapter, then enter the bootloader program // Reset the SIM_Adapter, then enter the bootloader program
@ -140,13 +147,13 @@ void I2C_Reset_EnterBootloader(void) {
StartTicks(); StartTicks();
I2C_init(); I2C_init();
I2C_SetResetStatus(0, 1, 1); I2C_SetResetStatus(0, 1, 1);
WaitMS(100); I2C_DELAY_100ms;
I2C_SetResetStatus(1, 1, 1); I2C_SetResetStatus(1, 1, 1);
WaitMS(10); I2C_DELAY_10ms;
} }
// Wait for the clock to go High. // Wait for the clock to go High.
bool WaitSCL_H_delay(uint32_t delay) { static bool WaitSCL_H_delay(uint32_t delay) {
while (delay--) { while (delay--) {
if (SCL_read) { if (SCL_read) {
return true; return true;
@ -158,11 +165,11 @@ bool WaitSCL_H_delay(uint32_t delay) {
// 5000 * 3.07us = 15350us. 15.35ms // 5000 * 3.07us = 15350us. 15.35ms
// 15000 * 3.07us = 46050us. 46.05ms // 15000 * 3.07us = 46050us. 46.05ms
bool WaitSCL_H(void) { static bool WaitSCL_H(void) {
return WaitSCL_H_delay(15000); return WaitSCL_H_delay(15000);
} }
bool WaitSCL_L_delay(uint32_t delay) { static bool WaitSCL_L_delay(uint32_t delay) {
while (delay--) { while (delay--) {
if (!SCL_read) { if (!SCL_read) {
return true; return true;
@ -172,26 +179,26 @@ bool WaitSCL_L_delay(uint32_t delay) {
return false; return false;
} }
// 5000 * 3.07us = 15350us. 15.35ms // 5000 * 3.07us = 15350us. 15.35ms
bool WaitSCL_L(void) { static bool WaitSCL_L(void) {
return WaitSCL_L_delay(15000); return WaitSCL_L_delay(15000);
} }
// Wait max 1800ms or until SCL goes LOW. // Wait max 1800ms or until SCL goes LOW.
// It timeout reading response from card // It timeout reading response from card
// Which ever comes first // Which ever comes first
bool WaitSCL_L_timeout(void) { static bool WaitSCL_L_timeout(void) {
volatile uint16_t delay = 1800; volatile uint32_t delay = 18000;
while (delay--) { while (delay--) {
// exit on SCL LOW // exit on SCL LOW
if (!SCL_read) if (!SCL_read)
return true; return true;
WaitMS(1); I2C_DELAY_100us;
} }
return (delay == 0); return (delay == 0);
} }
bool I2C_Start(void) { static bool I2C_Start(void) {
I2C_DELAY_XCLK(4); I2C_DELAY_XCLK(4);
SDA_H; SDA_H;
@ -209,7 +216,7 @@ bool I2C_Start(void) {
return true; return true;
} }
bool I2C_WaitForSim() { static bool I2C_WaitForSim(void) {
// wait for data from card // wait for data from card
if (!WaitSCL_L_timeout()) if (!WaitSCL_L_timeout())
@ -218,14 +225,14 @@ bool I2C_WaitForSim() {
// 8051 speaks with smart card. // 8051 speaks with smart card.
// 1000*50*3.07 = 153.5ms // 1000*50*3.07 = 153.5ms
// 1byte transfer == 1ms with max frame being 256bytes // 1byte transfer == 1ms with max frame being 256bytes
if (!WaitSCL_H_delay(10 * 1000 * 50)) if (!WaitSCL_H_delay(20 * 1000 * 50))
return false; return false;
return true; return true;
} }
// send i2c STOP // send i2c STOP
void I2C_Stop(void) { static void I2C_Stop(void) {
SCL_L; SCL_L;
I2C_DELAY_2CLK; I2C_DELAY_2CLK;
SDA_L; SDA_L;
@ -238,7 +245,7 @@ void I2C_Stop(void) {
} }
// Send i2c ACK // Send i2c ACK
void I2C_Ack(void) { static void I2C_Ack(void) {
SCL_L; SCL_L;
I2C_DELAY_2CLK; I2C_DELAY_2CLK;
SDA_L; SDA_L;
@ -251,7 +258,7 @@ void I2C_Ack(void) {
} }
// Send i2c NACK // Send i2c NACK
void I2C_NoAck(void) { static void I2C_NoAck(void) {
SCL_L; SCL_L;
I2C_DELAY_2CLK; I2C_DELAY_2CLK;
SDA_H; SDA_H;
@ -263,7 +270,7 @@ void I2C_NoAck(void) {
I2C_DELAY_2CLK; I2C_DELAY_2CLK;
} }
bool I2C_WaitAck(void) { static bool I2C_WaitAck(void) {
SCL_L; SCL_L;
I2C_DELAY_1CLK; I2C_DELAY_1CLK;
SDA_H; SDA_H;
@ -282,7 +289,7 @@ bool I2C_WaitAck(void) {
return true; return true;
} }
void I2C_SendByte(uint8_t data) { static void I2C_SendByte(uint8_t data) {
uint8_t bits = 8; uint8_t bits = 8;
while (bits--) { while (bits--) {
@ -308,7 +315,7 @@ void I2C_SendByte(uint8_t data) {
SCL_L; SCL_L;
} }
int16_t I2C_ReadByte(void) { static int16_t I2C_ReadByte(void) {
uint8_t bits = 8, b = 0; uint8_t bits = 8, b = 0;
SDA_H; SDA_H;
@ -433,7 +440,9 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
// extra wait 500us (514us measured) // extra wait 500us (514us measured)
// 200us (xx measured) // 200us (xx measured)
WaitUS(600); // WaitUS(600);
I2C_DELAY_600us;
bool bBreak = true; bool bBreak = true;
uint16_t readcount = 0; uint16_t readcount = 0;
@ -474,7 +483,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
*data = (uint8_t)tmp & 0xFF; *data = (uint8_t)tmp & 0xFF;
len--; len--;
// 读取的第一个字节为后续长度
// The first byte in response is the message length // The first byte in response is the message length
if (!readcount && (len > *data)) { if (!readcount && (len > *data)) {
len = *data; len = *data;
@ -601,7 +610,7 @@ bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t d
} }
void I2C_print_status(void) { void I2C_print_status(void) {
DbpString(_BLUE_("Smart card module (ISO 7816)")); DbpString(_CYAN_("Smart card module (ISO 7816)"));
uint8_t maj, min; uint8_t maj, min;
if (I2C_get_version(&maj, &min) == PM3_SUCCESS) if (I2C_get_version(&maj, &min) == PM3_SUCCESS)
Dbprintf(" version................." _YELLOW_("v%x.%02d"), maj, min); Dbprintf(" version................." _YELLOW_("v%x.%02d"), maj, min);
@ -617,13 +626,12 @@ int I2C_get_version(uint8_t *maj, uint8_t *min) {
*maj = resp[0]; *maj = resp[0];
*min = resp[1]; *min = resp[1];
return PM3_SUCCESS; return PM3_SUCCESS;
} else {
return PM3_EDEVNOTSUPP;
} }
return PM3_EDEVNOTSUPP;
} }
// Will read response from smart card module, retries 3 times to get the data. // Will read response from smart card module, retries 3 times to get the data.
bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) { static bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) {
uint8_t i = 3; uint8_t i = 3;
int16_t len = 0; int16_t len = 0;
@ -799,7 +807,8 @@ void SmartCardUpgrade(uint64_t arg0) {
} }
// writing takes time. // writing takes time.
WaitMS(50); // WaitMS(50);
I2C_DELAY_100ms;
// read // read
res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);

View file

@ -520,7 +520,7 @@ static RAMFUNC int OutOfNDecoding(int bit) {
// Manchester // Manchester
//============================================================================= //=============================================================================
static tDemodIc Demod; static tDemodIc Demod;
static void DemodIcReset() { static void DemodIcReset(void) {
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.posCount = 0; Demod.posCount = 0;
Demod.syncBit = 0; Demod.syncBit = 0;
@ -985,7 +985,7 @@ void RAMFUNC SniffIClass(void) {
switch_off(); switch_off();
} }
void rotateCSN(uint8_t *originalCSN, uint8_t *rotatedCSN) { static void rotateCSN(uint8_t *originalCSN, uint8_t *rotatedCSN) {
int i; int i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i + 1) % 8] << 5); rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i + 1) % 8] << 5);
@ -1146,7 +1146,7 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) {
} }
// Only SOF // Only SOF
static void CodeIClassTagSOF() { static void CodeIClassTagSOF(void) {
//So far a dummy implementation, not used //So far a dummy implementation, not used
//int lastProxToAirDuration =0; //int lastProxToAirDuration =0;
@ -1757,7 +1757,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *wait) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare iClass reader command to send to FPGA // Prepare iClass reader command to send to FPGA
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CodeIClassCommand(const uint8_t *cmd, int len) { static void CodeIClassCommand(const uint8_t *cmd, int len) {
int i, j, k; int i, j, k;
ToSendReset(); ToSendReset();
@ -1793,7 +1793,7 @@ void CodeIClassCommand(const uint8_t *cmd, int len) {
ToSendMax++; ToSendMax++;
} }
void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) { static void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) {
// This is tied to other size changes // This is tied to other size changes
CodeIClassCommand(frame, len); CodeIClassCommand(frame, len);
@ -1802,9 +1802,9 @@ void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) {
TransmitIClassCommand(ToSend, ToSendMax, &wait); TransmitIClassCommand(ToSend, ToSendMax, &wait);
LED_A_ON(); LED_A_ON();
LogTrace(frame, len, rsamples, rsamples, NULL, true); LogTrace(frame, len, g_rsamples, g_rsamples, NULL, true);
} }
void ReaderTransmitIClass(uint8_t *frame, int len) { static void ReaderTransmitIClass(uint8_t *frame, int len) {
ReaderTransmitIClass_ext(frame, len, 330); ReaderTransmitIClass_ext(frame, len, 330);
} }
@ -1862,16 +1862,16 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) {
return false; return false;
} }
int ReaderReceiveIClass(uint8_t *receivedAnswer) { static int ReaderReceiveIClass(uint8_t *receivedAnswer) {
if (GetIClassAnswer(receivedAnswer, 0, NULL) == false) if (GetIClassAnswer(receivedAnswer, 0, NULL) == false)
return 0; return 0;
LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); LogTrace(receivedAnswer, Demod.len, g_rsamples, g_rsamples, NULL, false);
return Demod.len; return Demod.len;
} }
void setupIclassReader() { static void setupIclassReader(void) {
LEDsoff(); LEDsoff();
@ -1898,7 +1898,7 @@ void setupIclassReader() {
LED_A_ON(); LED_A_ON();
} }
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) { static bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) {
while (retries-- > 0) { while (retries-- > 0) {
ReaderTransmitIClass(command, cmdsize); ReaderTransmitIClass(command, cmdsize);
@ -1935,7 +1935,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re
* 1 = Got CSN * 1 = Got CSN
* 2 = Got CSN and CC * 2 = Got CSN and CC
*/ */
uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { static uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
// act_all... // act_all...
static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
@ -2000,7 +2000,7 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
// we got all data; // we got all data;
return 2; return 2;
} }
uint8_t handshakeIclassTag(uint8_t *card_data) { static uint8_t handshakeIclassTag(uint8_t *card_data) {
return handshakeIclassTag_ext(card_data, false); return handshakeIclassTag_ext(card_data, false);
} }
@ -2458,7 +2458,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
BigBuf_free(); BigBuf_free();
} }
bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) { static 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 resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t write[] = { 0x80 | 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 memcpy(write + 2, data, 12); // data + mac

View file

@ -31,9 +31,9 @@ static uint32_t iso14a_timeout;
// if iso14443a not active - transmit/receive dont try to execute // if iso14443a not active - transmit/receive dont try to execute
static bool hf_field_active = false; static bool hf_field_active = false;
uint8_t colpos = 0; static uint8_t colpos = 0;
int rsamples = 0; int g_rsamples = 0;
uint8_t trigger = 0; uint8_t g_trigger = 0;
// the block number for the ISO14443-4 PCB // the block number for the ISO14443-4 PCB
static uint8_t iso14_pcb_blocknum = 0; static uint8_t iso14_pcb_blocknum = 0;
@ -67,7 +67,7 @@ static uint8_t iso14_pcb_blocknum = 0;
#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1) #define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1)
// The FPGA will report its internal sending delay in // The FPGA will report its internal sending delay in
uint16_t FpgaSendQueueDelay; static uint16_t FpgaSendQueueDelay;
// the 5 first bits are the number of bits buffered in mod_sig_buf // the 5 first bits are the number of bits buffered in mod_sig_buf
// the last three bits are the remaining ticks/2 after the mod_sig_buf shift // the last three bits are the remaining ticks/2 after the mod_sig_buf shift
#define DELAY_FPGA_QUEUE (FpgaSendQueueDelay<<1) #define DELAY_FPGA_QUEUE (FpgaSendQueueDelay<<1)
@ -123,7 +123,7 @@ static uint32_t LastProxToAirDuration;
#define SEC_Z 0xc0 #define SEC_Z 0xc0
void iso14a_set_trigger(bool enable) { void iso14a_set_trigger(bool enable) {
trigger = enable; g_trigger = enable;
} }
void iso14a_set_timeout(uint32_t timeout) { void iso14a_set_timeout(uint32_t timeout) {
@ -184,14 +184,14 @@ static tUart14a Uart;
// 0011 - a 2 tick wide pause, or a three tick wide pause shifted left // 0011 - a 2 tick wide pause, or a three tick wide pause shifted left
// 0111 - a 2 tick wide pause shifted left // 0111 - a 2 tick wide pause shifted left
// 1001 - a 2 tick wide pause shifted right // 1001 - a 2 tick wide pause shifted right
const bool Mod_Miller_LUT[] = { static const bool Mod_Miller_LUT[] = {
false, true, false, true, false, false, false, true, false, true, false, true, false, false, false, true,
false, true, false, false, false, false, false, false false, true, false, false, false, false, false, false
}; };
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
tUart14a *GetUart14a() { tUart14a *GetUart14a(void) {
return &Uart; return &Uart;
} }
@ -351,11 +351,11 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
// 8 ticks modulated: A collision. Save the collision position and treat as Sequence D // 8 ticks modulated: A collision. Save the collision position and treat as Sequence D
// Note 1: the bitstream may start at any time. We therefore need to sync. // Note 1: the bitstream may start at any time. We therefore need to sync.
// Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only) // Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only)
tDemod14a Demod; static tDemod14a Demod;
// Lookup-Table to decide if 4 raw bits are a modulation. // Lookup-Table to decide if 4 raw bits are a modulation.
// We accept three or four "1" in any position // We accept three or four "1" in any position
const bool Mod_Manchester_LUT[] = { static const bool Mod_Manchester_LUT[] = {
false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true,
false, false, false, true, false, true, true, true false, false, false, true, false, true, true, true
}; };
@ -363,7 +363,7 @@ const bool Mod_Manchester_LUT[] = {
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4]) #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
#define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])
tDemod14a *GetDemod14a() { tDemod14a *GetDemod14a(void) {
return &Demod; return &Demod;
} }
void Demod14aReset(void) { void Demod14aReset(void) {
@ -480,7 +480,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. // Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits.
RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { static RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) {
Demod.twoBits = (Demod.twoBits << 8) | bit; Demod.twoBits = (Demod.twoBits << 8) | bit;
if (Demod.state == DEMOD_14A_UNSYNCD) { if (Demod.state == DEMOD_14A_UNSYNCD) {
@ -1150,8 +1150,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
// Such a response is less time critical, so we can prepare them on the fly // Such a response is less time critical, so we can prepare them on the fly
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64 #define DYNAMIC_RESPONSE_BUFFER_SIZE 64
#define DYNAMIC_MODULATION_BUFFER_SIZE 512 #define DYNAMIC_MODULATION_BUFFER_SIZE 512
uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE]; uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0};
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE]; uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0};
tag_response_info_t dynamic_response_info = { tag_response_info_t dynamic_response_info = {
.response = dynamic_response_buffer, .response = dynamic_response_buffer,
.response_n = 0, .response_n = 0,
@ -1613,7 +1613,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
// prepare a delayed transfer. This simply shifts ToSend[] by a number // prepare a delayed transfer. This simply shifts ToSend[] by a number
// of bits specified in the delay parameter. // of bits specified in the delay parameter.
void PrepareDelayedTransfer(uint16_t delay) { static void PrepareDelayedTransfer(uint16_t delay) {
delay &= 0x07; delay &= 0x07;
if (!delay) return; if (!delay) return;
@ -1683,7 +1683,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare reader command (in bits, support short frames) to send to FPGA // Prepare reader command (in bits, support short frames) to send to FPGA
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *par) { static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *par) {
int last = 0; int last = 0;
ToSendReset(); ToSendReset();
@ -1759,10 +1759,11 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare reader command to send to FPGA // Prepare reader command to send to FPGA
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *par) { /*
static void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *par) {
CodeIso14443aBitsAsReaderPar(cmd, len * 8, par); CodeIso14443aBitsAsReaderPar(cmd, len * 8, par);
} }
*/
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Wait for commands from reader // Wait for commands from reader
// Stop when button is pressed (return 1) or field was gone (return 2) // Stop when button is pressed (return 1) or field was gone (return 2)
@ -2144,7 +2145,7 @@ void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t
CodeIso14443aBitsAsReaderPar(frame, bits, par); CodeIso14443aBitsAsReaderPar(frame, bits, par);
// Send command to tag // Send command to tag
TransmitFor14443a(ToSend, ToSendMax, timing); TransmitFor14443a(ToSend, ToSendMax, timing);
if (trigger) LED_A_ON(); if (g_trigger) LED_A_ON();
LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true); LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true);
} }
@ -2153,7 +2154,7 @@ void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *tim
ReaderTransmitBitsPar(frame, len * 8, par, timing); ReaderTransmitBitsPar(frame, len * 8, par, timing);
} }
void ReaderTransmitBits(uint8_t *frame, uint16_t len, uint32_t *timing) { static void ReaderTransmitBits(uint8_t *frame, uint16_t len, uint32_t *timing) {
// Generate parity and redirect // Generate parity and redirect
uint8_t par[MAX_PARITY_SIZE] = {0x00}; uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(frame, len / 8, par); GetParity(frame, len / 8, par);
@ -2167,7 +2168,7 @@ void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing) {
ReaderTransmitBitsPar(frame, len * 8, par, timing); ReaderTransmitBitsPar(frame, len * 8, par, timing);
} }
int ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *par) { static int ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *par) {
if (!GetIso14443aAnswerFromTag(receivedAnswer, par, offset)) if (!GetIso14443aAnswerFromTag(receivedAnswer, par, offset))
return false; return false;
LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false); LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false);
@ -2769,7 +2770,7 @@ OUT:
// Determine the distance between two nonces. // Determine the distance between two nonces.
// Assume that the difference is small, but we don't know which is first. // Assume that the difference is small, but we don't know which is first.
// Therefore try in alternating directions. // Therefore try in alternating directions.
int32_t dist_nt(uint32_t nt1, uint32_t nt2) { static int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
if (nt1 == nt2) return 0; if (nt1 == nt2) return 0;

View file

@ -91,7 +91,7 @@ static struct {
uint8_t *output; uint8_t *output;
} Uart; } Uart;
static void Uart14bReset() { static void Uart14bReset(void) {
Uart.state = STATE_14B_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
Uart.shiftReg = 0; Uart.shiftReg = 0;
Uart.bitCnt = 0; Uart.bitCnt = 0;
@ -134,7 +134,7 @@ static struct {
} Demod; } Demod;
// Clear out the state of the "UART" that receives from the tag. // Clear out the state of the "UART" that receives from the tag.
static void Demod14bReset() { static void Demod14bReset(void) {
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.posCount = 0; Demod.posCount = 0;
@ -641,9 +641,9 @@ void SimulateIso14443bTag(uint32_t pupi) {
if (cardSTATE == SIM_NOFIELD) { if (cardSTATE == SIM_NOFIELD) {
#if defined RDV4 #if defined RDV4
vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
#else #else
vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
#endif #endif
if (vHf > MF_MINFIELDV) { if (vHf > MF_MINFIELDV) {
cardSTATE = SIM_IDLE; cardSTATE = SIM_IDLE;
@ -765,7 +765,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) {
// The soft decision on the bit uses an estimate of just the // The soft decision on the bit uses an estimate of just the
// quadrant of the reference angle, not the exact angle. // quadrant of the reference angle, not the exact angle.
#define MAKE_SOFT_DECISION() { \ #define MAKE_SOFT_DECISION(void) { \
if (Demod.sumI > 0) { \ if (Demod.sumI > 0) { \
v = ci; \ v = ci; \
} else { \ } else { \
@ -780,7 +780,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) {
// Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by abs(ci) + abs(cq) // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by abs(ci) + abs(cq)
// Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq))) // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq)))
#define CHECK_FOR_SUBCARRIER_old() { \ #define CHECK_FOR_SUBCARRIER_old(void) { \
if (ci < 0) { \ if (ci < 0) { \
if (cq < 0) { /* ci < 0, cq < 0 */ \ if (cq < 0) { /* ci < 0, cq < 0 */ \
if (cq < ci) { \ if (cq < ci) { \
@ -813,7 +813,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) {
} }
//note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow //note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow
#define CHECK_FOR_SUBCARRIER() { v = MAX(myI, myQ) + (MIN(myI, myQ) >> 1); } #define CHECK_FOR_SUBCARRIER(void) { v = MAX(myI, myQ) + (MIN(myI, myQ) >> 1); }
switch (Demod.state) { switch (Demod.state) {
case DEMOD_UNSYNCD: case DEMOD_UNSYNCD:
@ -964,7 +964,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) {
* Demodulate the samples we received from the tag, also log to tracebuffer * Demodulate the samples we received from the tag, also log to tracebuffer
* quiet: set to 'TRUE' to disable debug output * quiet: set to 'TRUE' to disable debug output
*/ */
static void GetTagSamplesFor14443bDemod() { static void GetTagSamplesFor14443bDemod(void) {
bool finished = false; bool finished = false;
// int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; // int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
uint32_t time_0 = 0, time_stop = 0; uint32_t time_0 = 0, time_stop = 0;
@ -1150,9 +1150,9 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) {
TransmitFor14443b_AsReader(); TransmitFor14443b_AsReader();
if (trigger) LED_A_ON(); if (g_trigger) LED_A_ON();
LogTrace(cmd, len, time_start, GetCountSspClk() - time_start, NULL, true); LogTrace(cmd, len, time_start, GetCountSspClk(), NULL, true);
} }
/* Sends an APDU to the tag /* Sends an APDU to the tag
@ -1195,7 +1195,7 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r
/** /**
* SRx Initialise. * SRx Initialise.
*/ */
uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) { static uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card) {
// INITIATE command: wake up the tag using the INITIATE // INITIATE command: wake up the tag using the INITIATE
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
// SELECT command (with space for CRC) // SELECT command (with space for CRC)
@ -1332,7 +1332,7 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card) {
// Set up ISO 14443 Type B communication (similar to iso14443a_setup) // Set up ISO 14443 Type B communication (similar to iso14443a_setup)
// field is setup for "Sending as Reader" // field is setup for "Sending as Reader"
void iso14443b_setup() { void iso14443b_setup(void) {
LEDsoff(); LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -1577,8 +1577,8 @@ void RAMFUNC SniffIso14443b(void) {
switch_off(); switch_off();
} }
void iso14b_set_trigger(bool enable) { static void iso14b_set_trigger(bool enable) {
trigger = enable; g_trigger = enable;
} }
/* /*

View file

@ -26,7 +26,7 @@
# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1)
#endif #endif
void iso14443b_setup(); void iso14443b_setup(void);
uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response);
uint8_t iso14443b_select_card(iso14b_card_select_t *card); uint8_t iso14443b_select_card(iso14b_card_select_t *card);
uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card); uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card);

View file

@ -431,7 +431,7 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) {
getNext = !getNext; getNext = !getNext;
} }
} }
time_stop = GetCountSspClk() - time_0 ; time_stop = GetCountSspClk();
int len = DemodAnswer(received, buf, counter); int len = DemodAnswer(received, buf, counter);
LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false); LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false);
BigBuf_free(); BigBuf_free();
@ -478,7 +478,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elap
} }
} }
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk();
int k = DemodAnswer(received, buf, counter); int k = DemodAnswer(received, buf, counter);
LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false); LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false);
return k; return k;
@ -522,7 +522,7 @@ void AcquireRawAdcSamplesIso15693(void) {
} }
LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); LogTrace(cmd, CMD_ID_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
@ -703,7 +703,7 @@ static void BuildInventoryResponse(uint8_t *cmdout, uint8_t *uid) {
// If you do not need the answer use NULL for *recv[] // If you do not need the answer use NULL for *recv[]
// return: length of received data // return: length of received data
// logging enabled // logging enabled
int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) { static int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) {
int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0; int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0;
@ -723,7 +723,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda
uint32_t time_start = GetCountSspClk(); uint32_t time_start = GetCountSspClk();
TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait); TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait);
LogTrace(send, sendlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); LogTrace(send, sendlen, time_start << 4, GetCountSspClk() << 4, NULL, true);
// Now wait for a response // Now wait for a response
if (outdata != NULL) { if (outdata != NULL) {
@ -741,7 +741,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda
// Decodes a message from a tag and displays its metadata and content // Decodes a message from a tag and displays its metadata and content
#define DBD15STATLEN 48 #define DBD15STATLEN 48
void DbdecodeIso15693Answer(int len, uint8_t *d) { static void DbdecodeIso15693Answer(int len, uint8_t *d) {
if (len > 3) { if (len > 3) {
char status[DBD15STATLEN + 1] = {0}; char status[DBD15STATLEN + 1] = {0};
@ -825,7 +825,7 @@ void ReaderIso15693(uint32_t parameter) {
uint8_t cmd[CMD_ID_RESP] = {0}; uint8_t cmd[CMD_ID_RESP] = {0};
BuildIdentifyRequest(cmd); BuildIdentifyRequest(cmd);
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait); TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); LogTrace(cmd, CMD_ID_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true);
// Now wait for a response // Now wait for a response
answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ; answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ;
@ -906,7 +906,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
time_start = GetCountSspClk(); time_start = GetCountSspClk();
TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait); TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
LogTrace(cmd, CMD_INV_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); LogTrace(cmd, CMD_INV_RESP, time_start << 4, GetCountSspClk() << 4, NULL, true);
if (DBGLEVEL >= DBG_EXTENDED) { if (DBGLEVEL >= DBG_EXTENDED) {
Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans, Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans,

View file

@ -64,8 +64,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// I/O interface abstraction (FPGA -> ARM) // I/O interface abstraction (FPGA -> ARM)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static uint8_t rx_byte_from_fpga(void) {
static inline uint8_t rx_byte_from_fpga() {
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
@ -92,7 +91,8 @@ static inline uint8_t rx_byte_from_fpga() {
// //
// Note: The SSC receiver is never synchronized the calculation may be performed // Note: The SSC receiver is never synchronized the calculation may be performed
// on a i/q pair from two subsequent correlations, but does not matter. // on a i/q pair from two subsequent correlations, but does not matter.
static inline int32_t sample_power() { // Note: inlining this function would fail with -Os
static int32_t sample_power(void) {
int32_t q = (int8_t)rx_byte_from_fpga(); int32_t q = (int8_t)rx_byte_from_fpga();
q = ABS(q); q = ABS(q);
int32_t i = (int8_t)rx_byte_from_fpga(); int32_t i = (int8_t)rx_byte_from_fpga();
@ -108,7 +108,9 @@ static inline int32_t sample_power() {
// //
// Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame // Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame
// has a delay loop that aligns rx_bit calls to the TAG tx timeslots. // has a delay loop that aligns rx_bit calls to the TAG tx timeslots.
static inline bool rx_bit() {
// Note: inlining this function would fail with -Os
static bool rx_bit(void) {
int32_t power; int32_t power;
for (size_t i = 0; i < 5; ++i) { for (size_t i = 0; i < 5; ++i) {
@ -127,7 +129,7 @@ static inline bool rx_bit() {
// be circumvented, but the adventage over bitbang would be little. // be circumvented, but the adventage over bitbang would be little.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static inline void tx_bit(bool bit) { static void tx_bit(bool bit) {
// insert pause // insert pause
LOW(GPIO_SSC_DOUT); LOW(GPIO_SSC_DOUT);
last_frame_end += RWD_TIME_PAUSE; last_frame_end += RWD_TIME_PAUSE;
@ -206,7 +208,7 @@ static uint32_t rx_frame(uint8_t len) {
return frame; return frame;
} }
static bool rx_ack() { static bool rx_ack(void) {
// change fpga into rx mode // change fpga into rx mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_848_KHZ
@ -382,7 +384,7 @@ static int16_t read_byte(uint16_t index, uint8_t cmd_sz) {
// Transmit write command, wait until (3.6ms) the tag sends back an unencrypted // Transmit write command, wait until (3.6ms) the tag sends back an unencrypted
// ACK ('1' bit) and forward the prng time based. // ACK ('1' bit) and forward the prng time based.
bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) { static bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) {
uint32_t cmd = index << 1 | LEGIC_WRITE; // prepare command uint32_t cmd = index << 1 | LEGIC_WRITE; // prepare command
uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc
cmd |= byte << (addr_sz + 1); // append value cmd |= byte << (addr_sz + 1); // append value
@ -431,7 +433,7 @@ void LegicRfInfo(void) {
// read MCC and check against UID // read MCC and check against UID
int16_t mcc = read_byte(4, card.cmdsize); int16_t mcc = read_byte(4, card.cmdsize);
int16_t calc_mcc = CRC8Legic(card.uid, 4);; int16_t calc_mcc = CRC8Legic(card.uid, 4);
if (mcc != calc_mcc) { if (mcc != calc_mcc) {
reply_mix(CMD_ACK, 0, 0, 0, 0, 0); reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
goto OUT; goto OUT;

View file

@ -65,7 +65,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Returns true if a pulse/pause is received within timeout // Returns true if a pulse/pause is received within timeout
static inline bool wait_for(bool value, const uint32_t timeout) { // Note: inlining this function would fail with -Os
static bool wait_for(bool value, const uint32_t timeout) {
while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
if (GetCountSspClk() > timeout) { if (GetCountSspClk() > timeout) {
return false; return false;
@ -83,7 +84,7 @@ static inline bool wait_for(bool value, const uint32_t timeout) {
// - A bit length >80.2us is a 1 // - A bit length >80.2us is a 1
// - A bit length <80.2us is a 0 // - A bit length <80.2us is a 0
// - A bit length >148.6us is a code violation // - A bit length >148.6us is a code violation
static inline int8_t rx_bit() { static int8_t rx_bit(void) {
// backup ts for threshold calculation // backup ts for threshold calculation
uint32_t bit_start = last_frame_end; uint32_t bit_start = last_frame_end;
@ -126,7 +127,8 @@ static inline int8_t rx_bit() {
// Note: The Subcarrier is not disabled during bits to prevent glitches. This is // Note: The Subcarrier is not disabled during bits to prevent glitches. This is
// not mandatory but results in a cleaner signal. tx_frame will disable // not mandatory but results in a cleaner signal. tx_frame will disable
// the subcarrier when the frame is done. // the subcarrier when the frame is done.
static inline void tx_bit(bool bit) { // Note: inlining this function would fail with -Os
static void tx_bit(bool bit) {
LED_C_ON(); LED_C_ON();
if (bit) { if (bit) {
@ -177,7 +179,7 @@ static void tx_frame(uint32_t frame, uint8_t len) {
LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, false); LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, false);
} }
static void tx_ack() { static void tx_ack(void) {
// wait for ack timeslot // wait for ack timeslot
last_frame_end += TAG_ACK_WAIT; last_frame_end += TAG_ACK_WAIT;
legic_prng_forward(TAG_ACK_WAIT / TAG_BIT_PERIOD - 1); legic_prng_forward(TAG_ACK_WAIT / TAG_BIT_PERIOD - 1);
@ -298,7 +300,7 @@ static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) {
return 0; return 0;
} }
static void init_tag() { static void init_tag(void) {
// configure FPGA // configure FPGA
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR

View file

@ -25,13 +25,18 @@
// T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6 // T0 = timer/carrier = 1500kHz/125kHz = 1500000/125000 = 6
//#define HITAG_T0 3 //#define HITAG_T0 3
//////////////////////////////////////////////////////////////////////////////
// Exported global variables
//////////////////////////////////////////////////////////////////////////////
bool g_logging = true;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Global variables // Global variables
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
bool rising_edge = false; static bool rising_edge = false;
bool logging = true; static bool reader_mode = false;
bool reader_mode = false;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Auxiliary functions // Auxiliary functions
@ -46,8 +51,8 @@ bool lf_test_periods(size_t expected, size_t count) {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Low frequency (LF) adc passthrough functionality // Low frequency (LF) adc passthrough functionality
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
uint8_t previous_adc_val = 0; static uint8_t previous_adc_val = 0;
uint8_t adc_avg = 0; static uint8_t adc_avg = 0;
void lf_sample_mean(void) { void lf_sample_mean(void) {
uint8_t periods = 0; uint8_t periods = 0;
@ -65,7 +70,7 @@ void lf_sample_mean(void) {
Dbprintf("LF ADC average %u", adc_avg); Dbprintf("LF ADC average %u", adc_avg);
} }
size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
size_t periods = 0; size_t periods = 0;
volatile uint8_t adc_val; volatile uint8_t adc_val;
uint8_t avg_peak = adc_avg + 3, avg_through = adc_avg - 3; uint8_t avg_peak = adc_avg + 3, avg_through = adc_avg - 3;
@ -90,7 +95,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
adc_val = AT91C_BASE_SSC->SSC_RHR; adc_val = AT91C_BASE_SSC->SSC_RHR;
periods++; periods++;
if (logging) logSampleSimple(adc_val); if (g_logging) logSampleSimple(adc_val);
// Only test field changes if state of adc values matter // Only test field changes if state of adc values matter
if (wait == false) { if (wait == false) {
@ -120,7 +125,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
if (periods >= max) return 0; if (periods >= max) return 0;
} }
} }
if (logging) logSampleSimple(0xFF); if (g_logging) logSampleSimple(0xFF);
return 0; return 0;
} }
@ -132,7 +137,7 @@ size_t lf_detect_gap(size_t max) {
return lf_count_edge_periods_ex(max, false, true); return lf_count_edge_periods_ex(max, false, true);
} }
void lf_reset_counter() { void lf_reset_counter(void) {
// TODO: find out the correct reset settings for tag and reader mode // TODO: find out the correct reset settings for tag and reader mode
// if (reader_mode) { // if (reader_mode) {
@ -147,11 +152,11 @@ void lf_reset_counter() {
// } // }
} }
bool lf_get_tag_modulation() { bool lf_get_tag_modulation(void) {
return (rising_edge == false); return (rising_edge == false);
} }
bool lf_get_reader_modulation() { bool lf_get_reader_modulation(void) {
return rising_edge; return rising_edge;
} }
@ -223,12 +228,12 @@ void lf_init(bool reader, bool simulate) {
uint32_t bufsize = 10000; uint32_t bufsize = 10000;
// use malloc // use malloc
if (logging) initSampleBufferEx(&bufsize, true); if (g_logging) initSampleBufferEx(&bufsize, true);
lf_sample_mean(); lf_sample_mean();
} }
void lf_finalize() { void lf_finalize(void) {
// Disable timers // Disable timers
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
@ -269,7 +274,7 @@ size_t lf_detect_field_drop(size_t max) {
periods++; periods++;
volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR; volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR;
if (logging) logSampleSimple(adc_val); if (g_logging) logSampleSimple(adc_val);
if (adc_val == 0) { if (adc_val == 0) {
rising_edge = false; rising_edge = false;

View file

@ -15,21 +15,21 @@
#include "util.h" #include "util.h"
#include "string.h" #include "string.h"
extern bool logging; extern bool g_logging;
void lf_sample_mean(void); void lf_sample_mean(void);
bool lf_test_periods(size_t expected, size_t count); bool lf_test_periods(size_t expected, size_t count);
size_t lf_count_edge_periods(size_t max); size_t lf_count_edge_periods(size_t max);
size_t lf_detect_gap(size_t max); size_t lf_detect_gap(size_t max);
void lf_reset_counter(); void lf_reset_counter(void);
bool lf_get_tag_modulation(); bool lf_get_tag_modulation(void);
bool lf_get_reader_modulation(); bool lf_get_reader_modulation(void);
void lf_wait_periods(size_t periods); void lf_wait_periods(size_t periods);
//void lf_init(bool reader); //void lf_init(bool reader);
void lf_init(bool reader, bool simulate); void lf_init(bool reader, bool simulate);
void lf_finalize(); void lf_finalize(void);
size_t lf_detect_field_drop(size_t max); size_t lf_detect_field_drop(size_t max);
bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len); bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len);
void lf_modulation(bool modulation); void lf_modulation(bool modulation);

View file

@ -198,7 +198,7 @@ void printT55xxConfig(void) {
#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") " | "); #define PRN_NA sprintf(s + strlen(s), _RED_("N/A") " | ");
DbpString(_BLUE_("LF T55XX config")); DbpString(_CYAN_("LF T55XX config"));
Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]"); Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]");
Dbprintf(" mode |start|write|write|write| read|write|write"); Dbprintf(" mode |start|write|write|write| read|write|write");
Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3"); Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3");
@ -261,8 +261,9 @@ void printT55xxConfig(void) {
else else
PRN_NA; PRN_NA;
// remove last space
s[strlen(s)] = 0; s[strlen(s)] = 0;
DbpString(s); DbpStringEx(FLAG_LOG, s, sizeof(s));
} }
DbpString(""); DbpString("");
} }
@ -621,7 +622,7 @@ void ReadTItag(void) {
StopTicks(); StopTicks();
} }
void WriteTIbyte(uint8_t b) { static void WriteTIbyte(uint8_t b) {
int i = 0; int i = 0;
// modulate 8 bits out to the antenna // modulate 8 bits out to the antenna
@ -1534,7 +1535,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
calccrc &= 0xff; calccrc &= 0xff;
calccrc = 0xff - calccrc; calccrc = 0xff - calccrc;
char *crcStr = (crc == calccrc) ? "ok" : "!crc"; const char *crcStr = (crc == calccrc) ? "ok" : "!crc";
Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]", version, facilitycode, number, code, code2, crc, crcStr); Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]", version, facilitycode, number, code, code2, crc, crcStr);
// if we're only looking for one tag // if we're only looking for one tag
@ -1570,10 +1571,10 @@ void TurnReadLFOn(uint32_t delay) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
// measure antenna strength. // measure antenna strength.
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); //int adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14);
WaitUS(delay); WaitUS(delay);
} }
void TurnReadLF_off(uint32_t delay) { static void TurnReadLF_off(uint32_t delay) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(delay); WaitUS(delay);
} }
@ -1585,7 +1586,7 @@ void TurnReadLF_off(uint32_t delay) {
#define T55_LLR_REF (136 * 8) #define T55_LLR_REF (136 * 8)
// Write one bit to chip // Write one bit to chip
void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { static void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
switch (bit) { switch (bit) {
case 0 : case 0 :
@ -1621,7 +1622,7 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
// num_bits - how many bits (low x bits of data) Max 32 bits at a time // num_bits - how many bits (low x bits of data) Max 32 bits at a time
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
// returns "Next" bit offset / bits stored (for next store) // returns "Next" bit offset / bits stored (for next store)
uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { static uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) {
int8_t next_offset = start_offset; int8_t next_offset = start_offset;
// Check if data will fit. // Check if data will fit.
@ -1645,7 +1646,7 @@ uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t
} }
// Send one downlink command to the card // Send one downlink command to the card
void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) { static void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) {
/* /*
arg bits arg bits
@ -2029,7 +2030,7 @@ void T55xx_ChkPwds(uint8_t flags) {
Dbprintf("[=] Baseline determined [%u]", baseline); Dbprintf("[=] Baseline determined [%u]", baseline);
uint8_t *pwds = BigBuf_get_EM_addr(); uint8_t *pwds = BigBuf_get_EM_addr();
uint16_t pwdCount = 0; uint16_t pwd_count = 0;
uint32_t candidate = 0; uint32_t candidate = 0;
#ifdef WITH_FLASH #ifdef WITH_FLASH
@ -2040,20 +2041,27 @@ void T55xx_ChkPwds(uint8_t flags) {
if (isok != sizeof(counter)) if (isok != sizeof(counter))
goto OUT; goto OUT;
pwdCount = (uint16_t)(counter[1] << 8 | counter[0]); pwd_count = (uint16_t)(counter[1] << 8 | counter[0]);
if (pwd_count == 0)
if (pwdCount == 0 || pwdCount == 0xFFFF)
goto OUT; goto OUT;
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwdCount * 4); // since flash can report way too many pwds, we need to limit it.
if (isok != pwdCount * 4) // bigbuff EM size is determined by CARD_MEMORY_SIZE
// a password is 4bytes.
uint16_t pwd_size_available = MIN(CARD_MEMORY_SIZE, pwd_count * 4);
// adjust available pwd_count
pwd_count = pwd_size_available / 4;
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwd_size_available);
if (isok != pwd_size_available)
goto OUT; goto OUT;
Dbprintf("[=] Password dictionary count %d ", pwdCount); Dbprintf("[=] Password dictionary count %d ", pwd_count);
#endif #endif
uint32_t pwd = 0, curr = 0, prev = 0; uint32_t pwd = 0, curr = 0, prev = 0;
for (uint16_t i = 0; i < pwdCount; ++i) { for (uint16_t i = 0; i < pwd_count; ++i) {
if (BUTTON_PRESS() && !data_available()) { if (BUTTON_PRESS() && !data_available()) {
goto OUT; goto OUT;
@ -2107,7 +2115,7 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) {
/*-------------- Cloning routines -----------*/ /*-------------- Cloning routines -----------*/
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { static void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
t55xx_write_block_t cmd; t55xx_write_block_t cmd;
cmd.pwd = 0; cmd.pwd = 0;
@ -2281,10 +2289,10 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
#define FWD_CMD_READ 0x9 #define FWD_CMD_READ 0x9
#define FWD_CMD_DISABLE 0x5 #define FWD_CMD_DISABLE 0x5
uint8_t forwardLink_data[64]; //array of forwarded bits static uint8_t forwardLink_data[64]; //array of forwarded bits
uint8_t *forward_ptr; //ptr for forward message preparation static uint8_t *forward_ptr; //ptr for forward message preparation
uint8_t fwd_bit_sz; //forwardlink bit counter static uint8_t fwd_bit_sz; //forwardlink bit counter
uint8_t *fwd_write_ptr; //forwardlink bit pointer static uint8_t *fwd_write_ptr; //forwardlink bit pointer
//==================================================================== //====================================================================
// prepares command bits // prepares command bits
@ -2299,7 +2307,7 @@ uint8_t *fwd_write_ptr; //forwardlink bit pointer
// These timings work for 4469/4269/4305 (with the 55*8 above) // These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 // WRITE_0 = 23*8 , 9*8
uint8_t Prepare_Cmd(uint8_t cmd) { static uint8_t Prepare_Cmd(uint8_t cmd) {
*forward_ptr++ = 0; //start bit *forward_ptr++ = 0; //start bit
*forward_ptr++ = 0; //second pause for 4050 code *forward_ptr++ = 0; //second pause for 4050 code
@ -2319,7 +2327,7 @@ uint8_t Prepare_Cmd(uint8_t cmd) {
// prepares address bits // prepares address bits
// see EM4469 spec // see EM4469 spec
//==================================================================== //====================================================================
uint8_t Prepare_Addr(uint8_t addr) { static uint8_t Prepare_Addr(uint8_t addr) {
register uint8_t line_parity; register uint8_t line_parity;
@ -2340,7 +2348,7 @@ uint8_t Prepare_Addr(uint8_t addr) {
// prepares data bits intreleaved with parity bits // prepares data bits intreleaved with parity bits
// see EM4469 spec // see EM4469 spec
//==================================================================== //====================================================================
uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) { static uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) {
register uint8_t column_parity; register uint8_t column_parity;
register uint8_t i, j; register uint8_t i, j;
@ -2376,7 +2384,7 @@ uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) {
// Requires: forwarLink_data filled with valid bits (1 bit per byte) // Requires: forwarLink_data filled with valid bits (1 bit per byte)
// fwd_bit_count set with number of bits to be sent // fwd_bit_count set with number of bits to be sent
//==================================================================== //====================================================================
void SendForward(uint8_t fwd_bit_count) { static void SendForward(uint8_t fwd_bit_count) {
// iceman, 21.3us increments for the USclock verification. // iceman, 21.3us increments for the USclock verification.
// 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead // 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead
@ -2410,7 +2418,7 @@ void SendForward(uint8_t fwd_bit_count) {
} }
} }
void EM4xLogin(uint32_t pwd) { static void EM4xLogin(uint32_t pwd) {
uint8_t len; uint8_t len;
forward_ptr = forwardLink_data; forward_ptr = forwardLink_data;
len = Prepare_Cmd(FWD_CMD_LOGIN); len = Prepare_Cmd(FWD_CMD_LOGIN);

View file

@ -15,10 +15,6 @@
#include "pm3_cmd.h" // struct #include "pm3_cmd.h" // struct
extern uint8_t decimation;
extern uint8_t bits_per_sample ;
extern bool averaging;
void AcquireRawAdcSamples125k(int divisor); void AcquireRawAdcSamples125k(int divisor);
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command); void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
void ReadTItag(void); void ReadTItag(void);

View file

@ -27,11 +27,11 @@ Default LF config is set to:
samples_to_skip = 0 samples_to_skip = 0
verbose = YES verbose = YES
*/ */
sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ; static sample_config config = { 1, 8, 1, LF_DIVISOR_125, 0, 0, 1} ;
void printConfig() { void printConfig(void) {
uint32_t d = config.divisor; uint32_t d = config.divisor;
DbpString(_BLUE_("LF Sampling config")); DbpString(_CYAN_("LF Sampling config"));
Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")" )", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")" )", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample); Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample);
Dbprintf(" [d] decimation..........%d", config.decimation); Dbprintf(" [d] decimation..........%d", config.decimation);
@ -90,7 +90,7 @@ sample_config *getSamplingConfig(void) {
* @param stream * @param stream
* @param bit * @param bit
*/ */
void pushBit(BitstreamOut *stream, uint8_t bit) { static void pushBit(BitstreamOut *stream, uint8_t bit) {
int bytepos = stream->position >> 3; // divide by 8 int bytepos = stream->position >> 3; // divide by 8
int bitpos = stream->position & 7; int bitpos = stream->position & 7;
*(stream->buffer + bytepos) &= ~(1 << (7 - bitpos)); *(stream->buffer + bytepos) &= ~(1 << (7 - bitpos));
@ -100,34 +100,37 @@ void pushBit(BitstreamOut *stream, uint8_t bit) {
} }
// Holds bit packed struct of samples. // Holds bit packed struct of samples.
BitstreamOut data = {0, 0, 0}; static BitstreamOut data = {0, 0, 0};
// internal struct to keep track of samples gathered // internal struct to keep track of samples gathered
sampling_t samples = {0, 0, 0, 0}; static sampling_t samples = {0, 0, 0, 0};
void initSampleBuffer(uint32_t *sample_size) { void initSampleBuffer(uint32_t *sample_size) {
initSampleBufferEx(sample_size, false); initSampleBufferEx(sample_size, false);
} }
void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) { void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
if (sample_size == NULL) {
Dbprintf("initSampleBufferEx, param NULL");
return;
}
BigBuf_free(); BigBuf_free();
// We can't erase the buffer now, it would drastically delay the acquisition // We can't erase the buffer now, it would drastically delay the acquisition
if (use_malloc) { if (use_malloc) {
if (sample_size == NULL || *sample_size == 0) { if (*sample_size == 0) {
*sample_size = BigBuf_max_traceLen(); *sample_size = BigBuf_max_traceLen();
data.buffer = BigBuf_get_addr(); data.buffer = BigBuf_get_addr();
} else { } else {
*sample_size = MIN(*sample_size, BigBuf_max_traceLen()); *sample_size = MIN(*sample_size, BigBuf_max_traceLen());
data.buffer = BigBuf_malloc(*sample_size); data.buffer = BigBuf_malloc(*sample_size);
} }
} else { } else {
if (sample_size == NULL || *sample_size == 0) { if (*sample_size == 0) {
*sample_size = BigBuf_max_traceLen(); *sample_size = BigBuf_max_traceLen();
} }
data.buffer = BigBuf_get_addr(); data.buffer = BigBuf_get_addr();
@ -140,7 +143,7 @@ void initSampleBufferEx(uint32_t *sample_size, bool use_malloc) {
samples.total_saved = 0; samples.total_saved = 0;
} }
uint32_t getSampleCounter() { uint32_t getSampleCounter(void) {
return samples.total_saved; return samples.total_saved;
} }
@ -256,7 +259,8 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
while (!BUTTON_PRESS()) { while (!BUTTON_PRESS()) {
// only every 1000th times, in order to save time when collecting samples. // only every 1000th times, in order to save time when collecting samples.
if (checked == 1000) { // interruptible only when logging not yet triggered
if ((checked == 1000) && (trigger_threshold > 0)) {
if (data_available()) { if (data_available()) {
checked = -1; checked = -1;
break; break;
@ -342,7 +346,7 @@ uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t samp
return DoAcquisition(1, 8, 0, trigger_threshold, verbose, sample_size, cancel_after, 0); return DoAcquisition(1, 8, 0, trigger_threshold, verbose, sample_size, cancel_after, 0);
} }
uint32_t ReadLF(bool reader_field, bool verbose, uint32_t sample_size) { static uint32_t ReadLF(bool reader_field, bool verbose, uint32_t sample_size) {
if (verbose) if (verbose)
printConfig(); printConfig();
@ -364,7 +368,7 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size) {
* Initializes the FPGA for sniffer-mode (field off), and acquires the samples. * Initializes the FPGA for sniffer-mode (field off), and acquires the samples.
* @return number of bits sampled * @return number of bits sampled
**/ **/
uint32_t SniffLF() { uint32_t SniffLF(void) {
BigBuf_Clear_ext(false); BigBuf_Clear_ext(false);
return ReadLF(false, true, 0); return ReadLF(false, true, 0);
} }
@ -522,7 +526,7 @@ void doCotagAcquisition(size_t sample_size) {
computeSignalProperties(dest, bufsize); computeSignalProperties(dest, bufsize);
} }
uint32_t doCotagAcquisitionManchester() { uint32_t doCotagAcquisitionManchester(void) {
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen(); uint16_t bufsize = BigBuf_max_traceLen();

View file

@ -40,7 +40,7 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size);
* Initializes the FPGA for sniff-mode (field off), and acquires the samples. * Initializes the FPGA for sniff-mode (field off), and acquires the samples.
* @return number of bits sampled * @return number of bits sampled
**/ **/
uint32_t SniffLF(); uint32_t SniffLF(void);
uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold, uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold,
bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip); bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip);
@ -73,7 +73,7 @@ void initSampleBuffer(uint32_t *sample_size);
void initSampleBufferEx(uint32_t *sample_size, bool use_malloc); void initSampleBufferEx(uint32_t *sample_size, bool use_malloc);
void logSampleSimple(uint8_t sample); void logSampleSimple(uint8_t sample);
void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg); void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg);
uint32_t getSampleCounter(); uint32_t getSampleCounter(void);
/** /**
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
@ -97,8 +97,8 @@ void LFSetupFPGAForADC(int divisor, bool reader_field);
*/ */
void setSamplingConfig(sample_config *sc); void setSamplingConfig(sample_config *sc);
sample_config *getSamplingConfig(); sample_config *getSamplingConfig(void);
void printConfig(); void printConfig(void);
#endif // __LFSAMPLING_H #endif // __LFSAMPLING_H

View file

@ -44,7 +44,7 @@
// send an incomplete dummy response in order to trigger the card's authentication failure timeout // send an incomplete dummy response in order to trigger the card's authentication failure timeout
#ifndef CHK_TIMEOUT #ifndef CHK_TIMEOUT
# define CHK_TIMEOUT() { \ # define CHK_TIMEOUT(void) { \
ReaderTransmit(&dummy_answer, 1, NULL); \ ReaderTransmit(&dummy_answer, 1, NULL); \
uint32_t timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT; \ uint32_t timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT; \
while (GetCountSspClk() < timeout) {}; \ while (GetCountSspClk() < timeout) {}; \
@ -627,7 +627,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
} }
// Return 1 if the nonce is invalid else return 0 // Return 1 if the nonce is invalid else return 0
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { static int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) & \ return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) & \
(oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) & \ (oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) & \
(oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))) ? 1 : 0; (oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))) ? 1 : 0;
@ -1229,7 +1229,7 @@ typedef struct chk_t {
// 2 = failed to select. // 2 = failed to select.
// 1 = wrong key // 1 = wrong key
// 0 = correct key // 0 = correct key
uint8_t chkKey(struct chk_t *c) { static uint8_t chkKey(struct chk_t *c) {
uint8_t i = 0, res = 2; uint8_t i = 0, res = 2;
while (i < 5) { while (i < 5) {
// this part is from Piwi's faster nonce collecting part in Hardnested. // this part is from Piwi's faster nonce collecting part in Hardnested.
@ -1250,7 +1250,7 @@ uint8_t chkKey(struct chk_t *c) {
return res; return res;
} }
uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { static uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
if (!iso14443a_fast_select_card(c->uid, c->cl)) if (!iso14443a_fast_select_card(c->uid, c->cl))
return 2; return 2;
@ -1275,7 +1275,7 @@ uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
return res; return res;
} }
void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { static void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) {
for (uint8_t s = 0; s < *sectorcnt; s++) { for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found A keys // skip already found A keys
@ -1293,7 +1293,7 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui
} }
} }
void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { static void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) {
for (uint8_t s = 0; s < *sectorcnt; s++) { for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found B keys // skip already found B keys
@ -1313,7 +1313,7 @@ void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui
// loop all A keys, // loop all A keys,
// when A is found but not B, try to read B. // when A is found but not B, try to read B.
void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { static void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) {
// read Block B, if A is found. // read Block B, if A is found.
for (uint8_t s = 0; s < *sectorcnt; ++s) { for (uint8_t s = 0; s < *sectorcnt; ++s) {
@ -1387,15 +1387,21 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
keyCount = size[1] << 8 | size[0]; keyCount = size[1] << 8 | size[0];
if (keyCount == 0 || keyCount == 0xFFFF) if (keyCount == 0)
goto OUT; goto OUT;
datain = BigBuf_malloc(keyCount * 6); // limit size of availlable for keys in bigbuff
// a key is 6bytes
uint16_t key_mem_available = MIN(BigBuf_get_size(), keyCount * 6);
keyCount = key_mem_available / 6;
datain = BigBuf_malloc(key_mem_available);
if (datain == NULL) if (datain == NULL)
goto OUT; goto OUT;
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET + 2, datain, keyCount * 6); isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET + 2, datain, key_mem_available);
if (isok != keyCount * 6) if (isok != key_mem_available)
goto OUT; goto OUT;
} }
@ -1702,14 +1708,16 @@ void MifareChkKeys(uint8_t *datain) {
bool found; bool found;
} PACKED keyresult; } PACKED keyresult;
keyresult.found = false; keyresult.found = false;
uint8_t blockNo, keyType; bool have_uid = false;
uint16_t keyCount;
bool clearTrace, have_uid = false; uint8_t keyType = datain[0];
uint8_t blockNo = datain[1];
bool clearTrace = datain[2];
uint16_t key_count = (datain[3] << 8) | datain[4];
uint16_t key_mem_available = MIN((PM3_CMD_DATA_SIZE - 5), key_count * 6);
key_count = key_mem_available / 6;
keyType = datain[0];
blockNo = datain[1];
clearTrace = datain[2];
keyCount = (datain[3] << 8) | datain[4];
datain += 5; datain += 5;
LEDsoff(); LEDsoff();
@ -1725,7 +1733,7 @@ void MifareChkKeys(uint8_t *datain) {
set_tracing(false); set_tracing(false);
for (i = 0; i < keyCount; i++) { for (i = 0; i < key_count; i++) {
// Iceman: use piwi's faster nonce collecting part in hardnested. // Iceman: use piwi's faster nonce collecting part in hardnested.
if (!have_uid) { // need a full select cycle to get the uid first if (!have_uid) { // need a full select cycle to get the uid first
@ -1840,7 +1848,7 @@ void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) {
int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL); int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL);
if (len != 1 || receivedAnswer[0] != CARD_ACK) { if (len != 1 || receivedAnswer[0] != CARD_ACK) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
break;; break;
} }
if (mifare_classic_halt(pcs, cuid)) { if (mifare_classic_halt(pcs, cuid)) {
@ -1932,7 +1940,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
int retval; int retval = PM3_SUCCESS;
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
retval = PM3_ESOFT; retval = PM3_ESOFT;
@ -1944,8 +1952,9 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
uint64_t ui64Key = emlGetKey(sectorNo, keytype); uint64_t ui64Key = emlGetKey(sectorNo, keytype);
if (sectorNo == 0) { if (sectorNo == 0) {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) { if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) {
retval = PM3_ESOFT;
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo); if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
break; goto out;
} }
} else { } else {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) { if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) {
@ -1971,10 +1980,8 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
} }
} }
if (mifare_classic_halt(pcs, cuid)) { int res = mifare_classic_halt(pcs, cuid);
if (DBGLEVEL > DBG_ERROR) (void)res;
Dbprintf("Halt error");
}
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished"); if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
@ -2000,9 +2007,9 @@ out:
// bit 6 - wipe tag. // bit 6 - wipe tag.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// magic uid card generation 1 commands // magic uid card generation 1 commands
uint8_t wupC1[] = { MIFARE_MAGICWUPC1 }; static uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
uint8_t wupC2[] = { MIFARE_MAGICWUPC2 }; static uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
uint8_t wipeC[] = { MIFARE_MAGICWIPEC }; static uint8_t wipeC[] = { MIFARE_MAGICWIPEC };
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
@ -2190,7 +2197,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
OnSuccessMagic(); OnSuccessMagic();
} }
void MifareCIdent() { void MifareCIdent(void) {
// variables // variables
uint8_t isGen = 0; uint8_t isGen = 0;
uint8_t rec[1] = {0x00}; uint8_t rec[1] = {0x00};
@ -2248,7 +2255,7 @@ OUT:
BigBuf_free(); BigBuf_free();
} }
void MifareHasStaticNonce() { void MifareHasStaticNonce(void) {
// variables // variables
int retval = PM3_SUCCESS, len; int retval = PM3_SUCCESS, len;
@ -2297,7 +2304,7 @@ OUT:
crypto1_deinit(pcs); crypto1_deinit(pcs);
} }
void OnSuccessMagic() { void OnSuccessMagic(void) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
set_tracing(false); set_tracing(false);

View file

@ -41,18 +41,17 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype);
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card 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); void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card? void MifareCIdent(void); // is "magic chinese" card?
void MifareHasStaticNonce(); // Has the tag a static nonce? void MifareHasStaticNonce(void); // Has the tag a static nonce?
void MifareSetMod(uint8_t *datain); void MifareSetMod(uint8_t *datain);
void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key); void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key);
void MifareUSetPwd(uint8_t arg0, uint8_t *datain); void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
void OnSuccessMagic(); void OnSuccessMagic(void);
void OnErrorMagic(uint8_t reason); void OnErrorMagic(uint8_t reason);
int32_t dist_nt(uint32_t nt1, uint32_t nt2); int32_t dist_nt(uint32_t nt1, uint32_t nt2);
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
//void RAMFUNC SniffMifare(uint8_t param); //void RAMFUNC SniffMifare(uint8_t param);
void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain);

View file

@ -25,7 +25,7 @@
#define RECEIVE_SIZE 64 #define RECEIVE_SIZE 64
// the block number for the ISO14443-4 PCB // the block number for the ISO14443-4 PCB
uint8_t pcb_blocknum = 0; static uint8_t pcb_blocknum = 0;
// Deselect card by sending a s-block. the crc is precalced for speed // Deselect card by sending a s-block. the crc is precalced for speed
static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4};
@ -33,10 +33,10 @@ static uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4};
/* PCB CID CMD PAYLOAD */ /* PCB CID CMD PAYLOAD */
//static uint8_t __res[MAX_FRAME_SIZE]; //static uint8_t __res[MAX_FRAME_SIZE];
struct desfire_key skey = {0}; static struct desfire_key skey = {0};
static desfirekey_t sessionkey = &skey; static desfirekey_t sessionkey = &skey;
bool InitDesfireCard() { bool InitDesfireCard(void) {
pcb_blocknum = 0; pcb_blocknum = 0;
@ -107,7 +107,7 @@ void MifareSendCommand(uint8_t *datain) {
LED_B_OFF(); LED_B_OFF();
} }
void MifareDesfireGetInformation() { void MifareDesfireGetInformation(void) {
LEDsoff(); LEDsoff();
@ -683,7 +683,7 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) {
// crc_update(&desfire_crc32, byte, 8); // crc_update(&desfire_crc32, byte, 8);
// uint32_t crc = crc_finish(&desfire_crc32); // uint32_t crc = crc_finish(&desfire_crc32);
void OnSuccess() { void OnSuccess(void) {
pcb_blocknum = 0; pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3, NULL); ReaderTransmit(deselect_cmd, 3, NULL);
if (mifare_ultra_halt()) { if (mifare_ultra_halt()) {

View file

@ -13,14 +13,14 @@
#include "common.h" #include "common.h"
bool InitDesfireCard(); bool InitDesfireCard(void);
void MifareSendCommand(uint8_t *datain); void MifareSendCommand(uint8_t *datain);
void MifareDesfireGetInformation(); void MifareDesfireGetInformation(void);
void MifareDES_Auth1(uint8_t *datain); void MifareDES_Auth1(uint8_t *datain);
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain); void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain);
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout); size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout);
void OnSuccess(); void OnSuccess(void);
void OnError(uint8_t reason); void OnError(uint8_t reason);
void OnErrorNG(uint16_t cmd, uint8_t reason); void OnErrorNG(uint16_t cmd, uint8_t reason);

View file

@ -539,9 +539,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
if (cardSTATE == MFEMUL_NOFIELD) { if (cardSTATE == MFEMUL_NOFIELD) {
#if defined RDV4 #if defined RDV4
vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; vHf = (MAX_ADC_HF_VOLTAGE_RDV40 * SumAdc(ADC_CHAN_HF_RDV40, 32)) >> 15;
#else #else
vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
#endif #endif
if (vHf > MF_MINFIELDV) { if (vHf > MF_MINFIELDV) {

View file

@ -308,7 +308,7 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, ui
} }
*/ */
void RAMFUNC MfSniffSend() { void RAMFUNC MfSniffSend(void) {
uint16_t tracelen = BigBuf_get_traceLen(); uint16_t tracelen = BigBuf_get_traceLen();
int packlen = tracelen; // total number of bytes to send int packlen = tracelen; // total number of bytes to send
uint8_t *data = BigBuf_get_addr(); uint8_t *data = BigBuf_get_addr();

View file

@ -355,7 +355,7 @@ int mifare_ultra_auth(uint8_t *keybytes) {
return 1; return 1;
} }
int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { static int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
uint16_t len = 0; uint16_t len = 0;
uint8_t bt[2] = {0x00, 0x00}; uint8_t bt[2] = {0x00, 0x00};
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
@ -509,7 +509,7 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) {
return mifare_classic_halt_ex(pcs); return mifare_classic_halt_ex(pcs);
} }
int mifare_ultra_halt() { int mifare_ultra_halt(void) {
uint16_t len = 0; uint16_t len = 0;
uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL);

View file

@ -75,7 +75,7 @@ int mifare_ultra_auth(uint8_t *keybytes);
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData);
//int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData); //int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_halt(); int mifare_ultra_halt(void);
// desfire // desfire
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);

View file

@ -127,7 +127,7 @@ typedef struct {
// internal buffer output // internal buffer output
static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) { static void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) {
if (idx < maxlen) { if (idx < maxlen) {
((char *)buffer)[idx] = character; ((char *)buffer)[idx] = character;
} }
@ -135,7 +135,7 @@ static inline void _out_buffer(char character, void *buffer, size_t idx, size_t
// internal null output // internal null output
static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) { static void _out_null(char character, void *buffer, size_t idx, size_t maxlen) {
(void)character; (void)character;
(void)buffer; (void)buffer;
(void)idx; (void)idx;
@ -144,7 +144,7 @@ static inline void _out_null(char character, void *buffer, size_t idx, size_t ma
// internal _putchar wrapper // internal _putchar wrapper
static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { static void _out_char(char character, void *buffer, size_t idx, size_t maxlen) {
(void)buffer; (void)buffer;
(void)idx; (void)idx;
(void)maxlen; (void)maxlen;
@ -155,7 +155,7 @@ static inline void _out_char(char character, void *buffer, size_t idx, size_t ma
// internal output function wrapper // internal output function wrapper
static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { static void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) {
(void)idx; (void)idx;
(void)maxlen; (void)maxlen;
if (character) { if (character) {
@ -167,7 +167,7 @@ static inline void _out_fct(char character, void *buffer, size_t idx, size_t max
// internal secure strlen // internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize' // \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char *str, size_t maxsize) { static unsigned int _strnlen_s(const char *str, size_t maxsize) {
const char *s; const char *s;
for (s = str; *s && maxsize--; ++s); for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str); return (unsigned int)(s - str);
@ -176,7 +176,7 @@ static inline unsigned int _strnlen_s(const char *str, size_t maxsize) {
// internal test if char is a digit (0-9) // internal test if char is a digit (0-9)
// \return true if char is a digit // \return true if char is a digit
static inline bool _is_digit(char ch) { static bool _is_digit(char ch) {
return (ch >= '0') && (ch <= '9'); return (ch >= '0') && (ch <= '9');
} }

View file

@ -173,7 +173,7 @@ bool IsBlock1PCF7931(uint8_t *block) {
return false; return false;
} }
void ReadPCF7931() { void ReadPCF7931(void) {
int found_blocks = 0; // successfully read blocks int found_blocks = 0; // successfully read blocks
int max_blocks = 8; // readable blocks int max_blocks = 8; // readable blocks
uint8_t memory_blocks[8][17]; // PCF content uint8_t memory_blocks[8][17]; // PCF content

View file

@ -6,7 +6,7 @@
size_t DemodPCF7931(uint8_t **outBlocks); size_t DemodPCF7931(uint8_t **outBlocks);
bool IsBlock0PCF7931(uint8_t *block); bool IsBlock0PCF7931(uint8_t *block);
bool IsBlock1PCF7931(uint8_t *block); bool IsBlock1PCF7931(uint8_t *block);
void ReadPCF7931(); void ReadPCF7931(void);
void SendCmdPCF7931(uint32_t *tab); void SendCmdPCF7931(uint32_t *tab);
bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p); bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p);
bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p); bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p);

View file

@ -47,7 +47,7 @@ typedef int ssize_t;
#define NBBY 8 /* number of bits in a byte */ #define NBBY 8 /* number of bits in a byte */
char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
#define hex2ascii(hex) (hex2ascii_data[hex]) #define hex2ascii(hex) (hex2ascii_data[hex])
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z'))) #define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))

View file

@ -108,7 +108,7 @@ static enum spiffs_mount_status {
RDV40_SPIFFS_UNKNOWN RDV40_SPIFFS_UNKNOWN
} RDV40_SPIFFS_MOUNT_STATUS; } RDV40_SPIFFS_MOUNT_STATUS;
int rdv40_spiffs_mounted() { static int rdv40_spiffs_mounted(void) {
int ret = 0; int ret = 0;
switch (RDV40_SPIFFS_MOUNT_STATUS) { switch (RDV40_SPIFFS_MOUNT_STATUS) {
@ -124,7 +124,7 @@ int rdv40_spiffs_mounted() {
return ret; return ret;
} }
int rdv40_spiffs_mount() { int rdv40_spiffs_mount(void) {
if (rdv40_spiffs_mounted()) { if (rdv40_spiffs_mounted()) {
Dbprintf("ERR: SPIFFS already mounted !"); Dbprintf("ERR: SPIFFS already mounted !");
return SPIFFS_ERR_MOUNTED; return SPIFFS_ERR_MOUNTED;
@ -146,7 +146,7 @@ int rdv40_spiffs_mount() {
return ret; return ret;
} }
int rdv40_spiffs_unmount() { int rdv40_spiffs_unmount(void) {
if (!rdv40_spiffs_mounted()) { if (!rdv40_spiffs_mounted()) {
Dbprintf("ERR: SPIFFS not mounted !"); Dbprintf("ERR: SPIFFS not mounted !");
return SPIFFS_ERR_NOT_MOUNTED; return SPIFFS_ERR_NOT_MOUNTED;
@ -162,7 +162,7 @@ int rdv40_spiffs_unmount() {
return ret; return ret;
} }
int rdv40_spiffs_check() { int rdv40_spiffs_check(void) {
rdv40_spiffs_lazy_mount(); rdv40_spiffs_lazy_mount();
SPIFFS_check(&fs); SPIFFS_check(&fs);
SPIFFS_gc_quick(&fs, 0); SPIFFS_gc_quick(&fs, 0);
@ -195,17 +195,17 @@ void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size) {
SPIFFS_close(&fs, fd); SPIFFS_close(&fs, fd);
} }
void rename_in_spiffs(const char *old_filename, const char *new_filename) { static void rename_in_spiffs(const char *old_filename, const char *new_filename) {
if (SPIFFS_rename(&fs, old_filename, new_filename) < 0) if (SPIFFS_rename(&fs, old_filename, new_filename) < 0)
Dbprintf("errno %i\n", SPIFFS_errno(&fs)); Dbprintf("errno %i\n", SPIFFS_errno(&fs));
} }
void remove_from_spiffs(const char *filename) { static void remove_from_spiffs(const char *filename) {
if (SPIFFS_remove(&fs, filename) < 0) if (SPIFFS_remove(&fs, filename) < 0)
Dbprintf("errno %i\n", SPIFFS_errno(&fs)); Dbprintf("errno %i\n", SPIFFS_errno(&fs));
} }
spiffs_stat stat_in_spiffs(const char *filename) { static spiffs_stat stat_in_spiffs(const char *filename) {
spiffs_stat s; spiffs_stat s;
if (SPIFFS_stat(&fs, filename, &s) < 0) if (SPIFFS_stat(&fs, filename, &s) < 0)
Dbprintf("errno %i\n", SPIFFS_errno(&fs)); Dbprintf("errno %i\n", SPIFFS_errno(&fs));
@ -217,7 +217,7 @@ uint32_t size_in_spiffs(const char *filename) {
return s.size; return s.size;
} }
rdv40_spiffs_fsinfo info_of_spiffs() { static rdv40_spiffs_fsinfo info_of_spiffs(void) {
rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_fsinfo fsinfo;
fsinfo.blockSize = SPIFFS_CFG_LOG_BLOCK_SZ; fsinfo.blockSize = SPIFFS_CFG_LOG_BLOCK_SZ;
fsinfo.pageSize = LOG_PAGE_SIZE; fsinfo.pageSize = LOG_PAGE_SIZE;
@ -238,7 +238,7 @@ int exists_in_spiffs(const char *filename) {
return rc == SPIFFS_OK; return rc == SPIFFS_OK;
} }
RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { static RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) {
RDV40SpiFFSFileType filetype = RDV40_SPIFFS_FILETYPE_UNKNOWN; RDV40SpiFFSFileType filetype = RDV40_SPIFFS_FILETYPE_UNKNOWN;
char symlinked[SPIFFS_OBJ_NAME_LEN]; char symlinked[SPIFFS_OBJ_NAME_LEN];
sprintf(symlinked, "%s.lnk", filename); sprintf(symlinked, "%s.lnk", filename);
@ -270,16 +270,16 @@ RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) {
} }
return filetype; return filetype;
} }
/*
int is_valid_filename(const char *filename) { static int is_valid_filename(const char *filename) {
if (filename == NULL) { if (filename == NULL) {
return false; return false;
} }
uint32_t len = strlen(filename); uint32_t len = strlen(filename);
return len > 0 && len < SPIFFS_OBJ_NAME_LEN; return len > 0 && len < SPIFFS_OBJ_NAME_LEN;
} }
*/
void copy_in_spiffs(const char *src, const char *dst) { static void copy_in_spiffs(const char *src, const char *dst) {
uint32_t size = size_in_spiffs((char *)src); uint32_t size = size_in_spiffs((char *)src);
uint8_t *mem = BigBuf_malloc(size); uint8_t *mem = BigBuf_malloc(size);
read_from_spiffs((char *)src, (uint8_t *)mem, size); read_from_spiffs((char *)src, (uint8_t *)mem, size);
@ -297,7 +297,7 @@ void copy_in_spiffs(const char *src, const char *dst) {
// 1 if the mount status actually changed // 1 if the mount status actually changed
// so you know what to do IN CASE you wished to set things "back to previous // so you know what to do IN CASE you wished to set things "back to previous
// state" // state"
int rdv40_spiffs_lazy_mount() { int rdv40_spiffs_lazy_mount(void) {
int changed = 0; int changed = 0;
if (!rdv40_spiffs_mounted()) { if (!rdv40_spiffs_mounted()) {
changed = rdv40_spiffs_mount(); changed = rdv40_spiffs_mount();
@ -309,7 +309,7 @@ int rdv40_spiffs_lazy_mount() {
} }
// unmount if not already // unmount if not already
int rdv40_spiffs_lazy_unmount() { int rdv40_spiffs_lazy_unmount(void) {
int changed = 0; int changed = 0;
if (rdv40_spiffs_mounted()) { if (rdv40_spiffs_mounted()) {
changed = rdv40_spiffs_unmount(); changed = rdv40_spiffs_unmount();
@ -362,7 +362,7 @@ void my_lazy_spiffs_act(){
// this lazy_mount since needed and can also report back the change on // this lazy_mount since needed and can also report back the change on
state implied by eventual mount, if needed rdv40_spiffs_lazy_read((const char state implied by eventual mount, if needed rdv40_spiffs_lazy_read((const char
*)".SHOULDRESET",(uint8_t *)resetret,4); if( resetret == "YESS" ) { uint8_t *)".SHOULDRESET",(uint8_t *)resetret,4); if( resetret == "YESS" ) { uint8_t
changed = rdv40_spiffs_lazy_format(); // this will imply change only if we where changed = rdv40_spiffs_lazy_format(void); // this will imply change only if we where
already mounted beforehand, was the case after our reading without further already mounted beforehand, was the case after our reading without further
rollback rdv40_spiffs_lazy_mount_rollback(changed); // so if we were mounted rollback rdv40_spiffs_lazy_mount_rollback(changed); // so if we were mounted
just get back to this state. If not, just don't. just get back to this state. If not, just don't.
@ -400,20 +400,20 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) {
// statement or some function taking function parameters // statement or some function taking function parameters
// TODO : forbid writing to a filename which already exists as lnk ! // TODO : forbid writing to a filename which already exists as lnk !
// TODO : forbid writing to a filename.lnk which already exists without lnk ! // TODO : forbid writing to a filename.lnk which already exists without lnk !
int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) {
RDV40_SPIFFS_SAFE_FUNCTION( RDV40_SPIFFS_SAFE_FUNCTION(
write_to_spiffs(filename, src, size); write_to_spiffs(filename, src, size);
) )
} }
int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) {
RDV40_SPIFFS_SAFE_FUNCTION( RDV40_SPIFFS_SAFE_FUNCTION(
append_to_spiffs(filename, src, size); append_to_spiffs(filename, src, size);
) )
} }
// todo integrate reading symlinks transparently // todo integrate reading symlinks transparently
int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { int rdv40_spiffs_read(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) {
RDV40_SPIFFS_SAFE_FUNCTION( RDV40_SPIFFS_SAFE_FUNCTION(
read_from_spiffs(filename, dst, size); read_from_spiffs(filename, dst, size);
) )
@ -444,7 +444,7 @@ int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel leve
) )
} }
int rdv40_spiffs_getfsinfo(rdv40_spiffs_fsinfo *fsinfo, RDV40SpiFFSSafetyLevel level) { static int rdv40_spiffs_getfsinfo(rdv40_spiffs_fsinfo *fsinfo, RDV40SpiFFSSafetyLevel level) {
RDV40_SPIFFS_SAFE_FUNCTION( // RDV40_SPIFFS_SAFE_FUNCTION( //
*fsinfo = info_of_spiffs(); // *fsinfo = info_of_spiffs(); //
) )
@ -536,13 +536,13 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///////// MISC HIGH LEVEL FUNCTIONS //////////////////////////////////////////// ///////// MISC HIGH LEVEL FUNCTIONS ////////////////////////////////////////////
#define SPIFFS_BANNER DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); #define SPIFFS_BANNER DbpString(_CYAN_("Flash Memory FileSystem tree (SPIFFS)"));
void rdv40_spiffs_safe_print_fsinfo() { void rdv40_spiffs_safe_print_fsinfo(void) {
rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_fsinfo fsinfo;
rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE);
DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)")); DbpString(_CYAN_("Flash Memory FileSystem Info (SPIFFS)"));
Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize); Dbprintf(" Logical Block Size........." _YELLOW_("%d")" bytes", fsinfo.blockSize);
@ -570,7 +570,7 @@ void rdv40_spiffs_safe_print_fsinfo() {
void rdv40_spiffs_safe_print_tree(uint8_t banner) { void rdv40_spiffs_safe_print_tree(uint8_t banner) {
if (banner) { if (banner) {
DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)")); DbpString(_CYAN_("Flash Memory FileSystem tree (SPIFFS)"));
Dbprintf("-------------------------------------"); Dbprintf("-------------------------------------");
} }
@ -603,7 +603,7 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) {
// Selftest function // Selftest function
void test_spiffs() { void test_spiffs(void) {
Dbprintf("----------------------------------------------"); Dbprintf("----------------------------------------------");
Dbprintf("Testing SPIFFS operations"); Dbprintf("Testing SPIFFS operations");
Dbprintf("----------------------------------------------"); Dbprintf("----------------------------------------------");

View file

@ -33,27 +33,27 @@ typedef struct rdv40_spiffs_fsinfo {
int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_check(); int rdv40_spiffs_check(void);
int rdv40_spiffs_lazy_unmount(); int rdv40_spiffs_lazy_unmount(void);
int rdv40_spiffs_lazy_mount(); int rdv40_spiffs_lazy_mount(void);
int rdv40_spiffs_lazy_mount_rollback(int changed); int rdv40_spiffs_lazy_mount_rollback(int changed);
int rdv40_spiffs_write(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_read(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_read(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_rename(char *old_filename, char *new_filename, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_rename(char *old_filename, char *new_filename, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_remove(char *filename, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_remove(char *filename, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level);
void write_to_spiffs(const char *filename, uint8_t *src, uint32_t size); void write_to_spiffs(const char *filename, uint8_t *src, uint32_t size);
void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size); void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size);
void test_spiffs(); void test_spiffs(void);
void rdv40_spiffs_safe_print_tree(uint8_t banner); void rdv40_spiffs_safe_print_tree(uint8_t banner);
int rdv40_spiffs_unmount(); int rdv40_spiffs_unmount(void);
int rdv40_spiffs_mount(); int rdv40_spiffs_mount(void);
int rdv40_spiffs_is_symlink(const char *s); int rdv40_spiffs_is_symlink(const char *s);
void rdv40_spiffs_safe_print_fsinfo(); void rdv40_spiffs_safe_print_fsinfo(void);
int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyLevel level);
void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size); void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size);
int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level);
int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level); int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level);
uint32_t size_in_spiffs(const char *filename); uint32_t size_in_spiffs(const char *filename);
int exists_in_spiffs(const char *filename); int exists_in_spiffs(const char *filename);

View file

@ -18,8 +18,6 @@
#include "string.h" #include "string.h"
#include "flashmem.h" #include "flashmem.h"
void Dbprintf(const char *fmt, ...);
//#include <stddef.h> //#include <stddef.h>
//#include <unistd.h> //#include <unistd.h>
// ----------- >8 ------------ // ----------- >8 ------------

View file

@ -39,13 +39,12 @@ s32_t SPIFFS_format(spiffs *fs) {
return -1; return -1;
} }
s32_t res;
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
spiffs_block_ix bix = 0; spiffs_block_ix bix = 0;
while (bix < fs->block_count) { while (bix < fs->block_count) {
fs->max_erase_count = 0; fs->max_erase_count = 0;
res = spiffs_erase_block(fs, bix); s32_t res = spiffs_erase_block(fs, bix);
if (res != SPIFFS_OK) { if (res != SPIFFS_OK) {
res = SPIFFS_ERR_ERASE_FAIL; res = SPIFFS_ERR_ERASE_FAIL;
} }
@ -1121,11 +1120,11 @@ s32_t SPIFFS_check(spiffs *fs) {
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
res = spiffs_lookup_consistency_check(fs, 0); res = spiffs_lookup_consistency_check(fs, 0);
(void)res;
res = spiffs_object_index_consistency_check(fs); res = spiffs_object_index_consistency_check(fs);
(void)res;
res = spiffs_page_consistency_check(fs); res = spiffs_page_consistency_check(fs);
(void)res;
res = spiffs_obj_lu_scan(fs); res = spiffs_obj_lu_scan(fs);
SPIFFS_UNLOCK(fs); SPIFFS_UNLOCK(fs);

View file

@ -14,69 +14,40 @@
#include "proxmark3_arm.h" #include "proxmark3_arm.h"
#include "appmain.h" #include "appmain.h"
#include "zlib.h" #include "lz4.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "string.h"
static uint8_t *next_free_memory; static uint8_t *next_free_memory;
extern struct common_area common_area; extern struct common_area common_area;
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__; extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) {
uint8_t *allocated_memory;
allocated_memory = next_free_memory;
next_free_memory += items * size;
return allocated_memory;
}
static void inflate_free(voidpf opaque, voidpf address) {
// nothing to do
}
static void uncompress_data_section(void) { static void uncompress_data_section(void) {
z_stream data_section;
next_free_memory = BigBuf_get_addr(); next_free_memory = BigBuf_get_addr();
int avail_in;
memcpy(&avail_in, &__data_start__, sizeof(int));
int avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
// uncompress data segment to RAM
uintptr_t p = (uintptr_t)&__data_src_start__;
int res = LZ4_decompress_safe((char *)p + 4, &__data_start__, avail_in, avail_out);
// initialize zstream structure
data_section.next_in = (uint8_t *) &__data_src_start__;
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
data_section.next_out = (uint8_t *) &__data_start__;
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
data_section.zalloc = &inflate_malloc;
data_section.zfree = &inflate_free;
data_section.opaque = NULL;
// initialize zlib for inflate
int res = inflateInit2(&data_section, 15);
if (res < 0) if (res < 0)
return; return;
// uncompress data segment to RAM
inflate(&data_section, Z_FINISH);
// save the size of the compressed data section // save the size of the compressed data section
common_area.arg1 = data_section.total_in; common_area.arg1 = res;
} }
void __attribute__((section(".startos"))) Vector(void) { void __attribute__((section(".startos"))) Vector(void);
void Vector(void) {
/* Stack should have been set up by the bootloader */ /* Stack should have been set up by the bootloader */
// char *src;
char *dst, *end;
uncompress_data_section(); uncompress_data_section();
/* Set up (that is: clear) BSS. */ /* Set up (that is: clear) BSS. */
dst = &__bss_start__; char *dst = &__bss_start__;
end = &__bss_end__; char *end = &__bss_end__;
while (dst < end) *dst++ = 0; while (dst < end) *dst++ = 0;
// Set up data segment: Copy from flash to ram
// src = &__data_src_start__;
// dst = &__data_start__;
// end = &__data_end__;
// while(dst < end) *dst++ = *src++;
AppMain(); AppMain();
} }
#endif #endif

View file

@ -20,6 +20,21 @@ void *memcpy(void *dest, const void *src, int len) {
return dest; return dest;
} }
void *memmove(void *dest, const void *src, size_t len) {
char *d = dest;
const char *s = src;
if (d < s)
while (len--)
*d++ = *s++;
else {
char *lasts = (char *)s + (len - 1);
char *lastd = d + (len - 1);
while (len--)
*lastd-- = *lasts--;
}
return dest;
}
void *memset(void *dest, int c, int len) { void *memset(void *dest, int c, int len) {
uint8_t *d = dest; uint8_t *d = dest;
while ((len--) > 0) { while ((len--) > 0) {

View file

@ -16,6 +16,7 @@
int strlen(const char *str); int strlen(const char *str);
void *memcpy(void *dest, const void *src, int len); void *memcpy(void *dest, const void *src, int len);
void *memmove(void *dest, const void *src, size_t len);
void *memset(void *dest, int c, int len); void *memset(void *dest, int c, int len);
int memcmp(const void *av, const void *bv, int len); int memcmp(const void *av, const void *bv, int len);
void memxor(uint8_t *dest, uint8_t *src, size_t len); void memxor(uint8_t *dest, uint8_t *src, size_t len);
@ -33,6 +34,8 @@ char *strrchr(const char *s, int c);
size_t strcspn(const char *s1, const char *s2); size_t strcspn(const char *s1, const char *s2);
char *strpbrk(const char *s1, const char *s2); char *strpbrk(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n); int strncmp(const char *s1, const char *s2, size_t n);
unsigned long strtoul(const char *p, char **out_p, int base);
long strtol(const char *p, char **out_p, int base);
char c_tolower(int c); char c_tolower(int c);
char c_isprint(unsigned char c); char c_isprint(unsigned char c);

View file

@ -49,9 +49,9 @@ void ReadThinFilm(void) {
#define SEC_D 0xf0 #define SEC_D 0xf0
#define SEC_E 0x0f #define SEC_E 0x0f
#define SEC_F 0x00 #define SEC_F 0x00
uint16_t FpgaSendQueueDelay; static uint16_t FpgaSendQueueDelay;
uint16_t ReadReaderField(void) { static uint16_t ReadReaderField(void) {
#if defined RDV4 #if defined RDV4
return AvgAdc(ADC_CHAN_HF_RDV40); return AvgAdc(ADC_CHAN_HF_RDV40);
#else #else
@ -71,7 +71,7 @@ static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) {
ToSendMax++; ToSendMax++;
} }
int EmSendCmdThinfilmRaw(uint8_t *resp, uint16_t respLen) { static int EmSendCmdThinfilmRaw(uint8_t *resp, uint16_t respLen) {
volatile uint8_t b; volatile uint8_t b;
uint16_t i = 0; uint16_t i = 0;
uint32_t ThisTransferTime; uint32_t ThisTransferTime;

View file

@ -30,10 +30,10 @@ uint32_t RAMFUNC GetCountUS(void);
void ResetUSClock(void); void ResetUSClock(void);
void SpinDelayCountUs(uint32_t us); void SpinDelayCountUs(uint32_t us);
void StartCountSspClk(); void StartCountSspClk(void);
void ResetSspClk(void); void ResetSspClk(void);
uint32_t RAMFUNC GetCountSspClk(); uint32_t RAMFUNC GetCountSspClk(void);
uint32_t RAMFUNC GetCountSspClkDelta(); uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start);
void StartTicks(void); void StartTicks(void);
uint32_t GetTicks(void); uint32_t GetTicks(void);

View file

@ -15,8 +15,8 @@ volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1; volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
uint32_t usart_baudrate = 0; uint32_t g_usart_baudrate = 0;
uint8_t usart_parity = 0; uint8_t g_usart_parity = 0;
/* /*
void usart_close(void) { void usart_close(void) {
// Reset the USART mode // Reset the USART mode
@ -41,8 +41,8 @@ void usart_close(void) {
static uint8_t us_inbuf1[USART_BUFFLEN]; static uint8_t us_inbuf1[USART_BUFFLEN];
static uint8_t us_inbuf2[USART_BUFFLEN]; static uint8_t us_inbuf2[USART_BUFFLEN];
uint8_t *usart_cur_inbuf = NULL; static uint8_t *usart_cur_inbuf = NULL;
uint16_t usart_cur_inbuf_off = 0; static uint16_t usart_cur_inbuf_off = 0;
static uint8_t us_rxfifo[USART_FIFOLEN]; static uint8_t us_rxfifo[USART_FIFOLEN];
static size_t us_rxfifo_low = 0; static size_t us_rxfifo_low = 0;
static size_t us_rxfifo_high = 0; static size_t us_rxfifo_high = 0;
@ -166,9 +166,9 @@ inline int usart_writebuffer_sync(uint8_t *data, size_t len) {
void usart_init(uint32_t baudrate, uint8_t parity) { void usart_init(uint32_t baudrate, uint8_t parity) {
if (baudrate != 0) if (baudrate != 0)
usart_baudrate = baudrate; g_usart_baudrate = baudrate;
if ((parity == 'N') || (parity == 'O') || (parity == 'E')) if ((parity == 'N') || (parity == 'O') || (parity == 'E'))
usart_parity = parity; g_usart_parity = parity;
// For a nice detailed sample, interrupt driven but still relevant. // For a nice detailed sample, interrupt driven but still relevant.
// See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf // See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf
@ -197,7 +197,7 @@ void usart_init(uint32_t baudrate, uint8_t parity) {
AT91C_US_NBSTOP_1_BIT | // 1 stop bit AT91C_US_NBSTOP_1_BIT | // 1 stop bit
AT91C_US_CHMODE_NORMAL; // channel mode: normal AT91C_US_CHMODE_NORMAL; // channel mode: normal
switch (usart_parity) { switch (g_usart_parity) {
case 'N': case 'N':
mode |= AT91C_US_PAR_NONE; // parity: none mode |= AT91C_US_PAR_NONE; // parity: none
break; break;
@ -227,9 +227,9 @@ void usart_init(uint32_t baudrate, uint8_t parity) {
// OVER = 1, -yes we are oversampling // OVER = 1, -yes we are oversampling
// baudrate == selected clock/8/CD --> this is ours // baudrate == selected clock/8/CD --> this is ours
// //
uint32_t brgr = MCK / (usart_baudrate << 3); uint32_t brgr = MCK / (g_usart_baudrate << 3);
// doing fp = round((mck / (usart_baudrate << 3) - brgr) * 8) with integers: // doing fp = round((mck / (g_usart_baudrate << 3) - brgr) * 8) with integers:
uint32_t fp = ((16 * MCK / (usart_baudrate << 3) - 16 * brgr) + 1) / 2; uint32_t fp = ((16 * MCK / (g_usart_baudrate << 3) - 16 * brgr) + 1) / 2;
pUS1->US_BRGR = (fp << 16) | brgr; pUS1->US_BRGR = (fp << 16) | brgr;

View file

@ -9,8 +9,8 @@
// Higher baudrates are pointless, only increasing overflow risk // Higher baudrates are pointless, only increasing overflow risk
extern uint32_t usart_baudrate; extern uint32_t g_usart_baudrate;
extern uint8_t usart_parity; extern uint8_t g_usart_parity;
void usart_init(uint32_t baudrate, uint8_t parity); void usart_init(uint32_t baudrate, uint8_t parity);
int usart_writebuffer_sync(uint8_t *data, size_t len); int usart_writebuffer_sync(uint8_t *data, size_t len);

View file

@ -83,7 +83,7 @@ uint8_t hex2int(char hexchar) {
} }
} }
void LEDsoff() { void LEDsoff(void) {
LED_A_OFF(); LED_A_OFF();
LED_B_OFF(); LED_B_OFF();
LED_C_OFF(); LED_C_OFF();
@ -289,40 +289,6 @@ int BUTTON_HELD(int ms) {
return BUTTON_ERROR; return BUTTON_ERROR;
} }
/* Similar to FpgaGatherVersion this formats stored version information
* into a string representation. It takes a pointer to the struct version_information,
* verifies the magic properties, then stores a formatted string, prefixed by
* prefix in dst.
*/
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) {
struct version_information *v = (struct version_information *)version_information;
dst[0] = 0;
strncat(dst, prefix, len - 1);
if (v->magic != VERSION_INFORMATION_MAGIC) {
strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1);
return;
}
if (v->versionversion != 1) {
strncat(dst, "Version information not understood\n", len - strlen(dst) - 1);
return;
}
if (!v->present) {
strncat(dst, "Version information not available\n", len - strlen(dst) - 1);
return;
}
strncat(dst, v->gitversion, len - strlen(dst) - 1);
if (v->clean == 0) {
strncat(dst, "-unclean", len - strlen(dst) - 1);
} else if (v->clean == 2) {
strncat(dst, "-suspect", len - strlen(dst) - 1);
}
strncat(dst, " ", len - strlen(dst) - 1);
strncat(dst, v->buildtime, len - strlen(dst) - 1);
strncat(dst, "\n", len - strlen(dst) - 1);
}
bool data_available(void) { bool data_available(void) {
#ifdef WITH_FPC_USART_HOST #ifdef WITH_FPC_USART_HOST
return usb_poll_validate_length() || (usart_rxdata_available() > 0); return usb_poll_validate_length() || (usart_rxdata_available() > 0);

View file

@ -55,15 +55,15 @@
#endif #endif
#ifndef REV16 #ifndef REV16
#define REV16(x) (REV8(x) + (REV8 (x >> 8) << 8)) #define REV16(x) (REV8(x) + (REV8 ((x) >> 8) << 8))
#endif #endif
#ifndef REV32 #ifndef REV32
#define REV32(x) (REV16(x) + (REV16(x >> 16) << 16)) #define REV32(x) (REV16(x) + (REV16((x) >> 16) << 16))
#endif #endif
#ifndef REV64 #ifndef REV64
#define REV64(x) (REV32(x) + (REV32(x >> 32) << 32)) #define REV64(x) (REV32(x) + (REV32((x) >> 32) << 32))
#endif #endif
#ifndef BIT32 #ifndef BIT32
@ -91,7 +91,6 @@ void SpinUp(uint32_t speed);
int BUTTON_CLICKED(int ms); int BUTTON_CLICKED(int ms);
int BUTTON_HELD(int ms); int BUTTON_HELD(int ms);
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
bool data_available(void); bool data_available(void);
#endif #endif

View file

@ -23,7 +23,7 @@ VERSIONSRC = version.c
# THUMBSRC := # THUMBSRC :=
# stdint.h provided locally until GCC 4.5 becomes C99 compliant # stdint.h provided locally until GCC 4.5 becomes C99 compliant
APP_CFLAGS = -I. -fno-strict-aliasing -ffunction-sections -fdata-sections APP_CFLAGS = -I. -ffunction-sections -fdata-sections
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
APP_CFLAGS += -fno-stack-protector -fno-pie APP_CFLAGS += -fno-stack-protector -fno-pie
@ -39,9 +39,12 @@ OBJS = $(OBJDIR)/bootrom.s19
# version.c should be remade on every compilation # version.c should be remade on every compilation
version.c: default_version.c version.c: default_version.c
$(info [=] GEN $@) $(info [=] GEN $@)
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@ $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@
all: $(OBJS) all: showinfo $(OBJS)
showinfo:
$(info compiler version: $(shell $(CC) --version|head -n 1))
tarbin: $(OBJS) tarbin: $(OBJS)
$(info [=] GEN $@) $(info [=] GEN $@)
@ -49,7 +52,7 @@ tarbin: $(OBJS)
$(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ) $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ)
$(info [=] LD $@) $(info [=] LD $@)
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS) $(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
clean: clean:
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o $(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
@ -68,7 +71,7 @@ uninstall:
$(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...) $(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...)
$(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) $(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
.PHONY: all clean help install .PHONY: all clean help install showinfo
help: help:
@echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Multi-OS Makefile, you are running on $(DETECTED_OS)
@echo Possible targets: @echo Possible targets:

View file

@ -10,6 +10,7 @@
#include "usb_cdc.h" #include "usb_cdc.h"
#include "proxmark3_arm.h" #include "proxmark3_arm.h"
#define DEBUG 0
struct common_area common_area __attribute__((section(".commonarea"))); struct common_area common_area __attribute__((section(".commonarea")));
unsigned int start_addr, end_addr, bootrom_unlocked; unsigned int start_addr, end_addr, bootrom_unlocked;
@ -37,21 +38,19 @@ static int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2,
} }
} }
int result = PM3_EUNDEF;
// Send frame and make sure all bytes are transmitted // Send frame and make sure all bytes are transmitted
return usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
result = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
return result;
} }
void DbpString(char *str) { #if DEBUG
static void DbpString(char *str) {
uint8_t len = 0; uint8_t len = 0;
while (str[len] != 0x00) while (str[len] != 0x00)
len++; len++;
reply_old(CMD_DEBUG_PRINT_STRING, len, 0, 0, (uint8_t *)str, len); reply_old(CMD_DEBUG_PRINT_STRING, len, 0, 0, (uint8_t *)str, len);
} }
#endif
static void ConfigClocks(void) { static void ConfigClocks(void) {
// we are using a 16 MHz crystal as the basis for everything // we are using a 16 MHz crystal as the basis for everything
@ -76,8 +75,8 @@ static void Fatal(void) {
for (;;) {}; for (;;) {};
} }
void UsbPacketReceived(uint8_t *packet, int len) { static void UsbPacketReceived(uint8_t *packet) {
int i, dont_ack = 0; int dont_ack = 0;
PacketCommandOLD *c = (PacketCommandOLD *)packet; PacketCommandOLD *c = (PacketCommandOLD *)packet;
//if ( len != sizeof(PacketCommandOLD`)) Fatal(); //if ( len != sizeof(PacketCommandOLD`)) Fatal();
@ -125,7 +124,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
// We need to offset the writes or it will not fill the correct bank write buffer. // We need to offset the writes or it will not fill the correct bank write buffer.
offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t); offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t);
} }
for (i = 0 + (64 * j); i < 64 + (64 * j); i++) { for (int i = 0 + (64 * j); i < 64 + (64 * j); i++) {
_flash_start[offset + i] = c->d.asDwords[i]; _flash_start[offset + i] = c->d.asDwords[i];
} }
@ -217,7 +216,7 @@ static void flash_mode(void) {
// Check if there is a usb packet available // Check if there is a usb packet available
if (usb_poll_validate_length()) { if (usb_poll_validate_length()) {
if (usb_read(rx, sizeof(rx))) { if (usb_read(rx, sizeof(rx))) {
UsbPacketReceived(rx, sizeof(rx)); UsbPacketReceived(rx);
} }
} }
@ -235,6 +234,7 @@ static void flash_mode(void) {
} }
} }
void BootROM(void);
void BootROM(void) { void BootROM(void) {
//------------ //------------
// First set up all the I/O pins; GPIOs configured directly, other ones // First set up all the I/O pins; GPIOs configured directly, other ones
@ -312,7 +312,7 @@ void BootROM(void) {
if (!common_area_present) { if (!common_area_present) {
/* Common area not ok, initialize it */ /* Common area not ok, initialize it */
int i; size_t i;
/* Makeshift memset, no need to drag util.c into this */ /* Makeshift memset, no need to drag util.c into this */
for (i = 0; i < sizeof(common_area); i++) for (i = 0; i < sizeof(common_area); i++)
((char *)&common_area)[i] = 0; ((char *)&common_area)[i] = 0;

View file

@ -4,14 +4,23 @@
# On Proxspace 3.3 or less, you need to install cmake: # On Proxspace 3.3 or less, you need to install cmake:
# pacman -S mingw-w64-x86_64-cmake # pacman -S mingw-w64-x86_64-cmake
# /mingw64/bin/cmake -G"MSYS Makefiles" .. # /mingw64/bin/cmake -G"MSYS Makefiles" ..
#
# Android cross-compilation:
# cmake \
# -DCMAKE_TOOLCHAIN_FILE=<path-to-your-android-ndk>/build/cmake/android.toolchain.cmake \
# -DANDROID_ABI=armeabi-v7a \
# -DANDROID_NATIVE_API_LEVEL=android-19 \
# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 ..
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(proxmark3) project(proxmark3)
SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)
if(CMAKE_VERSION VERSION_LESS "3.7.0") if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif() endif()
if (NOT SKIPQT EQUAL 1)
if(APPLE AND EXISTS /usr/local/opt/qt5) if(APPLE AND EXISTS /usr/local/opt/qt5)
# Homebrew installs Qt5 (up to at least 5.11.0) in # Homebrew installs Qt5 (up to at least 5.11.0) in
# /usr/local/qt5. Ensure that it can be found by CMake # /usr/local/qt5. Ensure that it can be found by CMake
@ -21,7 +30,7 @@ if(APPLE AND EXISTS /usr/local/opt/qt5)
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package, # QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
endif() endif(APPLE AND EXISTS /usr/local/opt/qt5)
set(QT_PACKAGELIST set(QT_PACKAGELIST
Qt5Core Qt5Core
Qt5Widgets Qt5Widgets
@ -30,191 +39,360 @@ set(QT_PACKAGELIST
set(Qt5_FOUND ON) set(Qt5_FOUND ON)
foreach(_qt_package IN LISTS QT_PACKAGELIST) foreach(_qt_package IN LISTS QT_PACKAGELIST)
find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS})
set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES})
if(NOT ${_qt_package}_FOUND) if(NOT ${_qt_package}_FOUND)
set(Qt5_FOUND OFF) set(Qt5_FOUND OFF)
endif(NOT ${_qt_package}_FOUND) endif(NOT ${_qt_package}_FOUND)
endforeach() endforeach()
endif (NOT SKIPQT EQUAL 1)
SET (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") find_package(PkgConfig)
if (NOT SKIPBT EQUAL 1)
pkg_search_module(BLUEZ QUIET bluez)
endif (NOT SKIPBT EQUAL 1)
add_subdirectory(deps) if (NOT SKIPPYTHON EQUAL 1)
pkg_search_module(PYTHON3 QUIET python3)
pkg_search_module(PYTHON3EMBED QUIET python3-embed)
endif (NOT SKIPPYTHON EQUAL 1)
# If build on android cross, we need to init source and build.
if (ANDROID)
set(CFLAGS_EXTERNAL_LIB CFLAGS=--target=${CMAKE_C_COMPILER_TARGET})
include(ExternalProject)
endif (ANDROID)
if (NOT SKIPREADLINE EQUAL 1)
if (APPLE)
find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH)
find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH)
endif (APPLE)
if (ANDROID)
ExternalProject_Add(ncurses
URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz
PREFIX deps/ncurses
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm
BUILD_IN_SOURCE ON
BUILD_COMMAND make -j2 libs
INSTALL_COMMAND ""
LOG_DOWNLOAD ON
)
ExternalProject_Add_StepTargets(ncurses configure build install)
ExternalProject_Add(readline
URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz
PREFIX deps/readline
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
BUILD_IN_SOURCE ON
BUILD_COMMAND make -j2
INSTALL_COMMAND ""
LOG_DOWNLOAD ON
)
ExternalProject_Add_StepTargets(readline configure build install)
set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/)
set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libncurses.a)
else (ANDROID)
find_path(READLINE_INCLUDE_DIRS readline/readline.h)
find_library(READLINE_LIBRARIES readline)
endif (ANDROID)
if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
set(READLINE_FOUND ON)
endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
endif (NOT SKIPREADLINE EQUAL 1)
if(ANDROID)
set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
ExternalProject_Add(bzip2
GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2
GIT_TAG platform-tools-30.0.2
PREFIX deps/bzip2
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2
CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x
BUILD_IN_SOURCE ON
BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a
INSTALL_COMMAND ""
LOG_DOWNLOAD ON
)
ExternalProject_Add_StepTargets(bzip2 configure build install)
set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a)
else()
set(BZIP2_LIBRARIES bz2)
endif(ANDROID)
if (BZIP2_LIBRARIES)
set(BZIP2_FOUND ON)
endif (BZIP2_LIBRARIES)
add_subdirectory(${PM3_ROOT}/client/deps deps)
set (TARGET_SOURCES set (TARGET_SOURCES
src/proxmark3.c ${PM3_ROOT}/common/commonutil.c
../common/commonutil.c ${PM3_ROOT}/common/util_posix.c
../common/util_posix.c ${PM3_ROOT}/common/parity.c
../common/parity.c ${PM3_ROOT}/common/bucketsort.c
../common/bucketsort.c ${PM3_ROOT}/common/crapto1/crapto1.c
../common/crapto1/crapto1.c ${PM3_ROOT}/common/crapto1/crypto1.c
../common/crapto1/crypto1.c ${PM3_ROOT}/common/crc.c
../common/crc.c ${PM3_ROOT}/common/crc16.c
../common/crc16.c ${PM3_ROOT}/common/crc32.c
../common/crc32.c ${PM3_ROOT}/common/crc64.c
../common/crc64.c ${PM3_ROOT}/common/lfdemod.c
../common/lfdemod.c ${PM3_ROOT}/common/legic_prng.c
../common/legic_prng.c ${PM3_ROOT}/common/iso15693tools.c
../common/iso15693tools.c ${PM3_ROOT}/common/cardhelper.c
../common/cardhelper.c ${PM3_ROOT}/common/generator.c
../common/generator.c ${PM3_ROOT}/client/src/crypto/asn1dump.c
src/crypto/asn1dump.c ${PM3_ROOT}/client/src/crypto/asn1utils.c
src/crypto/asn1utils.c ${PM3_ROOT}/client/src/crypto/libpcrypto.c
src/crypto/libpcrypto.c ${PM3_ROOT}/client/src/emv/test/cda_test.c
src/emv/test/cda_test.c ${PM3_ROOT}/client/src/emv/test/crypto_test.c
src/emv/test/crypto_test.c ${PM3_ROOT}/client/src/emv/test/cryptotest.c
src/emv/test/cryptotest.c ${PM3_ROOT}/client/src/emv/test/dda_test.c
src/emv/test/dda_test.c ${PM3_ROOT}/client/src/emv/test/sda_test.c
src/emv/test/sda_test.c ${PM3_ROOT}/client/src/emv/apduinfo.c
src/emv/apduinfo.c ${PM3_ROOT}/client/src/emv/cmdemv.c
src/emv/cmdemv.c ${PM3_ROOT}/client/src/emv/crypto.c
src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c
src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c
src/emv/dol.c ${PM3_ROOT}/client/src/emv/dump.c
src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c
src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c
src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c
src/emv/emv_pki_priv.c ${PM3_ROOT}/client/src/emv/emv_roca.c
src/emv/emv_roca.c ${PM3_ROOT}/client/src/emv/emv_tags.c
src/emv/emv_tags.c ${PM3_ROOT}/client/src/emv/emvcore.c
src/emv/emvcore.c ${PM3_ROOT}/client/src/emv/emvjson.c
src/emv/emvjson.c ${PM3_ROOT}/client/src/emv/tlv.c
src/emv/tlv.c ${PM3_ROOT}/client/src/fido/additional_ca.c
src/fido/additional_ca.c ${PM3_ROOT}/client/src/fido/cbortools.c
src/fido/cbortools.c ${PM3_ROOT}/client/src/fido/cose.c
src/fido/cose.c ${PM3_ROOT}/client/src/fido/fidocore.c
src/fido/fidocore.c ${PM3_ROOT}/client/src/loclass/cipher.c
src/loclass/cipher.c ${PM3_ROOT}/client/src/loclass/cipherutils.c
src/loclass/cipherutils.c ${PM3_ROOT}/client/src/loclass/elite_crack.c
src/loclass/elite_crack.c ${PM3_ROOT}/client/src/loclass/hash1_brute.c
src/loclass/hash1_brute.c ${PM3_ROOT}/client/src/loclass/ikeys.c
src/loclass/ikeys.c ${PM3_ROOT}/client/src/mifare/mad.c
src/mifare/mad.c ${PM3_ROOT}/client/src/mifare/mfkey.c
src/mifare/mfkey.c ${PM3_ROOT}/client/src/mifare/mifare4.c
src/mifare/mifare4.c ${PM3_ROOT}/client/src/mifare/mifaredefault.c
src/mifare/mifaredefault.c ${PM3_ROOT}/client/src/mifare/mifarehost.c
src/mifare/mifarehost.c ${PM3_ROOT}/client/src/mifare/ndef.c
src/mifare/ndef.c ${PM3_ROOT}/client/src/mifare/desfire_crypto.c
src/mifare/desfire_crypto.c ${PM3_ROOT}/client/src/uart/uart_posix.c
src/uart/uart_posix.c ${PM3_ROOT}/client/src/uart/uart_win32.c
src/uart/uart_win32.c ${PM3_ROOT}/client/src/ui/overlays.ui
src/ui/overlays.ui ${PM3_ROOT}/client/src/aidsearch.c
src/aidsearch.c ${PM3_ROOT}/client/src/cmdanalyse.c
src/cmdanalyse.c ${PM3_ROOT}/client/src/cmdcrc.c
src/cmdcrc.c ${PM3_ROOT}/client/src/cmddata.c
src/cmddata.c ${PM3_ROOT}/client/src/cmdflashmem.c
src/cmdflashmem.c ${PM3_ROOT}/client/src/cmdflashmemspiffs.c
src/cmdflashmemspiffs.c ${PM3_ROOT}/client/src/cmdhf.c
src/cmdhf.c ${PM3_ROOT}/client/src/cmdhf14a.c
src/cmdhf14a.c ${PM3_ROOT}/client/src/cmdhf14b.c
src/cmdhf14b.c ${PM3_ROOT}/client/src/cmdhf15.c
src/cmdhf15.c ${PM3_ROOT}/client/src/cmdhfcryptorf.c
src/cmdhfcryptorf.c ${PM3_ROOT}/client/src/cmdhfepa.c
src/cmdhfepa.c ${PM3_ROOT}/client/src/cmdhffelica.c
src/cmdhffelica.c ${PM3_ROOT}/client/src/cmdhffido.c
src/cmdhffido.c ${PM3_ROOT}/client/src/cmdhficlass.c
src/cmdhficlass.c ${PM3_ROOT}/client/src/cmdhflegic.c
src/cmdhflegic.c ${PM3_ROOT}/client/src/cmdhflist.c
src/cmdhflist.c ${PM3_ROOT}/client/src/cmdhflto.c
src/cmdhflto.c ${PM3_ROOT}/client/src/cmdhfmf.c
src/cmdhfmf.c ${PM3_ROOT}/client/src/cmdhfmfdes.c
src/cmdhfmfdes.c ${PM3_ROOT}/client/src/cmdhfmfhard.c
src/cmdhfmfhard.c ${PM3_ROOT}/client/src/cmdhfmfp.c
src/cmdhfmfp.c ${PM3_ROOT}/client/src/cmdhfmfu.c
src/cmdhfmfu.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c
src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c
src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhw.c
src/cmdhw.c ${PM3_ROOT}/client/src/cmdlf.c
src/cmdlf.c ${PM3_ROOT}/client/src/cmdlfawid.c
src/cmdlfawid.c ${PM3_ROOT}/client/src/cmdlfcotag.c
src/cmdlfcotag.c ${PM3_ROOT}/client/src/cmdlfem4x.c
src/cmdlfem4x.c ${PM3_ROOT}/client/src/cmdlffdx.c
src/cmdlffdx.c ${PM3_ROOT}/client/src/cmdlfgallagher.c
src/cmdlfgallagher.c ${PM3_ROOT}/client/src/cmdlfguard.c
src/cmdlfguard.c ${PM3_ROOT}/client/src/cmdlfhid.c
src/cmdlfhid.c ${PM3_ROOT}/client/src/cmdlfhitag.c
src/cmdlfhitag.c ${PM3_ROOT}/client/src/cmdlfindala.c
src/cmdlfindala.c ${PM3_ROOT}/client/src/cmdlfio.c
src/cmdlfio.c ${PM3_ROOT}/client/src/cmdlfjablotron.c
src/cmdlfjablotron.c ${PM3_ROOT}/client/src/cmdlfkeri.c
src/cmdlfkeri.c ${PM3_ROOT}/client/src/cmdlfmotorola.c
src/cmdlfmotorola.c ${PM3_ROOT}/client/src/cmdlfnedap.c
src/cmdlfnedap.c ${PM3_ROOT}/client/src/cmdlfnexwatch.c
src/cmdlfnexwatch.c ${PM3_ROOT}/client/src/cmdlfnoralsy.c
src/cmdlfnoralsy.c ${PM3_ROOT}/client/src/cmdlfpac.c
src/cmdlfpac.c ${PM3_ROOT}/client/src/cmdlfparadox.c
src/cmdlfparadox.c ${PM3_ROOT}/client/src/cmdlfpcf7931.c
src/cmdlfpcf7931.c ${PM3_ROOT}/client/src/cmdlfpresco.c
src/cmdlfpresco.c ${PM3_ROOT}/client/src/cmdlfpyramid.c
src/cmdlfpyramid.c ${PM3_ROOT}/client/src/cmdlfsecurakey.c
src/cmdlfsecurakey.c ${PM3_ROOT}/client/src/cmdlft55xx.c
src/cmdlft55xx.c ${PM3_ROOT}/client/src/cmdlfti.c
src/cmdlfti.c ${PM3_ROOT}/client/src/cmdlfverichip.c
src/cmdlfverichip.c ${PM3_ROOT}/client/src/cmdlfviking.c
src/cmdlfviking.c ${PM3_ROOT}/client/src/cmdlfvisa2000.c
src/cmdlfvisa2000.c ${PM3_ROOT}/client/src/cmdmain.c
src/cmdmain.c ${PM3_ROOT}/client/src/cmdparser.c
src/cmdparser.c ${PM3_ROOT}/client/src/cmdscript.c
src/cmdscript.c ${PM3_ROOT}/client/src/cmdsmartcard.c
src/cmdsmartcard.c ${PM3_ROOT}/client/src/cmdtrace.c
src/cmdtrace.c ${PM3_ROOT}/client/src/cmdusart.c
src/cmdusart.c ${PM3_ROOT}/client/src/cmdwiegand.c
src/cmdwiegand.c ${PM3_ROOT}/client/src/comms.c
src/comms.c ${PM3_ROOT}/client/src/fileutils.c
src/fileutils.c ${PM3_ROOT}/client/src/flash.c
src/flash.c ${PM3_ROOT}/client/src/graph.c
src/graph.c ${PM3_ROOT}/client/src/jansson_path.c
src/preferences.c ${PM3_ROOT}/client/src/preferences.c
src/pm3_binlib.c ${PM3_ROOT}/client/src/pm3_binlib.c
src/pm3_bitlib.c ${PM3_ROOT}/client/src/pm3_bitlib.c
src/prng.c ${PM3_ROOT}/client/src/prng.c
src/scandir.c ${PM3_ROOT}/client/src/scandir.c
src/scripting.c ${PM3_ROOT}/client/src/scripting.c
src/tea.c ${PM3_ROOT}/client/src/tea.c
src/ui.c ${PM3_ROOT}/client/src/ui.c
src/util.c ${PM3_ROOT}/client/src/util.c
src/whereami.c ${PM3_ROOT}/client/src/wiegand_formats.c
src/wiegand_formats.c ${PM3_ROOT}/client/src/wiegand_formatutils.c
src/wiegand_formatutils.c ${CMAKE_BINARY_DIR}/version.c
)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/version.c
COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c
DEPENDS ${PM3_ROOT}/common/default_version.c
) )
set(ADDITIONAL_SRC "") set(ADDITIONAL_SRC "")
set(ADDITIONAL_LNK "") set(ADDITIONAL_LNK "")
set(ADDITIONAL_DIRS "")
set(ADDITIONAL_LNKDIRS "")
set(X86_CPUS x86 x86_64 i686) set(X86_CPUS x86 x86_64 i686)
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
if (APPLE) if (APPLE)
message("Apple device detected.") message("Apple device detected.")
set(ADDITIONAL_SRC src/util_darwin.h src/util_darwin.m ${ADDITIONAL_SRC}) set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC})
set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit")
endif (APPLE) endif (APPLE)
if (Qt5_FOUND) if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
message("Qt5 library found, building gui :)")
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set (TARGET_SOURCES set (TARGET_SOURCES
src/proxgui.cpp ${PM3_ROOT}/client/src/proxgui.cpp
src/proxguiqt.cpp ${PM3_ROOT}/client/src/proxguiqt.cpp
${TARGET_SOURCES}) ${TARGET_SOURCES})
add_definitions("-DHAVE_GUI") add_definitions("-DHAVE_GUI")
set(ADDITIONAL_LNK Qt5::Core Qt5::Widgets Qt5::Gui ${ADDITIONAL_LNK}) set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK})
else (Qt5_FOUND) else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
message("Qt5 library not found, not building gui")
set(TARGET_SOURCES set(TARGET_SOURCES
src/guidummy.cpp ${PM3_ROOT}/client/src/guidummy.cpp
${TARGET_SOURCES}) ${TARGET_SOURCES})
endif (Qt5_FOUND) endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND))
add_executable( if (NOT SKIPBT EQUAL 1)
proxmark3 if (BLUEZ_FOUND)
add_definitions("-DHAVE_BLUEZ")
set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK})
endif (BLUEZ_FOUND)
endif(NOT SKIPBT EQUAL 1)
if (NOT SKIPPYTHON EQUAL 1)
if (PYTHON3EMBED_FOUND)
add_definitions(-DHAVE_PYTHON)
set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK})
set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS})
elseif (PYTHON3_FOUND)
add_definitions(-DHAVE_PYTHON)
set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK})
set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS})
endif (PYTHON3EMBED_FOUND)
endif (NOT SKIPPYTHON EQUAL 1)
if (NOT SKIPREADLINE EQUAL 1)
if (READLINE_FOUND)
add_definitions("-DHAVE_READLINE")
set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK})
endif (READLINE_FOUND)
endif(NOT SKIPREADLINE EQUAL 1)
if (BZIP2_FOUND)
set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK})
else (BZIP2_FOUND)
message(FATAL_ERROR "Bzip2 not found")
endif (BZIP2_FOUND)
message("===================================================================")
if (SKIPQT EQUAL 1)
message("GUI support: skipped")
else (SKIPQT EQUAL 1)
if (Qt5_FOUND)
message("GUI support: QT5 found, enabled")
else (Qt5_FOUND)
message("GUI support: QT5 not found, disabled")
endif (Qt5_FOUND)
endif (SKIPQT EQUAL 1)
if (SKIPBT EQUAL 1)
message("native BT support: skipped")
else (SKIPBT EQUAL 1)
if (BLUEZ_FOUND)
message("native BT support: Bluez found, enabled")
else (BLUEZ_FOUND)
message("native BT support: Bluez not found, disabled")
endif (BLUEZ_FOUND)
endif(SKIPBT EQUAL 1)
if (SKIPPYTHON EQUAL 1)
message("Python3 library: skipped")
else (SKIPPYTHON EQUAL 1)
if (PYTHON3EMBED_FOUND)
message("Python3 library: Python3 embed found, enabled")
elseif (PYTHON_FOUND)
message("Python3 library: Python3 found, enabled")
else (PYTHON3EMBED_FOUND)
message("Python3 library: Python3 not found, disabled")
endif (PYTHON3EMBED_FOUND)
endif(SKIPPYTHON EQUAL 1)
if (SKIPREADLINE EQUAL 1)
message("Readline library: skipped")
else (SKIPREADLINE EQUAL 1)
if (READLINE_FOUND)
message("Readline library: enabled")
else (READLINE_FOUND)
message("Readline library: Readline not found, disabled")
endif (READLINE_FOUND)
endif(SKIPREADLINE EQUAL 1)
message("===================================================================")
add_executable(proxmark3
${PM3_ROOT}/client/src/proxmark3.c
${TARGET_SOURCES} ${TARGET_SOURCES}
${ADDITIONAL_SRC} ${ADDITIONAL_SRC}
) )
target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3)
if (ANDROID)
if (NOT SKIPREADLINE EQUAL 1)
add_dependencies(proxmark3 ncurses readline)
endif (NOT SKIPREADLINE EQUAL 1)
add_dependencies(proxmark3 bzip2)
endif (ANDROID)
if (MINGW) if (MINGW)
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
@ -228,34 +406,59 @@ if (MINGW)
endif (MINGW) endif (MINGW)
target_include_directories(proxmark3 PRIVATE target_include_directories(proxmark3 PRIVATE
../common ${PM3_ROOT}/common
../common_fpga ${PM3_ROOT}/common_fpga
../include ${PM3_ROOT}/include
src ${PM3_ROOT}/client/src
${PM3_ROOT}/client/include
${ADDITIONAL_DIRS}
) )
if (APPLE) if (NOT APPLE)
set_target_properties(proxmark3 PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks, -L/usr/local/opt/readline/lib")
set_target_properties(proxmark3 PROPERTIES COMPILE_FLAGS "-I/usr/local/opt/readline/include")
else (APPLE)
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
endif (APPLE) endif (NOT APPLE)
find_library(cliparser REQUIRED) find_library(pm3rrg_rdv4_cliparser REQUIRED)
find_library(jansson REQUIRED) find_library(pm3rrg_rdv4_jansson REQUIRED)
find_library(tinycbor REQUIRED) find_library(pm3rrg_rdv4_tinycbor REQUIRED)
find_library(lua REQUIRED) find_library(pm3rrg_rdv4_lua REQUIRED)
find_library(mbedtls REQUIRED) find_library(pm3rrg_rdv4_mbedtls REQUIRED)
find_library(reveng REQUIRED) find_library(pm3rrg_rdv4_reveng REQUIRED)
find_library(z REQUIRED) find_library(pm3rrg_rdv4_hardnested REQUIRED)
find_library(hardnested REQUIRED) find_library(pm3rrg_rdv4_whereami REQUIRED)
target_link_libraries(proxmark3 PRIVATE readline pthread m mbedtls cliparser jansson lua tinycbor amiibo reveng z hardnested ${ADDITIONAL_LNK}) target_link_libraries(proxmark3 PRIVATE
m
pm3rrg_rdv4_mbedtls
pm3rrg_rdv4_cliparser
pm3rrg_rdv4_jansson
pm3rrg_rdv4_lua
pm3rrg_rdv4_tinycbor
pm3rrg_rdv4_amiibo
pm3rrg_rdv4_reveng
pm3rrg_rdv4_hardnested
pm3rrg_rdv4_whereami
${ADDITIONAL_LNK})
if (NOT SKIPPTHREAD EQUAL 1)
target_link_libraries(proxmark3 PRIVATE pthread)
endif (NOT SKIPPTHREAD EQUAL 1)
if (NOT SKIPPYTHON EQUAL 1)
# OSX have a hard time compiling python3 dependency with older cmake.
if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
if (NOT CMAKE_VERSION VERSION_LESS 3.13)
target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS})
elseif (APPLE)
message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" )
endif (NOT CMAKE_VERSION VERSION_LESS 3.13)
endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND)
endif (NOT SKIPPYTHON EQUAL 1)
install(TARGETS proxmark3 DESTINATION "bin") install(TARGETS proxmark3 DESTINATION "bin")
install(DIRECTORY cmdscripts lualibs luascripts resources dictionaries DESTINATION "share/proxmark3") install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3")
add_custom_command(OUTPUT lualibs/pm3_cmd.lua add_custom_command(OUTPUT lualibs/pm3_cmd.lua
COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua" COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua"

View file

@ -4,26 +4,163 @@
# the license. # the license.
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# 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)
# Must be called before any Makefile include # Must be called before any Makefile include
ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST)))) ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
include ../Makefile.defs include ../Makefile.defs
INSTALLBIN = proxmark3 INSTALLBIN = proxmark3
INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries INSTALLSHARE = cmdscripts lualibs luascripts pyscripts resources dictionaries
VPATH = ../common src VPATH = ../common src
vpath %.dic dictionaries vpath %.dic dictionaries
OBJDIR = obj OBJDIR = obj
LDLIBS ?= -L/usr/local/lib ifeq ($(platform),Darwin)
LDLIBS += -lreadline -lpthread -lm # cf brew info qt: qt not symlinked anymore
PKG_CONFIG_ENV := PKG_CONFIG_PATH=/usr/local/opt/qt/lib/pkgconfig
endif
###################
# local libraries #
###################
## Amiibo
AMIIBOLIBPATH = ./deps/amiitool
AMIIBOLIBINC = -I$(AMIIBOLIBPATH)
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
## Cliparser / Argtable3
CLIPARSERLIBPATH = ./deps/cliparser
CLIPARSERLIBINC = -I$(CLIPARSERLIBPATH)
CLIPARSERLIB = $(CLIPARSERLIBPATH)/libcliparser.a
## Hardnested
HARDNESTEDLIBPATH = ./deps/hardnested
HARDNESTEDLIBINC = -I$(HARDNESTEDLIBPATH)
HARDNESTEDLIB = $(HARDNESTEDLIBPATH)/libhardnested.a
## Jansson
JANSSONLIBPATH = ./deps/jansson
JANSSONLIBINC = -I$(JANSSONLIBPATH)
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
## Lua
LUALIBPATH = ./deps/liblua
LUALIBINC = -I$(LUALIBPATH)
LUALIB = $(LUALIBPATH)/liblua.a
LUAPLATFORM = generic
ifneq (,$(findstring MINGW,$(platform)))
LUAPLATFORM = mingw
else
ifeq ($(platform),Darwin)
LUAPLATFORM = macosx
else
LUALIB += -ldl
LUAPLATFORM = linux
endif
endif
## Reveng
REVENGLIBPATH = ./deps/reveng
REVENGLIBINC = -I$(REVENGLIBPATH)
REVENGLIB = $(REVENGLIBPATH)/libreveng.a
## Tinycbor
TINYCBORLIBPATH = ./deps/tinycbor
TINYCBORLIBINC = -I$(TINYCBORLIBPATH)
TINYCBORLIB = $(TINYCBORLIBPATH)/tinycbor.a
## Whereami
WHEREAMILIBPATH = ./deps/whereami
WHEREAMILIBINC = -I$(WHEREAMILIBPATH)
WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a
##########################
# common local libraries #
##########################
## mbed TLS
MBEDTLSLIBPATH = ../common/mbedtls
MBEDTLSLIBINC = -I$(MBEDTLSLIBPATH)
MBEDTLSLIB = $(OBJDIR)/libmbedtls.a
########################################################
# optional system libraries to replace local libraries #
########################################################
## Amiibo
# not distributed as system library
LDLIBS += $(AMIIBOLIB)
INCLUDES += $(AMIIBOLIBINC)
## Cliparser / Argtable3
# not distributed as system library
LDLIBS += $(CLIPARSERLIB)
INCLUDES += $(CLIPARSERLIBINC)
## Hardnested
# not distributed as system library
LDLIBS += $(HARDNESTEDLIB)
INCLUDES += $(HARDNESTEDLIBINC)
## Jansson
ifneq ($(SKIPJANSSONSYSTEM),1)
JANSSONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags jansson 2>/dev/null)
JANSSONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs jansson 2>/dev/null)
ifneq ($(JANSSONLDLIBS),)
JANSSONLIB = $(JANSSONLDLIBS)
JANSSONLIBINC = $(JANSSONINCLUDES)
JANSSON_FOUND = 1
endif
endif
LDLIBS += $(JANSSONLIB)
INCLUDES += $(JANSSONLIBINC)
## Lua
ifneq ($(SKIPLUASYSTEM),1)
LUAINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags lua5.2 2>/dev/null)
LUALDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs lua5.2 2>/dev/null)
ifneq ($(LUALDLIBS),)
LUALIB = $(LUALDLIBS)
LUALIBINC = $(LUAINCLUDES)
LUA_FOUND = 1
endif
endif
LDLIBS += $(LUALIB)
INCLUDES += $(LUALIBINC)
## mbed TLS
# system library cannot be used because it is compiled by default without CMAC support
LDLIBS +=$(MBEDTLSLIB)
INCLUDES += $(MBEDTLSLIBINC)
## Reveng
# not distributed as system library
LDLIBS += $(REVENGLIB)
INCLUDES += $(REVENGLIBINC)
## Tinycbor
# not distributed as system library
LDLIBS += $(TINYCBORLIB)
INCLUDES += $(TINYCBORLIBINC)
## Whereami
ifneq ($(SKIPWHEREAMISYSTEM),1)
ifneq (,$(wildcard /usr/include/whereami.h))
WHEREAMILIB = -lwhereami
WHEREAMILIBINC =
WHEREAMI_FOUND = 1
endif
endif
LDLIBS += $(WHEREAMILIB)
INCLUDES += $(WHEREAMILIBINC)
####################
# system libraries #
####################
## Atomic
# RPi Zero gcc requires -latomic # RPi Zero gcc requires -latomic
# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld # but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
# doesn't recognize option --as-needed # doesn't recognize option --as-needed
@ -31,35 +168,111 @@ ifneq ($(platform),Darwin)
LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed
endif endif
# local libraries ## BZIP2
LUALIBPATH = ./deps/liblua LDLIBS += -lbz2
LUALIB = $(LUALIBPATH)/liblua.a
JANSSONLIBPATH = ./deps/jansson
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
CBORLIBPATH = ./deps/tinycbor
CBORLIB = $(CBORLIBPATH)/tinycbor.a
REVENGPATH = ./deps/reveng
REVENGLIB = $(REVENGPATH)/libreveng.a
AMIIBOLIBPATH = ./deps/amiitool
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
HARDNESTEDPATH = ./deps/hardnested
HARDNESTEDLIB = $(HARDNESTEDPATH)/libhardnested.a
CLIPARSERPATH = ./deps/cliparser
CLIPARSERLIB = $(CLIPARSERPATH)/libcliparser.a
# common libraries ## Bluez (optional)
MBEDTLSLIBPATH = ../common/mbedtls ifneq ($(SKIPBT),1)
MBEDTLSLIB = $(OBJDIR)/libmbedtls.a BTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags bluez 2>/dev/null)
ZLIBPATH = ../common/zlib BTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs bluez 2>/dev/null)
ZLIB = $(OBJDIR)/libz.a ifneq ($(BTLDLIBS),)
BTLIB = $(BTLDLIBS)
BTLIBINC = $(BTINCLUDES)
BT_FOUND = 1
endif
endif
LDLIBS += $(BTLIB)
INCLUDES += $(BTLIBINC)
LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH) -I$(HARDNESTEDPATH) -I$(CLIPARSERPATH) ## Math
INCLUDES_CLIENT = -I./src -I../include -I../common -I../common_fpga $(LIBS) LDLIBS += -lm
CFLAGS ?= -Wall -Werror -O3
## Pthread
# Some have no pthread, e.g. termux
ifneq ($(SKIPPTHREAD),1)
LDLIBS += -lpthread
endif
## Python3 (optional)
ifneq ($(SKIPPYTHON),1)
PYTHONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags python3 2>/dev/null)
PYTHONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs python3 2>/dev/null)
ifneq ($(PYTHONLDLIBS),)
PYTHONLIB = $(PYTHONLDLIBS)
PYTHONLIBINC = $(PYTHONINCLUDES)
PYTHON_FOUND = 1
else
# since python3.8, applications willing to embed python must use -embed:
PYTHONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags python3-embed 2>/dev/null)
PYTHONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs python3-embed 2>/dev/null)
ifneq ($(PYTHONLDLIBS),)
PYTHONLIB = $(PYTHONLDLIBS)
PYTHONLIBINC = $(PYTHONINCLUDES)
PYTHON_FOUND = 1
endif
endif
endif
LDLIBS += $(PYTHONLIB)
INCLUDES += $(PYTHONLIBINC)
## QT5 (or QT4 fallback) (optional)
ifneq ($(SKIPQT),1)
# Check for correctly configured Qt5
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null)
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic
ifneq ($(QTLDLIBS),)
QT5_FOUND = 1
else
# if Qt5 not found check for correctly configured Qt4
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags QtCore QtGui 2>/dev/null)
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null)
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore)
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore)
endif
ifeq ($(QTLDLIBS),)
# if both pkg-config commands failed, search in common places
ifneq ($(QTDIR),)
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
# QT5
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui -I$(QTDIR)/include/QtWidgets
QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets
QT5_FOUND = 1
else
# QT4
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
endif
MOC = $(QTDIR)/bin/moc
UIC = $(QTDIR)/bin/uic
endif
endif
ifneq ($(QTLDLIBS),)
QT_FOUND = 1
endif
endif
LDLIBS += $(QTLDLIBS)
CXXINCLUDES += $(QTINCLUDES)
## Readline
ifneq ($(SKIPREADLINE),1)
ifeq ($(platform),Darwin)
LDLIBS += -L/usr/local/opt/readline/lib
INCLUDES += -I/usr/local/opt/readline/include
endif
LDLIBS += -lreadline
READLINE_FOUND = 1
endif
#######################################################################################################
CFLAGS ?= $(DEFCFLAGS)
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
PM3CFLAGS = $(CFLAGS) $(INCLUDES_CLIENT) PM3CFLAGS = $(CFLAGS)
PM3CFLAGS += -I./src -I../include -I../common -I../common_fpga $(INCLUDES)
# WIP Testing # WIP Testing
#PM3CFLAGS = $(CFLAGS) -std=c11 -pedantic $(INCLUDES_CLIENT) #PM3CFLAGS += -std=c11 -pedantic
PREFIX ?= /usr/local PREFIX ?= /usr/local
ifneq (,$(findstring MINGW,$(platform))) ifneq (,$(findstring MINGW,$(platform)))
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
@ -69,158 +282,158 @@ ifneq (,$(findstring MINGW,$(platform)))
PM3CFLAGS += -D_ISOC99_SOURCE PM3CFLAGS += -D_ISOC99_SOURCE
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850 PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
endif endif
ifeq ($(READLINE_FOUND),1)
PM3CFLAGS += -DHAVE_READLINE
endif
ifeq ($(BT_FOUND),1)
PM3CFLAGS += -DHAVE_BLUEZ
endif
ifeq ($(PYTHON_FOUND),1)
PM3CFLAGS += -DHAVE_PYTHON
endif
CXXFLAGS ?= -Wall -Werror -O3 CXXFLAGS ?= -Wall -Werror -O3
PM3CXXFLAGS = $(CXXFLAGS) -I../include PM3CXXFLAGS = $(CXXFLAGS)
PM3CXXFLAGS += -I../include
LUAPLATFORM = generic ifeq ($(QT_FOUND),1)
ifneq (,$(findstring MINGW,$(platform))) PM3CFLAGS += -DHAVE_GUI
LUAPLATFORM = mingw PM3CXXFLAGS += -DQT_NO_DEBUG
else ifeq ($(QT5_FOUND),1)
ifeq ($(platform),Darwin)
LUAPLATFORM = macosx
OBJCSRCS = util_darwin.m
LDFLAGS += -framework Foundation -framework AppKit
LDLIBS := -L/usr/local/opt/readline/lib $(LDLIBS)
LIBS := -I/usr/local/opt/readline/include $(LIBS)
# cf brew info qt: qt not symlinked anymore
PKG_CONFIG_ENV := PKG_CONFIG_ENV=/usr/local/opt/qt/lib/pkgconfig
else
LUALIB += -ldl
LUAPLATFORM = linux
endif
endif
ifneq ($(SKIPQT),1)
# Check for correctly configured Qt5
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null)
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic
ifeq ($(QTINCLUDES), )
# if Qt5 not found check for correctly configured Qt4
QTINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags QtCore QtGui 2>/dev/null)
QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null)
MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore)
UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore)
else
# On OSX Qt5 is claiming for a C++11 compiler (gnu++14 works too, but if nothing it fails) # On OSX Qt5 is claiming for a C++11 compiler (gnu++14 works too, but if nothing it fails)
PM3CXXFLAGS += -fPIC -std=c++11 PM3CXXFLAGS += -fPIC -std=c++11
endif endif
ifeq ($(QTINCLUDES), )
# if both pkg-config commands failed, search in common places
ifneq ($(QTDIR), )
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
QTINCLUDES += -I$(QTDIR)/include/QtWidgets
QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core
PM3CXXFLAGS += -fPIC -std=c++11
endif endif
MOC = $(QTDIR)/bin/moc
UIC = $(QTDIR)/bin/uic PM3LDFLAGS = $(LDFLAGS)
ifeq ($(platform),Darwin)
PM3LDFLAGS += -framework Foundation -framework AppKit
endif endif
###################
# printing status #
###################
$(info ===================================================================)
$(info Client platform: $(platform))
ifeq ($(SKIPQT),1)
$(info GUI support: skipped)
else
ifeq ($(QT_FOUND),1)
ifeq ($(QT5_FOUND),1)
$(info GUI support: QT5 found, enabled)
else
$(info GUI support: QT4 found, enabled)
endif
else
$(info GUI support: QT not found, disabled)
endif endif
endif endif
ifneq ($(QTLDLIBS),) ifeq ($(SKIPBT),1)
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp $(info native BT support: skipped)
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
PM3CFLAGS += -DHAVE_GUI
PM3CXXFLAGS += -DQT_NO_DEBUG
else else
QTGUISRCS = guidummy.cpp ifeq ($(BT_FOUND),1)
QTGUIOBJS = $(OBJDIR)/guidummy.o $(info native BT support: Bluez found, enabled)
else
$(info native BT support: Bluez not found, disabled)
endif endif
endif
ifeq ($(SKIPJANSSONSYSTEM),1)
$(info Jansson library: local library forced)
else ifeq ($(JANSSON_FOUND),1)
$(info Jansson library: system library found)
else
$(info Jansson library: system library not found, using local library)
endif
ifeq ($(SKIPLUASYSTEM),1)
$(info Lua library: local library forced)
else
ifeq ($(LUA_FOUND),1)
$(info Lua library: system library found)
else
$(info Lua library: system library not found, using local library)
endif
endif
ifeq ($(SKIPPYTHON),1)
$(info Python3 library: skipped)
else
ifeq ($(PYTHON_FOUND),1)
$(info Python3 library: Python3 v$(shell pkg-config --modversion python3) found, enabled)
else
$(info Python3 library: Python3 not found, disabled)
endif
endif
ifeq ($(SKIPREADLINE),1)
$(info Readline library: skipped)
else
ifeq ($(READLINE_FOUND),1)
$(info Readline library: enabled)
else
$(info Readline library: Readline not found, disabled)
endif
endif
ifeq ($(SKIPWHEREAMISYSTEM),1)
$(info Whereami library: local library forced)
else
ifeq ($(WHEREAMI_FOUND),1)
$(info Whereami library: system library found)
else
$(info Whereami library: system library not found, using local library)
endif
endif
$(info compiler version: $(shell $(CC) --version|head -n 1))
$(info ===================================================================)
################
# dependencies #
################
# Flags to generate temporary dependency files # Flags to generate temporary dependency files
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
# make temporary to final dependency files after successful compilation # make temporary to final dependency files after successful compilation
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
CORESRCS = uart/uart_posix.c \ ################
uart/uart_win32.c \ # enumerations #
ui.c \ ################
commonutil.c \
util.c \
util_posix.c \
scandir.c \
crc16.c \
crc32.c \
comms.c
CMDSRCS = crapto1/crapto1.c \ SRCS = aidsearch.c \
crapto1/crypto1.c \
mifare/mifaredefault.c \
mifare/mfkey.c \
tea.c \
fido/additional_ca.c \
fido/cose.c \
fido/cbortools.c \
fido/fidocore.c \
crypto/asn1dump.c \
crypto/libpcrypto.c\
crypto/asn1utils.c\
loclass/cipher.c \
loclass/cipherutils.c \
loclass/ikeys.c \
loclass/elite_crack.c \
fileutils.c \
whereami.c \
mifare/mifarehost.c \
parity.c \
crc.c \
crc64.c \
legic_prng.c \
iso15693tools.c \
prng.c \
generator.c \
graph.c \
cmddata.c \
lfdemod.c \
emv/crypto_polarssl.c\
emv/crypto.c\
emv/emv_pk.c\
emv/emv_pki.c\
emv/emv_pki_priv.c\
emv/test/cryptotest.c\
emv/apduinfo.c \
emv/dump.c \
emv/tlv.c \
emv/emv_tags.c \
emv/dol.c \
emv/emvjson.c\
emv/emvcore.c \
emv/test/crypto_test.c\
emv/test/sda_test.c\
emv/test/dda_test.c\
emv/test/cda_test.c\
emv/cmdemv.c \
emv/emv_roca.c \
mifare/mifare4.c \
mifare/mad.c \
mifare/ndef.c \
mifare/desfire_crypto.c \
cmdanalyse.c \ cmdanalyse.c \
cmdcrc.c \
cmddata.c \
cmdflashmem.c \
cmdflashmemspiffs.c \
cmdhf.c \ cmdhf.c \
cmdhflist.c \
aidsearch.c \
cmdhf14a.c \ cmdhf14a.c \
cmdhf14b.c \ cmdhf14b.c \
cmdhf15.c \ cmdhf15.c \
cmdhfcryptorf.c \
cmdhfepa.c \ cmdhfepa.c \
cmdhflegic.c \ cmdhffelica.c \
cmdhffido.c \
cmdhficlass.c \ cmdhficlass.c \
cmdhflegic.c \
cmdhflist.c \
cmdhflto.c \
cmdhfmf.c \ cmdhfmf.c \
cmdhfmfdes.c \
cmdhfmfhard.c \
cmdhfmfu.c \ cmdhfmfu.c \
cmdhfmfp.c \ cmdhfmfp.c \
cmdhfmfhard.c \
cmdhfmfdes.c \
cmdhftopaz.c \
cmdhffido.c \
cmdhffelica.c \
cmdhfthinfilm.c \ cmdhfthinfilm.c \
cmdhfcryptorf.c \ cmdhftopaz.c \
cmdhflto.c \
cmdhw.c \ cmdhw.c \
cmdlf.c \ cmdlf.c \
cmdlfawid.c \ cmdlfawid.c \
@ -231,12 +444,13 @@ CMDSRCS = crapto1/crapto1.c \
cmdlfgallagher.c \ cmdlfgallagher.c \
cmdlfhid.c \ cmdlfhid.c \
cmdlfhitag.c \ cmdlfhitag.c \
cmdlfio.c \
cmdlfindala.c \ cmdlfindala.c \
cmdlfio.c \
cmdlfjablotron.c \ cmdlfjablotron.c \
cmdlfkeri.c \ cmdlfkeri.c \
cmdlfnexwatch.c \ cmdlfmotorola.c \
cmdlfnedap.c \ cmdlfnedap.c \
cmdlfnexwatch.c \
cmdlfnoralsy.c \ cmdlfnoralsy.c \
cmdlfpac.c \ cmdlfpac.c \
cmdlfparadox.c \ cmdlfparadox.c \
@ -248,48 +462,123 @@ CMDSRCS = crapto1/crapto1.c \
cmdlfti.c \ cmdlfti.c \
cmdlfviking.c \ cmdlfviking.c \
cmdlfvisa2000.c \ cmdlfvisa2000.c \
cmdlfmotorola.c \ cmdmain.c \
cmdtrace.c \ cmdparser.c \
cmdflashmem.c \ cmdscript.c \
cmdflashmemspiffs.c \
cmdsmartcard.c \ cmdsmartcard.c \
cmdtrace.c \
cmdusart.c \ cmdusart.c \
cmdwiegand.c \ cmdwiegand.c \
cmdparser.c \ comms.c \
cmdmain.c \ crypto/asn1dump.c \
pm3_binlib.c \ crypto/asn1utils.c\
scripting.c \ crypto/libpcrypto.c\
cmdscript.c \ emv/apduinfo.c \
pm3_bitlib.c \ emv/cmdemv.c \
cmdcrc.c \ emv/crypto.c\
bucketsort.c \ emv/crypto_polarssl.c\
emv/dol.c \
emv/dump.c \
emv/emv_pk.c\
emv/emv_pki.c\
emv/emv_pki_priv.c\
emv/emv_roca.c \
emv/emv_tags.c \
emv/emvcore.c \
emv/emvjson.c\
emv/tlv.c \
emv/test/crypto_test.c\
emv/test/cryptotest.c\
emv/test/cda_test.c\
emv/test/dda_test.c\
emv/test/sda_test.c\
fido/additional_ca.c \
fido/cose.c \
fido/cbortools.c \
fido/fidocore.c \
fileutils.c \
flash.c \ flash.c \
generator.c \
graph.c \
jansson_path.c \
loclass/cipher.c \
loclass/cipherutils.c \
loclass/elite_crack.c \
loclass/ikeys.c \
mifare/desfire_crypto.c \
mifare/mad.c \
mifare/mfkey.c \
mifare/mifare4.c \
mifare/mifaredefault.c \
mifare/mifarehost.c \
mifare/ndef.c \
pm3_binlib.c \
pm3_bitlib.c \
preferences.c \
prng.c \
proxmark3.c \
scandir.c \
uart/uart_posix.c \
uart/uart_win32.c \
scripting.c \
tea.c \
ui.c \
util.c \
version.c \
wiegand_formats.c \ wiegand_formats.c \
wiegand_formatutils.c \ wiegand_formatutils.c
# common
SRCS += bucketsort.c \
cardhelper.c \ cardhelper.c \
preferences.c crapto1/crapto1.c \
crapto1/crypto1.c \
crc.c \
crc16.c \
crc32.c \
crc64.c \
commonutil.c \
iso15693tools.c \
legic_prng.c \
lfdemod.c \
parity.c \
util_posix.c
# gui
ifeq ($(QT_FOUND),1)
CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp
else
CXXSRCS = guidummy.cpp
endif
# OS X
ifeq ($(platform),Darwin)
OBJCSRCS = util_darwin.m
endif
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) OBJS = $(SRCS:%.c=$(OBJDIR)/%.o)
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o)
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o) OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
BINS = proxmark3 BINS = proxmark3
CLEAN = $(BINS) src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
CLEAN = $(BINS) src/version.c src/*.moc.cpp src/ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
# transition: cleaning also old path stuff # transition: cleaning also old path stuff
CLEAN += flasher *.moc.cpp ui/ui_overlays.h CLEAN += flasher *.moc.cpp ui/ui_overlays.h
###########
# targets #
###########
# need to assign dependancies to build these first... # need to assign dependancies to build these first...
all: $(BINS) all: $(BINS)
all-static: LDLIBS:=-static $(LDLIBS) all-static: LDLIBS:=-static $(LDLIBS)
all-static: $(BINS) all-static: $(BINS)
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) $(QTLDLIBS) proxmark3: $(OBJS) amiibo cliparser jansson hardnested lua mbedtls reveng tinycbor whereami lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) $(HARDNESTEDLIB) $(CLIPARSERLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
$(info [=] LD $@) $(info [=] LD $@)
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(LDLIBS) -o $@ $(Q)$(LD) $(PM3LDFLAGS) $(OBJS) $(LDLIBS) -o $@
src/proxgui.cpp: src/ui/ui_overlays.h src/proxgui.cpp: src/ui/ui_overlays.h
@ -312,13 +601,16 @@ lualibs/mfc_default_keys.lua : mfc_default_keys.dic
clean: clean:
$(Q)$(RM) $(CLEAN) $(Q)$(RM) $(CLEAN)
$(Q)$(RMDIR) $(OBJDIR) $(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 $(CBORLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) clean $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) clean $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) clean
@# Just in case someone compiled within these dirs:
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
install: all install: all
$(info [@] Installing client to $(DESTDIR)$(PREFIX)...) $(info [@] Installing client to $(DESTDIR)$(PREFIX)...)
@ -346,45 +638,62 @@ tarbin: $(BINS)
$(info [=] TAR ../proxmark3-$(platform)-bin.tar) $(info [=] TAR ../proxmark3-$(platform)-bin.tar)
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
# local libraries: ###########################
$(LUALIB): # local libraries targets #
$(info [*] MAKE liblua for $(LUAPLATFORM)) ###########################
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
$(JANSSONLIB): amiibo:
$(info [*] MAKE jansson) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
$(CBORLIB):
$(info [*] MAKE tinycbor)
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all
$(REVENGLIB):
$(info [*] MAKE reveng)
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all
$(HARDNESTEDLIB):
$(info [*] MAKE hardnested)
$(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDPATH) all
$(AMIIBOLIB):
$(info [*] MAKE amiibo)
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all $(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all
$(CLIPARSERLIB): cliparser:
$(info [*] MAKE cliparser) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(CLIPARSERPATH) all $(Q)$(MAKE) --no-print-directory -C $(CLIPARSERLIBPATH) all
# common libraries: hardnested:
$(MBEDTLSLIB): $(info [*] MAKE $@)
$(info [*] MAKE mbedtls) $(Q)$(MAKE) --no-print-directory -C $(HARDNESTEDLIBPATH) all
jansson:
ifneq ($(JANSSON_FOUND),1)
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
endif
lua:
ifneq ($(LUA_FOUND),1)
$(info [*] MAKE $@ for $(LUAPLATFORM))
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
endif
mbedtls:
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all $(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
$(ZLIB): reveng:
$(info [*] MAKE zlib) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all $(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) all
.PHONY: all clean install uninstall tinycbor:
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) all
whereami:
ifneq ($(WHEREAMI_FOUND),1)
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
endif
########
# misc #
########
.PHONY: all clean install uninstall tarbin amiibo cliparser hardnested jansson lua mbedtls reveng tinycbor whereami
# version.c should be remade on every compilation
src/version.c: default_version.c
$(info [=] GEN $@)
$(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@
# easy printing of MAKE VARIABLES # easy printing of MAKE VARIABLES
print-%: ; @echo $* = $($*) print-%: ; @echo $* = $($*)
@ -400,7 +709,7 @@ $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d $(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
$(info [-] CXX $<) $(info [-] CXX $<)
$(Q)$(MKDIR) $(dir $@) $(Q)$(MKDIR) $(dir $@)
$(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $< $(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(CXXINCLUDES) -c -o $@ $<
$(Q)$(POSTCOMPILE) $(Q)$(POSTCOMPILE)
%.o: %.m %.o: %.m
@ -410,10 +719,9 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $< $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
$(Q)$(POSTCOMPILE) $(Q)$(POSTCOMPILE)
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS)) \ DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS))
$(OBJDIR)/proxmark3.d
$(DEPENDENCY_FILES): ; $(DEPENDENCY_FILES): ;
.PRECIOUS: $(DEPENDENCY_FILES) .PRECIOUS: $(DEPENDENCY_FILES)

View file

@ -0,0 +1,183 @@
# version
cmake_minimum_required(VERSION 3.4.1)
# We are build on android platform, so we need add def "ANDROID"
# NDK version for SDK 19 doesn't implement the whole C++11 standard in the STL.
# see: https://stackoverflow.com/questions/44736135/ndk-clang-error-undefined-reference-to-localeconv
# so we need add def getlocaledecpoint()='.'
add_definitions(-DANDROID -D"getlocaledecpoint\(\)='.'")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -fvisibility=hidden -w")
# Root path into client
set(PM3_ROOT ../../)
add_subdirectory(../deps deps)
# client resources
add_library(pm3rrg_rdv4 SHARED
${PM3_ROOT}/common/util_posix.c
${PM3_ROOT}/common/crapto1/crapto1.c
${PM3_ROOT}/common/crapto1/crypto1.c
${PM3_ROOT}/common/crc.c
${PM3_ROOT}/common/crc16.c
${PM3_ROOT}/common/crc32.c
${PM3_ROOT}/common/crc64.c
${PM3_ROOT}/common/cardhelper.c
${PM3_ROOT}/common/parity.c
${PM3_ROOT}/common/commonutil.c
${PM3_ROOT}/common/generator.c
${PM3_ROOT}/common/lfdemod.c
${PM3_ROOT}/common/iso15693tools.c
${PM3_ROOT}/common/bucketsort.c
${PM3_ROOT}/common/legic_prng.c
# client inside
${PM3_ROOT}/client/src/fileutils.c
${PM3_ROOT}/client/src/uart/uart_posix.c
${PM3_ROOT}/client/src/loclass/cipherutils.c
${PM3_ROOT}/client/src/loclass/cipher.c
${PM3_ROOT}/client/src/loclass/ikeys.c
${PM3_ROOT}/client/src/loclass/elite_crack.c
${PM3_ROOT}/client/src/emv/emvcore.c
${PM3_ROOT}/client/src/emv/cmdemv.c
${PM3_ROOT}/client/src/emv/tlv.c
${PM3_ROOT}/client/src/emv/dol.c
${PM3_ROOT}/client/src/emv/emv_tags.c
${PM3_ROOT}/client/src/emv/emv_roca.c
${PM3_ROOT}/client/src/emv/dump.c
${PM3_ROOT}/client/src/emv/crypto_polarssl.c
${PM3_ROOT}/client/src/emv/crypto.c
${PM3_ROOT}/client/src/emv/emv_pk.c
${PM3_ROOT}/client/src/emv/emv_pki.c
${PM3_ROOT}/client/src/emv/emvjson.c
${PM3_ROOT}/client/src/emv/apduinfo.c
${PM3_ROOT}/client/src/emv/test/cryptotest.c
${PM3_ROOT}/client/src/emv/test/sda_test.c
${PM3_ROOT}/client/src/emv/test/dda_test.c
${PM3_ROOT}/client/src/emv/test/cda_test.c
${PM3_ROOT}/client/src/emv/test/crypto_test.c
${PM3_ROOT}/client/src/emv/test/cryptotest.c
${PM3_ROOT}/client/src/emv/test/sda_test.c
${PM3_ROOT}/client/src/emv/test/dda_test.c
${PM3_ROOT}/client/src/emv/test/cda_test.c
${PM3_ROOT}/client/src/emv/test/crypto_test.c
${PM3_ROOT}/client/src/crypto/libpcrypto.c
${PM3_ROOT}/client/src/crypto/asn1utils.c
${PM3_ROOT}/client/src/crypto/asn1dump.c
${PM3_ROOT}/client/src/mifare/mad.c
${PM3_ROOT}/client/src/mifare/mfkey.c
${PM3_ROOT}/client/src/mifare/mifare4.c
${PM3_ROOT}/client/src/mifare/mifarehost.c
${PM3_ROOT}/client/src/mifare/ndef.c
${PM3_ROOT}/client/src/mifare/desfire_crypto.c
${PM3_ROOT}/client/src/mifare/mifaredefault.c
${PM3_ROOT}/client/src/fido/cose.c
${PM3_ROOT}/client/src/fido/fidocore.c
${PM3_ROOT}/client/src/fido/cbortools.c
${PM3_ROOT}/client/src/fido/additional_ca.c
${PM3_ROOT}/client/src/preferences.c
${PM3_ROOT}/client/src/graph.c
${PM3_ROOT}/client/src/ui.c
${PM3_ROOT}/client/src/tea.c
${PM3_ROOT}/client/src/util.c
${PM3_ROOT}/client/src/comms.c
${PM3_ROOT}/client/src/cmdcrc.c
${PM3_ROOT}/client/src/cmdanalyse.c
${PM3_ROOT}/client/src/cmddata.c
${PM3_ROOT}/client/src/cmdtrace.c
${PM3_ROOT}/client/src/cmdhf.c
${PM3_ROOT}/client/src/cmdhflto.c
${PM3_ROOT}/client/src/aidsearch.c
${PM3_ROOT}/client/src/cmdhf14a.c
${PM3_ROOT}/client/src/cmdhf14b.c
${PM3_ROOT}/client/src/cmdwiegand.c
${PM3_ROOT}/client/src/wiegand_formatutils.c
${PM3_ROOT}/client/src/wiegand_formats.c
${PM3_ROOT}/client/src/cmdlfmotorola.c
${PM3_ROOT}/client/src/cmdlfgallagher.c
${PM3_ROOT}/client/src/cmdhf15.c
${PM3_ROOT}/client/src/cmdhfepa.c
${PM3_ROOT}/client/src/cmdhflegic.c
${PM3_ROOT}/client/src/cmdhfthinfilm.c
${PM3_ROOT}/client/src/cmdflashmemspiffs.c
${PM3_ROOT}/client/src/cmdhffelica.c
${PM3_ROOT}/client/src/cmdhficlass.c
${PM3_ROOT}/client/src/cmdhflist.c
${PM3_ROOT}/client/src/cmdhfmf.c
${PM3_ROOT}/client/src/cmdhfmfdes.c
${PM3_ROOT}/client/src/cmdhfmfu.c
${PM3_ROOT}/client/src/cmdhfmfp.c
${PM3_ROOT}/client/src/cmdhffido.c
${PM3_ROOT}/client/src/cmdhftopaz.c
${PM3_ROOT}/client/src/cmdhw.c
${PM3_ROOT}/client/src/cmdlf.c
${PM3_ROOT}/client/src/cmdlfkeri.c
${PM3_ROOT}/client/src/cmdlffdx.c
${PM3_ROOT}/client/src/cmdlfio.c
${PM3_ROOT}/client/src/cmdlfem4x.c
${PM3_ROOT}/client/src/cmdlfhid.c
${PM3_ROOT}/client/src/cmdlfnedap.c
${PM3_ROOT}/client/src/cmdlfguard.c
${PM3_ROOT}/client/src/cmdlfhitag.c
${PM3_ROOT}/client/src/cmdlfjablotron.c
${PM3_ROOT}/client/src/cmdsmartcard.c
${PM3_ROOT}/client/src/cmdlfti.c
${PM3_ROOT}/client/src/cmdlfpac.c
${PM3_ROOT}/client/src/cmdlfnoralsy.c
${PM3_ROOT}/client/src/cmdlfnexwatch.c
${PM3_ROOT}/client/src/cmdlfpresco.c
${PM3_ROOT}/client/src/cmdlfindala.c
${PM3_ROOT}/client/src/cmdlfviking.c
${PM3_ROOT}/client/src/cmdlfsecurakey.c
${PM3_ROOT}/client/src/cmdlfpyramid.c
${PM3_ROOT}/client/src/cmdlfparadox.c
${PM3_ROOT}/client/src/cmdlfcotag.c
${PM3_ROOT}/client/src/cmdlfawid.c
${PM3_ROOT}/client/src/cmdparser.c
${PM3_ROOT}/client/src/cmdscript.c
${PM3_ROOT}/client/src/cmdlfvisa2000.c
${PM3_ROOT}/client/src/cmdmain.c
${PM3_ROOT}/client/src/cmdflashmem.c
${PM3_ROOT}/client/src/scripting.c
${PM3_ROOT}/client/src/pm3_binlib.c
${PM3_ROOT}/client/src/pm3_bitlib.c
${PM3_ROOT}/client/src/cmdlft55xx.c
${PM3_ROOT}/client/src/cmdlfpcf7931.c
${PM3_ROOT}/client/src/cmdhfmfhard.c
${PM3_ROOT}/client/src/cmdusart.c
${PM3_ROOT}/client/src/jansson_path.c
# android resources
jni_tools.c
pm3_main.c
)
# includes
target_include_directories(pm3rrg_rdv4 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${PM3_ROOT}/include/
${PM3_ROOT}/common
${PM3_ROOT}/common_fpga
${PM3_ROOT}/client/src)
find_library(pm3rrg_rdv4_cliparser REQUIRED)
find_library(pm3rrg_rdv4_jansson REQUIRED)
find_library(pm3rrg_rdv4_tinycbor REQUIRED)
find_library(pm3rrg_rdv4_lua REQUIRED)
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
find_library(pm3rrg_rdv4_reveng REQUIRED)
find_library(pm3rrg_rdv4_hardnested REQUIRED)
find_library(pm3rrg_rdv4_whereami REQUIRED)
target_link_libraries(pm3rrg_rdv4
bz2
pm3rrg_rdv4_hardnested
pm3rrg_rdv4_mbedtls
pm3rrg_rdv4_cliparser
pm3rrg_rdv4_jansson
pm3rrg_rdv4_lua
pm3rrg_rdv4_tinycbor
pm3rrg_rdv4_amiibo
pm3rrg_rdv4_reveng
pm3rrg_rdv4_whereami
android
log)

View file

@ -0,0 +1,81 @@
//
// Created by DXL on 2017/9/1.
//
//including header
#include <malloc.h>
#include <jni_tools.h>
#include "stdbool.h"
// native thread attach label
static bool g_IsAttach;
// get current env for jvm
JNIEnv *getJniEnv() {
JNIEnv *currentThreadEnv;
g_IsAttach = false;
if ((*g_JavaVM)->GetEnv(g_JavaVM, (void **) &currentThreadEnv, JNI_VERSION_1_4) != JNI_OK) {
LOGE("Get Env Fail!");
if ((*g_JavaVM)->AttachCurrentThread(g_JavaVM, &currentThreadEnv, NULL) != JNI_OK) {
LOGE("Attach the current thread Fail!");
g_IsAttach = false;
return NULL;
} else {
g_IsAttach = true;
LOGE("Attach the current thread Success!");
return currentThreadEnv;
}
} else {
g_IsAttach = false;
//LOGE("Get Env Success!");
return currentThreadEnv;
}
}
// detach native thread from jvm
void detachThread() {
if (g_IsAttach) {
(*g_JavaVM)->DetachCurrentThread(g_JavaVM);
}
}
// cmd arg parse
CMD *parse_command_line(const char *commandStr) {
CMD *cmd = (CMD *) malloc(sizeof(CMD));
if (!cmd) {
return NULL;
}
// copy the source to the heap
char *pTmp = strdup(commandStr);
// new memory size is default 20 for char **
int size = 20;
cmd->cmd = (char **) malloc(size * sizeof(char **));
if (!cmd->cmd) {
free(cmd);
return NULL;
}
// parse
char *pStr = strtok(pTmp, " ");
cmd->cmd[0] = pStr;
int count = 1;
for (; pStr != NULL; ++count) {
// Capacity expansion
if (count == (size - 1)) {
size += 20;
cmd->cmd = (char **) realloc(cmd->cmd, size * sizeof(char **));
}
pStr = strtok(NULL, " ");
if (pStr) {
cmd->cmd[count] = pStr;
}
}
cmd->len = (count - 1);
return cmd;
}
// cmd arg struct free
void free_command_line(CMD *cmd) {
free(cmd->cmd[0]);
free(cmd->cmd);
free(cmd);
}

View file

@ -0,0 +1,40 @@
//
// Created by dell on 2017/9/1.
//
#ifndef DXL_TOOLS_H
#define DXL_TOOLS_H
#include <jni.h>
#include <android/log.h>
#include <string.h>
//JNI LOG
#define TAG "PM3"
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)
// a global jvm instance
JavaVM *g_JavaVM;
// get current env for jvm
JNIEnv *getJniEnv();
// detach native thread from jvm must native thread can detach!
void detachThread();
typedef struct {
char **cmd;
int len;
} CMD;
// cmd arg parse
CMD *parse_command_line(const char *commandStr);
// cmd arg struct free
void free_command_line(CMD *);
#endif //DXL_TOOLS_H

167
client/android/pm3_main.c Normal file
View file

@ -0,0 +1,167 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// 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.
//-----------------------------------------------------------------------------
// Main binary
//-----------------------------------------------------------------------------
#include "proxmark3.h"
#include <stdlib.h>
#include <stdio.h> // for Mingw readline
#include <limits.h>
#include <unistd.h>
#include <ctype.h>
#include "usart_defs.h"
#include "util_posix.h"
#include "proxgui.h"
#include "cmdmain.h"
#include "ui.h"
#include "cmdhw.h"
#include "whereami.h"
#include "comms.h"
#include "fileutils.h"
#include "jni_tools.h"
//iceman, todo: proxify socker server name. Maybe set in preferences?
#define PM3_LOCAL_SOCKET_SERVER "DXL.COM.ASL"
void ShowGraphWindow(void) {
}
void HideGraphWindow(void) {
}
void RepaintGraphWindow(void) {
}
int push_cmdscriptfile(char *path, bool stayafter) {
return PM3_SUCCESS;
}
static char *g_android_executable_directory = NULL;
static const char *g_android_user_directory = NULL;
const char *get_executable_directory(void) {
if (g_android_executable_directory == NULL) {
char buf[FILE_PATH_SIZE] = {0};
getcwd(buf, sizeof(buf));
strncat(buf, PATHSEP, 1);
g_android_executable_directory = strdup(buf);
}
return g_android_executable_directory;
}
const char *get_user_directory(void) {
return g_android_user_directory;
}
static bool OpenPm3(void) {
if (conn.run) {
return true;
}
// Open with LocalSocket. Not a tcp connection!
bool ret = OpenProxmark("socket:"PM3_LOCAL_SOCKET_SERVER, false, 1000, false, 115200);
return ret;
}
/*
* Transfers to the command buffer and waits for a new command to be executed
* */
jint Console(JNIEnv *env, jobject instance, jstring cmd_) {
if (!conn.run) {
if (OpenPm3() && TestProxmark() == PM3_SUCCESS) {
LOGD("Connected to device");
PrintAndLogEx(SUCCESS, "Connected to device");
} else {
LOGD("Failed to connect to device");
PrintAndLogEx(ERR, "Failed to connect to device");
CloseProxmark();
}
}
PrintAndLogEx(NORMAL, "");
char *cmd = (char *)((*env)->GetStringUTFChars(env, cmd_, 0));
int ret = CommandReceived(cmd);
if (ret == 99) {
// exit / quit
// TODO: implement this
PrintAndLogEx(NORMAL, "Asked to exit, can't really do that yet...");
}
(*env)->ReleaseStringUTFChars(env, cmd_, cmd);
return ret;
}
/*
* Is client running!
* */
jboolean IsClientRunning(JNIEnv *env, jobject instance) {
return (jboolean)((jboolean) conn.run);
}
/*
* test hw and hw and client.
* */
jboolean TestPm3(JNIEnv *env, jobject instance) {
if (open() == false) {
CloseProxmark();
return false;
}
bool ret = (TestProxmark() == PM3_SUCCESS);
return (jboolean)(ret);
}
/*
* stop pm3 client
* */
void ClosePm3(JNIEnv *env, jobject instance) {
CloseProxmark();
}
/*
* native function map to jvm
* */
//iceman: todo, pm3:ify java class root. Return codes, should match PM3_E* codes.
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *jniEnv = NULL;
if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
(*jniEnv)->GetJavaVM(jniEnv, &g_JavaVM);
jclass clazz = (*jniEnv)->FindClass(jniEnv, "cn/rrg/natives/Proxmark3RRGRdv4Tools");
if (clazz == NULL) {
return -1;
}
jclass clz_test = (*jniEnv)->FindClass(jniEnv, "cn/rrg/devices/Proxmark3RRGRdv4");
JNINativeMethod methods[] = {
{"startExecute", "(Ljava/lang/String;)I", (void *) Console},
{"stopExecute", "()V", (void *) ClosePm3},
{"isExecuting", "()Z", (void *) IsClientRunning}
};
JNINativeMethod methods1[] = {
{"testPm3", "()Z", (void *) TestPm3},
{"closePm3", "()V", ClosePm3}
};
if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
return -1;
}
if ((*jniEnv)->RegisterNatives(jniEnv, clz_test, methods1, sizeof(methods1) / sizeof(methods1[0])) != JNI_OK) {
return -1;
}
(*jniEnv)->DeleteLocalRef(jniEnv, clazz);
(*jniEnv)->DeleteLocalRef(jniEnv, clz_test);
return JNI_VERSION_1_4;
}

View file

@ -1,9 +1,27 @@
include(cliparser.cmake) if (NOT TARGET pm3rrg_rdv4_amiibo)
include(tinycbor.cmake)
include(jansson.cmake)
include(lua.cmake)
include(mbedtls.cmake)
include(amiibo.cmake) include(amiibo.cmake)
include(reveng.cmake) endif()
include(zlib.cmake) if (NOT TARGET pm3rrg_rdv4_cliparser)
include(cliparser.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_hardnested)
include(hardnested.cmake) include(hardnested.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_jansson)
include(jansson.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_lua)
include(lua.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_mbedtls)
include(mbedtls.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_reveng)
include(reveng.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_tinycbor)
include(tinycbor.cmake)
endif()
if (NOT TARGET pm3rrg_rdv4_whereami)
include(whereami.cmake)
endif()

View file

@ -5,12 +5,20 @@
#amiitool.c $(MYSRCS) ../../../../common/../../commonutil.c ../ui.c -lreadline -lm ../../../../common/mbedtls/libmbedtls.a \ #amiitool.c $(MYSRCS) ../../../../common/../../commonutil.c ../ui.c -lreadline -lm ../../../../common/mbedtls/libmbedtls.a \
#-o amiitool #-o amiitool
add_library(amiibo STATIC add_library(pm3rrg_rdv4_amiibo STATIC
amiitool/amiibo.c amiitool/amiibo.c
amiitool/drbg.c amiitool/drbg.c
amiitool/keygen.c amiitool/keygen.c
) )
target_include_directories(amiibo PRIVATE ../../include ../../common) if (NOT TARGET pm3rrg_rdv4_mbedtls)
target_include_directories(amiibo INTERFACE amiitool) include(mbedtls.cmake)
target_compile_options(amiibo PRIVATE -Wall -Werror -O3) endif()
find_library(pm3rrg_rdv4_mbedtls REQUIRED)
target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE
m
pm3rrg_rdv4_mbedtls)
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE ../../include ../../common)
target_include_directories(pm3rrg_rdv4_amiibo INTERFACE amiitool)
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON)

Some files were not shown because too many files have changed in this diff Show more