mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
commit
a901d386b9
602 changed files with 10111 additions and 7852 deletions
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
patreon: iceman1001
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -35,9 +35,11 @@ Makefile.platform
|
||||||
!client/hardnested/*.bin
|
!client/hardnested/*.bin
|
||||||
!client/hardnested/tables/*.z
|
!client/hardnested/tables/*.z
|
||||||
client/ui/ui_overlays.h
|
client/ui/ui_overlays.h
|
||||||
|
client/reveng/bmptst
|
||||||
|
|
||||||
hardnested_stats.txt
|
hardnested_stats.txt
|
||||||
proxmark3
|
proxmark3
|
||||||
|
proxmark3-flasher
|
||||||
flasher
|
flasher
|
||||||
!flasher/
|
!flasher/
|
||||||
lua
|
lua
|
||||||
|
@ -71,8 +73,9 @@ tools/jtag_openocd/openocd_configuration
|
||||||
ppls patches/*
|
ppls patches/*
|
||||||
*- Copy.*
|
*- Copy.*
|
||||||
|
|
||||||
client/lualibs/mf_default_keys.lua
|
client/lualibs/mfc_default_keys.lua
|
||||||
client/lualibs/pm3_cmd.lua
|
client/lualibs/pm3_cmd.lua
|
||||||
# recompiled
|
# recompiled
|
||||||
fpga_version_info.c
|
fpga_version_info.c
|
||||||
|
|
||||||
|
.proxmark3/*
|
||||||
|
|
43
.travis.yml
43
.travis.yml
|
@ -15,9 +15,18 @@ matrix:
|
||||||
include:
|
include:
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode11
|
osx_image: xcode11
|
||||||
|
env: MAKE_PARAMS='PLATFORM_EXTRAS='
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode11
|
||||||
|
env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
sudo: required
|
sudo: required
|
||||||
|
env: MAKE_PARAMS='PLATFORM_EXTRAS='
|
||||||
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
|
sudo: required
|
||||||
|
env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
@ -27,27 +36,23 @@ addons:
|
||||||
homebrew:
|
homebrew:
|
||||||
packages:
|
packages:
|
||||||
- readline
|
- readline
|
||||||
- p7zip
|
|
||||||
- libusb-compat
|
|
||||||
- perl
|
|
||||||
- qt5
|
- qt5
|
||||||
- wget
|
|
||||||
- RfidResearchGroup/proxmark3/arm-none-eabi-gcc
|
- RfidResearchGroup/proxmark3/arm-none-eabi-gcc
|
||||||
taps: RfidResearchGroup/proxmark3
|
taps: RfidResearchGroup/proxmark3
|
||||||
|
|
||||||
install:
|
|
||||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
|
||||||
brew info proxmark3;
|
|
||||||
brew options proxmark3;
|
|
||||||
brew install --HEAD proxmark3;
|
|
||||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
|
||||||
make all;
|
|
||||||
fi
|
|
||||||
|
|
||||||
script:
|
install:
|
||||||
|
if ! arm-none-eabi-gcc -v; then
|
||||||
|
echo "arm-none-eabi-gcc [ERROR]";
|
||||||
|
travis_terminate 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
make clean;
|
||||||
|
make all V=1 "$MAKE_PARAMS";
|
||||||
|
|
||||||
|
script:
|
||||||
## start and run a test script
|
## start and run a test script
|
||||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||||
proxmark3 -h ;
|
./pm3test.sh;
|
||||||
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||||
./client/proxmark3 -h ;
|
./pm3test.sh;
|
||||||
fi
|
fi
|
||||||
|
|
4
.vscode/tasks.json
vendored
4
.vscode/tasks.json
vendored
|
@ -14,13 +14,13 @@
|
||||||
{
|
{
|
||||||
"label": "flash fullimage",
|
"label": "flash fullimage",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "./flash-fullimage.sh",
|
"command": "sudo ./pm3-flash-fullimage",
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "FLASH BOOTROM",
|
"label": "FLASH BOOTROM",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "./flash-bootrom.sh",
|
"command": "sudo ./pm3-flash-bootrom",
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
40
CHANGELOG.md
40
CHANGELOG.md
|
@ -3,14 +3,38 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
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]
|
||||||
|
- Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox)
|
||||||
|
- Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001)
|
||||||
|
- Fix `hf iclass clone` - last block always fails (@iceman1001)
|
||||||
|
- Chg `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001)
|
||||||
|
- Chg `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001)
|
||||||
|
- Rename `hf iclass writeblk` -> `hf iclass wrbl` to match hf mf wrbl (@iceman1001)
|
||||||
|
- Rename `hf iclass readblk` -> `hf iclass rdbl` to match hf mf rdbl (@iceman1001)
|
||||||
|
- Add cmdscript example and show usage with shebang (@doegox)
|
||||||
|
- Add instructions for Fedora (@doegox)
|
||||||
|
- Chg reduce the list of requirements to the minimum and move to QT5 (@doegox)
|
||||||
|
- Add `make install` and reorganize/rename stuffs accordingly (@doegox)
|
||||||
|
- Add searchFile for several types of files (@doegox / @iceman1001)
|
||||||
|
- Chg posix sh version of mkversion (@doegox)
|
||||||
|
- Chg remove entirely ncurses, not needed nowadays (@doegox)
|
||||||
|
- Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-)
|
||||||
|
- Chg `hf iclass encrypt` - now takes transport key as param. (@iceman1001)
|
||||||
|
- Chg `hf iclass decrypt` - now takes transport key as param. (@iceman1001)
|
||||||
|
- Chg `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001)
|
||||||
|
- Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox)
|
||||||
|
- Chg optimization of iclass mac calculations on deviceside (@pwpiwi)
|
||||||
|
- Add `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath)
|
||||||
|
- Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox)
|
||||||
|
- Change Lua directory scripts/ to luascript/ (@doegox)
|
||||||
|
- Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox)
|
||||||
- Fix reveng integration for all platforms else than WIN32 (@doegox)
|
- Fix reveng integration for all platforms else than WIN32 (@doegox)
|
||||||
- Add cheat sheet for easy operations of the Proxmark3 (scund00r)
|
- Add cheat sheet for easy operations of the Proxmark3 (scund00r)
|
||||||
- Chg commands are now in green in the helptext list (@iceman1001)
|
- Chg commands are now in green in the helptext list (@iceman1001)
|
||||||
- Fix 'script run ndefdump' - better exit messages when failing (@iceman1001)
|
- Fix `script run ndefdump` - better exit messages when failing (@iceman1001)
|
||||||
- Fix 'hf iclass dump' - now also saves in EML format (@iceman1001)
|
- Fix `hf iclass dump` - now also saves in EML format (@iceman1001)
|
||||||
- Fix 'hf iclass sim 3' - now works on legacy readers and legacy SE readers (@iceman1001)
|
- Fix `hf iclass sim 3` - now works on legacy readers and legacy SE readers (@iceman1001)
|
||||||
- Rework hitag2 read/write help (@ViRb3)
|
- Rework hitag2 read/write help (@ViRb3)
|
||||||
- Add 'lf nedap' - encoding / decoding (anon)
|
- Add `lf nedap` - encoding / decoding (anon)
|
||||||
- Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox)
|
- Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox)
|
||||||
- Add VSCode tasks (@ViRb3)
|
- Add VSCode tasks (@ViRb3)
|
||||||
- Better warn user of hardcoded hitag info (@ViRb3)
|
- Better warn user of hardcoded hitag info (@ViRb3)
|
||||||
|
@ -18,10 +42,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Fix hitag password write offset by 1 (@ViRb3)
|
- Fix hitag password write offset by 1 (@ViRb3)
|
||||||
- Fix momentarily flash read/write of dicts (@doegox/@cjbrigato)
|
- Fix momentarily flash read/write of dicts (@doegox/@cjbrigato)
|
||||||
- Add some more default keys (@anon)
|
- Add some more default keys (@anon)
|
||||||
- Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox)
|
- Add `hf thinfilm sim` simulating Thinfilm NFC barcode tags (@doegox)
|
||||||
- Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox)
|
- Add `hf thinfilm list` specific trace decoding (Thinfilm NFC barcode tags) (@doegox)
|
||||||
- Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001)
|
- Fix `hf topaz reader` - don't crash when trying to read a Thinfilm tag (@iceman1001)
|
||||||
- Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001)
|
- Add `hf thinfilm info` - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001)
|
||||||
- Add FPGA LF adc path (@anon)
|
- Add FPGA LF adc path (@anon)
|
||||||
- Add ECC support / check for NID_secp128r1 (@pwpiwi)
|
- Add ECC support / check for NID_secp128r1 (@pwpiwi)
|
||||||
- Add some more default keys (ollibolli)
|
- Add some more default keys (ollibolli)
|
||||||
|
|
131
COMPILING.txt
131
COMPILING.txt
|
@ -1,131 +1,2 @@
|
||||||
The project compiles on Linux, Mac OS X and Windows (MinGW/MSYS).
|
|
||||||
|
|
||||||
it requires:
|
|
||||||
- gcc >= 4.8
|
|
||||||
- libpthread
|
|
||||||
- libreadline
|
|
||||||
- libusb
|
|
||||||
- perl
|
|
||||||
- an ARM cross-compiler to compile the firmware
|
|
||||||
- libncurses5-dev
|
|
||||||
|
|
||||||
and optionally QT for the GUI
|
|
||||||
|
|
||||||
|
|
||||||
To compile, just run "make".
|
|
||||||
|
|
||||||
===========
|
|
||||||
= Windows =
|
|
||||||
===========
|
|
||||||
|
|
||||||
Rather than download and install every one of these packages, a new ProxSpace
|
|
||||||
environment archive file will be made available for download on the project
|
|
||||||
page at @Gator96100's repo
|
|
||||||
|
|
||||||
Afterwards just clone the iceman repo or download someone elses. Read instructions on @Gator96100 repo page. (https://github.com/Gator96100/ProxSpace/)
|
|
||||||
|
|
||||||
Download the ProxSpace environment archive and extract it to C:\
|
|
||||||
|
|
||||||
Links
|
|
||||||
https://github.com/Gator96100/ProxSpace/archive/master.zip
|
|
||||||
|
|
||||||
|
|
||||||
============
|
|
||||||
= Mac OS X =
|
|
||||||
============
|
|
||||||
|
|
||||||
Installing from HomeBrew tap
|
|
||||||
---------------------------
|
|
||||||
This method is recommended and tested on macOS Sierra 10.12.3
|
|
||||||
|
|
||||||
1. Install homebrew if you haven't yet already done so: http://brew.sh/
|
|
||||||
|
|
||||||
2. Tap proxmark repo:
|
|
||||||
brew tap iceman1001/proxmark3
|
|
||||||
|
|
||||||
3. Install Proxmark3:
|
|
||||||
|
|
||||||
Stable release
|
|
||||||
brew install proxmark3
|
|
||||||
|
|
||||||
Latest non-stable from GitHub (use this if previous command fails)
|
|
||||||
brew install --HEAD proxmark3
|
|
||||||
|
|
||||||
For more information go to https://github.com/iceman1001/homebrew-proxmark3
|
|
||||||
|
|
||||||
Upgrading HomeBrew tap formula
|
|
||||||
-----------------------------
|
|
||||||
*This method is useful for those looking to run bleeding-edge versions of iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.*
|
|
||||||
|
|
||||||
Tested on macOS Sierra 10.12.6
|
|
||||||
|
|
||||||
*Note: This assumes you have already installed iceman's fork from HomeBrew as mentioned above*
|
|
||||||
|
|
||||||
1. Force HomeBrew to pull the latest source from github
|
|
||||||
`brew upgrade --fetch-HEAD iceman1001/proxmark3/proxmark3`
|
|
||||||
|
|
||||||
2. Flash the bootloader
|
|
||||||
* With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark 3 as you plug it into a USB port. After about 5 seconds let go of the button and run this command
|
|
||||||
`$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf`
|
|
||||||
* After the bootloader finishes flashing, unplug your Proxmark3 from your machine
|
|
||||||
|
|
||||||
3. Flash fullimage.elf
|
|
||||||
* Press and hold the button on your Proxmark 3 and keep it held as you plug the Proxmark 3 back into the USB port; continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!"*
|
|
||||||
|
|
||||||
`$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf`
|
|
||||||
|
|
||||||
4. Enjoy the update
|
|
||||||
|
|
||||||
Compilling from source manually (Legacy)
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Tested on OSX 10.10 Yosemite
|
|
||||||
|
|
||||||
1 - Install Xcode and Xcode Command Line Tools
|
|
||||||
|
|
||||||
2 - Install Homebrew and dependencies
|
|
||||||
brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig
|
|
||||||
|
|
||||||
3 - Download DevKitARM for OSX
|
|
||||||
http://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r44/
|
|
||||||
Unpack devkitARM_r44-osx.tar.bz2 to proxmark3 directory.
|
|
||||||
|
|
||||||
4 - Edit proxmark3/client/Makefile adding path to readline and qt5
|
|
||||||
|
|
||||||
LDLIBS = -L/usr/local/opt/readline/lib -L/usr/local/opt/qt5/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
|
|
||||||
CFLAGS = -std=c99 -I/usr/local/opt/qt5/include -I/usr/local/opt/readline/include -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
|
||||||
|
|
||||||
If your old brew intallation use /usr/local/Cellar/ path replace /usr/local/opt/readline/lib with your actuall readline and qt5 path. See homebrew manuals.
|
|
||||||
|
|
||||||
5 - Set Environment
|
|
||||||
|
|
||||||
export DEVKITPRO=$HOME/proxmark3/
|
|
||||||
export DEVKITARM=$DEVKITPRO/devkitARM
|
|
||||||
export PATH=${PATH}:${DEVKITARM}/bin
|
|
||||||
|
|
||||||
|
|
||||||
============
|
|
||||||
= Linux =
|
|
||||||
============
|
|
||||||
|
|
||||||
1 - Download
|
|
||||||
|
|
||||||
A precompiled DevKitARM cross compiler tool chain package can be found at
|
|
||||||
http://sourceforge.net/projects/devkitpro/files/devkitARM
|
|
||||||
Select the one you need (32bit or 64bit) and unpack to a convinient place, eg
|
|
||||||
$HOME/proxmark3/. It will create a devkitARM/ subdirectory.
|
|
||||||
|
|
||||||
You will also need a general compiling environment on your computer for
|
|
||||||
the client and the libusb headers. In most distributions you will get all you
|
|
||||||
need with the lsb-package (Linux Standard Base). In debian/ubuntu you simply
|
|
||||||
call `aptitude install lsb libusb-dev libreadline-dev libreadline6`.
|
|
||||||
|
|
||||||
For the graphical plot view, you might need the qtlibs (debian/ubuntu:
|
|
||||||
libqt4-dev), too.
|
|
||||||
|
|
||||||
2 - Set Environment
|
|
||||||
|
|
||||||
export DEVKITPRO=$HOME/proxmark3/
|
|
||||||
export DEVKITARM=$DEVKITPRO/devkitARM
|
|
||||||
export PATH=${PATH}:${DEVKITARM}/bin
|
|
||||||
|
|
||||||
|
Refer to doc/md/Installation_Instructions/ for up-to-date intructions for various platforms.
|
||||||
|
|
176
Makefile
176
Makefile
|
@ -1,86 +1,131 @@
|
||||||
# Hide full compilation line:
|
|
||||||
ifneq ($(V),1)
|
|
||||||
Q?=@
|
|
||||||
endif
|
|
||||||
# To see full command lines, use make V=1
|
|
||||||
|
|
||||||
GZIP=gzip
|
|
||||||
# Windows' echo echos its input verbatim, on Posix there is some
|
|
||||||
# amount of shell command line parsing going on. echo "" on
|
|
||||||
# Windows yields literal "", on Linux yields an empty line
|
|
||||||
ifeq ($(shell echo ""),)
|
|
||||||
# This is probably a proper system, so we can use uname
|
|
||||||
DELETE=rm -rf
|
|
||||||
FLASH_TOOL=client/flasher
|
|
||||||
platform=$(shell uname)
|
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
|
||||||
FLASH_PORT=com3
|
|
||||||
PATHSEP=\\#
|
|
||||||
else
|
|
||||||
FLASH_PORT=/dev/ttyACM0
|
|
||||||
PATHSEP=/
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
# Assume that we are running on native Windows
|
|
||||||
DELETE=del /q
|
|
||||||
FLASH_TOOL=client/flasher.exe
|
|
||||||
platform=Windows
|
|
||||||
FLASH_PORT=com3
|
|
||||||
PATHSEP=\\#
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
include Makefile.defs
|
||||||
-include Makefile.platform
|
-include Makefile.platform
|
||||||
-include .Makefile.options.cache
|
-include .Makefile.options.cache
|
||||||
include common_arm/Makefile.hal
|
include common_arm/Makefile.hal
|
||||||
|
|
||||||
all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/%
|
# preserve relative DESTDIR path for subdir makes
|
||||||
|
ifneq (,$(DESTDIR))
|
||||||
|
# realpath needs the directory to exist
|
||||||
|
$(shell $(MKDIR) $(DESTDIR))
|
||||||
|
MYDESTDIR:=$(realpath $(DESTDIR))
|
||||||
|
ifeq (,$(MYDESTDIR))
|
||||||
|
$(error Can't create $(DESTDIR))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/%
|
||||||
|
|
||||||
|
INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py
|
||||||
|
INSTALLSIMFW=sim011.bin sim011.sha512.txt
|
||||||
|
INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage
|
||||||
|
INSTALLSHARES=tools/jtag_openocd traces
|
||||||
|
INSTALLDOCS=doc/*.md doc/md
|
||||||
|
|
||||||
|
install: all common/install
|
||||||
|
|
||||||
|
common/install:
|
||||||
|
$(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...)
|
||||||
|
ifneq (,$(INSTALLSCRIPTS))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLSCRIPTS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLSHARES))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLSHARES) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLDOCS))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLDOCS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLTOOLS))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
||||||
|
$(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLSIMFW))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
$(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
endif
|
||||||
|
ifeq ($(platform),Linux)
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(UDEV_PREFIX)
|
||||||
|
$(Q)$(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
|
endif
|
||||||
|
|
||||||
|
uninstall: common/uninstall
|
||||||
|
|
||||||
|
common/uninstall:
|
||||||
|
$(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...)
|
||||||
|
ifneq (,$(INSTALLSCRIPTS))
|
||||||
|
$(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script)))
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLSHARES))
|
||||||
|
$(Q)$(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share)))
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLDOCS))
|
||||||
|
$(Q)$(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc)))
|
||||||
|
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLTOOLS))
|
||||||
|
$(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool)))
|
||||||
|
endif
|
||||||
|
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
||||||
|
ifneq (,$(INSTALLSIMFW))
|
||||||
|
$(Q)$(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
|
||||||
|
endif
|
||||||
|
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
ifeq ($(platform),Linux)
|
||||||
|
$(Q)$(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
|
endif
|
||||||
|
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
|
||||||
mfkey/%: FORCE
|
mfkey/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
nonce2key/%: FORCE
|
nonce2key/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
fpga_compress/%: FORCE
|
fpga_compress/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
bootrom/%: FORCE cleanifplatformchanged
|
bootrom/%: FORCE cleanifplatformchanged
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
armsrc/%: FORCE cleanifplatformchanged fpga_compress/%
|
armsrc/%: FORCE cleanifplatformchanged fpga_compress/%
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
client/%: FORCE
|
client/%: FORCE
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/%
|
recovery/all: bootrom/all armsrc/all
|
||||||
|
recovery/install: bootrom/all armsrc/all
|
||||||
|
recovery/%: FORCE cleanifplatformchanged
|
||||||
$(info [*] MAKE $@)
|
$(info [*] MAKE $@)
|
||||||
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@)
|
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||||
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
||||||
|
|
||||||
.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged
|
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Multi-OS Makefile"
|
@echo "Multi-OS Makefile"
|
||||||
@echo
|
@echo
|
||||||
@echo "Possible targets:"
|
@echo "Possible targets:"
|
||||||
@echo "+ all - Make all targets: bootrom, armsrc and OS-specific host tools"
|
@echo "+ all - Make all targets: bootrom, fullimage and OS-specific host tools"
|
||||||
@echo "+ clean - Clean in all targets"
|
@echo "+ clean - Clean in all targets"
|
||||||
|
@echo "+ .../clean - Clean in specified target and its deps, e.g. bootrom/clean"
|
||||||
|
@echo "+ (un)install - Install/uninstall Proxmark files in the system, default to /usr/local/share,
|
||||||
|
@echo " else provide a PREFIX. See Maintainers.md for more options"
|
||||||
@echo
|
@echo
|
||||||
@echo "+ bootrom - Make bootrom"
|
@echo "+ bootrom - Make bootrom"
|
||||||
@echo "+ os - Make armsrc (includes fpga)"
|
@echo "+ fullimage - Make armsrc fullimage (includes fpga)"
|
||||||
@echo "+ flash-bootrom - Make bootrom and flash it"
|
@echo "+ recovery - Make bootrom and fullimage files for JTAG flashing"
|
||||||
@echo "+ flash-os - Make armsrc and flash os image (includes fpga)"
|
|
||||||
@echo "+ flash-all - Make bootrom and armsrc and flash bootrom and os image"
|
|
||||||
@echo "+ recovery - Make bootrom and armsrc images for JTAG flashing"
|
|
||||||
@echo
|
@echo
|
||||||
@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 "+ 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 "+ checks - 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"
|
||||||
|
@ -89,7 +134,17 @@ client: client/all
|
||||||
|
|
||||||
bootrom: bootrom/all
|
bootrom: bootrom/all
|
||||||
|
|
||||||
os: armsrc/all
|
# aliases fullimage = armsrc
|
||||||
|
|
||||||
|
fullimage: armsrc/all
|
||||||
|
|
||||||
|
fullimage/all: armsrc/all
|
||||||
|
|
||||||
|
fullimage/clean: armsrc/clean
|
||||||
|
|
||||||
|
fullimage/install: armsrc/install
|
||||||
|
|
||||||
|
fullimage/uninstall: armsrc/uninstall
|
||||||
|
|
||||||
recovery: recovery/all
|
recovery: recovery/all
|
||||||
|
|
||||||
|
@ -99,17 +154,8 @@ nonce2key: nonce2key/all
|
||||||
|
|
||||||
fpga_compress: fpga_compress/all
|
fpga_compress: fpga_compress/all
|
||||||
|
|
||||||
flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL)
|
|
||||||
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<)
|
|
||||||
|
|
||||||
flash-os: armsrc/obj/fullimage.elf $(FLASH_TOOL)
|
|
||||||
$(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<)
|
|
||||||
|
|
||||||
flash-all: bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf $(FLASH_TOOL)
|
|
||||||
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^))
|
|
||||||
|
|
||||||
newtarbin:
|
newtarbin:
|
||||||
$(DELETE) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
|
$(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
|
||||||
@touch proxmark3-$(platform)-bin.tar
|
@touch proxmark3-$(platform)-bin.tar
|
||||||
|
|
||||||
tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin
|
tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin
|
||||||
|
|
46
Makefile.defs
Normal file
46
Makefile.defs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Hide full compilation line:
|
||||||
|
ifneq ($(V),1)
|
||||||
|
Q?=@
|
||||||
|
endif
|
||||||
|
# To see full command lines, use make V=1
|
||||||
|
|
||||||
|
# been here
|
||||||
|
DEFSBEENHERE = true
|
||||||
|
|
||||||
|
CP = cp -a
|
||||||
|
GZIP = gzip
|
||||||
|
MKDIR = mkdir -p
|
||||||
|
RM = rm -f
|
||||||
|
RMDIR = rm -rf
|
||||||
|
# rmdir only if dir is empty, tolerate failure
|
||||||
|
RMDIR_SOFT = -rmdir
|
||||||
|
MV = mv
|
||||||
|
TOUCH = touch
|
||||||
|
FALSE = false
|
||||||
|
TAR = tar
|
||||||
|
TARFLAGS ?= -v --ignore-failed-read -r
|
||||||
|
TARFLAGS += -C .. -f
|
||||||
|
CROSS ?= arm-none-eabi-
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
LD = g++
|
||||||
|
|
||||||
|
PATHSEP=/
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
UDEV_PREFIX ?= /etc/udev/rules.d
|
||||||
|
INSTALLBINRELPATH ?= bin
|
||||||
|
INSTALLSHARERELPATH ?= share/proxmark3
|
||||||
|
INSTALLFWRELPATH ?= share/proxmark3/firmware
|
||||||
|
INSTALLTOOLSRELPATH ?= share/proxmark3/tools
|
||||||
|
INSTALLDOCSRELPATH ?= share/doc/proxmark3
|
||||||
|
|
||||||
|
platform = $(shell uname)
|
||||||
|
DETECTED_OS=$(platform)
|
||||||
|
|
||||||
|
ifeq ($(platform),Darwin)
|
||||||
|
AR= /usr/bin/ar rcs
|
||||||
|
RANLIB= /usr/bin/ranlib
|
||||||
|
else
|
||||||
|
AR= ar rcs
|
||||||
|
RANLIB= ranlib
|
||||||
|
endif
|
76
Makefile.host
Normal file
76
Makefile.host
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# This Makefile might have been called from various subdirs, trying to find our Makefile.defs
|
||||||
|
ifeq ($(DEFSBEENHERE),)
|
||||||
|
-include Makefile.defs
|
||||||
|
endif
|
||||||
|
ifeq ($(DEFSBEENHERE),)
|
||||||
|
-include ../Makefile.defs
|
||||||
|
endif
|
||||||
|
ifeq ($(DEFSBEENHERE),)
|
||||||
|
-include ../../Makefile.defs
|
||||||
|
endif
|
||||||
|
ifeq ($(DEFSBEENHERE),)
|
||||||
|
$(error Can't find Makefile.defs)
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS ?= -Wall -Werror -O3
|
||||||
|
CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES)
|
||||||
|
|
||||||
|
vpath %.c $(MYSRCPATHS)
|
||||||
|
|
||||||
|
# Flags to generate temporary dependency files
|
||||||
|
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
|
# make temporary to final dependency files after successful compilation
|
||||||
|
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
||||||
|
|
||||||
|
BINDIR := .
|
||||||
|
OBJDIR := obj
|
||||||
|
|
||||||
|
MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
|
CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
||||||
|
|
||||||
|
all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(Q)$(RM) $(CLEAN)
|
||||||
|
$(Q)$(RMDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
ifneq (,$(INSTALLTOOLS))
|
||||||
|
$(info [@] Installing $(BINS) to $(DESTDIR)$(PREFIX)...)
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLTOOLS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
||||||
|
endif
|
||||||
|
@true
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
ifneq (,$(INSTALLTOOLS))
|
||||||
|
$(info [@] Uninstalling $(BINS) from $(DESTDIR)$(PREFIX)...)
|
||||||
|
$(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool)))
|
||||||
|
endif
|
||||||
|
@true
|
||||||
|
|
||||||
|
.PHONY: all clean install uninstall
|
||||||
|
|
||||||
|
$(BINDIR)/$(LIB_A): $(MYOBJS)
|
||||||
|
$(info [=] AR $(notdir $@))
|
||||||
|
$(Q)$(AR) $@ $(MYOBJS)
|
||||||
|
$(Q)$(RANLIB) $@
|
||||||
|
|
||||||
|
$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS)
|
||||||
|
$(info [=] LD $(notdir $@))
|
||||||
|
$(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o : %.c | $(OBJDIR)
|
||||||
|
$(info [-] CC $<)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
|
$(OBJDIR):
|
||||||
|
$(Q)$(MKDIR) $(OBJDIR)
|
||||||
|
|
||||||
|
DEPENDENCY_FILES = $(MYOBJS:%.o=%.d) $(BINS:%=$(OBJDIR)/%.d)
|
||||||
|
|
||||||
|
$(DEPENDENCY_FILES): ;
|
||||||
|
.PRECIOUS: $(DEPENDENCY_FILES)
|
||||||
|
|
||||||
|
-include $(DEPENDENCY_FILES)
|
43
README.md
43
README.md
|
@ -1,8 +1,8 @@
|
||||||
# RRG / Iceman repo, dedicated to Proxmark3 RDV4.0
|
# RRG / Iceman repo - Proxmark3
|
||||||
|
|
||||||
This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
|
This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well.
|
||||||
|
|
||||||
_Note that it also supports other Proxmark3 platforms as well!_
|
It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
|
||||||
|
|
||||||
|
|
||||||
| Releases | Linux & OSX CI | Windows CI |
|
| Releases | Linux & OSX CI | Windows CI |
|
||||||
|
@ -17,16 +17,23 @@ _Note that it also supports other Proxmark3 platforms as well!_
|
||||||
| ------------------- |:-------------------:| -------------------:|
|
| ------------------- |:-------------------:| -------------------:|
|
||||||
|[What has changed?](#what-has-changed) | [Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)|
|
|[What has changed?](#what-has-changed) | [Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)|
|
||||||
|[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) |
|
|[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) |
|
||||||
|[Why didn't you base it on official PM3 Master?](#why-didnt-you-base-it-on-official-pm3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
|
|[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)|
|
||||||
|[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
|
|[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
|
||||||
|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|
|
|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|
|
||||||
|[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)|
|
|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)|
|
||||||
|[Notes on Frame format](/doc/new_frame_format.md)|||
|
|[Notes on frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)|
|
||||||
|[Notes on external flash](/doc/ext_flash_notes.md)|||
|
|[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)|
|
||||||
|[Notes on Termux / Android](/doc/termux_notes.md)|||
|
|[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)|
|
||||||
|
|[Notes on wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)|
|
||||||
|
|[Notes on loclass](/doc/loclass_notes.md)|||
|
||||||
|
|[Notes on paths](/doc/path_notes.md)|||
|
||||||
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) ||
|
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) ||
|
||||||
|[Donations](#Donations)|||
|
|[Donations](#Donations)|||
|
||||||
|
|
||||||
|
## Support on other Proxmark3 platforms
|
||||||
|
|
||||||
|
In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)
|
||||||
|
|
||||||
## What has changed?
|
## What has changed?
|
||||||
|
|
||||||
On the hardware side:
|
On the hardware side:
|
||||||
|
@ -38,11 +45,13 @@ On the hardware side:
|
||||||
On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
|
On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
This fork now compiles just fine on
|
|
||||||
|
This repo now compiles just fine on
|
||||||
|
- Proxspace v3.2
|
||||||
- Windows/mingw environment with Qt5.6.1 & GCC 4.8
|
- Windows/mingw environment with Qt5.6.1 & GCC 4.8
|
||||||
- Ubuntu 1404, 1510, 1604, 1804, 1904
|
- Ubuntu 1404, 1510, 1604, 1804, 1904
|
||||||
- Mac OS X / Homebrew
|
- Mac OS X / Homebrew
|
||||||
- ParrotOS, Gentoo, Pentoo
|
- 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
|
||||||
|
|
||||||
|
@ -54,15 +63,26 @@ If you intend to contribute to the code, please read the [coding style notes](HA
|
||||||
- Internal notes on [external flash](/doc/ext_flash_notes.md)
|
- Internal notes on [external flash](/doc/ext_flash_notes.md)
|
||||||
- Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)
|
- Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)
|
||||||
- Internal notes on [Termux / Android](/doc/termux_notes.md)
|
- Internal notes on [Termux / Android](/doc/termux_notes.md)
|
||||||
|
- Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md)
|
||||||
|
- Internal notes on [loclass](/doc/loclass_notes.md)
|
||||||
|
- Internal notes on [EMV](/doc/emv_notes.md)
|
||||||
|
- Internal notes on [Paths](/doc/path_notes.md)
|
||||||
|
|
||||||
## Cheat sheet
|
## 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)
|
||||||
|
|
||||||
|
## Maintainers ( package, distro )
|
||||||
|
|
||||||
|
To all distro, package maintainers, we tried to make your life easier. `make install` is now available and if you want to know more.
|
||||||
|
- [Maintainers](/doc/md/Development/Maintainers.md)
|
||||||
|
|
||||||
## Why didn't you base it on official Proxmark3 Master?
|
## Why didn't you base it on official Proxmark3 Master?
|
||||||
|
|
||||||
The separation from official Proxmark3 repo gives us a lot of freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the official Proxmark3 repo with RDV40 specific code.
|
The separation from official Proxmark3 repo gives us a lot of freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the official Proxmark3 repo with RDV40 specific code.
|
||||||
|
|
||||||
## Proxmark3 GUI
|
## Proxmark3 GUI
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -78,6 +98,7 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st
|
||||||
- updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish)
|
- updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish)
|
||||||
|
|
||||||
# Donations
|
# Donations
|
||||||
|
|
||||||
Nothing says thank you as much as a donation. So if you feel the love, do feel free to become a iceman patron. For some tiers it comes with rewards.
|
Nothing says thank you as much as a donation. So if you feel the love, do feel free to become a iceman patron. For some tiers it comes with rewards.
|
||||||
|
|
||||||
https://www.patreon.com/iceman1001
|
https://www.patreon.com/iceman1001
|
||||||
|
|
143
appveyor.yml
143
appveyor.yml
|
@ -73,14 +73,77 @@ clone_script:
|
||||||
Write-Host "[ OK ]" -ForegroundColor Green
|
Write-Host "[ OK ]" -ForegroundColor Green
|
||||||
|
|
||||||
|
|
||||||
Write-Host "Update msys2 packages..." -NoNewLine
|
Write-Host "Update msys2 packages..."
|
||||||
|
|
||||||
$env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path"
|
$env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path"
|
||||||
|
|
||||||
|
Function ExecUpdate($Name, $Cmd, $ErrorLine) {
|
||||||
|
|
||||||
C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1
|
Write-Host "Exec [$Name]... " -NoNewLine
|
||||||
|
#--- begin Job
|
||||||
|
|
||||||
|
$Job = Start-Job -Name "$Name" -ScriptBlock {
|
||||||
|
$env:Path = "C:\ProxSpace\msys\bin;$env:Path"
|
||||||
|
Set-Location $using:PWD
|
||||||
|
|
||||||
C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1
|
$sb=[scriptblock]::Create("$using:Cmd")
|
||||||
|
#execute scriptblock
|
||||||
|
$Cond=&$sb
|
||||||
|
|
||||||
|
return $Cond
|
||||||
|
}
|
||||||
|
|
||||||
|
#--- end Job
|
||||||
|
|
||||||
|
$JobTime=[System.Environment]::TickCount
|
||||||
|
while($true) {
|
||||||
|
Try {
|
||||||
|
$Res = Receive-Job -Job $Job -Keep 2>&1 6>&1
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
$Res = ""
|
||||||
|
Write-host "error in Receive-Job"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Res -is "String" -and $Res -like "*$ErrorLine*"){
|
||||||
|
Write-host "Exit by stop phrase" -ForegroundColor Green
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Res -is [Object]){
|
||||||
|
[bool]$needexit = $false
|
||||||
|
ForEach($line in $Res){
|
||||||
|
if ($line -like "*$ErrorLine*"){
|
||||||
|
Write-host "Exit by stop phrase [obj]" -ForegroundColor Green
|
||||||
|
$needexit = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($needexit) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Wait-Job $Job -Timeout 5){
|
||||||
|
Write-host "Exit by end job" -ForegroundColor Green
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([System.Environment]::TickCount-$JobTime -gt 1000000) {
|
||||||
|
Write-host "Exit by timeout" -ForegroundColor Yellow
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove-Job -Force $Job
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2"
|
||||||
|
|
||||||
|
ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2"
|
||||||
|
|
||||||
|
Write-Host "Update " -NoNewLine
|
||||||
|
|
||||||
Write-Host "[ OK ]" -ForegroundColor Green
|
Write-Host "[ OK ]" -ForegroundColor Green
|
||||||
install:
|
install:
|
||||||
- ps: >-
|
- ps: >-
|
||||||
|
@ -130,54 +193,38 @@ build_script:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(Test-Path C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z)){
|
if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){
|
||||||
|
|
||||||
throw "Files in hardnested\tables not exists."
|
throw "Files in client\resources\hardnested_tables is not exists."
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#copy
|
#install
|
||||||
|
|
||||||
Write-Host "Copy release files..." -NoNewLine -ForegroundColor Yellow
|
Write-Host "Installing..." -NoNewLine -ForegroundColor Yellow
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release
|
New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\pm3\client\*.exe C:\ProxSpace\Release
|
bash -c -i 'make install DESTDIR=Release PREFIX='
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\arm
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\pm3\armsrc\obj\*.elf C:\ProxSpace\Release\arm
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\pm3\bootrom\obj\*.elf C:\ProxSpace\Release\arm
|
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\scripts
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\pm3\client\scripts\*.lua C:\ProxSpace\Release\scripts
|
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\hardnested\tables
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\pm3\client\hardnested\*.bin C:\ProxSpace\Release\hardnested
|
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z C:\ProxSpace\Release\hardnested\tables
|
|
||||||
|
|
||||||
# dll files
|
# dll files
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\Release
|
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\pm3\Release\bin
|
||||||
|
|
||||||
Write-Host "[ OK ]" -ForegroundColor Green
|
Write-Host "[ OK ]" -ForegroundColor Green
|
||||||
|
|
||||||
|
@ -199,7 +246,7 @@ build_script:
|
||||||
|
|
||||||
cd C:\ProxSpace
|
cd C:\ProxSpace
|
||||||
|
|
||||||
7z a release.zip C:\ProxSpace\Release
|
7z a release.zip C:\ProxSpace\pm3\Release
|
||||||
|
|
||||||
Push-AppveyorArtifact release.zip -DeploymentName "$releasename"
|
Push-AppveyorArtifact release.zip -DeploymentName "$releasename"
|
||||||
|
|
||||||
|
@ -218,7 +265,7 @@ test_script:
|
||||||
|
|
||||||
|
|
||||||
Function ExecTest($Name, $File, $Cmd, $CheckResult) {
|
Function ExecTest($Name, $File, $Cmd, $CheckResult) {
|
||||||
|
|
||||||
#--- begin Job
|
#--- begin Job
|
||||||
|
|
||||||
$Job = Start-Job -ScriptBlock {
|
$Job = Start-Job -ScriptBlock {
|
||||||
|
@ -256,6 +303,13 @@ test_script:
|
||||||
if ($Cond -is "String" -and $Cond -like "*true*"){
|
if ($Cond -is "String" -and $Cond -like "*true*"){
|
||||||
$res= $true
|
$res= $true
|
||||||
}
|
}
|
||||||
|
ForEach($line in $Cond){
|
||||||
|
if ($line -like "*passed*"){
|
||||||
|
$res = $true
|
||||||
|
$Cond = $line
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
} Else {
|
} Else {
|
||||||
$res=$Cond
|
$res=$Cond
|
||||||
}
|
}
|
||||||
|
@ -287,6 +341,7 @@ test_script:
|
||||||
Remove-Job -Force $Job
|
Remove-Job -Force $Job
|
||||||
|
|
||||||
if(!$res){
|
if(!$res){
|
||||||
|
Write-host "--------------------- tests fail" -ForegroundColor Red
|
||||||
$global:TestsPassed=$false
|
$global:TestsPassed=$false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,30 +352,34 @@ test_script:
|
||||||
|
|
||||||
#file test
|
#file test
|
||||||
|
|
||||||
ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\Release\proxmark3.exe}
|
ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\pm3\Release\bin\proxmark3.exe}
|
||||||
|
|
||||||
ExecTest "arm image exists" "\arm\fullimage1.elf" {Test-Path C:\ProxSpace\Release\arm\fullimage.elf}
|
ExecTest "arm bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\bootrom.elf}
|
||||||
|
|
||||||
ExecTest "bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\Release\arm\bootrom.elf}
|
ExecTest "arm image exists" "fullimage.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\fullimage.elf}
|
||||||
|
|
||||||
ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\Release\hardnested\tables\*.z}
|
ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin}
|
||||||
|
|
||||||
|
ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z}
|
||||||
|
|
||||||
ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip}
|
ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip}
|
||||||
|
|
||||||
|
|
||||||
#proxmark logic tests
|
#proxmark logic tests
|
||||||
|
|
||||||
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q wait && echo Passed || echo Failed'}
|
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h 2>&1 | grep -q wait && echo passed || echo failed'}
|
||||||
|
|
||||||
ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo Passed || echo Failed'}
|
ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo passed || echo failed'}
|
||||||
|
|
||||||
ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo Passed || echo Failed'}
|
ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo passed || echo failed'}
|
||||||
|
|
||||||
|
|
||||||
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc"
|
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc"
|
||||||
|
|
||||||
ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
||||||
|
|
||||||
|
ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok"
|
||||||
|
|
||||||
|
|
||||||
#proxmark crypto tests
|
#proxmark crypto tests
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,13 @@ include ../common_arm/Makefile.common
|
||||||
|
|
||||||
COMMON_FLAGS = -Os
|
COMMON_FLAGS = -Os
|
||||||
|
|
||||||
|
INSTALLFW = $(OBJDIR)/fullimage.elf
|
||||||
|
ifneq (,$(FWTAG))
|
||||||
|
INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf))
|
||||||
|
else
|
||||||
|
INSTALLFWTAG = $(notdir $(INSTALLFW))
|
||||||
|
endif
|
||||||
|
|
||||||
OBJS = $(OBJDIR)/fullimage.s19
|
OBJS = $(OBJDIR)/fullimage.s19
|
||||||
FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress
|
FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress
|
||||||
|
|
||||||
|
@ -144,7 +151,7 @@ all: $(OBJS)
|
||||||
# version.c should be remade on every time fullimage.stage1.elf should be remade
|
# version.c 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)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
|
$(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 $@)
|
||||||
|
@ -203,17 +210,26 @@ tarbin: $(OBJS)
|
||||||
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)
|
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(Q)$(DELETE) $(DEPENDENCY_FILES)
|
$(Q)$(RM) $(DEPENDENCY_FILES)
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.z
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.z
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.bin
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.bin
|
||||||
$(Q)$(DELETE) version.c
|
$(Q)$(RM) version.c
|
||||||
|
|
||||||
.PHONY: all clean help
|
install: all
|
||||||
|
$(info [@] Installing fullimage to $(DESTDIR)$(PREFIX)...)
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG)
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
$(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...)
|
||||||
|
$(Q)$(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG)
|
||||||
|
|
||||||
|
.PHONY: all clean help install uninstall
|
||||||
help:
|
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:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Default standalone if no standalone specified
|
# Default standalone if no standalone specified
|
||||||
DEFAULT_STANDALONE=LF_SAMYRUN
|
DEFAULT_STANDALONE=LF_SAMYRUN
|
||||||
HELP_EXAMPLE_STANDALONE=HF_COLIN
|
HELP_EXAMPLE_STANDALONE=HF_YOUNG
|
||||||
# (you can set explicitly STANDALONE= to disable standalone modes)
|
# (you can set explicitly STANDALONE= to disable standalone modes)
|
||||||
STANDALONE?=$(DEFAULT_STANDALONE)
|
STANDALONE?=$(DEFAULT_STANDALONE)
|
||||||
STANDALONE_REQ_DEFS=
|
STANDALONE_REQ_DEFS=
|
||||||
|
|
|
@ -229,7 +229,7 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||||
if (DBGLEVEL > 1)
|
if (DBGLEVEL > 1)
|
||||||
Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts);
|
Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts);
|
||||||
|
|
||||||
SpinErr(0, 200, 5); // blink led A
|
SpinErr(LED_A, 200, 5);
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -518,7 +518,7 @@ failtag:
|
||||||
if (cjcuid == 0) {
|
if (cjcuid == 0) {
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s BUG: 0000_CJCUID! Retrying...", _XRED_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%s>>%s BUG: 0000_CJCUID! Retrying...", _XRED_, _XWHITE_);
|
||||||
SpinErr(0, 100, 8);
|
SpinErr(LED_A, 100, 8);
|
||||||
goto failtag;
|
goto failtag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ failtag:
|
||||||
cjTabulize();
|
cjTabulize();
|
||||||
DbprintfEx(FLAG_NEWLINE, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _XRED_, _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _XRED_, _XWHITE_);
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
SpinErr(1, 100, 8);
|
SpinErr(LED_B, 100, 8);
|
||||||
SpinOff(100);
|
SpinOff(100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -672,7 +672,7 @@ failtag:
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
|
|
||||||
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
|
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
|
||||||
SpinErr(2, 100, 8);
|
SpinErr(LED_C, 100, 8);
|
||||||
SpinOff(100);
|
SpinOff(100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -778,7 +778,7 @@ readysim:
|
||||||
DbprintfEx(FLAG_NEWLINE, "- [ LA FIN ] -\r\n%s`-> You can take shell back :) ...", _XWHITE_);
|
DbprintfEx(FLAG_NEWLINE, "- [ LA FIN ] -\r\n%s`-> You can take shell back :) ...", _XWHITE_);
|
||||||
cjSetCursLeft();
|
cjSetCursLeft();
|
||||||
vtsend_set_attribute(NULL, 0);
|
vtsend_set_attribute(NULL, 0);
|
||||||
SpinErr(3, 100, 16);
|
SpinErr(LED_D, 100, 16);
|
||||||
SpinDown(75);
|
SpinDown(75);
|
||||||
SpinOff(100);
|
SpinOff(100);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -24,131 +24,112 @@ void ModInfo(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// samy's sniff and repeat routine for LF
|
// samy's sniff and repeat routine for LF
|
||||||
|
|
||||||
|
// LEDS.
|
||||||
|
// A , B == which bank (recording)
|
||||||
|
// FLASHING A, B = clone bank
|
||||||
|
// C = playing bank A
|
||||||
|
// D = playing bank B
|
||||||
|
|
||||||
void RunMod() {
|
void RunMod() {
|
||||||
StandAloneMode();
|
StandAloneMode();
|
||||||
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
|
||||||
|
|
||||||
uint32_t high[OPTS], low[OPTS];
|
uint32_t high[OPTS], low[OPTS];
|
||||||
int selected = 0;
|
int selected = 0;
|
||||||
int playing = 0;
|
|
||||||
int cardRead = 0;
|
#define STATE_READ 0
|
||||||
bool gotCard;
|
#define STATE_SIM 1
|
||||||
// Turn on selected LED
|
#define STATE_CLONE 2
|
||||||
LED(selected + 1, 0);
|
|
||||||
|
uint8_t state = STATE_READ;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// exit from SamyRun, send a usbcommand.
|
// exit from SamyRun, send a usbcommand.
|
||||||
if (data_available()) break;
|
if (data_available()) break;
|
||||||
|
|
||||||
// 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(280);
|
||||||
|
if ( button_pressed != BUTTON_HOLD )
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
#define BUTTON_NO_CLICK 0
|
||||||
|
#define BUTTON_SINGLE_CLICK -1
|
||||||
|
#define BUTTON_DOUBLE_CLICK -2
|
||||||
|
*/
|
||||||
|
|
||||||
Dbprintf("button %d", button_pressed);
|
if ( state == STATE_READ ) {
|
||||||
SpinDelay(300);
|
|
||||||
|
|
||||||
// Button was held for a second, begin recording
|
if (selected == 0) {
|
||||||
if (button_pressed > 0 && cardRead == 0) {
|
LED_A_ON();
|
||||||
LEDsoff();
|
LED_B_OFF();
|
||||||
LED(selected + 1, 0);
|
} else {
|
||||||
LED(LED_D, 0);
|
LED_B_ON();
|
||||||
|
LED_A_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_C_OFF();
|
||||||
|
LED_D_OFF();
|
||||||
|
|
||||||
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
// record
|
// record
|
||||||
DbpString("[=] starting recording");
|
DbpString("[=] starting recording");
|
||||||
|
|
||||||
// wait for button to be released
|
// findone, high, low, no ledcontrol (A)
|
||||||
while (BUTTON_PRESS())
|
uint32_t hi = 0, lo = 0;
|
||||||
WDT_HIT();
|
CmdHIDdemodFSK(1, &hi, &lo, 0);
|
||||||
|
high[selected] = hi;
|
||||||
|
low[selected] = lo;
|
||||||
|
|
||||||
/* need this delay to prevent catching some weird data */
|
Dbprintf("[=] recorded bank %x | %x%08x", selected, high[selected], low[selected]);
|
||||||
SpinDelay(500);
|
|
||||||
|
|
||||||
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
|
// got nothing. blink and loop.
|
||||||
Dbprintf("[=] recorded bank %x | %x %08x", selected, high[selected], low[selected]);
|
if ( hi == 0 && lo == 0 ) {
|
||||||
|
SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12);
|
||||||
LEDsoff();
|
Dbprintf("[=] recorded nothing, looping");
|
||||||
LED(selected + 1, 0);
|
continue;
|
||||||
// Finished recording
|
|
||||||
// If we were previously playing, set playing off
|
|
||||||
// so next button push begins playing what we recorded
|
|
||||||
playing = 0;
|
|
||||||
cardRead = 1;
|
|
||||||
|
|
||||||
gotCard = true;
|
|
||||||
} else if (button_pressed > 0 && cardRead == 1) {
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
LED(LED_A, 0);
|
|
||||||
|
|
||||||
// record
|
|
||||||
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
|
|
||||||
|
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
/* need this delay to prevent catching some weird data */
|
|
||||||
SpinDelay(500);
|
|
||||||
|
|
||||||
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
|
||||||
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
|
|
||||||
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
// Finished recording
|
|
||||||
|
|
||||||
// If we were previously playing, set playing off
|
|
||||||
// so next button push begins playing what we recorded
|
|
||||||
playing = 0;
|
|
||||||
cardRead = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change where to record (or begin playing)
|
|
||||||
else if (button_pressed && gotCard) {
|
|
||||||
// Next option if we were previously playing
|
|
||||||
if (playing)
|
|
||||||
selected = (selected + 1) % OPTS;
|
|
||||||
|
|
||||||
playing = !playing;
|
|
||||||
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
|
|
||||||
// Begin transmitting
|
|
||||||
if (playing) {
|
|
||||||
|
|
||||||
LED(LED_B, 0);
|
|
||||||
DbpString("[=] playing");
|
|
||||||
|
|
||||||
// wait for button to be released
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
|
|
||||||
CmdHIDsimTAG(high[selected], low[selected], false);
|
|
||||||
DbpString("[=] done playing");
|
|
||||||
|
|
||||||
if (BUTTON_HELD(1000) > 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* We pressed a button so ignore it here with a delay */
|
|
||||||
SpinDelay(300);
|
|
||||||
|
|
||||||
// when done, we're done playing, move to next option
|
|
||||||
selected = (selected + 1) % OPTS;
|
|
||||||
playing = !playing;
|
|
||||||
LEDsoff();
|
|
||||||
LED(selected + 1, 0);
|
|
||||||
} else {
|
|
||||||
while (BUTTON_PRESS())
|
|
||||||
WDT_HIT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpinErr( (select==0) ? LED_A : LED_B, 250, 2);
|
||||||
|
state = STATE_SIM;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else if ( state == STATE_SIM ) {
|
||||||
|
|
||||||
|
LED_C_ON(); // Simulate
|
||||||
|
LED_D_OFF();
|
||||||
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
|
Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
|
// high, low, no led control(A) no time limit
|
||||||
|
CmdHIDsimTAGEx(high[selected], low[selected], false, -1);
|
||||||
|
SpinErr( LED_C, 250, 2);
|
||||||
|
state = STATE_CLONE;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else if ( state == STATE_CLONE ) {
|
||||||
|
|
||||||
|
LED_C_OFF();
|
||||||
|
LED_D_ON(); // clone
|
||||||
|
WAIT_BUTTON_RELEASED();
|
||||||
|
|
||||||
|
Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]);
|
||||||
|
|
||||||
|
// high2, high, low, no longFMT
|
||||||
|
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
|
||||||
|
state = STATE_READ;
|
||||||
|
SpinErr( LED_D, 250, 2);
|
||||||
|
selected = (selected + 1) % OPTS;
|
||||||
|
LEDsoff();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
DbpString("[=] exiting samyrun");
|
||||||
DbpString("[=] exiting");
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
|
@ -447,15 +447,12 @@ void SendCapabilities(void) {
|
||||||
|
|
||||||
// Show some leds in a pattern to identify StandAlone mod is running
|
// Show some leds in a pattern to identify StandAlone mod is running
|
||||||
void StandAloneMode(void) {
|
void StandAloneMode(void) {
|
||||||
|
DbpString("Stand-alone mode, no computer necessary");
|
||||||
DbpString("Stand-alone mode! No PC necessary.");
|
|
||||||
|
|
||||||
SpinDown(50);
|
SpinDown(50);
|
||||||
SpinOff(50);
|
SpinDelay(50);
|
||||||
SpinUp(50);
|
SpinUp(50);
|
||||||
SpinOff(50);
|
SpinDelay(50);
|
||||||
SpinDown(50);
|
SpinDown(50);
|
||||||
SpinDelay(500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -800,7 +797,12 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_T55XX_WAKEUP: {
|
case CMD_LF_T55XX_WAKEUP: {
|
||||||
T55xxWakeUp(packet->oldarg[0], packet->oldarg[1]);
|
struct p {
|
||||||
|
uint32_t password;
|
||||||
|
uint8_t flags;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
T55xxWakeUp(payload->password, payload->flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_T55XX_RESET_READ: {
|
case CMD_LF_T55XX_RESET_READ: {
|
||||||
|
@ -1134,7 +1136,8 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MIFARE_EML_LOAD: {
|
case CMD_HF_MIFARE_EML_LOAD: {
|
||||||
MifareECardLoad(packet->oldarg[0], packet->oldarg[1]);
|
mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes;
|
||||||
|
MifareECardLoadExt(payload->sectorcnt, payload->keytype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Work with "magic Chinese" card
|
// Work with "magic Chinese" card
|
||||||
|
@ -1228,18 +1231,36 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ICLASS_WRITEBL: {
|
case CMD_HF_ICLASS_WRITEBL: {
|
||||||
iClass_WriteBlock(packet->oldarg[0], packet->data.asBytes);
|
struct p {
|
||||||
|
uint8_t blockno;
|
||||||
|
uint8_t data[12];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
iClass_WriteBlock(payload->blockno, payload->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// iceman2019, unused?
|
||||||
case CMD_HF_ICLASS_READCHECK: { // auth step 1
|
case CMD_HF_ICLASS_READCHECK: { // auth step 1
|
||||||
iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]);
|
iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ICLASS_READBL: {
|
case CMD_HF_ICLASS_READBL: {
|
||||||
iClass_ReadBlk(packet->oldarg[0]);
|
/*
|
||||||
|
struct p {
|
||||||
|
uint8_t blockno;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
*/
|
||||||
|
iClass_ReadBlk( packet->data.asBytes[0] );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ICLASS_AUTH: { //check
|
case CMD_HF_ICLASS_AUTH: { //check
|
||||||
|
/*
|
||||||
|
struct p {
|
||||||
|
uint8_t mac[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
*/
|
||||||
iClass_Authentication(packet->data.asBytes);
|
iClass_Authentication(packet->data.asBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1273,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ICLASS_CLONE: {
|
case CMD_HF_ICLASS_CLONE: {
|
||||||
iClass_Clone(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
|
struct p {
|
||||||
|
uint8_t startblock;
|
||||||
|
uint8_t endblock;
|
||||||
|
uint8_t data[];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
iClass_Clone(payload->startblock, payload->endblock, payload->data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
int cs_win_snprintf(char *str, size_t size, const char *format, ...);
|
int cs_win_snprintf(char *str, size_t size, const char *format, ...);
|
||||||
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||||
#if _MSC_VER >= 1700
|
#if _MSC_VER >= 1700
|
||||||
#include <stdint.h>
|
#include "stdint.h"
|
||||||
#else
|
#else
|
||||||
typedef _int64 int64_t;
|
typedef _int64 int64_t;
|
||||||
typedef unsigned _int64 uint64_t;
|
typedef unsigned _int64 uint64_t;
|
||||||
|
|
336
armsrc/iclass.c
336
armsrc/iclass.c
|
@ -55,7 +55,11 @@
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
|
|
||||||
static int timeout = 4096;
|
static int g_wait = 290;
|
||||||
|
static int timeout = 5000;
|
||||||
|
static uint32_t time_rdr = 0;
|
||||||
|
static uint32_t time_response = 0;
|
||||||
|
|
||||||
static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay);
|
static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay);
|
||||||
int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf);
|
int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf);
|
||||||
|
|
||||||
|
@ -151,7 +155,7 @@ typedef struct {
|
||||||
static tUartIc Uart;
|
static tUartIc Uart;
|
||||||
|
|
||||||
static void OnError(uint8_t reason) {
|
static void OnError(uint8_t reason) {
|
||||||
reply_old(CMD_ACK, 0, reason, 0, 0, 0);
|
reply_mix(CMD_ACK, 0, reason, 0, 0, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,10 +164,12 @@ static void uart_reset(void) {
|
||||||
Uart.synced = false;
|
Uart.synced = false;
|
||||||
Uart.frame = false;
|
Uart.frame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_init(uint8_t *data) {
|
static void uart_init(uint8_t *data) {
|
||||||
Uart.buf = data;
|
Uart.buf = data;
|
||||||
uart_reset();
|
uart_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_bit(uint8_t bit) {
|
static void uart_bit(uint8_t bit) {
|
||||||
static uint8_t buf = 0xff;
|
static uint8_t buf = 0xff;
|
||||||
static uint8_t n_buf;
|
static uint8_t n_buf;
|
||||||
|
@ -889,9 +895,7 @@ void RAMFUNC SniffIClass(void) {
|
||||||
|
|
||||||
// time ZERO, the point from which it all is calculated.
|
// time ZERO, the point from which it all is calculated.
|
||||||
time_0 = GetCountSspClk();
|
time_0 = GetCountSspClk();
|
||||||
|
|
||||||
int divi = 0;
|
|
||||||
uint8_t tag_byte = 0, foo = 0;
|
|
||||||
// loop and listen
|
// loop and listen
|
||||||
// every sample (1byte in data),
|
// every sample (1byte in data),
|
||||||
// contains HIGH nibble = reader data
|
// contains HIGH nibble = reader data
|
||||||
|
@ -902,12 +906,11 @@ void RAMFUNC SniffIClass(void) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
if (BUTTON_PRESS() || data_available()) break;
|
if (BUTTON_PRESS() || data_available()) break;
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
|
|
||||||
previous_data <<= 8;
|
previous_data <<= 8;
|
||||||
previous_data |= *data;
|
previous_data |= *data;
|
||||||
|
@ -921,14 +924,6 @@ void RAMFUNC SniffIClass(void) {
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE;
|
AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*data & 0xF) {
|
|
||||||
//tag_byte <<= 1;
|
|
||||||
tag_byte ^= (1 << 4);
|
|
||||||
foo ^= (1 << (3 - divi));
|
|
||||||
Dbprintf(" %d|%x == %d|%x", tag_byte, tag_byte, foo, foo);
|
|
||||||
}
|
|
||||||
divi++;
|
|
||||||
|
|
||||||
// every odd sample
|
// every odd sample
|
||||||
if (sniffCounter & 0x01) {
|
if (sniffCounter & 0x01) {
|
||||||
// no need to try decoding reader data if the tag is sending
|
// no need to try decoding reader data if the tag is sending
|
||||||
|
@ -958,8 +953,6 @@ void RAMFUNC SniffIClass(void) {
|
||||||
LED_C_INV();
|
LED_C_INV();
|
||||||
// LOW nibble is always tag data.
|
// LOW nibble is always tag data.
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
||||||
uint32_t tag_byte =
|
uint32_t tag_byte =
|
||||||
((previous_data & 0x0F000000) >> 8 ) |
|
((previous_data & 0x0F000000) >> 8 ) |
|
||||||
((previous_data & 0x000F0000) >> 4 ) |
|
((previous_data & 0x000F0000) >> 4 ) |
|
||||||
|
@ -969,8 +962,8 @@ void RAMFUNC SniffIClass(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF);
|
uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF);
|
||||||
if (ManchesterDecoding_iclass(foo)) {
|
if (ManchesterDecoding_iclass(tag_byte)) {
|
||||||
time_stop = GetCountSspClk() - time_0;
|
time_stop = GetCountSspClk() - time_0;
|
||||||
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
|
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
|
||||||
DemodIcReset();
|
DemodIcReset();
|
||||||
|
@ -980,17 +973,15 @@ void RAMFUNC SniffIClass(void) {
|
||||||
}
|
}
|
||||||
TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD);
|
TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD);
|
||||||
}
|
}
|
||||||
tag_byte = 0;
|
|
||||||
foo = 0;
|
|
||||||
divi = 0;
|
|
||||||
}
|
}
|
||||||
} // end main loop
|
} // end main loop
|
||||||
|
|
||||||
|
/*
|
||||||
if (DBGLEVEL >= 1) {
|
if (DBGLEVEL >= 1) {
|
||||||
DbpString("[+] Sniff statistics:");
|
DbpString("[+] Sniff statistics:");
|
||||||
Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false);
|
Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,12 +1014,11 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
if (BUTTON_PRESS() || data_available()) return false;
|
if (BUTTON_PRESS() || data_available()) return false;
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
|
|
||||||
// keep tx buffer in a defined state anyway.
|
// keep tx buffer in a defined state anyway.
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
|
||||||
|
@ -1048,6 +1038,7 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static uint8_t encode4Bits(const uint8_t b) {
|
static uint8_t encode4Bits(const uint8_t b) {
|
||||||
// OTA, the least significant bits first
|
// OTA, the least significant bits first
|
||||||
// Manchester encoding added
|
// Manchester encoding added
|
||||||
|
@ -1094,6 +1085,9 @@ static uint8_t encode4Bits(const uint8_t b) {
|
||||||
return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
|
return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint8_t lut_enc[] = { 0xAA, 0x6A, 0x9A, 0x5A, 0xA6, 0x66, 0x96, 0x56, 0xA9, 0x69, 0x99, 0x59, 0xA5, 0x65, 0x95, 0x55 };
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Prepare tag messages
|
// Prepare tag messages
|
||||||
|
@ -1140,8 +1134,8 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
uint8_t b = cmd[i];
|
uint8_t b = cmd[i];
|
||||||
ToSend[++ToSendMax] = encode4Bits(b & 0xF); // least significant half
|
ToSend[++ToSendMax] = lut_enc[b & 0xF]; // least significant half
|
||||||
ToSend[++ToSendMax] = encode4Bits((b >> 4) & 0xF); // most significant half
|
ToSend[++ToSendMax] = lut_enc[(b >> 4) & 0xF]; // most significant half
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send EOF
|
// Send EOF
|
||||||
|
@ -1427,9 +1421,9 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
uint32_t time_0 = GetCountSspClk();
|
uint32_t time_0 = GetCountSspClk();
|
||||||
uint32_t t2r_stime = 0, t2r_etime = 0;
|
uint32_t t2r_stime = 0, t2r_etime = 0;
|
||||||
uint32_t r2t_stime, r2t_etime = 0;
|
uint32_t r2t_stime, r2t_etime = 0;
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
bool buttonPressed = false;
|
bool buttonPressed = false;
|
||||||
|
uint8_t cmd, options, block;
|
||||||
|
|
||||||
while (!exitLoop) {
|
while (!exitLoop) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -1450,7 +1444,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
|
|
||||||
LED_C_ON(); //Signal tracer
|
LED_C_ON(); //Signal tracer
|
||||||
|
|
||||||
if (receivedCmd[0] == ICLASS_CMD_ACTALL) { // 0x0A
|
cmd = receivedCmd[0] & 0xF;
|
||||||
|
options = (receivedCmd[0] >> 4) & 0xFF;
|
||||||
|
block = receivedCmd[1];
|
||||||
|
|
||||||
|
if (cmd == ICLASS_CMD_ACTALL) { // 0x0A
|
||||||
// Reader in anticollission phase
|
// Reader in anticollission phase
|
||||||
modulated_response = resp_sof;
|
modulated_response = resp_sof;
|
||||||
modulated_response_size = resp_sof_Len; //order = 1;
|
modulated_response_size = resp_sof_Len; //order = 1;
|
||||||
|
@ -1458,7 +1456,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
trace_data_size = sizeof(sof_data);
|
trace_data_size = sizeof(sof_data);
|
||||||
// adjusted for 330 + (160*num of slot)
|
// adjusted for 330 + (160*num of slot)
|
||||||
goto send;
|
goto send;
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C
|
} else if (cmd == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
// Reader asks for anticollission CSN
|
// Reader asks for anticollission CSN
|
||||||
modulated_response = resp_anticoll;
|
modulated_response = resp_anticoll;
|
||||||
|
@ -1470,7 +1468,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
|
|
||||||
if (len == 4) {
|
if (len == 4) {
|
||||||
// block0,1,2,5 is always readable.
|
// block0,1,2,5 is always readable.
|
||||||
switch (receivedCmd[1]) {
|
switch (block) {
|
||||||
case 0: // csn (0c 00)
|
case 0: // csn (0c 00)
|
||||||
modulated_response = resp_csn;
|
modulated_response = resp_csn;
|
||||||
modulated_response_size = resp_csn_len;
|
modulated_response_size = resp_csn_len;
|
||||||
|
@ -1503,7 +1501,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
if (simulationMode == MODE_FULLSIM) { // 0x0C
|
if (simulationMode == MODE_FULLSIM) { // 0x0C
|
||||||
//Read block
|
//Read block
|
||||||
//Take the data...
|
//Take the data...
|
||||||
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
|
memcpy(data_generic_trace, emulator + (block << 3), 8);
|
||||||
AddCrc(data_generic_trace, 8);
|
AddCrc(data_generic_trace, 8);
|
||||||
trace_data = data_generic_trace;
|
trace_data = data_generic_trace;
|
||||||
trace_data_size = 10;
|
trace_data_size = 10;
|
||||||
|
@ -1516,7 +1514,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
}
|
}
|
||||||
}//swith
|
}//swith
|
||||||
}// if 4
|
}// if 4
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81
|
} else if (cmd == ICLASS_CMD_SELECT) { // 0x81
|
||||||
// Reader selects anticollission CSN.
|
// Reader selects anticollission CSN.
|
||||||
// Tag sends the corresponding real CSN
|
// Tag sends the corresponding real CSN
|
||||||
modulated_response = resp_csn;
|
modulated_response = resp_csn;
|
||||||
|
@ -1524,23 +1522,15 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
trace_data = csn_data;
|
trace_data = csn_data;
|
||||||
trace_data_size = sizeof(csn_data);
|
trace_data_size = sizeof(csn_data);
|
||||||
goto send;
|
goto send;
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88
|
} else if (cmd == ICLASS_CMD_READCHECK ) { // 0x88
|
||||||
// Read e-purse (88 02)
|
// Read e-purse KD (88 02) KC (18 02)
|
||||||
modulated_response = resp_cc;
|
modulated_response = resp_cc;
|
||||||
modulated_response_size = resp_cc_len; //order = 4;
|
modulated_response_size = resp_cc_len; //order = 4;
|
||||||
trace_data = card_challenge_data;
|
trace_data = card_challenge_data;
|
||||||
trace_data_size = sizeof(card_challenge_data);
|
trace_data_size = sizeof(card_challenge_data);
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
goto send;
|
goto send;
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18
|
} else if (cmd == ICLASS_CMD_CHECK) { // 0x05
|
||||||
// Read e-purse (18 02)
|
|
||||||
modulated_response = resp_cc;
|
|
||||||
modulated_response_size = resp_cc_len; //order = 4;
|
|
||||||
trace_data = card_challenge_data;
|
|
||||||
trace_data_size = sizeof(card_challenge_data);
|
|
||||||
LED_B_ON();
|
|
||||||
goto send;
|
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_CHECK) { // 0x05
|
|
||||||
// Reader random and reader MAC!!!
|
// Reader random and reader MAC!!!
|
||||||
if (simulationMode == MODE_FULLSIM) {
|
if (simulationMode == MODE_FULLSIM) {
|
||||||
// NR, from reader, is in receivedCmd +1
|
// NR, from reader, is in receivedCmd +1
|
||||||
|
@ -1578,17 +1568,17 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto send;
|
goto send;
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
|
} else if (cmd == ICLASS_CMD_HALT && options == 0 && len == 1) {
|
||||||
// Reader ends the session
|
// Reader ends the session
|
||||||
modulated_response = resp_sof;
|
modulated_response = resp_sof;
|
||||||
modulated_response_size = 0; //order = 0;
|
modulated_response_size = 0; //order = 0;
|
||||||
trace_data = NULL;
|
trace_data = NULL;
|
||||||
trace_data_size = 0;
|
trace_data_size = 0;
|
||||||
goto send;
|
goto send;
|
||||||
} else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06
|
} else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06
|
||||||
//Read block
|
//Read block
|
||||||
//Take the data...
|
//Take the data...
|
||||||
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4);
|
memcpy(data_generic_trace, emulator + (block << 3), 8 * 4);
|
||||||
AddCrc(data_generic_trace, 8 * 4);
|
AddCrc(data_generic_trace, 8 * 4);
|
||||||
trace_data = data_generic_trace;
|
trace_data = data_generic_trace;
|
||||||
trace_data_size = 34;
|
trace_data_size = 34;
|
||||||
|
@ -1596,7 +1586,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
memcpy(modulated_response, ToSend, ToSendMax);
|
memcpy(modulated_response, ToSend, ToSendMax);
|
||||||
modulated_response_size = ToSendMax;
|
modulated_response_size = ToSendMax;
|
||||||
goto send;
|
goto send;
|
||||||
} else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) {
|
} else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_UPDATE) {
|
||||||
|
|
||||||
//Probably the reader wants to update the nonce. Let's just ignore that for now.
|
//Probably the reader wants to update the nonce. Let's just ignore that for now.
|
||||||
// OBS! If this is implemented, don't forget to regenerate the cipher_state
|
// OBS! If this is implemented, don't forget to regenerate the cipher_state
|
||||||
|
@ -1640,7 +1630,7 @@ send:
|
||||||
A legit tag has about 330us delay between reader EOT and tag SOF.
|
A legit tag has about 330us delay between reader EOT and tag SOF.
|
||||||
**/
|
**/
|
||||||
if (modulated_response_size > 0) {
|
if (modulated_response_size > 0) {
|
||||||
t2r_stime = (GetCountSspClk() - time_0) << 4;
|
t2r_stime = GetCountSspClkDelta(time_0) << 4;
|
||||||
SendIClassAnswer(modulated_response, modulated_response_size, 0);
|
SendIClassAnswer(modulated_response, modulated_response_size, 0);
|
||||||
t2r_etime = ((GetCountSspClk() - time_0) << 4) - t2r_stime;
|
t2r_etime = ((GetCountSspClk() - time_0) << 4) - t2r_stime;
|
||||||
}
|
}
|
||||||
|
@ -1676,12 +1666,12 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
|
||||||
uint16_t checked = 0;
|
uint16_t checked = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
if (BUTTON_PRESS() || data_available()) return 0;
|
if (BUTTON_PRESS() || data_available()) return 0;
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
|
|
||||||
// Prevent rx holding register from overflowing
|
// Prevent rx holding register from overflowing
|
||||||
if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {
|
if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {
|
||||||
b = AT91C_BASE_SSC->SSC_RHR;
|
b = AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
@ -1710,14 +1700,16 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Transmit the command (to the tag) that was placed in ToSend[].
|
// Transmit the command (to the tag) that was placed in ToSend[].
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) {
|
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *wait) {
|
||||||
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
volatile uint32_t b;
|
|
||||||
bool firstpart = true;
|
bool firstpart = true;
|
||||||
uint8_t sendbyte;
|
uint8_t sendbyte;
|
||||||
|
|
||||||
|
time_rdr = 0;
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||||
|
|
||||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||||
|
|
||||||
// make sure we timeout previous comms.
|
// make sure we timeout previous comms.
|
||||||
|
@ -1747,20 +1739,9 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
|
||||||
|
|
||||||
if (c >= len) break;
|
if (c >= len) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent rx holding register from overflowing
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
|
||||||
b = AT91C_BASE_SSC->SSC_RHR;
|
|
||||||
(void)b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samples) {
|
time_rdr = GetCountSspClk();
|
||||||
if (wait)
|
|
||||||
*samples = (c + *wait) << 3;
|
|
||||||
else
|
|
||||||
*samples = c << 3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1804,17 +1785,12 @@ void CodeIClassCommand(const uint8_t *cmd, int len) {
|
||||||
|
|
||||||
void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) {
|
void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) {
|
||||||
|
|
||||||
int samples = 0;
|
|
||||||
|
|
||||||
// This is tied to other size changes
|
// This is tied to other size changes
|
||||||
CodeIClassCommand(frame, len);
|
CodeIClassCommand(frame, len);
|
||||||
|
|
||||||
// Select the card
|
// Select the card
|
||||||
TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
|
TransmitIClassCommand(ToSend, ToSendMax, &wait);
|
||||||
if (trigger)
|
LED_A_ON();
|
||||||
LED_A_ON();
|
|
||||||
|
|
||||||
rsamples += samples;
|
|
||||||
|
|
||||||
LogTrace(frame, len, rsamples, rsamples, NULL, true);
|
LogTrace(frame, len, rsamples, rsamples, NULL, true);
|
||||||
}
|
}
|
||||||
|
@ -1827,22 +1803,20 @@ void ReaderTransmitIClass(uint8_t *frame, int len) {
|
||||||
// If a response is captured return TRUE
|
// If a response is captured return TRUE
|
||||||
// If it takes too long return FALSE
|
// If it takes too long return FALSE
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed) {
|
static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) {
|
||||||
// buffer needs to be 512 bytes
|
// buffer needs to be 512 bytes
|
||||||
// maxLen is not used...
|
// maxLen is not used...
|
||||||
|
|
||||||
int c = 0;
|
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
|
||||||
|
LED_D_ON();
|
||||||
|
// Set FPGA mode to "reader listen mode", no modulation (listen
|
||||||
|
// only, since we are receiving, not transmitting).
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
// Setup UART/DEMOD to receive
|
// Setup UART/DEMOD to receive
|
||||||
DemodIcInit(receivedResponse);
|
DemodIcInit(receivedResponse);
|
||||||
|
|
||||||
if (elapsed) *elapsed = 0;
|
SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments.
|
||||||
|
|
||||||
// Set FPGA mode to "reader listen mode", no modulation (listen
|
|
||||||
// only, since we are receiving, not transmitting).
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
|
|
||||||
SpinDelayUs(320); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments.
|
|
||||||
|
|
||||||
// clear RXRDY:
|
// clear RXRDY:
|
||||||
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
@ -1850,38 +1824,28 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
|
||||||
|
|
||||||
uint16_t checked = 0;
|
uint16_t checked = 0;
|
||||||
|
|
||||||
|
uint32_t card_start = GetCountSspClk();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
if (BUTTON_PRESS() || data_available()) return false;
|
if (BUTTON_PRESS() || data_available()) return false;
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// keep tx buffer in a defined state anyway.
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
|
||||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
|
||||||
// To make use of exact timing of next command from reader!!
|
|
||||||
if (elapsed)(*elapsed)++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
|
|
||||||
// Wait for byte be become available in rx holding register
|
// Wait for byte be become available in rx holding register
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
if (c >= timeout) return false;
|
|
||||||
|
|
||||||
c++;
|
|
||||||
|
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
skip = !skip;
|
skip = !skip;
|
||||||
if (skip) continue;
|
if (skip) continue;
|
||||||
|
|
||||||
if (ManchesterDecoding_iclass(b & 0x0f)) {
|
if (ManchesterDecoding_iclass(b & 0x0f)) {
|
||||||
if (samples)
|
time_response = GetCountSspClk() - card_start;
|
||||||
*samples = c << 3;
|
|
||||||
return true;
|
return true;
|
||||||
|
} else if (GetCountSspClkDelta(card_start) > timeout && Demod.state == DEMOD_IC_UNSYNCD) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1889,18 +1853,11 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReaderReceiveIClass(uint8_t *receivedAnswer) {
|
int ReaderReceiveIClass(uint8_t *receivedAnswer) {
|
||||||
int samples = 0;
|
|
||||||
|
|
||||||
if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL))
|
if (GetIClassAnswer(receivedAnswer, 0, NULL) == false)
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
rsamples += samples;
|
|
||||||
|
|
||||||
LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false);
|
LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false);
|
||||||
|
|
||||||
if (samples == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1924,25 +1881,34 @@ void setupIclassReader() {
|
||||||
// Now give it time to spin up.
|
// Now give it time to spin up.
|
||||||
// Signal field is on with the appropriate LED
|
// Signal field is on with the appropriate LED
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||||
SpinDelay(300);
|
SpinDelay(500);
|
||||||
|
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, uint8_t retries) {
|
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) {
|
||||||
while (retries-- > 0) {
|
while (retries-- > 0) {
|
||||||
|
|
||||||
ReaderTransmitIClass(command, cmdsize);
|
ReaderTransmitIClass(command, cmdsize);
|
||||||
|
|
||||||
//iceman - if received size is bigger than expected, we smash the stack here
|
//iceman - if received size is bigger than expected, we smash the stack here
|
||||||
// since its called with fixed sized arrays
|
// since its called with fixed sized arrays
|
||||||
|
|
||||||
|
// update/write command takes 4ms to 15ms before responding
|
||||||
|
int old_wait = g_wait;
|
||||||
|
if ( (command[0] & 0xF) == ICLASS_CMD_UPDATE)
|
||||||
|
g_wait = 3900;
|
||||||
|
|
||||||
uint8_t got_n = ReaderReceiveIClass(resp);
|
uint8_t got_n = ReaderReceiveIClass(resp);
|
||||||
|
|
||||||
|
g_wait = old_wait;
|
||||||
|
|
||||||
// 0xBB is the internal debug separator byte..
|
// 0xBB is the internal debug separator byte..
|
||||||
if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) {
|
if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) {
|
||||||
//try again
|
//try again
|
||||||
|
// SpinDelayUs(360);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,26 +1930,30 @@ 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 };
|
||||||
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
|
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
|
||||||
static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
static uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 };
|
uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
|
||||||
|
|
||||||
|
// Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) willbe used
|
||||||
|
// bit 7: parity.
|
||||||
|
|
||||||
if (use_credit_key)
|
if (use_credit_key)
|
||||||
readcheck_cc[0] = ICLASS_CMD_READCHECK_KC;
|
readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
|
||||||
|
|
||||||
uint8_t resp[ICLASS_BUFFER_SIZE] = {0};
|
uint8_t resp[ICLASS_BUFFER_SIZE] = {0};
|
||||||
uint8_t read_status = 0;
|
|
||||||
|
|
||||||
// Send act_all
|
// Send act_all ( 330 timeout + 160 timeslot);
|
||||||
ReaderTransmitIClass_ext(act_all, 1, 330 + 160);
|
ReaderTransmitIClass_ext(act_all, 1, 330 + 180);
|
||||||
|
|
||||||
// Card present?
|
// Card present?
|
||||||
if (!ReaderReceiveIClass(resp)) return read_status;//Fail
|
if (ReaderReceiveIClass(resp) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
//Send Identify
|
//Send Identify
|
||||||
ReaderTransmitIClass(identify, 1);
|
ReaderTransmitIClass(identify, 1);
|
||||||
|
|
||||||
//We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
|
//We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
|
||||||
uint8_t len = ReaderReceiveIClass(resp);
|
if ( ReaderReceiveIClass(resp) != 10 )
|
||||||
if (len != 10) return read_status;//Fail
|
return 0;
|
||||||
|
|
||||||
//Copy the Anti-collision CSN to our select-packet
|
//Copy the Anti-collision CSN to our select-packet
|
||||||
memcpy(&select[1], resp, 8);
|
memcpy(&select[1], resp, 8);
|
||||||
|
@ -1992,31 +1962,33 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
|
||||||
ReaderTransmitIClass(select, sizeof(select));
|
ReaderTransmitIClass(select, sizeof(select));
|
||||||
|
|
||||||
//We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
|
//We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
|
||||||
len = ReaderReceiveIClass(resp);
|
if ( ReaderReceiveIClass(resp) != 10)
|
||||||
if (len != 10) return read_status;//Fail
|
return 0;
|
||||||
|
|
||||||
//Success - level 1, we got CSN
|
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
|
||||||
//Save CSN in response data
|
|
||||||
memcpy(card_data, resp, 8);
|
|
||||||
|
|
||||||
//Flag that we got to at least stage 1, read CSN
|
|
||||||
read_status = 1;
|
|
||||||
|
|
||||||
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
|
|
||||||
// ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
// ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
||||||
// if (ReaderReceiveIClass(resp) == 8) {
|
// if (ReaderReceiveIClass(resp) == 8) {
|
||||||
// //Save CC (e-purse) in response data
|
// //Save CC (e-purse) in response data
|
||||||
// memcpy(card_data+8, resp, 8);
|
// memcpy(card_data+8, resp, 8);
|
||||||
// read_status++;
|
// read_status++;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
//Success - level 1, we got CSN
|
||||||
|
//Save CSN in response data
|
||||||
|
memcpy(card_data, resp, 8);
|
||||||
|
|
||||||
|
bool isBlk_2 = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3);
|
||||||
|
|
||||||
bool isOK = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3);
|
//Flag that we got to at least stage 1, read CSN
|
||||||
if (!isOK) return read_status;
|
if ( isBlk_2 == false) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//Save CC (e-purse) in response data
|
//Save CC (e-purse) in response data
|
||||||
memcpy(card_data + 8, resp, 8);
|
memcpy(card_data + 8, resp, 8);
|
||||||
read_status++;
|
|
||||||
return read_status;
|
// we got all data;
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
uint8_t handshakeIclassTag(uint8_t *card_data) {
|
uint8_t handshakeIclassTag(uint8_t *card_data) {
|
||||||
return handshakeIclassTag_ext(card_data, false);
|
return handshakeIclassTag_ext(card_data, false);
|
||||||
|
@ -2057,7 +2029,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// if only looking for one card try 2 times if we missed it the first time
|
// if only looking for one card try 2 times if we missed it the first time
|
||||||
if (try_once && tryCnt > 2) {
|
if (try_once && tryCnt > 10) {
|
||||||
if (DBGLEVEL > 1) DbpString("Failed to find a tag");
|
if (DBGLEVEL > 1) DbpString("Failed to find a tag");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2140,7 +2112,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SEND %c", send ? 'y' : 'n');
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SEND %c", send ? 'y' : 'n');
|
||||||
|
|
||||||
if (send) {
|
if (send) {
|
||||||
reply_old(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
|
reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
|
||||||
if (abort_after_read) {
|
if (abort_after_read) {
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
return;
|
return;
|
||||||
|
@ -2151,19 +2123,18 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
}
|
}
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
userCancelled = BUTTON_PRESS() || data_available();
|
userCancelled = BUTTON_PRESS() || data_available();
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userCancelled) {
|
if (userCancelled) {
|
||||||
reply_old(CMD_ACK, 0xFF, 0, 0, card_data, 0);
|
reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
} else {
|
} else {
|
||||||
reply_old(CMD_ACK, 0, 0, 0, card_data, 0);
|
reply_mix(CMD_ACK, 0, 0, 0, card_data, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2311,8 +2282,8 @@ void iClass_Authentication(uint8_t *mac) {
|
||||||
//memcpy(check+5, mac, 4);
|
//memcpy(check+5, mac, 4);
|
||||||
|
|
||||||
// 6 retries
|
// 6 retries
|
||||||
bool isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6);
|
uint8_t isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6);
|
||||||
reply_mix(CMD_ACK, isOK, 0, 0, 0, 0);
|
reply_ng(CMD_HF_ICLASS_AUTH, PM3_SUCCESS, (uint8_t*)&isOK ,sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct iclass_premac {
|
typedef struct iclass_premac {
|
||||||
|
@ -2333,10 +2304,10 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
|
||||||
uint8_t keyCount = arg1 & 0xFF;
|
uint8_t keyCount = arg1 & 0xFF;
|
||||||
uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||||
uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 };
|
uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
|
||||||
|
|
||||||
if (use_credit_key)
|
if (use_credit_key)
|
||||||
readcheck_cc[0] = ICLASS_CMD_READCHECK_KC;
|
readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
|
||||||
|
|
||||||
// select card / e-purse
|
// select card / e-purse
|
||||||
uint8_t card_data[6 * 8] = {0};
|
uint8_t card_data[6 * 8] = {0};
|
||||||
|
@ -2355,12 +2326,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
|
||||||
uint8_t startup_limit = 10;
|
uint8_t startup_limit = 10;
|
||||||
while (read_status != 2) {
|
while (read_status != 2) {
|
||||||
|
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
if (BUTTON_PRESS() || !data_available()) goto out;
|
if (BUTTON_PRESS() || !data_available()) goto out;
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
|
|
||||||
read_status = handshakeIclassTag_ext(card_data, use_credit_key);
|
read_status = handshakeIclassTag_ext(card_data, use_credit_key);
|
||||||
if (startup_limit-- == 0) {
|
if (startup_limit-- == 0) {
|
||||||
|
@ -2371,16 +2341,17 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
|
||||||
};
|
};
|
||||||
// since handshakeIclassTag_ext call sends s readcheck, we start with sending first response.
|
// since handshakeIclassTag_ext call sends s readcheck, we start with sending first response.
|
||||||
|
|
||||||
|
checked = 0;
|
||||||
|
|
||||||
// Keychunk loop
|
// Keychunk loop
|
||||||
for (i = 0; i < keyCount; i++) {
|
for (i = 0; i < keyCount; i++) {
|
||||||
|
|
||||||
// Allow button press / usb cmd to interrupt device
|
// Allow button press / usb cmd to interrupt device
|
||||||
if (checked == 1000) {
|
if (checked == 2000) {
|
||||||
if (BUTTON_PRESS() || !data_available()) goto out;
|
if (BUTTON_PRESS() || !data_available()) goto out;
|
||||||
checked = 0;
|
checked = 0;
|
||||||
} else {
|
|
||||||
checked++;
|
|
||||||
}
|
}
|
||||||
|
checked++;
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
@ -2396,8 +2367,6 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
|
||||||
if (isOK)
|
if (isOK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
SpinDelayUs(400); //iClass (iso15693-2) should timeout after 330us.
|
|
||||||
|
|
||||||
// Auth Sequence MUST begin with reading e-purse. (block2)
|
// Auth Sequence MUST begin with reading e-purse. (block2)
|
||||||
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
|
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
|
||||||
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
||||||
|
@ -2433,10 +2402,14 @@ bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len) {
|
||||||
// turn off afterwards
|
// turn off afterwards
|
||||||
// readblock 8 + 2. only want 8.
|
// readblock 8 + 2. only want 8.
|
||||||
void iClass_ReadBlk(uint8_t blockno) {
|
void iClass_ReadBlk(uint8_t blockno) {
|
||||||
uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
struct p {
|
||||||
bool isOK = iClass_ReadBlock(blockno, data, sizeof(data));
|
bool isOK;
|
||||||
reply_mix(CMD_ACK, isOK, 0, 0, data, sizeof(data));
|
uint8_t blockdata[8];
|
||||||
|
} PACKED result;
|
||||||
|
|
||||||
|
result.isOK = iClass_ReadBlock(blockno, result.blockdata, sizeof(result.blockdata));
|
||||||
switch_off();
|
switch_off();
|
||||||
|
reply_ng(CMD_HF_ICLASS_READBL, PM3_SUCCESS, (uint8_t *)&result, sizeof(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn off afterwards
|
// turn off afterwards
|
||||||
|
@ -2448,7 +2421,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
uint8_t *dataout = BigBuf_malloc(255 * 8);
|
uint8_t *dataout = BigBuf_malloc(255 * 8);
|
||||||
if (dataout == NULL) {
|
if (dataout == NULL) {
|
||||||
DbpString("[!] out of memory");
|
DbpString("[!] fail to allocate memory");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2468,39 +2441,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
|
||||||
}
|
}
|
||||||
memcpy(dataout + (blkCnt * 8), blockdata, 8);
|
memcpy(dataout + (blkCnt * 8), blockdata, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_off();
|
||||||
//return pointer to dump memory in arg3
|
//return pointer to dump memory in arg3
|
||||||
reply_mix(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0);
|
reply_mix(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0);
|
||||||
switch_off();
|
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) {
|
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[] = { 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
|
||||||
AddCrc(write + 1, 13);
|
AddCrc(write + 1, 13);
|
||||||
|
return sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5);
|
||||||
bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5);
|
|
||||||
if (isOK) { //if reader responded correctly
|
|
||||||
|
|
||||||
//if response is not equal to write values
|
|
||||||
if (memcmp(write + 2, resp, 8)) {
|
|
||||||
|
|
||||||
//if not programming key areas (note key blocks don't get programmed with actual key data it is xor data)
|
|
||||||
if (blockno != 3 && blockno != 4) {
|
|
||||||
isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isOK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn off afterwards
|
// turn off afterwards
|
||||||
void iClass_WriteBlock(uint8_t blockno, uint8_t *data) {
|
void iClass_WriteBlock(uint8_t blockno, uint8_t *data) {
|
||||||
bool isOK = iClass_WriteBlock_ext(blockno, data);
|
uint8_t isOK = iClass_WriteBlock_ext(blockno, data);
|
||||||
reply_mix(CMD_ACK, isOK, 0, 0, 0, 0);
|
|
||||||
switch_off();
|
switch_off();
|
||||||
|
reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t*)&isOK, sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn off afterwards
|
// turn off afterwards
|
||||||
|
@ -2509,23 +2469,19 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
|
||||||
int total_block = (endblock - startblock) + 1;
|
int total_block = (endblock - startblock) + 1;
|
||||||
for (i = 0; i < total_block; i++) {
|
for (i = 0; i < total_block; i++) {
|
||||||
// block number
|
// block number
|
||||||
if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) {
|
if (iClass_WriteBlock_ext(startblock + i, data + (i * 12))) {
|
||||||
Dbprintf("Write block [%02x] successful", i + startblock);
|
Dbprintf("Write block [%02x] successful", startblock + i);
|
||||||
written++;
|
written++;
|
||||||
} else {
|
} else {
|
||||||
if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) {
|
Dbprintf("Write block [%02x] failed", startblock + i);
|
||||||
Dbprintf("Write block [%02x] successful", i + startblock);
|
|
||||||
written++;
|
|
||||||
} else {
|
|
||||||
Dbprintf("Write block [%02x] failed", i + startblock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (written == total_block)
|
|
||||||
DbpString("Clone complete");
|
|
||||||
else
|
|
||||||
DbpString("Clone incomplete");
|
|
||||||
|
|
||||||
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
|
|
||||||
switch_off();
|
switch_off();
|
||||||
|
|
||||||
|
uint8_t isOK = 0;
|
||||||
|
if (written == total_block)
|
||||||
|
isOK = 1;
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1672,26 +1672,11 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
|
||||||
// clear TXRDY
|
// clear TXRDY
|
||||||
AT91C_BASE_SSC->SSC_THR = SEC_Y;
|
AT91C_BASE_SSC->SSC_THR = SEC_Y;
|
||||||
|
|
||||||
volatile uint8_t b;
|
|
||||||
uint16_t c = 0;
|
uint16_t c = 0;
|
||||||
uint32_t sendtimer = GetTickCount();
|
|
||||||
uint32_t cntr = 0;
|
|
||||||
while (c < len) {
|
while (c < len) {
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||||
AT91C_BASE_SSC->SSC_THR = cmd[c++];
|
AT91C_BASE_SSC->SSC_THR = cmd[c];
|
||||||
cntr = 0;
|
c++;
|
||||||
} else {
|
|
||||||
if (cntr++ > 1000) {
|
|
||||||
cntr = 0;
|
|
||||||
if (GetTickCount() - sendtimer > 100)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//iceman test
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
|
||||||
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
|
||||||
(void)b;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -941,7 +941,7 @@ static void fcSTT(int *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// compose fc/X fc/Y waveform (FSKx)
|
// compose fc/X fc/Y waveform (FSKx)
|
||||||
static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
|
static uint8_t fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
uint8_t halfFC = fc >> 1;
|
uint8_t halfFC = fc >> 1;
|
||||||
uint8_t wavesPerClock = clock / fc;
|
uint8_t wavesPerClock = clock / fc;
|
||||||
|
@ -966,12 +966,15 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
|
||||||
*n += fc;
|
*n += fc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* This code interfers with FSK2 and I don't see any example of FSK1 simulation in the code...
|
||||||
if (!modAdjOk) { //fsk1
|
if (!modAdjOk) { //fsk1
|
||||||
memset(dest + (*n), 0, mod - (mod >> 1));
|
memset(dest + (*n), 0, mod - (mod >> 1));
|
||||||
memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1);
|
memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1);
|
||||||
*n += mod;
|
*n += mod;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare a waveform pattern in the buffer based on the ID given then
|
// prepare a waveform pattern in the buffer based on the ID given then
|
||||||
|
@ -1059,17 +1062,17 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk,
|
||||||
|
|
||||||
int n = 0, i = 0;
|
int n = 0, i = 0;
|
||||||
uint16_t modCnt = 0;
|
uint16_t modCnt = 0;
|
||||||
|
uint8_t mod = 0;
|
||||||
|
|
||||||
if (separator) {
|
if (separator) {
|
||||||
//int fsktype = ( fchigh == 8 && fclow == 5) ? 1 : 2;
|
//int fsktype = ( fchigh == 8 && fclow == 5) ? 1 : 2;
|
||||||
//fcSTT(&n);
|
//fcSTT(&n);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < bitslen; i++) {
|
for (i = 0; i < bitslen; i++) {
|
||||||
if (bits[i])
|
if (bits[i])
|
||||||
fcAll(fclow, &n, clk, &modCnt);
|
mod = fcAll(fchigh, &n, clk+mod, &modCnt);
|
||||||
else
|
else
|
||||||
fcAll(fchigh, &n, clk, &modCnt);
|
mod = fcAll(fclow, &n, clk+mod, &modCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -1306,7 +1309,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
hi2 = hi = lo = idx = 0;
|
hi2 = hi = lo = idx = 0;
|
||||||
}
|
}
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
DbpString("Stopped");
|
DbpString("HID fsk demod stopped");
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2060,6 +2063,7 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) {
|
||||||
|
|
||||||
//-- Turn and leave field on to let the begin repeating transmission
|
//-- Turn and leave field on to let the begin repeating transmission
|
||||||
TurnReadLFOn(20 * 1000);
|
TurnReadLFOn(20 * 1000);
|
||||||
|
reply_ng(CMD_LF_T55XX_WAKEUP, PM3_SUCCESS, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1342,8 +1342,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
|
|
||||||
for (uint16_t i = s_point; i < keyCount; ++i) {
|
for (uint16_t i = s_point; i < keyCount; ++i) {
|
||||||
|
|
||||||
//if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point);
|
|
||||||
|
|
||||||
// Allow button press / usb cmd to interrupt device
|
// Allow button press / usb cmd to interrupt device
|
||||||
if (BUTTON_PRESS() && !data_available()) {
|
if (BUTTON_PRESS() && !data_available()) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
@ -1525,6 +1523,33 @@ OUT:
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
|
// special trick ecfill
|
||||||
|
if (use_flashmem && foundkeys == allkeys) {
|
||||||
|
|
||||||
|
uint8_t block[16] = {0};
|
||||||
|
for (int i = 0; i < sectorcnt; i++) {
|
||||||
|
|
||||||
|
uint8_t blockno;
|
||||||
|
if (i < 32) {
|
||||||
|
blockno = (i * 4) ^ 0x3;
|
||||||
|
} else {
|
||||||
|
blockno = (32 * 4 + (i - 32) * 16) ^ 0xF;
|
||||||
|
}
|
||||||
|
// get ST
|
||||||
|
emlGetMem(block, blockno, 1);
|
||||||
|
|
||||||
|
memcpy(block, k_sector[i].keyA, 6);
|
||||||
|
memcpy(block + 10, k_sector[i].keyB, 6);
|
||||||
|
|
||||||
|
emlSetMem_xt(block, blockno, 1, sizeof(block));
|
||||||
|
}
|
||||||
|
int oldbg = DBGLEVEL;
|
||||||
|
DBGLEVEL = DBG_NONE;
|
||||||
|
MifareECardLoad(sectorcnt, 0);
|
||||||
|
MifareECardLoad(sectorcnt, 1);
|
||||||
|
DBGLEVEL = oldbg;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// partial/none keys found
|
// partial/none keys found
|
||||||
reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0);
|
reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0);
|
||||||
|
@ -1669,10 +1694,15 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) {
|
||||||
// Load a card into the emulator memory
|
// Load a card into the emulator memory
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int MifareECardLoad(uint32_t arg0, uint32_t arg1) {
|
int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType) {
|
||||||
|
int retval = MifareECardLoad(numSectors, keyType);
|
||||||
|
reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MifareECardLoad(uint8_t numSectors, uint8_t keyType) {
|
||||||
|
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
uint8_t numSectors = arg0;
|
|
||||||
uint8_t keyType = arg1;
|
|
||||||
struct Crypto1State mpcs = {0, 0};
|
struct Crypto1State mpcs = {0, 0};
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
@ -1683,68 +1713,63 @@ int MifareECardLoad(uint32_t arg0, uint32_t arg1) {
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_B_OFF();
|
|
||||||
LED_C_OFF();
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
bool isOK = true;
|
int retval;
|
||||||
|
|
||||||
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||||
isOK = false;
|
retval = PM3_ESOFT;
|
||||||
if (DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (DBGLEVEL > DBG_ERROR) Dbprintf("Can't select card");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
|
for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||||
uint64_t ui64Key = emlGetKey(sectorNo, keyType);
|
uint64_t ui64Key = emlGetKey(sectorNo, keyType);
|
||||||
if (sectorNo == 0) {
|
if (sectorNo == 0) {
|
||||||
if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
|
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
|
||||||
if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);
|
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
|
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
|
||||||
isOK = false;
|
retval = PM3_ESOFT;
|
||||||
if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
|
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
||||||
if (isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
|
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
|
||||||
isOK = false;
|
retval = PM3_ESOFT;
|
||||||
if (DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
|
if (DBGLEVEL > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (isOK) {
|
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
|
||||||
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
|
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||||
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
} else { // sector trailer, keep the keys, set only the AC
|
||||||
} else { // sector trailer, keep the keys, set only the AC
|
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||||
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
|
||||||
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
|
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||||
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mifare_classic_halt(pcs, cuid))
|
if (mifare_classic_halt(pcs, cuid)) {
|
||||||
if (DBGLEVEL >= 1)
|
if (DBGLEVEL > DBG_ERROR)
|
||||||
Dbprintf("Halt error");
|
Dbprintf("Halt error");
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------- crypto1 destroy
|
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
|
||||||
|
|
||||||
|
out:
|
||||||
crypto1_destroy(pcs);
|
crypto1_destroy(pcs);
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
if (DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");
|
|
||||||
|
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
return (isOK) ? PM3_SUCCESS : PM3_EUNDEF;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1955,6 +1980,8 @@ void MifareCIdent() {
|
||||||
#define GEN_1A 1
|
#define GEN_1A 1
|
||||||
#define GEN_1B 2
|
#define GEN_1B 2
|
||||||
#define GEN_2 4
|
#define GEN_2 4
|
||||||
|
#define GEN_UNFUSED 5
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
uint8_t isGen = 0;
|
uint8_t isGen = 0;
|
||||||
uint8_t rec[1] = {0x00};
|
uint8_t rec[1] = {0x00};
|
||||||
|
@ -1970,19 +1997,19 @@ void MifareCIdent() {
|
||||||
|
|
||||||
// Generation 1 test
|
// Generation 1 test
|
||||||
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
||||||
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
|
||||||
goto TEST2;
|
if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
||||||
};
|
|
||||||
|
|
||||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||||
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
|
||||||
isGen = GEN_1B;
|
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
|
||||||
goto OUT;
|
isGen = GEN_1B;
|
||||||
};
|
goto OUT;
|
||||||
isGen = GEN_1A;
|
};
|
||||||
goto OUT;
|
isGen = GEN_1A;
|
||||||
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
TEST2:
|
|
||||||
// reset card
|
// reset card
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
|
@ -1990,6 +2017,12 @@ TEST2:
|
||||||
|
|
||||||
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
|
||||||
if (res == 2) {
|
if (res == 2) {
|
||||||
|
Dbprintf("cident AA55C396 == %08X", cuid);
|
||||||
|
if (cuid == 0xAA55C396) {
|
||||||
|
isGen = GEN_UNFUSED;
|
||||||
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
ReaderTransmit(rats, sizeof(rats), NULL);
|
ReaderTransmit(rats, sizeof(rats), NULL);
|
||||||
res = ReaderReceive(buf, par);
|
res = ReaderReceive(buf, par);
|
||||||
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) {
|
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) {
|
||||||
|
|
|
@ -31,7 +31,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
void MifareEMemClr(void);
|
void MifareEMemClr(void);
|
||||||
void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain);
|
void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain);
|
||||||
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
|
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
|
||||||
int MifareECardLoad(uint32_t arg0, uint32_t arg1);
|
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype);
|
||||||
|
int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType);
|
||||||
|
|
||||||
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card
|
void 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);
|
||||||
|
|
|
@ -60,11 +60,59 @@
|
||||||
-- MHS 2015
|
-- MHS 2015
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
The runtime of opt_doTagMAC_2() with the MHS optimized version was 403 microseconds on Proxmark3.
|
||||||
|
This was still to slow for some newer readers which didn't want to wait that long.
|
||||||
|
|
||||||
|
Further optimizations to speedup the MAC calculations:
|
||||||
|
* Optimized opt_Tt logic
|
||||||
|
* Look up table for opt_select
|
||||||
|
* Removing many unnecessary bit maskings (& 0x1)
|
||||||
|
* updating state in place instead of alternating use of a second state structure
|
||||||
|
* remove the necessity to reverse bits of input and output bytes
|
||||||
|
|
||||||
|
opt_doTagMAC_2() now completes in 270 microseconds.
|
||||||
|
|
||||||
|
-- piwi 2019
|
||||||
|
**/
|
||||||
|
|
||||||
#include "optimized_cipher.h"
|
#include "optimized_cipher.h"
|
||||||
|
|
||||||
#define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14)^ (s->t >> 10)^ (s->t >> 8)^ (s->t >> 5)^ (s->t >> 4)^ (s->t >> 1)^ s->t))
|
static const uint8_t opt_select_LUT[256] = {
|
||||||
|
00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04,
|
||||||
|
01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04,
|
||||||
|
06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06,
|
||||||
|
07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06,
|
||||||
|
06, 05, 04, 07, 04, 05, 06, 07, 02, 01, 01, 02, 00, 01, 03, 02,
|
||||||
|
03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06,
|
||||||
|
00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00,
|
||||||
|
05, 06, 07, 04, 06, 07, 04, 05, 05, 06, 06, 05, 06, 07, 05, 04,
|
||||||
|
02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06,
|
||||||
|
03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06,
|
||||||
|
02, 01, 00, 03, 00, 01, 02, 03, 02, 01, 01, 02, 00, 01, 03, 02,
|
||||||
|
03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02,
|
||||||
|
04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00,
|
||||||
|
01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04,
|
||||||
|
04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04,
|
||||||
|
01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00
|
||||||
|
};
|
||||||
|
|
||||||
#define opt_B(s) (((s->b >> 6) ^ (s->b >> 5) ^ (s->b >> 4) ^ (s->b)) & 0x1)
|
/********************** the table above has been generated with this code: ********
|
||||||
|
#include "util.h"
|
||||||
|
static void init_opt_select_LUT(void) {
|
||||||
|
for (int r = 0; r < 256; r++) {
|
||||||
|
uint8_t r_ls2 = r << 2;
|
||||||
|
uint8_t r_and_ls2 = r & r_ls2;
|
||||||
|
uint8_t r_or_ls2 = r | r_ls2;
|
||||||
|
uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3);
|
||||||
|
uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r;
|
||||||
|
uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r;
|
||||||
|
opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1);
|
||||||
|
}
|
||||||
|
print_result("", opt_select_LUT, 256);
|
||||||
|
}
|
||||||
|
***********************************************************************************/
|
||||||
|
|
||||||
#define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\
|
#define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\
|
||||||
|(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\
|
|(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\
|
||||||
|
@ -74,9 +122,6 @@
|
||||||
* Some background on the expression above can be found here...
|
* Some background on the expression above can be found here...
|
||||||
uint8_t xopt__select(bool x, bool y, uint8_t r)
|
uint8_t xopt__select(bool x, bool y, uint8_t r)
|
||||||
{
|
{
|
||||||
uint8_t r_ls2 = r << 2;
|
|
||||||
uint8_t r_and_ls2 = r & r_ls2;
|
|
||||||
uint8_t r_or_ls2 = r | r_ls2;
|
|
||||||
|
|
||||||
//r: r0 r1 r2 r3 r4 r5 r6 r7
|
//r: r0 r1 r2 r3 r4 r5 r6 r7
|
||||||
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
|
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
|
||||||
|
@ -96,82 +141,95 @@ uint8_t xopt__select(bool x, bool y, uint8_t r)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void opt_successor(const uint8_t *k, State *s, bool y, State *successor) {
|
static void opt_successor(const uint8_t *k, State *s, uint8_t y) {
|
||||||
uint8_t Tt = 1 & opt_T(s);
|
// #define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14) ^ (s->t >> 10) ^ (s->t >> 8) ^ (s->t >> 5) ^ (s->t >> 4)^ (s->t >> 1) ^ s->t))
|
||||||
|
// uint8_t Tt = opt_T(s);
|
||||||
|
uint16_t Tt = s->t & 0xc533;
|
||||||
|
Tt = Tt ^ (Tt >> 1);
|
||||||
|
Tt = Tt ^ (Tt >> 4);
|
||||||
|
Tt = Tt ^ (Tt >> 10);
|
||||||
|
Tt = Tt ^ (Tt >> 8);
|
||||||
|
|
||||||
successor->t = (s->t >> 1);
|
s->t = (s->t >> 1);
|
||||||
successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15;
|
s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15;
|
||||||
|
|
||||||
successor->b = s->b >> 1;
|
uint8_t opt_B = s->b;
|
||||||
successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7;
|
opt_B ^= s->b >> 6;
|
||||||
|
opt_B ^= s->b >> 5;
|
||||||
|
opt_B ^= s->b >> 4;
|
||||||
|
|
||||||
successor->r = (k[opt__select(Tt, y, s->r)] ^ successor->b) + s->l ;
|
s->b = s->b >> 1;
|
||||||
successor->l = successor->r + s->r;
|
s->b |= (opt_B ^ s->r) << 7;
|
||||||
|
|
||||||
|
uint8_t opt_select = opt_select_LUT[s->r] & 0x04;
|
||||||
|
opt_select |= (opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02;
|
||||||
|
opt_select |= (opt_select_LUT[s->r] ^ Tt) & 0x01;
|
||||||
|
|
||||||
|
uint8_t r = s->r;
|
||||||
|
s->r = (k[opt_select] ^ s->b) + s->l ;
|
||||||
|
s->l = s->r + r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) {
|
static void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) {
|
||||||
State x2;
|
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
uint8_t head;
|
uint8_t head;
|
||||||
head = 1 & (in[i] >> 7);
|
head = in[i];
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 6);
|
head >>= 1;
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 5);
|
head >>= 1;
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 4);
|
head >>= 1;
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 3);
|
head >>= 1;
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 2);
|
head >>= 1;
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 1);
|
head >>= 1;
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head);
|
||||||
|
|
||||||
head = 1 & in[i];
|
head >>= 1;
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, s, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
//For tag MAC, an additional 32 zeroes
|
//For tag MAC, an additional 32 zeroes
|
||||||
if (add32Zeroes) {
|
if (add32Zeroes) {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
opt_successor(k, s, 0, &x2);
|
opt_successor(k, s, 0);
|
||||||
opt_successor(k, &x2, 0, s);
|
opt_successor(k, s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_output(const uint8_t *k, State *s, uint8_t *buffer) {
|
static void opt_output(const uint8_t *k, State *s, uint8_t *buffer) {
|
||||||
State temp = {0, 0, 0, 0};
|
|
||||||
for (uint8_t times = 0; times < 4; times++) {
|
for (uint8_t times = 0; times < 4; times++) {
|
||||||
uint8_t bout = 0;
|
uint8_t bout = 0;
|
||||||
bout |= (s->r & 0x4) << 5;
|
bout |= (s->r & 0x4) >> 2;
|
||||||
opt_successor(k, s, 0, &temp);
|
opt_successor(k, s, 0);
|
||||||
bout |= (temp.r & 0x4) << 4;
|
|
||||||
opt_successor(k, &temp, 0, s);
|
|
||||||
bout |= (s->r & 0x4) << 3;
|
|
||||||
opt_successor(k, s, 0, &temp);
|
|
||||||
bout |= (temp.r & 0x4) << 2;
|
|
||||||
opt_successor(k, &temp, 0, s);
|
|
||||||
bout |= (s->r & 0x4) << 1;
|
|
||||||
opt_successor(k, s, 0, &temp);
|
|
||||||
bout |= (temp.r & 0x4) ;
|
|
||||||
opt_successor(k, &temp, 0, s);
|
|
||||||
bout |= (s->r & 0x4) >> 1;
|
bout |= (s->r & 0x4) >> 1;
|
||||||
opt_successor(k, s, 0, &temp);
|
opt_successor(k, s, 0);
|
||||||
bout |= (temp.r & 0x4) >> 2;
|
bout |= (s->r & 0x4);
|
||||||
opt_successor(k, &temp, 0, s);
|
opt_successor(k, s, 0);
|
||||||
|
bout |= (s->r & 0x4) << 1;
|
||||||
|
opt_successor(k, s, 0);
|
||||||
|
bout |= (s->r & 0x4) << 2;
|
||||||
|
opt_successor(k, s, 0);
|
||||||
|
bout |= (s->r & 0x4) << 3;
|
||||||
|
opt_successor(k, s, 0);
|
||||||
|
bout |= (s->r & 0x4) << 4;
|
||||||
|
opt_successor(k, s, 0);
|
||||||
|
bout |= (s->r & 0x4) << 5;
|
||||||
|
opt_successor(k, s, 0);
|
||||||
buffer[times] = bout;
|
buffer[times] = bout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) {
|
static void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) {
|
||||||
State _init = {
|
State _init = {
|
||||||
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||||
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||||
|
@ -183,45 +241,25 @@ void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) {
|
||||||
opt_output(k, &_init, out);
|
opt_output(k, &_init, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rev_byte(uint8_t b) {
|
|
||||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void opt_reverse_arraybytecpy(uint8_t *dest, uint8_t *src, size_t len) {
|
|
||||||
uint8_t i;
|
|
||||||
for (i = 0; i < len ; i++)
|
|
||||||
dest[i] = rev_byte(src[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
|
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
|
||||||
static uint8_t cc_nr[12];
|
|
||||||
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
|
|
||||||
uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0};
|
uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
opt_MAC(div_key_p, cc_nr, dest);
|
opt_MAC(div_key_p, cc_nr_p, dest);
|
||||||
//The output MAC must also be reversed
|
memcpy(mac, dest, 4);
|
||||||
opt_reverse_arraybytecpy(mac, dest, 4);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
|
void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
|
||||||
static uint8_t cc_nr[8 + 4 + 4];
|
|
||||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
|
|
||||||
State _init = {
|
State _init = {
|
||||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||||
0x4c, // b
|
0x4c, // b
|
||||||
0xE012 // t
|
0xE012 // t
|
||||||
};
|
};
|
||||||
opt_suc(div_key_p, &_init, cc_nr, 12, true);
|
opt_suc(div_key_p, &_init, cc_p, 12, true);
|
||||||
uint8_t dest [] = {0, 0, 0, 0};
|
opt_output(div_key_p, &_init, mac);
|
||||||
opt_output(div_key_p, &_init, dest);
|
|
||||||
//The output MAC must also be reversed
|
|
||||||
opt_reverse_arraybytecpy(mac, dest, 4);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tag MAC can be divided (both can, but no point in dividing the reader mac) into
|
* The tag MAC can be divided (both can, but no point in dividing the reader mac) into
|
||||||
* two functions, since the first 8 bytes are known, we can pre-calculate the state
|
* two functions, since the first 8 bytes are known, we can pre-calculate the state
|
||||||
|
@ -231,17 +269,16 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
|
||||||
* @return the cipher state
|
* @return the cipher state
|
||||||
*/
|
*/
|
||||||
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
||||||
static uint8_t cc_nr[8];
|
|
||||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
|
|
||||||
State _init = {
|
State _init = {
|
||||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||||
0x4c, // b
|
0x4c, // b
|
||||||
0xE012 // t
|
0xE012 // t
|
||||||
};
|
};
|
||||||
opt_suc(div_key_p, &_init, cc_nr, 8, false);
|
opt_suc(div_key_p, &_init, cc_p, 8, false);
|
||||||
return _init;
|
return _init;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The second part of the tag MAC calculation, since the CC is already calculated into the state,
|
* The second part of the tag MAC calculation, since the CC is already calculated into the state,
|
||||||
* this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag
|
* this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag
|
||||||
|
@ -252,13 +289,7 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
||||||
* @param div_key_p - the key to use
|
* @param div_key_p - the key to use
|
||||||
*/
|
*/
|
||||||
void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p) {
|
void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p) {
|
||||||
static uint8_t _nr[4];
|
opt_suc(div_key_p, &_init, nr, 4, true);
|
||||||
opt_reverse_arraybytecpy(_nr, nr, 4);
|
opt_output(div_key_p, &_init, mac);
|
||||||
opt_suc(div_key_p, &_init, _nr, 4, true);
|
|
||||||
|
|
||||||
uint8_t dest [] = {0, 0, 0, 0};
|
|
||||||
opt_output(div_key_p, &_init, dest);
|
|
||||||
//The output MAC must also be reversed
|
|
||||||
opt_reverse_arraybytecpy(mac, dest, 4);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define OPTIMIZED_CIPHER_H
|
#define OPTIMIZED_CIPHER_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "string.h"
|
||||||
/**
|
/**
|
||||||
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
|
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
|
||||||
* consisting of the following four components:
|
* consisting of the following four components:
|
||||||
|
|
|
@ -94,7 +94,10 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
|
||||||
} else {
|
} else {
|
||||||
// Error
|
// Error
|
||||||
if (++warnings > 10) {
|
if (++warnings > 10) {
|
||||||
Dbprintf("Error: too many detection errors, aborting.");
|
|
||||||
|
if ( DBGLEVEL >= DBG_EXTENDED )
|
||||||
|
Dbprintf("Error: too many detection errors, aborting.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,27 +138,38 @@ bool IsBlock0PCF7931(uint8_t *block) {
|
||||||
// assuming all RFU bits are set to 0
|
// assuming all RFU bits are set to 0
|
||||||
// if PAC is enabled password is set to 0
|
// if PAC is enabled password is set to 0
|
||||||
if (block[7] == 0x01) {
|
if (block[7] == 0x01) {
|
||||||
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7)
|
||||||
|
&& !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
} else if (block[7] == 0x00) {
|
} else if (block[7] == 0x00) {
|
||||||
if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBlock1PCF7931(uint8_t *block) {
|
bool IsBlock1PCF7931(uint8_t *block) {
|
||||||
// assuming all RFU bits are set to 0
|
// assuming all RFU bits are set to 0
|
||||||
if (block[10] == 0
|
|
||||||
&& block[11] == 0
|
|
||||||
&& block[12] == 0
|
|
||||||
&& block[13] == 0) {
|
|
||||||
|
|
||||||
if ((block[14] & 0x7f) <= 9
|
uint8_t rb1 = block[14] & 0x80;
|
||||||
&& block[15] <= 9) {
|
uint8_t rfb = block[14] & 0x7f;
|
||||||
|
uint8_t rlb = block[15];
|
||||||
|
|
||||||
|
if (block[10] == 0
|
||||||
|
&& block[11] == 0
|
||||||
|
&& block[12] == 0
|
||||||
|
&& block[13] == 0) {
|
||||||
|
// block 1 is sent only if (RLB >= 1 && RFB <= 1) or RB1 enabled
|
||||||
|
if (rfb <= rlb
|
||||||
|
&& rfb <= 9
|
||||||
|
&& rlb <= 9
|
||||||
|
&& ((rfb <= 1 && rlb >= 1) || rb1)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,21 +202,28 @@ void ReadPCF7931() {
|
||||||
|
|
||||||
// exit if no block is received
|
// exit if no block is received
|
||||||
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
||||||
Dbprintf("Error, no tag or bad tag");
|
|
||||||
|
if ( DBGLEVEL >= DBG_INFO )
|
||||||
|
Dbprintf("[!!] Error, no tag or bad tag");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// exit if too many errors during reading
|
// exit if too many errors during reading
|
||||||
if (tries > 50 && (2 * errors > tries)) {
|
if (tries > 50 && (2 * errors > tries)) {
|
||||||
Dbprintf("Error reading the tag");
|
|
||||||
Dbprintf("Here is the partial content");
|
if ( DBGLEVEL >= DBG_INFO )
|
||||||
|
Dbprintf("[!!] Error reading the tag, only partial content");
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// our logic breaks if we don't get at least two blocks
|
// our logic breaks if we don't get at least two blocks
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
|
// skip if all 0s block or no blocks
|
||||||
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
|
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// add block to single blocks list
|
||||||
if (single_blocks_cnt < max_blocks) {
|
if (single_blocks_cnt < max_blocks) {
|
||||||
for (i = 0; i < single_blocks_cnt; ++i) {
|
for (i = 0; i < single_blocks_cnt; ++i) {
|
||||||
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
|
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
|
||||||
|
@ -212,6 +233,7 @@ void ReadPCF7931() {
|
||||||
}
|
}
|
||||||
if (j != 1) {
|
if (j != 1) {
|
||||||
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
|
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
|
||||||
|
print_result("got single block", single_blocks[single_blocks_cnt], 16);
|
||||||
single_blocks_cnt++;
|
single_blocks_cnt++;
|
||||||
}
|
}
|
||||||
j = 0;
|
j = 0;
|
||||||
|
@ -220,7 +242,12 @@ void ReadPCF7931() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
|
if ( DBGLEVEL >= DBG_EXTENDED )
|
||||||
|
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
print_result("got consecutive blocks", tmp_blocks[i], 16);
|
||||||
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (!found_0_1) {
|
if (!found_0_1) {
|
||||||
|
@ -279,10 +306,12 @@ void ReadPCF7931() {
|
||||||
}
|
}
|
||||||
++tries;
|
++tries;
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
Dbprintf("Button pressed, stopping.");
|
if ( DBGLEVEL >= DBG_EXTENDED)
|
||||||
|
Dbprintf("Button pressed, stopping.");
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
} while (found_blocks != max_blocks);
|
} while (found_blocks < max_blocks);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
|
@ -305,7 +334,7 @@ end:
|
||||||
|
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
}
|
}
|
||||||
reply_old(CMD_ACK, 0, 0, 0, 0, 0);
|
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
||||||
|
@ -391,8 +420,12 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
|
||||||
@param data : data to write
|
@param data : data to write
|
||||||
*/
|
*/
|
||||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
||||||
Dbprintf("Initialization delay : %d us", init_delay);
|
|
||||||
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
|
if ( DBGLEVEL >= DBG_INFO ) {
|
||||||
|
Dbprintf("Initialization delay : %d us", init_delay);
|
||||||
|
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
|
||||||
|
}
|
||||||
|
|
||||||
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
|
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
|
||||||
Dbprintf("Block address : %02x", address);
|
Dbprintf("Block address : %02x", address);
|
||||||
Dbprintf("Byte address : %02x", byte);
|
Dbprintf("Byte address : %02x", byte);
|
||||||
|
@ -411,8 +444,10 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui
|
||||||
void SendCmdPCF7931(uint32_t *tab) {
|
void SendCmdPCF7931(uint32_t *tab) {
|
||||||
uint16_t u = 0, tempo = 0;
|
uint16_t u = 0, tempo = 0;
|
||||||
|
|
||||||
Dbprintf("Sending data frame...");
|
if ( DBGLEVEL >= DBG_INFO ) {
|
||||||
|
Dbprintf("Sending data frame...");
|
||||||
|
}
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
|
||||||
|
@ -454,7 +489,6 @@ void SendCmdPCF7931(uint32_t *tab) {
|
||||||
SpinDelay(200);
|
SpinDelay(200);
|
||||||
|
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||||
LED(0xFFFF, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -468,13 +502,13 @@ bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) {
|
||||||
uint32_t u;
|
uint32_t u;
|
||||||
for (u = 0; u < 8; ++u) {
|
for (u = 0; u < 8; ++u) {
|
||||||
if (byte & (1 << u)) { //bit is 1
|
if (byte & (1 << u)) { //bit is 1
|
||||||
if (AddBitPCF7931(1, tab, l, p) == 1) return 1;
|
if (AddBitPCF7931(1, tab, l, p) == 1) return true;
|
||||||
} else { //bit is 0
|
} else { //bit is 0
|
||||||
if (AddBitPCF7931(0, tab, l, p) == 1) return 1;
|
if (AddBitPCF7931(0, tab, l, p) == 1) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a bits for building the data frame of PCF7931 tags
|
/* Add a bits for building the data frame of PCF7931 tags
|
||||||
|
@ -487,7 +521,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
|
||||||
uint8_t u = 0;
|
uint8_t u = 0;
|
||||||
|
|
||||||
//we put the cursor at the last value of the array
|
//we put the cursor at the last value of the array
|
||||||
for (u = 0; tab[u] != 0; u += 3) { }
|
for (u = 0; tab[u] != 0; u += 3) { };
|
||||||
|
|
||||||
if (b == 1) { //add a bit 1
|
if (b == 1) { //add a bit 1
|
||||||
if (u == 0)
|
if (u == 0)
|
||||||
|
@ -497,7 +531,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
|
||||||
|
|
||||||
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
|
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
|
||||||
tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p;
|
tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p;
|
||||||
return 0;
|
return false;
|
||||||
} else { //add a bit 0
|
} else { //add a bit 0
|
||||||
|
|
||||||
if (u == 0)
|
if (u == 0)
|
||||||
|
@ -507,9 +541,9 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
|
||||||
|
|
||||||
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
|
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
|
||||||
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p;
|
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p;
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a custom pattern in the data frame
|
/* Add a custom pattern in the data frame
|
||||||
|
@ -526,5 +560,5 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) {
|
||||||
tab[u + 1] = b + tab[u];
|
tab[u + 1] = b + tab[u];
|
||||||
tab[u + 2] = c + tab[u + 1];
|
tab[u + 2] = c + tab[u + 1];
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,9 +96,9 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////// SPIFFS LOW LEVEL OPERATIONS /////////////////////////////////////////////
|
////// SPIFFS LOW LEVEL OPERATIONS /////////////////////////////////////////////
|
||||||
static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ];
|
static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ] __attribute__((aligned));
|
||||||
static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ];
|
static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ] __attribute__((aligned));
|
||||||
static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ];
|
static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ] __attribute__((aligned));
|
||||||
|
|
||||||
static spiffs fs;
|
static spiffs fs;
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,13 @@ uint32_t RAMFUNC GetCountSspClk(void) {
|
||||||
return tmp_count;
|
return tmp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) {
|
||||||
|
uint32_t stop = GetCountSspClk();
|
||||||
|
if ( stop >= start )
|
||||||
|
return stop - start;
|
||||||
|
return (UINT32_MAX - start) + stop;
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Timer for bitbanging, or LF stuff when you need a very precis timer
|
// Timer for bitbanging, or LF stuff when you need a very precis timer
|
||||||
// 1us = 1.5ticks
|
// 1us = 1.5ticks
|
||||||
|
|
|
@ -33,6 +33,7 @@ void SpinDelayCountUs(uint32_t us);
|
||||||
void StartCountSspClk();
|
void StartCountSspClk();
|
||||||
void ResetSspClk(void);
|
void ResetSspClk(void);
|
||||||
uint32_t RAMFUNC GetCountSspClk();
|
uint32_t RAMFUNC GetCountSspClk();
|
||||||
|
uint32_t RAMFUNC GetCountSspClkDelta();
|
||||||
|
|
||||||
void StartTicks(void);
|
void StartTicks(void);
|
||||||
uint32_t GetTicks(void);
|
uint32_t GetTicks(void);
|
||||||
|
|
|
@ -90,6 +90,7 @@ void LEDsoff() {
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8
|
||||||
void LED(int led, int ms) {
|
void LED(int led, int ms) {
|
||||||
if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE
|
if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
@ -123,26 +124,27 @@ void SpinOff(uint32_t pause) {
|
||||||
SpinDelay(pause);
|
SpinDelay(pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0=A, 1=B, 2=C, 3=D
|
// Blinks..
|
||||||
|
// A = 1, B = 2, C = 4, D = 8
|
||||||
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
|
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
|
||||||
SpinOff(speed);
|
SpinOff(speed);
|
||||||
NTIME(times) {
|
NTIME(times) {
|
||||||
switch (led) {
|
|
||||||
case 0:
|
if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE
|
||||||
LED_A_INV();
|
LED_A_INV();
|
||||||
break;
|
if (led & LED_B) // Proxmark3 historical mapping: LED_GREEN
|
||||||
case 1:
|
LED_B_INV();
|
||||||
LED_B_INV();
|
if (led & LED_C) // Proxmark3 historical mapping: LED_RED
|
||||||
break;
|
LED_C_INV();
|
||||||
case 2:
|
if (led & LED_D) // Proxmark3 historical mapping: LED_RED2
|
||||||
LED_C_INV();
|
LED_D_INV();
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
LED_D_INV();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SpinDelay(speed);
|
SpinDelay(speed);
|
||||||
}
|
}
|
||||||
|
LED_A_OFF();
|
||||||
|
LED_B_OFF();
|
||||||
|
LED_C_OFF();
|
||||||
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpinDown(uint32_t speed) {
|
void SpinDown(uint32_t speed) {
|
||||||
|
|
|
@ -31,12 +31,14 @@ APP_CFLAGS += -fno-stack-protector -fno-pie
|
||||||
# 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
|
||||||
|
|
||||||
|
INSTALLFW = $(OBJDIR)/bootrom.elf
|
||||||
|
|
||||||
OBJS = $(OBJDIR)/bootrom.s19
|
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)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
|
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@
|
||||||
|
|
||||||
all: $(OBJS)
|
all: $(OBJS)
|
||||||
|
|
||||||
|
@ -49,14 +51,23 @@ $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ)
|
||||||
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map
|
||||||
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d
|
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d
|
||||||
$(Q)$(DELETE) version.c
|
$(Q)$(RM) version.c
|
||||||
|
|
||||||
.PHONY: all clean help
|
install: all
|
||||||
|
$(info [@] Installing bootrom to $(DESTDIR)$(PREFIX)...)
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
$(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...)
|
||||||
|
$(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
|
||||||
|
|
||||||
|
.PHONY: all clean help install
|
||||||
help:
|
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:
|
||||||
|
|
223
client/Makefile
223
client/Makefile
|
@ -9,35 +9,20 @@
|
||||||
# Add -DNOFORCE to disable the -F switch
|
# Add -DNOFORCE to disable the -F switch
|
||||||
# Add -DPRESETS to compile with preset models (edit config.h)
|
# Add -DPRESETS to compile with preset models (edit config.h)
|
||||||
|
|
||||||
# Hide full compilation line:
|
# Must be called before any Makefile include
|
||||||
ifneq ($(V),1)
|
ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||||
Q?=@
|
|
||||||
endif
|
|
||||||
# To see full command lines, use make V=1
|
|
||||||
|
|
||||||
CC = gcc
|
include ../Makefile.defs
|
||||||
CXX = g++
|
|
||||||
LD = g++
|
|
||||||
TAR = tar
|
|
||||||
TARFLAGS = -C .. --ignore-failed-read -rvf
|
|
||||||
RM = rm -f
|
|
||||||
MV = mv
|
|
||||||
TOUCH = touch
|
|
||||||
FALSE = false
|
|
||||||
|
|
||||||
ENV_LDFLAGS := $(LDFLAGS)
|
INSTALLBIN = proxmark3
|
||||||
ENV_CFLAGS := $(CFLAGS)
|
INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries
|
||||||
|
|
||||||
platform = $(shell uname)
|
VPATH = ../common uart
|
||||||
|
vpath %.dic dictionaries
|
||||||
VPATH = ../common ../common/zlib uart
|
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
|
||||||
LDLIBS =
|
LDLIBS ?= -L/usr/local/lib
|
||||||
ifneq ($(platform),Darwin)
|
LDLIBS += -lreadline -lpthread -lm
|
||||||
LDLIBS += -L/opt/local/lib
|
|
||||||
endif
|
|
||||||
LDLIBS += -L/usr/local/lib -lreadline -lpthread -lm
|
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -46,23 +31,35 @@ 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
|
||||||
LUALIBPATH = ./liblua
|
LUALIBPATH = ./liblua
|
||||||
LUALIB = $(LUALIBPATH)/liblua.a
|
LUALIB = $(LUALIBPATH)/liblua.a
|
||||||
JANSSONLIBPATH = ./jansson
|
JANSSONLIBPATH = ./jansson
|
||||||
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
|
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
|
||||||
MBEDTLSLIBPATH = ../common/mbedtls
|
|
||||||
MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a
|
|
||||||
CBORLIBPATH = ./tinycbor
|
CBORLIBPATH = ./tinycbor
|
||||||
CBORLIB = $(CBORLIBPATH)/tinycbor.a
|
CBORLIB = $(CBORLIBPATH)/tinycbor.a
|
||||||
REVENGFLAGS = -DPRESETS
|
REVENGPATH = ./reveng
|
||||||
LIBS = -I../common/zlib -Iuart -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH)
|
REVENGLIB = $(REVENGPATH)/libreveng.a
|
||||||
INCLUDES_CLIENT = -I. -I../include -I../common -I/opt/local/include $(LIBS)
|
AMIIBOLIBPATH = ./amiitool
|
||||||
LDFLAGS = $(ENV_LDFLAGS)
|
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
|
||||||
CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) -Wall -Werror -g -O3
|
|
||||||
|
# common libraries
|
||||||
|
MBEDTLSLIBPATH = ../common/mbedtls
|
||||||
|
MBEDTLSLIB = $(OBJDIR)/libmbedtls.a
|
||||||
|
ZLIBPATH = ../common/zlib
|
||||||
|
ZLIB = $(OBJDIR)/libz.a
|
||||||
|
|
||||||
|
LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH)
|
||||||
|
INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS)
|
||||||
|
CFLAGS ?= -Wall -Werror -g -O3
|
||||||
|
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
|
||||||
|
PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT)
|
||||||
|
PREFIX ?= /usr/local
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
CFLAGS += -mno-ms-bitfields
|
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
||||||
endif
|
endif
|
||||||
CXXFLAGS = -I../include -Wall -O3
|
CXXFLAGS ?= -Wall -Werror -O3
|
||||||
|
PM3CXXFLAGS = $(CXXFLAGS) -I../include
|
||||||
|
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
|
@ -76,7 +73,6 @@ else
|
||||||
LIBS := -I/usr/local/opt/readline/include $(LIBS)
|
LIBS := -I/usr/local/opt/readline/include $(LIBS)
|
||||||
else
|
else
|
||||||
LUALIB += -ldl
|
LUALIB += -ldl
|
||||||
LDLIBS += -ltermcap -lncurses
|
|
||||||
LUAPLATFORM = linux
|
LUAPLATFORM = linux
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -93,7 +89,7 @@ ifeq ($(QTINCLUDES), )
|
||||||
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
||||||
UIC = $(shell pkg-config --variable=uic_location QtCore)
|
UIC = $(shell pkg-config --variable=uic_location QtCore)
|
||||||
else
|
else
|
||||||
CXXFLAGS += -std=c++11 -fPIC
|
PM3CXXFLAGS += -std=c++11 -fPIC
|
||||||
endif
|
endif
|
||||||
ifeq ($(QTINCLUDES), )
|
ifeq ($(QTINCLUDES), )
|
||||||
# if both pkg-config commands failed, search in common places
|
# if both pkg-config commands failed, search in common places
|
||||||
|
@ -103,7 +99,7 @@ ifeq ($(QTINCLUDES), )
|
||||||
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
|
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
|
||||||
QTINCLUDES += -I$(QTDIR)/include/QtWidgets
|
QTINCLUDES += -I$(QTDIR)/include/QtWidgets
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core
|
QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core
|
||||||
CXXFLAGS += -std=c++11 -fPIC
|
PM3CXXFLAGS += -std=c++11 -fPIC
|
||||||
endif
|
endif
|
||||||
MOC = $(QTDIR)/bin/moc
|
MOC = $(QTDIR)/bin/moc
|
||||||
UIC = $(QTDIR)/bin/uic
|
UIC = $(QTDIR)/bin/uic
|
||||||
|
@ -113,7 +109,7 @@ endif
|
||||||
|
|
||||||
ifneq ($(QTLDLIBS),)
|
ifneq ($(QTLDLIBS),)
|
||||||
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
||||||
CFLAGS += -DHAVE_GUI
|
PM3CFLAGS += -DHAVE_GUI
|
||||||
else
|
else
|
||||||
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
||||||
endif
|
endif
|
||||||
|
@ -121,7 +117,7 @@ endif
|
||||||
# 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
|
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
|
||||||
|
|
||||||
CORESRCS = uart_posix.c \
|
CORESRCS = uart_posix.c \
|
||||||
uart_win32.c \
|
uart_win32.c \
|
||||||
|
@ -150,7 +146,7 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
loclass/cipherutils.c \
|
loclass/cipherutils.c \
|
||||||
loclass/ikeys.c \
|
loclass/ikeys.c \
|
||||||
loclass/elite_crack.c \
|
loclass/elite_crack.c \
|
||||||
loclass/fileutils.c \
|
fileutils.c \
|
||||||
whereami.c \
|
whereami.c \
|
||||||
mifare/mifarehost.c \
|
mifare/mifarehost.c \
|
||||||
parity.c \
|
parity.c \
|
||||||
|
@ -241,7 +237,8 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
cmdscript.c \
|
cmdscript.c \
|
||||||
pm3_bitlib.c \
|
pm3_bitlib.c \
|
||||||
cmdcrc.c \
|
cmdcrc.c \
|
||||||
bucketsort.c
|
bucketsort.c \
|
||||||
|
flash.c
|
||||||
|
|
||||||
cpu_arch = $(shell uname -m)
|
cpu_arch = $(shell uname -m)
|
||||||
ifneq ($(findstring 86, $(cpu_arch)), )
|
ifneq ($(findstring 86, $(cpu_arch)), )
|
||||||
|
@ -254,24 +251,11 @@ ifeq ($(MULTIARCHSRCS), )
|
||||||
CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c
|
CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c
|
|
||||||
ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
|
|
||||||
#-DDEBUG -Dverbose=1
|
|
||||||
|
|
||||||
REVENGSRCS = reveng/preset.c \
|
|
||||||
reveng/reveng.c \
|
|
||||||
reveng/cli.c \
|
|
||||||
reveng/bmpbit.c \
|
|
||||||
reveng/model.c \
|
|
||||||
reveng/poly.c
|
|
||||||
|
|
||||||
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
|
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
|
||||||
|
|
||||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
|
||||||
ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o)
|
|
||||||
REVENGOBJS = $(REVENGSRCS:%.c=$(OBJDIR)/%.o)
|
|
||||||
MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \
|
MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \
|
||||||
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \
|
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \
|
||||||
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \
|
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \
|
||||||
|
@ -295,23 +279,21 @@ ifeq "$(SUPPORTS_AVX512)" "True"
|
||||||
MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o)
|
MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
BINS = proxmark3 flasher
|
BINS = proxmark3
|
||||||
CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst
|
CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
||||||
|
# transition: make sure old flasher is gone too
|
||||||
|
CLEAN += flasher
|
||||||
|
|
||||||
# need to assign dependancies to build these first...
|
# need to assign dependancies to build these first...
|
||||||
all: lua_build jansson_build mbedtls_build cbor_build $(BINS)
|
all: $(BINS)
|
||||||
|
|
||||||
all-static: LDLIBS:=-static $(LDLIBS)
|
all-static: LDLIBS:=-static $(LDLIBS)
|
||||||
all-static: $(BINS)
|
all-static: $(BINS)
|
||||||
|
|
||||||
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS)
|
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(QTLDLIBS)
|
||||||
proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua
|
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
|
||||||
$(info [=] LD $@)
|
$(info [=] LD $@)
|
||||||
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(LDLIBS) -o $@
|
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS)
|
|
||||||
$(info [=] LD $@)
|
|
||||||
$(Q)$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
|
||||||
|
|
||||||
proxgui.cpp: ui/ui_overlays.h
|
proxgui.cpp: ui/ui_overlays.h
|
||||||
|
|
||||||
|
@ -327,115 +309,144 @@ lualibs/pm3_cmd.lua: ../include/pm3_cmd.h
|
||||||
$(info [=] GEN $@)
|
$(info [=] GEN $@)
|
||||||
$(Q)awk -f pm3_cmd_h2lua.awk $^ > $@
|
$(Q)awk -f pm3_cmd_h2lua.awk $^ > $@
|
||||||
|
|
||||||
lualibs/mf_default_keys.lua : default_keys.dic
|
lualibs/mfc_default_keys.lua : mfc_default_keys.dic
|
||||||
$(info [=] GEN $@)
|
$(info [=] GEN $@)
|
||||||
$(Q)awk -f default_keys_dic2lua.awk $^ > $@
|
$(Q)awk -f default_keys_dic2lua.awk $^ > $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(Q)$(RM) $(CLEAN)
|
$(Q)$(RM) $(CLEAN)
|
||||||
|
$(Q)$(RMDIR) $(OBJDIR)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean
|
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(info [@] Installing client to $(DESTDIR)$(PREFIX)...)
|
||||||
|
ifneq (,$(INSTALLBIN))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLBIN) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLSHARE))
|
||||||
|
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
$(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
|
||||||
|
endif
|
||||||
|
@true
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
$(info [@] Uninstalling client from $(DESTDIR)$(PREFIX)...)
|
||||||
|
ifneq (,$(INSTALLBIN))
|
||||||
|
$(Q)$(RM) $(foreach tool,$(INSTALLBIN),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(tool)))
|
||||||
|
endif
|
||||||
|
ifneq (,$(INSTALLSHARE))
|
||||||
|
$(Q)$(RMDIR) $(foreach tool,$(INSTALLSHARE),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(tool)))
|
||||||
|
endif
|
||||||
|
@true
|
||||||
|
|
||||||
tarbin: $(BINS)
|
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/%)
|
||||||
|
|
||||||
lua_build:
|
# local libraries:
|
||||||
|
$(LUALIB):
|
||||||
$(info [*] MAKE liblua for $(LUAPLATFORM))
|
$(info [*] MAKE liblua for $(LUAPLATFORM))
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
|
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
|
||||||
|
|
||||||
jansson_build:
|
$(JANSSONLIB):
|
||||||
$(info [*] MAKE jansson)
|
$(info [*] MAKE jansson)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
|
||||||
|
|
||||||
mbedtls_build:
|
$(CBORLIB):
|
||||||
$(info [*] MAKE mbedtls)
|
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) all
|
|
||||||
|
|
||||||
cbor_build:
|
|
||||||
$(info [*] MAKE tinycbor)
|
$(info [*] MAKE tinycbor)
|
||||||
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all
|
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all
|
||||||
|
|
||||||
|
$(REVENGLIB):
|
||||||
|
$(info [*] MAKE reveng)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all
|
||||||
|
|
||||||
reveng/bmptst: reveng/bmpbit.c reveng/config.h reveng/reveng.h
|
$(AMIIBOLIB):
|
||||||
$(CC) $(CFLAGS) $(REVENGFLAGS) -DBMPTST -o $@ $<
|
$(info [*] MAKE amiibo)
|
||||||
( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) )
|
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all
|
||||||
|
|
||||||
.PHONY: all clean
|
# common libraries:
|
||||||
|
$(MBEDTLSLIB):
|
||||||
|
$(info [*] MAKE mbedtls)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
|
||||||
|
|
||||||
|
$(ZLIB):
|
||||||
|
$(info [*] MAKE zlib)
|
||||||
|
$(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
|
||||||
|
|
||||||
|
.PHONY: all clean install uninstall
|
||||||
|
|
||||||
# easy printing of MAKE VARIABLES
|
# easy printing of MAKE VARIABLES
|
||||||
print-%: ; @echo $* = $($*)
|
print-%: ; @echo $* = $($*)
|
||||||
|
|
||||||
$(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d
|
$(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d
|
||||||
$(info [-] CC(NOSIMD) $<)
|
$(info [-] CC(NOSIMD) $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(PM3CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d && $(TOUCH) $@
|
||||||
|
|
||||||
$(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d
|
$(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d
|
||||||
$(info [-] CC(MMX) $<)
|
$(info [-] CC(MMX) $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(PM3CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d && $(TOUCH) $@
|
||||||
|
|
||||||
$(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d
|
$(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d
|
||||||
$(info [-] CC(SSE2) $<)
|
$(info [-] CC(SSE2) $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(PM3CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d && $(TOUCH) $@
|
||||||
|
|
||||||
$(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d
|
$(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d
|
||||||
$(info [-] CC(AVX) $<)
|
$(info [-] CC(AVX) $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d && $(TOUCH) $@
|
||||||
|
|
||||||
$(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d
|
$(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d
|
||||||
$(info [-] CC(AVX2) $<)
|
$(info [-] CC(AVX2) $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d && $(TOUCH) $@
|
||||||
|
|
||||||
$(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d
|
$(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d
|
||||||
$(info [-] CC(AVX512) $<)
|
$(info [-] CC(AVX512) $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
$(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d
|
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $<
|
||||||
|
$(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d && $(TOUCH) $@
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
||||||
$(info [-] CC $<)
|
$(info [-] CC $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
|
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
|
||||||
$(info [-] CXX $<)
|
$(info [-] CXX $<)
|
||||||
$(Q)$(CXX) $(DEPFLAGS) $(CXXFLAGS) $(QTINCLUDES) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $<
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
%.o: %.m
|
%.o: %.m
|
||||||
$(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
|
$(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
|
||||||
$(info [-] CC $<)
|
$(info [-] CC $<)
|
||||||
$(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
|
$(Q)$(MKDIR) $(dir $@)
|
||||||
|
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
|
||||||
$(Q)$(POSTCOMPILE)
|
$(Q)$(POSTCOMPILE)
|
||||||
|
|
||||||
#$(CMDOBJS) $(COREOBJS): $(notdir $(%.c)) %.d
|
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVENGSRCS)) \
|
||||||
# $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
|
|
||||||
# $(POSTCOMPILE)
|
|
||||||
|
|
||||||
#$(ZLIBOBJS): $(notdir $(%.c)) %.d
|
|
||||||
# $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $<
|
|
||||||
# $(POSTCOMPILE)
|
|
||||||
|
|
||||||
#$(QTGUIOBJS): $(notdir $(%.cpp)) %.d
|
|
||||||
# $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $<
|
|
||||||
# $(POSTCOMPILE)
|
|
||||||
|
|
||||||
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(REVENGSRCS)) \
|
|
||||||
$(patsubst %.o, %.d, $(MULTIARCHOBJS)) \
|
$(patsubst %.o, %.d, $(MULTIARCHOBJS)) \
|
||||||
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
|
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
|
||||||
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \
|
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \
|
||||||
$(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d
|
$(OBJDIR)/proxmark3.d
|
||||||
|
|
||||||
$(DEPENDENCY_FILES): ;
|
$(DEPENDENCY_FILES): ;
|
||||||
.PRECIOUS: $(DEPENDENCY_FILES)
|
.PRECIOUS: $(DEPENDENCY_FILES)
|
||||||
|
|
||||||
-include $(DEPENDENCY_FILES)
|
-include $(DEPENDENCY_FILES)
|
||||||
|
|
||||||
|
|
19
client/amiitool/Makefile
Normal file
19
client/amiitool/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
MYSRCPATHS =
|
||||||
|
MYINCLUDES = -I. -I.. -I../jansson -I../../common/ -I../../include/
|
||||||
|
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
|
||||||
|
MYDEFS =
|
||||||
|
MYSRCS = \
|
||||||
|
amiibo.c \
|
||||||
|
drbg.c \
|
||||||
|
keygen.c
|
||||||
|
|
||||||
|
LIB_A = libamiibo.a
|
||||||
|
|
||||||
|
include ../../Makefile.host
|
||||||
|
|
||||||
|
# just for testing amiitool before complete migration into a lib:
|
||||||
|
|
||||||
|
amiitool:
|
||||||
|
gcc $(CFLAGS) \
|
||||||
|
amiitool.c $(MYSRCS) ../../common/commonutil.c ../ui.c -lreadline -lm ../../common/mbedtls/libmbedtls.a \
|
||||||
|
-o amiitool
|
|
@ -8,6 +8,7 @@
|
||||||
#include "amiibo.h"
|
#include "amiibo.h"
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
|
#include "commonutil.h"
|
||||||
|
|
||||||
#define HMAC_POS_DATA 0x008
|
#define HMAC_POS_DATA 0x008
|
||||||
#define HMAC_POS_TAG 0x1B4
|
#define HMAC_POS_TAG 0x1B4
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "keygen.h"
|
#include "keygen.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define NFC3D_AMIIBO_SIZE 520
|
#define NFC3D_AMIIBO_SIZE 520
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <amiibo.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "../loclass/fileutils.h"
|
#include "fileutils.h"
|
||||||
|
#include "amiibo.h"
|
||||||
|
#include "getopt.h"
|
||||||
|
|
||||||
#define NTAG215_SIZE 540
|
#define NTAG215_SIZE 540
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ static char *self;
|
||||||
|
|
||||||
void amiitool_usage() {
|
void amiitool_usage() {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"amiitool build %i (commit %s-%08x)\n"
|
/*"amiitool build %i (commit %s-%08x)\n"*/
|
||||||
"by Marcos Del Sol Vives <marcos@dracon.es>\n"
|
"by Marcos Del Sol Vives <marcos@dracon.es>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n"
|
"Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n"
|
||||||
|
@ -28,7 +29,7 @@ void amiitool_usage() {
|
||||||
" -s input save file, save from this file will replace input file ones.\n"
|
" -s input save file, save from this file will replace input file ones.\n"
|
||||||
" -o output file. If not specified, stdout will be used.\n"
|
" -o output file. If not specified, stdout will be used.\n"
|
||||||
" -l decrypt files with invalid signatures.\n",
|
" -l decrypt files with invalid signatures.\n",
|
||||||
, self
|
self
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +63,9 @@ int main(int argc, char **argv) {
|
||||||
case 'i':
|
case 'i':
|
||||||
infile = optarg;
|
infile = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'k':
|
||||||
|
keyfile = optarg;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
savefile = optarg;
|
savefile = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -83,7 +87,8 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc3d_amiibo_keys amiiboKeys;
|
nfc3d_amiibo_keys amiiboKeys;
|
||||||
|
if (! LoadAmiikey(amiiboKeys, keyfile))
|
||||||
|
return 5;
|
||||||
|
|
||||||
uint8_t original[NTAG215_SIZE];
|
uint8_t original[NTAG215_SIZE];
|
||||||
uint8_t modified[NFC3D_AMIIBO_SIZE];
|
uint8_t modified[NFC3D_AMIIBO_SIZE];
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "drbg.h"
|
#include "drbg.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mbedtls/md.h>
|
#include "mbedtls/md.h"
|
||||||
|
|
||||||
void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) {
|
void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) {
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
|
|
|
@ -19,7 +19,7 @@ void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const ui
|
||||||
uint8_t *start = output;
|
uint8_t *start = output;
|
||||||
|
|
||||||
// 1: Copy whole type string
|
// 1: Copy whole type string
|
||||||
output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString));
|
output = (uint8_t *)strcpy((char *)output, baseKeys->typeString);
|
||||||
|
|
||||||
// 2: Append (16 - magicBytesSize) from the input seed
|
// 2: Append (16 - magicBytesSize) from the input seed
|
||||||
size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize;
|
size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "lfdemod.h" // for demod code
|
#include "lfdemod.h" // for demod code
|
||||||
#include "loclass/cipherutils.h" // for decimating samples in getsamples
|
#include "loclass/cipherutils.h" // for decimating samples in getsamples
|
||||||
#include "cmdlfem4x.h" // askem410xdecode
|
#include "cmdlfem4x.h" // askem410xdecode
|
||||||
|
#include "fileutils.h" // searchFile
|
||||||
|
|
||||||
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||||
size_t DemodBufferLen = 0;
|
size_t DemodBufferLen = 0;
|
||||||
|
@ -38,6 +39,7 @@ static int usage_data_printdemodbuf(void) {
|
||||||
PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)");
|
PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)");
|
||||||
PrintAndLogEx(NORMAL, " o <offset> enter offset in # of bits");
|
PrintAndLogEx(NORMAL, " o <offset> enter offset in # of bits");
|
||||||
PrintAndLogEx(NORMAL, " l <length> enter length to print in # of bits or hex characters respectively");
|
PrintAndLogEx(NORMAL, " l <length> enter length to print in # of bits or hex characters respectively");
|
||||||
|
PrintAndLogEx(NORMAL, " s strip leading zeroes, i.e. set offset to first bit equal to one");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_data_manrawdecode(void) {
|
static int usage_data_manrawdecode(void) {
|
||||||
|
@ -401,6 +403,7 @@ void printDemodBuff(void) {
|
||||||
int CmdPrintDemodBuff(const char *Cmd) {
|
int CmdPrintDemodBuff(const char *Cmd) {
|
||||||
bool hexMode = false;
|
bool hexMode = false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
bool lstrip = false;
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
uint32_t length = 512;
|
uint32_t length = 512;
|
||||||
char cmdp = 0;
|
char cmdp = 0;
|
||||||
|
@ -422,6 +425,10 @@ int CmdPrintDemodBuff(const char *Cmd) {
|
||||||
if (!length) errors = true;
|
if (!length) errors = true;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
lstrip = true;
|
||||||
|
cmdp ++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -435,6 +442,15 @@ int CmdPrintDemodBuff(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "Demodbuffer is empty");
|
PrintAndLogEx(NORMAL, "Demodbuffer is empty");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
if (lstrip) {
|
||||||
|
char *buf = (char *)(DemodBuffer + offset);
|
||||||
|
length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length;
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
if (buf[i] == 1) break;
|
||||||
|
}
|
||||||
|
offset += i;
|
||||||
|
}
|
||||||
length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length;
|
length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length;
|
||||||
|
|
||||||
if (hexMode) {
|
if (hexMode) {
|
||||||
|
@ -1646,11 +1662,20 @@ static int CmdLoad(const char *Cmd) {
|
||||||
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
|
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
|
||||||
memcpy(filename, Cmd, len);
|
memcpy(filename, Cmd, len);
|
||||||
|
|
||||||
FILE *f = fopen(filename, "r");
|
char *path;
|
||||||
|
if (searchFile(&path, TRACES_SUBDIR, filename, ".pm3", true) != PM3_SUCCESS) {
|
||||||
|
if (searchFile(&path, TRACES_SUBDIR, filename, "", false) != PM3_SUCCESS) {
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
PrintAndLogEx(WARNING, "couldn't open '%s'", filename);
|
PrintAndLogEx(WARNING, "couldn't open '%s'", path);
|
||||||
|
free(path);
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
GraphTraceLen = 0;
|
GraphTraceLen = 0;
|
||||||
char line[80];
|
char line[80];
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
|
|
||||||
#include "pmflash.h"
|
#include "pmflash.h"
|
||||||
#include "loclass/fileutils.h" //saveFile
|
#include "fileutils.h" //saveFile
|
||||||
#include "comms.h" //getfromdevice
|
#include "comms.h" //getfromdevice
|
||||||
#include "cmdflashmemspiffs.h" // spiffs commands
|
#include "cmdflashmemspiffs.h" // spiffs commands
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ static int usage_flashmem_load(void) {
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0
|
PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0
|
||||||
PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024
|
PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024
|
||||||
PrintAndLogEx(NORMAL, " mem load f default_keys m");
|
PrintAndLogEx(NORMAL, " mem load f mfc_default_keys m");
|
||||||
PrintAndLogEx(NORMAL, " mem load f default_pwd t");
|
PrintAndLogEx(NORMAL, " mem load f t55xx_default_pwds t");
|
||||||
PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i");
|
PrintAndLogEx(NORMAL, " mem load f iclass_default_keys i");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_flashmem_dump(void) {
|
static int usage_flashmem_dump(void) {
|
||||||
|
@ -209,9 +209,8 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
datalen += 2;
|
datalen += 2;
|
||||||
break;
|
break;
|
||||||
case DICTIONARY_NONE:
|
case DICTIONARY_NONE:
|
||||||
res = loadFile(filename, ".bin", data, FLASH_MEM_MAX_SIZE, &datalen);
|
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
|
||||||
//int res = loadFileEML( filename, data, &datalen);
|
if (res != PM3_SUCCESS) {
|
||||||
if (res) {
|
|
||||||
free(data);
|
free(data);
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
@ -223,7 +222,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// not needed when we transite to loadxxxx_safe methods.(iceman)
|
||||||
uint8_t *newdata = realloc(data, datalen);
|
uint8_t *newdata = realloc(data, datalen);
|
||||||
if (newdata == NULL) {
|
if (newdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "pmflash.h"
|
#include "pmflash.h"
|
||||||
#include "loclass/fileutils.h" //saveFile
|
#include "fileutils.h" //saveFile
|
||||||
#include "comms.h" //getfromdevice
|
#include "comms.h" //getfromdevice
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
@ -330,12 +330,15 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||||
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
|
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
|
||||||
PrintAndLogEx(FAILED, "Filename too long");
|
PrintAndLogEx(FAILED, "Filename too long");
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
param_getstr(Cmd, cmdp + 1, destfilename, 32);
|
param_getstr(Cmd, cmdp + 1, destfilename, 32);
|
||||||
|
if (strlen(destfilename) == 0) {
|
||||||
|
PrintAndLogEx(FAILED, "Destination Filename missing or invalid");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -345,42 +348,20 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destfilename[0] == '\0') {
|
|
||||||
PrintAndLogEx(FAILED, "Destination Filename missing or invalid");
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validations
|
// Validations
|
||||||
if (errors || cmdp == 0) {
|
if (errors || cmdp == 0)
|
||||||
usage_flashmemspiffs_load();
|
return usage_flashmemspiffs_load();
|
||||||
return PM3_EINVARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t datalen = 0;
|
size_t datalen = 0;
|
||||||
int res = 0;
|
uint8_t *data = NULL;
|
||||||
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t));
|
|
||||||
|
|
||||||
res = loadFile(filename, "", data, FLASH_MEM_MAX_SIZE, &datalen);
|
int res = loadFile_safe(filename, "", (void **)&data, &datalen);
|
||||||
// int res = loadFileEML( filename, data, &datalen);
|
// int res = loadFileEML( filename, data, &datalen);
|
||||||
if (res) {
|
if (res != PM3_SUCCESS) {
|
||||||
free(data);
|
free(data);
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (datalen > FLASH_MEM_MAX_SIZE) {
|
|
||||||
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
|
|
||||||
free(data);
|
|
||||||
return PM3_EOVFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *newdata = realloc(data, datalen);
|
|
||||||
if (newdata == NULL) {
|
|
||||||
free(data);
|
|
||||||
return PM3_EMALLOC;
|
|
||||||
} else {
|
|
||||||
data = newdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to mount before multiple operation so the lazy writes/append will not
|
// We want to mount before multiple operation so the lazy writes/append will not
|
||||||
// trigger a mount + umount each loop iteration (lazy ops device side)
|
// trigger a mount + umount each loop iteration (lazy ops device side)
|
||||||
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
||||||
|
@ -425,6 +406,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||||
if (!isok) {
|
if (!isok) {
|
||||||
conn.block_after_ACK = false;
|
conn.block_after_ACK = false;
|
||||||
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
||||||
|
free(data);
|
||||||
return PM3_EFLASH;
|
return PM3_EFLASH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,18 +76,23 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Checking for known tags...\n");
|
PrintAndLogEx(INFO, "Checking for known tags...\n");
|
||||||
|
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
|
||||||
if (IfPm3NfcBarcode()) {
|
if (IfPm3NfcBarcode()) {
|
||||||
if (infoThinFilm(false) == PM3_SUCCESS) {
|
if (infoThinFilm(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag...");
|
||||||
if (IfPm3Iso14443a()) {
|
if (IfPm3Iso14443a()) {
|
||||||
if (infoHF14A(false, false) > 0) {
|
if (infoHF14A(false, false) > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
|
||||||
if (IfPm3Iso15693()) {
|
if (IfPm3Iso15693()) {
|
||||||
if (readHF15Uid(false) == 1) {
|
if (readHF15Uid(false) == 1) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n");
|
||||||
|
@ -97,25 +102,33 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
// until refactoring of ISO15693 cmds, this is needed.
|
// until refactoring of ISO15693 cmds, this is needed.
|
||||||
DropField();
|
DropField();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for LEGIC tag...");
|
||||||
if (IfPm3Legicrf()) {
|
if (IfPm3Legicrf()) {
|
||||||
if (readLegicUid(false) == PM3_SUCCESS) {
|
if (readLegicUid(false) == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for Topaz tag...");
|
||||||
if (IfPm3Iso14443a()) {
|
if (IfPm3Iso14443a()) {
|
||||||
if (readTopazUid() == PM3_SUCCESS) {
|
if (readTopazUid() == PM3_SUCCESS) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14b and iclass is the longest test (put last)
|
// 14b and iclass is the longest test (put last)
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag...");
|
||||||
if (IfPm3Iso14443a()) {
|
if (IfPm3Iso14443a()) {
|
||||||
if (readHF14B(false) == 1) {
|
if (readHF14B(false) == 1) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag...");
|
||||||
if (IfPm3Iclass()) {
|
if (IfPm3Iclass()) {
|
||||||
if (readIclass(false, false) == 1) {
|
if (readIclass(false, false) == 1) {
|
||||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n");
|
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n");
|
||||||
|
@ -133,7 +146,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n");
|
PrintAndLogEx(FAILED, "\nNo known/supported 13.56 MHz tags found\n");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +221,7 @@ static command_t CommandTable[] = {
|
||||||
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
||||||
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
|
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
|
||||||
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
|
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
|
||||||
{"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags [preliminary]"},
|
{"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags"},
|
||||||
{"sniff", CmdHFSniff, IfPm3Hfsniff, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Sniff"},
|
{"sniff", CmdHFSniff, IfPm3Hfsniff, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Sniff"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -133,7 +133,7 @@ static const manufactureName manufactureMapping[] = {
|
||||||
{ 0x61, "Wearlinks Technology Inc. China" },
|
{ 0x61, "Wearlinks Technology Inc. China" },
|
||||||
{ 0x62, "Userstar Information Systems Co., Ltd Taiwan" },
|
{ 0x62, "Userstar Information Systems Co., Ltd Taiwan" },
|
||||||
{ 0x63, "Pragmatic Printing Ltd. UK" },
|
{ 0x63, "Pragmatic Printing Ltd. UK" },
|
||||||
{ 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico – LSI-TEC Brazil" },
|
{ 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico - LSI-TEC Brazil" },
|
||||||
{ 0x65, "Tendyron Corporation China" },
|
{ 0x65, "Tendyron Corporation China" },
|
||||||
{ 0x66, "MUTO Smart Co., Ltd. Korea" },
|
{ 0x66, "MUTO Smart Co., Ltd. Korea" },
|
||||||
{ 0x67, "ON Semiconductor USA" },
|
{ 0x67, "ON Semiconductor USA" },
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "cmdhf14b.h"
|
#include "cmdhf14b.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "loclass/fileutils.h"
|
#include "fileutils.h"
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "comms.h" // clearCommandBuffer
|
#include "comms.h" // clearCommandBuffer
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "crc16.h" // iso15 crc
|
#include "crc16.h" // iso15 crc
|
||||||
#include "cmddata.h" // getsamples
|
#include "cmddata.h" // getsamples
|
||||||
#include "loclass/fileutils.h" // savefileEML
|
#include "fileutils.h" // savefileEML
|
||||||
|
|
||||||
#define FrameSOF Iso15693FrameSOF
|
#define FrameSOF Iso15693FrameSOF
|
||||||
#define Logic0 Iso15693Logic0
|
#define Logic0 Iso15693Logic0
|
||||||
|
|
|
@ -44,7 +44,7 @@ static int CmdHelp(const char *Cmd);
|
||||||
static int CmdHFFidoInfo(const char *cmd) {
|
static int CmdHFFidoInfo(const char *cmd) {
|
||||||
|
|
||||||
if (cmd && strlen(cmd) > 0)
|
if (cmd && strlen(cmd) > 0)
|
||||||
PrintAndLogEx(WARNING, "WARNING: command don't have any parameters.\n");
|
PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n");
|
||||||
|
|
||||||
// info about 14a part
|
// info about 14a part
|
||||||
infoHF14A(false, false);
|
infoHF14A(false, false);
|
||||||
|
@ -75,14 +75,14 @@ static int CmdHFFidoInfo(const char *cmd) {
|
||||||
|
|
||||||
if (!strncmp((char *)buf, "U2F_V2", 7)) {
|
if (!strncmp((char *)buf, "U2F_V2", 7)) {
|
||||||
if (!strncmp((char *)buf, "FIDO_2_0", 8)) {
|
if (!strncmp((char *)buf, "FIDO_2_0", 8)) {
|
||||||
PrintAndLogEx(INFO, "FIDO2 authenricator detected. Version: %.*s", len, buf);
|
PrintAndLogEx(INFO, "FIDO2 authenticator detected. Version: %.*s", len, buf);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "FIDO authenricator detected (not standard U2F).");
|
PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F).");
|
||||||
PrintAndLogEx(INFO, "Non U2F authenticator version:");
|
PrintAndLogEx(INFO, "Non U2F authenticator version:");
|
||||||
dump_buffer((const unsigned char *)buf, len, NULL, 0);
|
dump_buffer((const unsigned char *)buf, len, NULL, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "FIDO U2F authenricator detected. Version: %.*s", len, buf);
|
PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", len, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = FIDO2GetInfo(buf, sizeof(buf), &len, &sw);
|
res = FIDO2GetInfo(buf, sizeof(buf), &len, &sw);
|
||||||
|
@ -91,13 +91,13 @@ static int CmdHFFidoInfo(const char *cmd) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (sw != 0x9000) {
|
if (sw != 0x9000) {
|
||||||
PrintAndLogEx(ERR, "FIDO2 version not exists (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
PrintAndLogEx(ERR, "FIDO2 version doesn't exist (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf[0]) {
|
if (buf[0]) {
|
||||||
PrintAndLogEx(ERR, "FIDO2 ger version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0]));
|
PrintAndLogEx(ERR, "FIDO2 get version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,14 +163,14 @@ static int CmdHFFidoRegister(const char *cmd) {
|
||||||
json_t *root = NULL;
|
json_t *root = NULL;
|
||||||
|
|
||||||
CLIParserInit("hf fido reg",
|
CLIParserInit("hf fido reg",
|
||||||
"Initiate a U2F token registration. Needs two 32-byte hash number. \nchallenge parameter (32b) and application parameter (32b).",
|
"Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).",
|
||||||
"Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n"
|
"Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n"
|
||||||
"\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"
|
"\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"
|
||||||
"\thf fido reg -p s0 s1 -> execute command with plain parameters");
|
"\thf fido reg -p s0 s1 -> execute command with plain parameters");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
arg_lit0("aA", "apdu", "show APDU requests and responses"),
|
||||||
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
|
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
|
||||||
arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
|
arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
|
||||||
arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"),
|
arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"),
|
||||||
|
@ -393,7 +393,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
|
||||||
json_t *root = NULL;
|
json_t *root = NULL;
|
||||||
|
|
||||||
CLIParserInit("hf fido auth",
|
CLIParserInit("hf fido auth",
|
||||||
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash number. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).",
|
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).",
|
||||||
"Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
|
"Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
|
||||||
"\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f "
|
"\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f "
|
||||||
"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters");
|
"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters");
|
||||||
|
@ -640,8 +640,8 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
char fname[300] = {0};
|
char fname[300] = {0};
|
||||||
|
|
||||||
CLIParserInit("hf fido make",
|
CLIParserInit("hf fido make",
|
||||||
"Execute a FIDO2 Make Credentional command. Needs json file with parameters. Sample file `fido2.json`. File can be placed in proxmark directory or in `proxmark/fido` directory.",
|
"Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
|
||||||
"Usage:\n\thf fido make -> execute command default parameters file `fido2.json`\n"
|
"Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n"
|
||||||
"\thf fido make test.json -> execute command with parameters file `text.json`");
|
"\thf fido make test.json -> execute command with parameters file `text.json`");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -713,7 +713,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (showCBOR) {
|
if (showCBOR) {
|
||||||
PrintAndLogEx(INFO, "CBOR make credentional request:");
|
PrintAndLogEx(INFO, "CBOR make credential request:");
|
||||||
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
||||||
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, false, data, datalen);
|
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, false, data, datalen);
|
||||||
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
||||||
|
@ -738,7 +738,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "MakeCredential result (%d b) OK.", len);
|
PrintAndLogEx(SUCCESS, "MakeCredential result (%d b) OK.", len);
|
||||||
if (showCBOR) {
|
if (showCBOR) {
|
||||||
PrintAndLogEx(SUCCESS, "CBOR make credentional response:");
|
PrintAndLogEx(SUCCESS, "CBOR make credential response:");
|
||||||
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
||||||
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, true, &buf[1], len - 1);
|
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, true, &buf[1], len - 1);
|
||||||
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
|
||||||
|
@ -766,8 +766,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
||||||
char fname[300] = {0};
|
char fname[300] = {0};
|
||||||
|
|
||||||
CLIParserInit("hf fido assert",
|
CLIParserInit("hf fido assert",
|
||||||
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") ". File can be placed in proxmark directory or in `proxmark/fido` directory.",
|
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
|
||||||
"Usage:\n\thf fido assert -> execute command default parameters file `fido2.json`\n"
|
"Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n"
|
||||||
"\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId");
|
"\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -775,7 +775,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
||||||
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
|
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
|
||||||
arg_lit0("cC", "cbor", "show CBOR decoded data"),
|
arg_lit0("cC", "cbor", "show CBOR decoded data"),
|
||||||
arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator don't store credential to its memory)"),
|
arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator doesn't store credential to its memory)"),
|
||||||
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
|
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -801,7 +801,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
|
||||||
|
|
||||||
SetAPDULogging(APDULogging);
|
SetAPDULogging(APDULogging);
|
||||||
|
|
||||||
int res = GetExistsFileNameJson("fido", "fido2", fname);
|
int res = GetExistsFileNameJson("fido", cjsonname, fname);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLogEx(ERR, "ERROR: Can't found the json file.");
|
PrintAndLogEx(ERR, "ERROR: Can't found the json file.");
|
||||||
return res;
|
return res;
|
||||||
|
|
1233
client/cmdhficlass.c
1233
client/cmdhficlass.c
File diff suppressed because it is too large
Load diff
|
@ -12,6 +12,7 @@
|
||||||
#define CMDHFICLASS_H__
|
#define CMDHFICLASS_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
|
||||||
typedef struct iclass_block {
|
typedef struct iclass_block {
|
||||||
uint8_t d[8];
|
uint8_t d[8];
|
||||||
|
@ -32,9 +33,8 @@ int readIclass(bool loop, bool verbose);
|
||||||
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
|
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
|
||||||
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
|
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
|
||||||
|
|
||||||
int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt);
|
void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list);
|
||||||
int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list);
|
void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list);
|
||||||
int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list);
|
|
||||||
void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list);
|
void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list);
|
||||||
void PrintPreCalc(iclass_prekey_t *list, int itemcnt);
|
void PrintPreCalc(iclass_prekey_t *list, int itemcnt);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
#include "loclass/fileutils.h" //saveFile
|
#include "fileutils.h" //saveFile
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -323,10 +323,31 @@ void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
switch (cmd[0]) {
|
uint8_t c = cmd[0] & 0x0F;
|
||||||
|
uint8_t parity = 0;
|
||||||
|
for ( uint8_t i=0; i<7; i++) {
|
||||||
|
parity ^= (cmd[0] >> i) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case ICLASS_CMD_HALT:
|
||||||
|
snprintf(exp, size, "HALT");
|
||||||
|
break;
|
||||||
|
case ICLASS_CMD_SELECT:
|
||||||
|
snprintf(exp, size, "SELECT");
|
||||||
|
break;
|
||||||
case ICLASS_CMD_ACTALL:
|
case ICLASS_CMD_ACTALL:
|
||||||
snprintf(exp, size, "ACTALL");
|
snprintf(exp, size, "ACTALL");
|
||||||
break;
|
break;
|
||||||
|
case ICLASS_CMD_DETECT:
|
||||||
|
snprintf(exp, size, "DETECT");
|
||||||
|
break;
|
||||||
|
case ICLASS_CMD_CHECK:
|
||||||
|
snprintf(exp, size, "CHECK");
|
||||||
|
break;
|
||||||
|
case ICLASS_CMD_READ4:
|
||||||
|
snprintf(exp, size, "READ4(%d)", cmd[1]);
|
||||||
|
break;
|
||||||
case ICLASS_CMD_READ_OR_IDENTIFY: {
|
case ICLASS_CMD_READ_OR_IDENTIFY: {
|
||||||
if (cmdsize > 1) {
|
if (cmdsize > 1) {
|
||||||
snprintf(exp, size, "READ(%d)", cmd[1]);
|
snprintf(exp, size, "READ(%d)", cmd[1]);
|
||||||
|
@ -335,36 +356,22 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ICLASS_CMD_SELECT:
|
|
||||||
snprintf(exp, size, "SELECT");
|
|
||||||
break;
|
|
||||||
case ICLASS_CMD_PAGESEL:
|
case ICLASS_CMD_PAGESEL:
|
||||||
snprintf(exp, size, "PAGESEL(%d)", cmd[1]);
|
snprintf(exp, size, "PAGESEL(%d)", cmd[1]);
|
||||||
break;
|
break;
|
||||||
case ICLASS_CMD_READCHECK_KC:
|
|
||||||
snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]);
|
|
||||||
break;
|
|
||||||
case ICLASS_CMD_READCHECK_KD:
|
|
||||||
snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]);
|
|
||||||
break;
|
|
||||||
case ICLASS_CMD_CHECK:
|
|
||||||
snprintf(exp, size, "CHECK");
|
|
||||||
break;
|
|
||||||
case ICLASS_CMD_DETECT:
|
|
||||||
snprintf(exp, size, "DETECT");
|
|
||||||
break;
|
|
||||||
case ICLASS_CMD_HALT:
|
|
||||||
snprintf(exp, size, "HALT");
|
|
||||||
break;
|
|
||||||
case ICLASS_CMD_UPDATE:
|
case ICLASS_CMD_UPDATE:
|
||||||
snprintf(exp, size, "UPDATE(%d)", cmd[1]);
|
snprintf(exp, size, "UPDATE(%d)", cmd[1]);
|
||||||
break;
|
break;
|
||||||
|
case ICLASS_CMD_READCHECK:
|
||||||
|
if ( ICLASS_CREDIT(c) ) {
|
||||||
|
snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]);
|
||||||
|
} else {
|
||||||
|
snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ICLASS_CMD_ACT:
|
case ICLASS_CMD_ACT:
|
||||||
snprintf(exp, size, "ACT");
|
snprintf(exp, size, "ACT");
|
||||||
break;
|
break;
|
||||||
case ICLASS_CMD_READ4:
|
|
||||||
snprintf(exp, size, "READ4(%d)", cmd[1]);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
snprintf(exp, size, "?");
|
snprintf(exp, size, "?");
|
||||||
break;
|
break;
|
||||||
|
|
953
client/cmdhfmf.c
953
client/cmdhfmf.c
File diff suppressed because it is too large
Load diff
|
@ -36,13 +36,14 @@
|
||||||
#include "hardnested/hardnested_bf_core.h"
|
#include "hardnested/hardnested_bf_core.h"
|
||||||
#include "hardnested/hardnested_bitarray_core.h"
|
#include "hardnested/hardnested_bitarray_core.h"
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
|
||||||
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
|
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
|
||||||
#define NUM_REDUCTION_WORKING_THREADS (num_CPUs())
|
#define NUM_REDUCTION_WORKING_THREADS (num_CPUs())
|
||||||
|
|
||||||
#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states
|
#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states
|
||||||
|
|
||||||
#define STATE_FILES_DIRECTORY "hardnested/tables/"
|
#define STATE_FILES_DIRECTORY "hardnested_tables/"
|
||||||
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z"
|
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z"
|
||||||
|
|
||||||
#define DEBUG_KEY_ELIMINATION
|
#define DEBUG_KEY_ELIMINATION
|
||||||
|
@ -248,10 +249,15 @@ static void init_bitflip_bitarrays(void) {
|
||||||
bitflip_bitarrays[odd_even][bitflip] = NULL;
|
bitflip_bitarrays[odd_even][bitflip] = NULL;
|
||||||
count_bitflip_bitarrays[odd_even][bitflip] = 1 << 24;
|
count_bitflip_bitarrays[odd_even][bitflip] = 1 << 24;
|
||||||
sprintf(state_file_name, STATE_FILE_TEMPLATE, odd_even, bitflip);
|
sprintf(state_file_name, STATE_FILE_TEMPLATE, odd_even, bitflip);
|
||||||
strcpy(state_files_path, get_my_executable_directory());
|
strcpy(state_files_path, STATE_FILES_DIRECTORY);
|
||||||
strcat(state_files_path, STATE_FILES_DIRECTORY);
|
|
||||||
strcat(state_files_path, state_file_name);
|
strcat(state_files_path, state_file_name);
|
||||||
FILE *statesfile = fopen(state_files_path, "rb");
|
char *path;
|
||||||
|
if (searchFile(&path, RESOURCES_SUBDIR, state_files_path, "", true) != PM3_SUCCESS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *statesfile = fopen(path, "rb");
|
||||||
|
free(path);
|
||||||
if (statesfile == NULL) {
|
if (statesfile == NULL) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -86,7 +86,7 @@ static int CmdHFMFPInfo(const char *cmd) {
|
||||||
// check SL0
|
// check SL0
|
||||||
uint8_t data[250] = {0};
|
uint8_t data[250] = {0};
|
||||||
int datalen = 0;
|
int datalen = 0;
|
||||||
// https://github.com/Proxmark/proxmark3/blob/master/client/scripts/mifarePlus.lua#L161
|
// https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161
|
||||||
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
|
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
|
||||||
int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen);
|
int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen);
|
||||||
if (!res && datalen > 1 && data[0] == 0x09) {
|
if (!res && datalen > 1 && data[0] == 0x09) {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "cmdhfmf.h"
|
#include "cmdhfmf.h"
|
||||||
#include "cmdhf14a.h"
|
#include "cmdhf14a.h"
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "loclass/fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
|
|
||||||
#define MAX_UL_BLOCKS 0x0F
|
#define MAX_UL_BLOCKS 0x0F
|
||||||
|
@ -2191,7 +2191,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||||
|
|
||||||
// convert old format to new format, if need
|
// convert old format to new format, if need
|
||||||
int res = convertOldMfuDump(&dump, &bytes_read);
|
int res = convertOldMfuDump(&dump, &bytes_read);
|
||||||
if (res) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format");
|
PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format");
|
||||||
free(dump);
|
free(dump);
|
||||||
return res;
|
return res;
|
||||||
|
@ -2519,7 +2519,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||||
|
|
||||||
if (param_gethex(Cmd, 0, uid, 14)) {
|
if (param_gethex(Cmd, 0, uid, 14)) {
|
||||||
PrintAndLogEx(WARNING, "UID must include 14 HEX symbols");
|
PrintAndLogEx(WARNING, "UID must include 14 HEX symbols");
|
||||||
return 1;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read block2.
|
// read block2.
|
||||||
|
@ -2527,7 +2527,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||||
SendCommandMIX(CMD_HF_MIFAREU_READBL, 2, 0, 0, NULL, 0);
|
SendCommandMIX(CMD_HF_MIFAREU_READBL, 2, 0, 0, NULL, 0);
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
return 2;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save old block2.
|
// save old block2.
|
||||||
|
@ -2544,7 +2544,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data));
|
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data));
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
return 3;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// block 1.
|
// block 1.
|
||||||
|
@ -2556,7 +2556,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data));
|
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data));
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
return 4;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// block 2.
|
// block 2.
|
||||||
|
@ -2568,9 +2568,9 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data));
|
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data));
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
return 5;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
|
static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
|
||||||
|
@ -2681,8 +2681,9 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
|
PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
|
||||||
PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
|
PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
|
||||||
|
|
||||||
|
mbedtls_des3_free(&ctx);
|
||||||
// next. from the diversify_key method.
|
// next. from the diversify_key method.
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
|
@ -2709,11 +2710,11 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
// 3: proprietary Anticollision
|
// 3: proprietary Anticollision
|
||||||
if (select_status == 0) {
|
if (select_status == 0) {
|
||||||
PrintAndLogEx(WARNING, "iso14443a card select failed");
|
PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
if (card.uidlen != 7) {
|
if (card.uidlen != 7) {
|
||||||
PrintAndLogEx(WARNING, "Wrong sized UID, expected 7bytes got %d", card.uidlen);
|
PrintAndLogEx(WARNING, "Wrong sized UID, expected 7bytes got %d", card.uidlen);
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
memcpy(uid, card.uid, sizeof(uid));
|
memcpy(uid, card.uid, sizeof(uid));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2732,7 +2733,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "------+----------+-----");
|
PrintAndLogEx(NORMAL, "------+----------+-----");
|
||||||
PrintAndLogEx(NORMAL, " Vingcard algo");
|
PrintAndLogEx(NORMAL, " Vingcard algo");
|
||||||
PrintAndLogEx(NORMAL, "--------------------");
|
PrintAndLogEx(NORMAL, "--------------------");
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
// Menu Stuff
|
// Menu Stuff
|
||||||
|
@ -2757,7 +2758,7 @@ static command_t CommandTable[] = {
|
||||||
static int CmdHelp(const char *Cmd) {
|
static int CmdHelp(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
CmdsHelp(CommandTable);
|
CmdsHelp(CommandTable);
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHFMFUltra(const char *Cmd) {
|
int CmdHFMFUltra(const char *Cmd) {
|
||||||
|
|
|
@ -60,10 +60,11 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos
|
||||||
compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2);
|
compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2);
|
||||||
bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2);
|
bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
|
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail"));
|
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail"));
|
||||||
}
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len*8, (barcode_len==16||barcode_len==32) ? _GREEN_("OK") : _YELLOW_("warning"));
|
||||||
PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len));
|
PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len));
|
||||||
if (barcode_len < 4) // too few to go to next decoding stages
|
if (barcode_len < 4) // too few to go to next decoding stages
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
|
@ -493,7 +493,7 @@ static int CmdTune(const char *Cmd) {
|
||||||
|
|
||||||
static int CmdVersion(const char *Cmd) {
|
static int CmdVersion(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
pm3_version(true);
|
pm3_version(true, false);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,7 +617,66 @@ int CmdHW(const char *Cmd) {
|
||||||
return CmdsParse(CommandTable, Cmd);
|
return CmdsParse(CommandTable, Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm3_version(bool verbose) {
|
void pm3_version(bool verbose, bool oneliner) {
|
||||||
|
|
||||||
|
#if defined(__MINGW64__)
|
||||||
|
# define PM3CLIENTCOMPILER "MinGW-w64 "
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
# define PM3CLIENTCOMPILER "MinGW "
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define PM3CLIENTCOMPILER "Clang/LLVM "
|
||||||
|
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||||
|
# define PM3CLIENTCOMPILER "GCC "
|
||||||
|
#else
|
||||||
|
# define PM3CLIENTCOMPILER "unknown compiler "
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(__MACH__)
|
||||||
|
# define PM3HOSTOS " OS:OSX"
|
||||||
|
#elif defined(__ANDROID__) || defined(ANDROID)
|
||||||
|
// must be tested before __linux__
|
||||||
|
# define PM3HOSTOS " OS:Android"
|
||||||
|
#elif defined(__linux__)
|
||||||
|
# define PM3HOSTOS " OS:Linux"
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
# define PM3HOSTOS " OS:FreeBSD"
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
# define PM3HOSTOS " OS:NetBSD"
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
|
# define PM3HOSTOS " OS:OpenBSD"
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
# define PM3HOSTOS " OS:Cygwin"
|
||||||
|
#elif defined(_WIN64) | defined(__WIN64__)
|
||||||
|
// must be tested before _WIN32
|
||||||
|
# define PM3HOSTOS " OS:Windows (64b)"
|
||||||
|
#elif defined(_WIN32) | defined(__WIN32__)
|
||||||
|
# define PM3HOSTOS " OS:Windows (32b)"
|
||||||
|
#else
|
||||||
|
# define PM3HOSTOS " OS:unknown"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
# define PM3HOSTARCH " ARCH:x86_64"
|
||||||
|
#elif defined(__i386__)
|
||||||
|
# define PM3HOSTARCH " ARCH:x86"
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
# define PM3HOSTARCH " ARCH:aarch64"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
# define PM3HOSTARCH " ARCH:arm"
|
||||||
|
#elif defined(__powerpc64__)
|
||||||
|
# define PM3HOSTARCH " ARCH:powerpc64"
|
||||||
|
#elif defined(__mips__)
|
||||||
|
# define PM3HOSTARCH " ARCH:mips"
|
||||||
|
#else
|
||||||
|
# define PM3HOSTARCH " ARCH:unknown"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (oneliner) {
|
||||||
|
// For "proxmark3 -v", simple printf, avoid logging
|
||||||
|
printf("Client: RRG/Iceman compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH "\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!verbose)
|
if (!verbose)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -630,11 +689,7 @@ void pm3_version(bool verbose) {
|
||||||
PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n");
|
PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n");
|
||||||
PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
|
PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
|
||||||
PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info?
|
PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info?
|
||||||
#if defined(__clang__)
|
PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH);
|
||||||
PrintAndLogEx(NORMAL, " compiled with Clang/LLVM "__VERSION__);
|
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
|
||||||
PrintAndLogEx(NORMAL, " compiled with GCC "__VERSION__);
|
|
||||||
#endif
|
|
||||||
PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]");
|
PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]");
|
||||||
PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
|
PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||||
PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
|
PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||||
|
|
|
@ -15,6 +15,6 @@
|
||||||
|
|
||||||
int CmdHW(const char *Cmd);
|
int CmdHW(const char *Cmd);
|
||||||
|
|
||||||
void pm3_version(bool verbose);
|
void pm3_version(bool verbose, bool oneliner);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,7 +58,7 @@ static int usage_lf_awid_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf awid sim 26 224 1337");
|
PrintAndLogEx(NORMAL, " lf awid sim 26 224 1337");
|
||||||
PrintAndLogEx(NORMAL, " lf awid sim 50 2001 deadc0de");
|
PrintAndLogEx(NORMAL, " lf awid sim 50 2001 13371337");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "hitag.h"
|
#include "hitag.h"
|
||||||
#include "loclass/fileutils.h" // savefile
|
#include "fileutils.h" // savefile
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "cmdlf.h"
|
#include "cmdlf.h"
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
/*
|
||||||
static int usage_lf_paradox_sim(void) {
|
static int usage_lf_paradox_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number.");
|
PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number.");
|
||||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||||
|
@ -38,6 +38,7 @@ static int usage_lf_paradox_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, " lf paradox sim 123 11223");
|
PrintAndLogEx(NORMAL, " lf paradox sim 123 11223");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded)
|
//Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded)
|
||||||
|
@ -111,8 +112,12 @@ static int CmdParadoxRead(const char *Cmd) {
|
||||||
return CmdParadoxDemod(Cmd);
|
return CmdParadoxDemod(Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdParadoxSim(const char *Cmd) {
|
|
||||||
|
|
||||||
|
static int CmdParadoxSim(const char *Cmd) {
|
||||||
|
PrintAndLogEx(INFO," To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
/*
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_paradox_sim();
|
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_paradox_sim();
|
||||||
|
|
||||||
|
@ -155,7 +160,7 @@ static int CmdParadoxSim(const char *Cmd) {
|
||||||
return resp.status;
|
return resp.status;
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"},
|
{"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"},
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -176,6 +176,9 @@ int CmdsParse(const command_t Commands[], const char *Cmd) {
|
||||||
memset(cmd_name, 0, sizeof(cmd_name));
|
memset(cmd_name, 0, sizeof(cmd_name));
|
||||||
sscanf(Cmd, "%127s%n", cmd_name, &len);
|
sscanf(Cmd, "%127s%n", cmd_name, &len);
|
||||||
str_lower(cmd_name);
|
str_lower(cmd_name);
|
||||||
|
// Comment
|
||||||
|
if (cmd_name[0] == '#')
|
||||||
|
return PM3_SUCCESS;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (Commands[i].Name) {
|
while (Commands[i].Name) {
|
||||||
if (0 == strcmp(Commands[i].Name, cmd_name)) {
|
if (0 == strcmp(Commands[i].Name, cmd_name)) {
|
||||||
|
|
|
@ -8,10 +8,6 @@
|
||||||
// Some lua scripting glue to proxmark core.
|
// Some lua scripting glue to proxmark core.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// this define is needed for scandir/alphasort to work
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -26,36 +22,10 @@
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "fileutils.h"
|
||||||
#ifdef _WIN32
|
|
||||||
#include "scandir.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int str_ends_with(const char *str, const char *suffix) {
|
|
||||||
|
|
||||||
if (str == NULL || suffix == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
size_t str_len = strlen(str);
|
|
||||||
size_t suffix_len = strlen(suffix);
|
|
||||||
|
|
||||||
if (suffix_len > str_len)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 0 == strncmp(str + str_len - suffix_len, suffix, suffix_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility to check the ending of a string (used to check file suffix)
|
|
||||||
*/
|
|
||||||
static bool endsWith(const char *base, const char *str) {
|
|
||||||
int blen = strlen(base);
|
|
||||||
int slen = strlen(str);
|
|
||||||
return (blen >= slen) && (0 == strcmp(base + blen - slen, str));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a sorted list of available commands, what it does is
|
* Generate a sorted list of available commands, what it does is
|
||||||
* generate a file listing of the script-directory for files
|
* generate a file listing of the script-directory for files
|
||||||
|
@ -63,31 +33,10 @@ static bool endsWith(const char *base, const char *str) {
|
||||||
*/
|
*/
|
||||||
static int CmdScriptList(const char *Cmd) {
|
static int CmdScriptList(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
int ret = searchAndList(LUA_SCRIPTS_SUBDIR, ".lua");
|
||||||
char const *exedir = get_my_executable_directory();
|
if (ret != PM3_SUCCESS)
|
||||||
if (exedir == NULL)
|
return ret;
|
||||||
return 0;
|
return searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd");
|
||||||
char script_directory_path[strlen(exedir) + strlen(LUA_SCRIPTS_DIRECTORY) + 1];
|
|
||||||
strcpy(script_directory_path, exedir);
|
|
||||||
strcpy(script_directory_path, get_my_executable_directory());
|
|
||||||
strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY);
|
|
||||||
|
|
||||||
struct dirent **namelist;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
n = scandir(script_directory_path, &namelist, NULL, alphasort);
|
|
||||||
if (n == -1) {
|
|
||||||
PrintAndLogEx(FAILED, "Couldn't open the scripts-directory");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < n; i++) {
|
|
||||||
if (str_ends_with(namelist[i]->d_name, ".lua"))
|
|
||||||
PrintAndLogEx(NORMAL, "%-21s", namelist[i]->d_name);
|
|
||||||
free(namelist[i]);
|
|
||||||
}
|
|
||||||
free(namelist);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,67 +46,81 @@ static int CmdScriptList(const char *Cmd) {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int CmdScriptRun(const char *Cmd) {
|
static int CmdScriptRun(const char *Cmd) {
|
||||||
// create new Lua state
|
|
||||||
lua_State *lua_state;
|
|
||||||
lua_state = luaL_newstate();
|
|
||||||
|
|
||||||
// load Lua libraries
|
char preferredName[128] = {0};
|
||||||
luaL_openlibs(lua_state);
|
|
||||||
|
|
||||||
//Sets the pm3 core libraries, that go a bit 'under the hood'
|
|
||||||
set_pm3_libraries(lua_state);
|
|
||||||
|
|
||||||
//Add the 'bin' library
|
|
||||||
set_bin_library(lua_state);
|
|
||||||
|
|
||||||
//Add the 'bit' library
|
|
||||||
set_bit_library(lua_state);
|
|
||||||
|
|
||||||
char script_name[128] = {0};
|
|
||||||
char arguments[256] = {0};
|
char arguments[256] = {0};
|
||||||
|
|
||||||
int name_len = 0;
|
int name_len = 0;
|
||||||
int arg_len = 0;
|
int arg_len = 0;
|
||||||
sscanf(Cmd, "%127s%n %255[^\n\r]%n", script_name, &name_len, arguments, &arg_len);
|
static uint8_t luascriptfile_idx = 0;
|
||||||
|
sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len);
|
||||||
|
|
||||||
const char *suffix = "";
|
char *script_path;
|
||||||
if (!endsWith(script_name, ".lua")) {
|
if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) {
|
||||||
suffix = ".lua";
|
int error;
|
||||||
|
if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) {
|
||||||
|
PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", script_path);
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments);
|
||||||
|
luascriptfile_idx++;
|
||||||
|
|
||||||
|
// create new Lua state
|
||||||
|
lua_State *lua_state;
|
||||||
|
lua_state = luaL_newstate();
|
||||||
|
|
||||||
|
// load Lua libraries
|
||||||
|
luaL_openlibs(lua_state);
|
||||||
|
|
||||||
|
//Sets the pm3 core libraries, that go a bit 'under the hood'
|
||||||
|
set_pm3_libraries(lua_state);
|
||||||
|
|
||||||
|
//Add the 'bin' library
|
||||||
|
set_bin_library(lua_state);
|
||||||
|
|
||||||
|
//Add the 'bit' library
|
||||||
|
set_bit_library(lua_state);
|
||||||
|
|
||||||
|
error = luaL_loadfile(lua_state, script_path);
|
||||||
|
free(script_path);
|
||||||
|
if (!error) {
|
||||||
|
lua_pushstring(lua_state, arguments);
|
||||||
|
lua_setglobal(lua_state, "args");
|
||||||
|
|
||||||
|
//Call it with 0 arguments
|
||||||
|
error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error,
|
||||||
|
}
|
||||||
|
if (error) { // if non-0, then an error
|
||||||
|
// the top of the stack should be the error string
|
||||||
|
if (!lua_isstring(lua_state, lua_gettop(lua_state)))
|
||||||
|
PrintAndLogEx(FAILED, "Error - but no error (?!)");
|
||||||
|
|
||||||
|
// get the top of the stack as the error and pop it off
|
||||||
|
const char *str = lua_tostring(lua_state, lua_gettop(lua_state));
|
||||||
|
lua_pop(lua_state, 1);
|
||||||
|
puts(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
//luaL_dofile(lua_state, buf);
|
||||||
|
// close the Lua state
|
||||||
|
lua_close(lua_state);
|
||||||
|
luascriptfile_idx--;
|
||||||
|
PrintAndLogEx(SUCCESS, "\nFinished %s\n", preferredName);
|
||||||
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) {
|
||||||
char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1];
|
PrintAndLogEx(SUCCESS, "Executing Cmd script: %s, args '%s'\n", script_path, arguments);
|
||||||
strcpy(script_path, get_my_executable_directory());
|
int ret = push_cmdscriptfile(script_path, true);
|
||||||
strcat(script_path, LUA_SCRIPTS_DIRECTORY);
|
if (ret != PM3_SUCCESS)
|
||||||
strcat(script_path, script_name);
|
PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_path);
|
||||||
strcat(script_path, suffix);
|
free(script_path);
|
||||||
|
return ret;
|
||||||
PrintAndLogEx(SUCCESS, "Executing: %s%s, args '%s'\n", script_name, suffix, arguments);
|
|
||||||
|
|
||||||
// run the Lua script
|
|
||||||
int error = luaL_loadfile(lua_state, script_path);
|
|
||||||
if (!error) {
|
|
||||||
lua_pushstring(lua_state, arguments);
|
|
||||||
lua_setglobal(lua_state, "args");
|
|
||||||
|
|
||||||
//Call it with 0 arguments
|
|
||||||
error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error,
|
|
||||||
}
|
}
|
||||||
if (error) { // if non-0, then an error
|
// file not found, let's search again to display the error messages
|
||||||
// the top of the stack should be the error string
|
int ret = PM3_EUNDEF;
|
||||||
if (!lua_isstring(lua_state, lua_gettop(lua_state)))
|
if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false);
|
||||||
PrintAndLogEx(FAILED, "Error - but no error (?!)");
|
if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false);
|
||||||
|
return ret;
|
||||||
// get the top of the stack as the error and pop it off
|
|
||||||
const char *str = lua_tostring(lua_state, lua_gettop(lua_state));
|
|
||||||
lua_pop(lua_state, 1);
|
|
||||||
puts(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
//luaL_dofile(lua_state, buf);
|
|
||||||
// close the Lua state
|
|
||||||
lua_close(lua_state);
|
|
||||||
PrintAndLogEx(SUCCESS, "\nFinished\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
|
@ -175,7 +138,7 @@ static command_t CommandTable[] = {
|
||||||
*/
|
*/
|
||||||
static int CmdHelp(const char *Cmd) {
|
static int CmdHelp(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place lua-scripts within the scripts/-folder. ");
|
PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place Lua-scripts within the luascripts/-folder. ");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
client/cmdscripts/rdv4_init_extflash.cmd
Executable file
6
client/cmdscripts/rdv4_init_extflash.cmd
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env -S pm3 -s
|
||||||
|
|
||||||
|
mem load f mfc_default_keys m
|
||||||
|
mem load f t55xx_default_pwds t
|
||||||
|
mem load f iclass_default_keys i
|
||||||
|
lf t55xx deviceconfig z p
|
|
@ -22,6 +22,7 @@
|
||||||
#include "crypto/libpcrypto.h" // sha512hash
|
#include "crypto/libpcrypto.h" // sha512hash
|
||||||
#include "emv/dump.h"
|
#include "emv/dump.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ static int usage_sm_upgrade(void) {
|
||||||
PrintAndLogEx(NORMAL, " f <filename> : firmware file name");
|
PrintAndLogEx(NORMAL, " f <filename> : firmware file name");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/SIM011.BIN");
|
PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/sim011.bin");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int usage_sm_setclock(void) {
|
static int usage_sm_setclock(void) {
|
||||||
|
@ -92,33 +93,35 @@ static int usage_sm_brute(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smart_loadjson(const char *preferredName, const char *suffix, json_t **root) {
|
static int smart_loadjson(const char *preferredName, json_t **root) {
|
||||||
|
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
|
|
||||||
if (preferredName == NULL) return 1;
|
if (preferredName == NULL) return 1;
|
||||||
if (suffix == NULL) return 1;
|
|
||||||
|
|
||||||
int retval = 0;
|
char *path;
|
||||||
int size = sizeof(char) * (strlen(get_my_executable_directory()) + strlen(preferredName) + strlen(suffix) + 10);
|
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json", false);
|
||||||
char *fileName = calloc(size, sizeof(char));
|
if (res != PM3_SUCCESS) {
|
||||||
sprintf(fileName, "%s%s.%s", get_my_executable_directory(), preferredName, suffix);
|
return PM3_EFILE;
|
||||||
*root = json_load_file(fileName, 0, &error);
|
}
|
||||||
|
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
*root = json_load_file(path, 0, &error);
|
||||||
if (!*root) {
|
if (!*root) {
|
||||||
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", fileName, error.line, error.text);
|
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
|
||||||
retval = 2;
|
retval = PM3_ESOFT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_is_array(*root)) {
|
if (!json_is_array(*root)) {
|
||||||
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", fileName);
|
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
|
||||||
retval = 3;
|
retval = PM3_ESOFT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", fileName);
|
PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path);
|
||||||
out:
|
out:
|
||||||
free(fileName);
|
free(path);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1038,7 @@ static int CmdSmartBruteforceSFI(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Importing AID list");
|
PrintAndLogEx(INFO, "Importing AID list");
|
||||||
json_t *root = NULL;
|
json_t *root = NULL;
|
||||||
smart_loadjson("aidlist", "json", &root);
|
smart_loadjson("aidlist", &root);
|
||||||
|
|
||||||
uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||||
if (!buf)
|
if (!buf)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "parity.h" // oddparity
|
#include "parity.h" // oddparity
|
||||||
#include "cmdhflist.h" // annotations
|
#include "cmdhflist.h" // annotations
|
||||||
#include "comms.h" // for sending cmds to device. GetFromBigBuf
|
#include "comms.h" // for sending cmds to device. GetFromBigBuf
|
||||||
#include "loclass/fileutils.h" // for saveFile
|
#include "fileutils.h" // for saveFile
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -294,6 +294,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||||
uint8_t parityBits = parityBytes[j >> 3];
|
uint8_t parityBits = parityBytes[j >> 3];
|
||||||
if (protocol != LEGIC
|
if (protocol != LEGIC
|
||||||
&& protocol != ISO_14443B
|
&& protocol != ISO_14443B
|
||||||
|
&& protocol != ISO_15693
|
||||||
|
&& protocol != ICLASS
|
||||||
&& protocol != ISO_7816_4
|
&& protocol != ISO_7816_4
|
||||||
&& protocol != PROTO_HITAG
|
&& protocol != PROTO_HITAG
|
||||||
&& protocol != THINFILM
|
&& protocol != THINFILM
|
||||||
|
@ -301,7 +303,18 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||||
&& (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) {
|
&& (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) {
|
||||||
|
|
||||||
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]);
|
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]);
|
||||||
} else {
|
} else if ( protocol == ICLASS && isResponse == false) {
|
||||||
|
uint8_t parity = 0;
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
parity ^= ((frame[0] >> i) & 1);
|
||||||
|
}
|
||||||
|
if ( parity == ((frame[0] >> 7) & 1)) {
|
||||||
|
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]);
|
||||||
|
} else {
|
||||||
|
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]);
|
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -763,8 +763,8 @@ static int CmdUsartRXhex(const char *Cmd) {
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"btpin", CmdUsartBtPin, IfPm3FpcUsartHostFromUsb, "Change BT add-on PIN"},
|
{"btpin", CmdUsartBtPin, IfPm3FpcUsartFromUsb, "Change BT add-on PIN"},
|
||||||
{"btfactory", CmdUsartBtFactory, IfPm3FpcUsartHostFromUsb, "Reset BT add-on to factory settings"},
|
{"btfactory", CmdUsartBtFactory, IfPm3FpcUsartFromUsb, "Reset BT add-on to factory settings"},
|
||||||
{"tx", CmdUsartTX, IfPm3FpcUsartDevFromUsb, "Send string over USART"},
|
{"tx", CmdUsartTX, IfPm3FpcUsartDevFromUsb, "Send string over USART"},
|
||||||
{"rx", CmdUsartRX, IfPm3FpcUsartDevFromUsb, "Receive string over USART"},
|
{"rx", CmdUsartRX, IfPm3FpcUsartDevFromUsb, "Receive string over USART"},
|
||||||
{"txrx", CmdUsartTXRX, IfPm3FpcUsartDevFromUsb, "Send string over USART and wait for response"},
|
{"txrx", CmdUsartTXRX, IfPm3FpcUsartDevFromUsb, "Send string over USART and wait for response"},
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "emv/emvjson.h"
|
#include "emv/emvjson.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
#ifndef PRINT_INDENT
|
#ifndef PRINT_INDENT
|
||||||
# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");}
|
# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");}
|
||||||
|
@ -235,25 +237,17 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *
|
||||||
static char *asn1_oid_description(const char *oid, bool with_group_desc) {
|
static char *asn1_oid_description(const char *oid, bool with_group_desc) {
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
json_t *root = NULL;
|
json_t *root = NULL;
|
||||||
char fname[300] = {0};
|
|
||||||
static char res[300];
|
static char res[300];
|
||||||
memset(res, 0x00, sizeof(res));
|
memset(res, 0x00, sizeof(res));
|
||||||
|
|
||||||
size_t len = strlen(get_my_executable_directory());
|
char *path;
|
||||||
if (len >= 300) len = 299;
|
if (searchFile(&path, RESOURCES_SUBDIR, "oids", ".json", false) != PM3_SUCCESS) {
|
||||||
|
return NULL;
|
||||||
strncpy(fname, get_my_executable_directory(), len);
|
|
||||||
strcat(fname, "crypto/oids.json");
|
|
||||||
if (access(fname, F_OK) < 0) {
|
|
||||||
strncpy(fname, get_my_executable_directory(), len);
|
|
||||||
strcat(fname, "oids.json");
|
|
||||||
if (access(fname, F_OK) < 0) {
|
|
||||||
goto error; // file not found
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load `oids.json`
|
// load `oids.json`
|
||||||
root = json_load_file(fname, 0, &error);
|
root = json_load_file(path, 0, &error);
|
||||||
|
free(path);
|
||||||
|
|
||||||
if (!root || !json_is_object(root)) {
|
if (!root || !json_is_object(root)) {
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#
|
|
||||||
# iClass Default Keys
|
|
||||||
# -- iceman fork version --
|
|
||||||
# -- contribute to this list, sharing is caring --
|
|
||||||
AEA684A6DAB23278 -- AA1
|
|
||||||
7665544332211000 -- key1/Kc from PicoPass 2k documentation
|
|
||||||
0123456789ABCDEF -- SAGEM
|
|
||||||
5b7c62c491c11b39 -- from loclass demo file.
|
|
||||||
F0E1D2C3B4A59687 -- Kd from PicoPass 2k documentation
|
|
||||||
5CBCF1DA45D5FB4F -- PicoPass Default Exchange Key
|
|
||||||
31ad7ebd2f282168 -- From HID multiclassSE reader
|
|
|
@ -1,966 +0,0 @@
|
||||||
#
|
|
||||||
# Mifare Default Keys
|
|
||||||
# -- iceman fork version --
|
|
||||||
# -- contribute to this list, sharing is caring --
|
|
||||||
#
|
|
||||||
ffffffffffff,//Defaultkey(firstkeyusedbyprogramifnouserdefinedkey)
|
|
||||||
000000000000,//Blankkey
|
|
||||||
a0a1a2a3a4a5,//NFCForumMADkey
|
|
||||||
b0b1b2b3b4b5,
|
|
||||||
c0c1c2c3c4c5,
|
|
||||||
d0d1d2d3d4d5,
|
|
||||||
aabbccddeeff,
|
|
||||||
4d3a99c351dd,
|
|
||||||
1a982c7e459a,
|
|
||||||
d3f7d3f7d3f7,// key A Wien
|
|
||||||
5a1b85fce20a,// key B Wien
|
|
||||||
714c5c886e97,
|
|
||||||
587ee5f9350f,
|
|
||||||
a0478cc39091,
|
|
||||||
533cb6c723f6,
|
|
||||||
8fd0a4f256e9,
|
|
||||||
#
|
|
||||||
d2ece8b9395e, //lib
|
|
||||||
#
|
|
||||||
# more Keys from mf_default_keys.lua
|
|
||||||
000000000001,
|
|
||||||
000000000002,
|
|
||||||
00000000000a,
|
|
||||||
00000000000b,
|
|
||||||
00000ffe2488,--VästtrafikenKeyB
|
|
||||||
010203040506,
|
|
||||||
0123456789ab,
|
|
||||||
0297927c0f77,--VästtrafikenKeyA
|
|
||||||
100000000000,
|
|
||||||
111111111111,
|
|
||||||
123456789abc,
|
|
||||||
12f2ee3478c1,
|
|
||||||
14d446e33363,
|
|
||||||
1999a3554a55,
|
|
||||||
200000000000,
|
|
||||||
222222222222,
|
|
||||||
26940b21ff5d,--RKFSLKeyA
|
|
||||||
27dd91f1fcf1,
|
|
||||||
2BA9621E0A36,--DirectoryandeventlogKeyB
|
|
||||||
333333333333,
|
|
||||||
33f974b42769,
|
|
||||||
34d1df9934c5,
|
|
||||||
434f4d4d4f41,--RKFJOJOGROUPKeyA
|
|
||||||
434f4d4d4f42,--RKFJOJOGROUPKeyB
|
|
||||||
43ab19ef5c31,
|
|
||||||
444444444444,
|
|
||||||
47524f555041,--RKFJOJOGROUPKeyA
|
|
||||||
47524f555042,--RKFJOJOGROUPKeyB
|
|
||||||
4AF9D7ADEBE4,--DirectoryandeventlogKeyA
|
|
||||||
4b0b20107ccb,--TNP3xxx
|
|
||||||
505249564141,--RKFJOJOPRIVAKeyA
|
|
||||||
505249564142,--RKFJOJOPRIVAKeyB
|
|
||||||
505249565441,
|
|
||||||
505249565442,
|
|
||||||
54726176656c,--VästtrafikenKeyA
|
|
||||||
555555555555,
|
|
||||||
55f5a5dd38c9,
|
|
||||||
569369c5a0e5,--kiev
|
|
||||||
5c598c9c58b5,--RKFSLKeyB
|
|
||||||
632193be1c3c,--kiev
|
|
||||||
644672bd4afe,--kiev
|
|
||||||
666666666666,
|
|
||||||
722bfcc5375f,--RKFRejskortDanmarkKeyA
|
|
||||||
776974687573,--VästtrafikenKeyB
|
|
||||||
777777777777,
|
|
||||||
888888888888,
|
|
||||||
8fe644038790,--kiev
|
|
||||||
999999999999,
|
|
||||||
99c636334433,
|
|
||||||
9de89e070277,--kiev
|
|
||||||
a00000000000,
|
|
||||||
a053a292a4af,
|
|
||||||
a64598a77478,--RKFSLKeyA
|
|
||||||
a94133013401,
|
|
||||||
aaaaaaaaaaaa,
|
|
||||||
abcdef123456,--Keyfromladyada.net
|
|
||||||
b00000000000,
|
|
||||||
b127c6f41436,
|
|
||||||
b5ff67cba951,--kiev
|
|
||||||
bbbbbbbbbbbb,
|
|
||||||
bd493a3962b6,
|
|
||||||
c934fe34d934,
|
|
||||||
cccccccccccc,
|
|
||||||
dddddddddddd,
|
|
||||||
e4d2770a89be,--RKFSLKeyB
|
|
||||||
ee0042f88840,--VästtrafikenKeyB
|
|
||||||
eeeeeeeeeeee,
|
|
||||||
eff603e1efe9,--kiev
|
|
||||||
f14ee7cae863,--kiev
|
|
||||||
f1a97341a9fc,
|
|
||||||
f1d83f964314,--RKFRejskortDanmarkKeyB
|
|
||||||
fc00018778f7,--VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA
|
|
||||||
44ab09010845,-- hotel system
|
|
||||||
85fed980ea5a,-- hotel system
|
|
||||||
314B49474956 --VIGIK1 A
|
|
||||||
564c505f4d41 --VIGIK1 B
|
|
||||||
ba5b895da162 --VIGIK1 B
|
|
||||||
# Vigik mystery Keys Mifare 1k EV1 (S50)
|
|
||||||
5c8ff9990da2, 16 A
|
|
||||||
75ccb59c9bed, 17 A
|
|
||||||
d01afeeb890a, 16 B
|
|
||||||
4b791bea7bcc, 17 B
|
|
||||||
#
|
|
||||||
4143414F5250,
|
|
||||||
a9b43414F585,--Tehran Railway
|
|
||||||
1FB235AC1388,--Tehran Railway
|
|
||||||
#
|
|
||||||
# Data from: http://irq5.io/2013/04/13/decoding-bcard-conference-badges/
|
|
||||||
f4a9ef2afc6d,--BCARD KeyB
|
|
||||||
#
|
|
||||||
# Data from: ...
|
|
||||||
89eac97f8c2a // S0 B
|
|
||||||
43c7600dee6b // S4 A
|
|
||||||
0120bf672a64 // S6 A
|
|
||||||
fb0b20df1f34 // S6 B
|
|
||||||
#
|
|
||||||
a9f953def0a3,
|
|
||||||
#
|
|
||||||
# Here be BIP keys...
|
|
||||||
3A42F33AF429,
|
|
||||||
1FC235AC1309,
|
|
||||||
6338A371C0ED,
|
|
||||||
243F160918D1,
|
|
||||||
F124C2578AD0,
|
|
||||||
9AFC42372AF1,
|
|
||||||
32AC3B90AC13,
|
|
||||||
682D401ABB09,
|
|
||||||
4AD1E273EAF1,
|
|
||||||
067DB45454A9,
|
|
||||||
E2C42591368A,
|
|
||||||
15FC4C7613FE,
|
|
||||||
2A3C347A1200,
|
|
||||||
68D30288910A,
|
|
||||||
16F3D5AB1139,
|
|
||||||
F59A36A2546D,
|
|
||||||
937A4FFF3011,
|
|
||||||
64E3C10394C2,
|
|
||||||
35C3D2CAEE88,
|
|
||||||
B736412614AF,
|
|
||||||
693143F10368,
|
|
||||||
324F5DF65310,
|
|
||||||
A3F97428DD01,
|
|
||||||
643FB6DE2217,
|
|
||||||
63F17A449AF0,
|
|
||||||
82F435DEDF01,
|
|
||||||
C4652C54261C,
|
|
||||||
0263DE1278F3,
|
|
||||||
D49E2826664F,
|
|
||||||
51284C3686A6,
|
|
||||||
3DF14C8000A1,
|
|
||||||
6A470D54127C,
|
|
||||||
#
|
|
||||||
# Data from: http://pastebin.com/AK9Bftpw
|
|
||||||
48ffe71294a0, -- Länstrafiken i Västerbotten
|
|
||||||
e3429281efc1, -- Länstrafiken i Västerbotten
|
|
||||||
16f21a82ec84, -- Länstrafiken i Västerbotten
|
|
||||||
460722122510, -- Länstrafiken i Västerbotten
|
|
||||||
#
|
|
||||||
# 3dprinter
|
|
||||||
AAFB06045877, --EPI Envisionte# 3dprinter
|
|
||||||
#
|
|
||||||
# gym
|
|
||||||
3e65e4fb65b3, --Fysiken A
|
|
||||||
25094df6f148, --Fysiken B
|
|
||||||
a05dbd98e0fc, -- CleverFit
|
|
||||||
#
|
|
||||||
d3b595e9dd63, -- Hotel KeyCard
|
|
||||||
afbecd121004, -- Hotel KeyCard
|
|
||||||
6471a5ef2d1a, -- SimonsVoss
|
|
||||||
#
|
|
||||||
# 24-7
|
|
||||||
D21762B2DE3B,
|
|
||||||
0E83A374B513,
|
|
||||||
1F1FFE000000,
|
|
||||||
A10F303FC879,
|
|
||||||
1322285230b8,
|
|
||||||
0C71BCFB7E72,
|
|
||||||
C3C88C6340B8,
|
|
||||||
F101622750B7,
|
|
||||||
1F107328DC8D,
|
|
||||||
710732200D34,
|
|
||||||
7C335FB121B5,
|
|
||||||
B39AE17435DC,
|
|
||||||
#
|
|
||||||
#
|
|
||||||
454841585443, -- key A
|
|
||||||
#
|
|
||||||
# Data from: http://pastebin.com/gQ6nk38G
|
|
||||||
D39BB83F5297,
|
|
||||||
85675B200017,
|
|
||||||
528C9DFFE28C,
|
|
||||||
C82EC29E3235,
|
|
||||||
3E3554AF0E12,
|
|
||||||
491CDCFB7752,
|
|
||||||
22C1BAE1AACD,
|
|
||||||
5F146716E373,
|
|
||||||
740E9A4F9AAF,
|
|
||||||
AC0E24C75527,
|
|
||||||
97184D136233,
|
|
||||||
E444D53D359F,
|
|
||||||
17758856B182,
|
|
||||||
A8966C7CC54B,
|
|
||||||
C6AD00254562,
|
|
||||||
AE3FF4EEA0DB,
|
|
||||||
5EB8F884C8D1,
|
|
||||||
FEE470A4CB58,
|
|
||||||
75D8690F21B6,
|
|
||||||
871B8C085997,
|
|
||||||
97D1101F18B0,
|
|
||||||
75EDE6A84460,
|
|
||||||
DF27A8F1CB8E,
|
|
||||||
B0C9DD55DD4D,
|
|
||||||
#
|
|
||||||
# Data from: http://bit.ly/1bdSbJl
|
|
||||||
A0B0C0D0E0F0,
|
|
||||||
A1B1C1D1E1F1,
|
|
||||||
#
|
|
||||||
# Data from: msk social
|
|
||||||
2735fc181807,
|
|
||||||
2aba9519f574,
|
|
||||||
84fd7f7a12b6,
|
|
||||||
186d8c4b93f9,
|
|
||||||
3a4bba8adaf0,
|
|
||||||
8765b17968a2,
|
|
||||||
40ead80721ce,
|
|
||||||
0db5e6523f7c,
|
|
||||||
51119dae5216,
|
|
||||||
83e3549ce42d,
|
|
||||||
136bdb246cac,
|
|
||||||
7de02a7f6025,
|
|
||||||
bf23a53c1f63,
|
|
||||||
cb9a1f2d7368,
|
|
||||||
c7c0adb3284f,
|
|
||||||
9f131d8c2057,
|
|
||||||
67362d90f973,
|
|
||||||
6202a38f69e2,
|
|
||||||
100533b89331,
|
|
||||||
653a87594079,
|
|
||||||
d8a274b2e026,
|
|
||||||
b20b83cb145c,
|
|
||||||
9afa6cb4fc3d,
|
|
||||||
#
|
|
||||||
# Data from http://pastebin.com/RRJUEDCM
|
|
||||||
0d258fe90296,
|
|
||||||
e55a3ca71826,
|
|
||||||
a4f204203f56,
|
|
||||||
eeb420209d0c,
|
|
||||||
911e52fd7ce4,
|
|
||||||
752fbb5b7b45,
|
|
||||||
66b03aca6ee9,
|
|
||||||
48734389edc3,
|
|
||||||
17193709adf4,
|
|
||||||
1acc3189578c,
|
|
||||||
c2b7ec7d4eb1,
|
|
||||||
369a4663acd2,
|
|
||||||
#
|
|
||||||
# Data from https://github.com/zhangjingye03/zxcardumper
|
|
||||||
# zxcard Key A/B
|
|
||||||
668770666644,
|
|
||||||
003003003003,
|
|
||||||
#
|
|
||||||
# Data from: http://phreakerclub.com/forum/showthread.php?p=41266
|
|
||||||
26973ea74321,
|
|
||||||
71f3a315ad26,
|
|
||||||
51044efb5aab,
|
|
||||||
ac70ca327a04,
|
|
||||||
eb0a8ff88ade,
|
|
||||||
#
|
|
||||||
# Data from: https://github.com/RadioWar/NFCGUI
|
|
||||||
44dd5a385aaf,
|
|
||||||
21a600056cb0,
|
|
||||||
b1aca33180a5,
|
|
||||||
dd61eb6bce22,
|
|
||||||
1565a172770f,
|
|
||||||
3e84d2612e2a,
|
|
||||||
f23442436765,
|
|
||||||
79674f96c771,
|
|
||||||
87df99d496cb,
|
|
||||||
c5132c8980bc,
|
|
||||||
a21680c27773,
|
|
||||||
f26e21edcee2,
|
|
||||||
675557ecc92e,
|
|
||||||
f4396e468114,
|
|
||||||
6db17c16b35b,
|
|
||||||
4186562a5bb2,
|
|
||||||
2feae851c199,
|
|
||||||
db1a3338b2eb,
|
|
||||||
157b10d84c6b,
|
|
||||||
a643f952ea57,
|
|
||||||
df37dcb6afb3,
|
|
||||||
4c32baf326e0,
|
|
||||||
91ce16c07ac5,
|
|
||||||
3c5d1c2bcd18,
|
|
||||||
c3f19ec592a2,
|
|
||||||
f72a29005459,
|
|
||||||
185fa3438949,
|
|
||||||
321a695bd266,
|
|
||||||
d327083a60a7,
|
|
||||||
45635ef66ef3,
|
|
||||||
5481986d2d62,
|
|
||||||
cba6ae869ad5,
|
|
||||||
645a166b1eeb,
|
|
||||||
a7abbc77cc9e,
|
|
||||||
f792c4c76a5c,
|
|
||||||
bfb6796a11db,
|
|
||||||
#
|
|
||||||
# Data from Salto A/B
|
|
||||||
6A1987C40A21,
|
|
||||||
7F33625BC129,
|
|
||||||
#
|
|
||||||
# Data from forum
|
|
||||||
2338b4913111,
|
|
||||||
#
|
|
||||||
# Data from stoye
|
|
||||||
cb779c50e1bd,
|
|
||||||
a27d3804c259,
|
|
||||||
003cc420001a,
|
|
||||||
f9861526130f,
|
|
||||||
381ece050fbd,
|
|
||||||
a57186bdd2b9,
|
|
||||||
48c739e21a04,
|
|
||||||
36abf5874ed7,
|
|
||||||
649d2abbbd20,
|
|
||||||
bbe8fffcf363,
|
|
||||||
ab4e7045e97d,
|
|
||||||
340e40f81cd8,
|
|
||||||
e4f65c0ef32c,
|
|
||||||
d2a597d76936,
|
|
||||||
a920f32fe93a,
|
|
||||||
86afd95200f7,
|
|
||||||
9b832a9881ff,
|
|
||||||
26643965b16e,
|
|
||||||
0c669993c776,
|
|
||||||
b468d1991af9,
|
|
||||||
d9a37831dce5,
|
|
||||||
2fc1f32f51b1,
|
|
||||||
0ffbf65b5a14,
|
|
||||||
c5cfe06d9ea3,
|
|
||||||
c0dece673829,
|
|
||||||
#
|
|
||||||
a56c2df9a26d,
|
|
||||||
#
|
|
||||||
# Data from: https://pastebin.com/vbwast74
|
|
||||||
#
|
|
||||||
68d3f7307c89,
|
|
||||||
568c9083f71c,--Smart Rider. Western Australian Public Transport Cards
|
|
||||||
# Vigik Keys
|
|
||||||
# Various sources :
|
|
||||||
# * https://github.com/DumpDos/Vigik
|
|
||||||
# * http://newffr.com/viewtopic.php?&forum=235&topic=11559
|
|
||||||
# * Own dumps
|
|
||||||
021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
|
|
||||||
2ef720f2af76,
|
|
||||||
414c41524f4e,
|
|
||||||
424c41524f4e,
|
|
||||||
4a6352684677,
|
|
||||||
bf1f4424af76,
|
|
||||||
536653644c65,
|
|
||||||
#
|
|
||||||
# Intratone Cogelec
|
|
||||||
# Data from http://bouzdeck.com/rfid/32-cloning-a-mifare-classic-1k-tag.html
|
|
||||||
484558414354,
|
|
||||||
a22ae129c013,
|
|
||||||
49fae4e3849f,
|
|
||||||
38fcf33072e0,
|
|
||||||
8ad5517b4b18,
|
|
||||||
509359f131b1,
|
|
||||||
6c78928e1317,
|
|
||||||
aa0720018738,
|
|
||||||
a6cac2886412,
|
|
||||||
62d0c424ed8e,
|
|
||||||
e64a986a5d94,
|
|
||||||
8fa1d601d0a2,
|
|
||||||
89347350bd36,
|
|
||||||
66d2b7dc39ef,
|
|
||||||
6bc1e1ae547d,
|
|
||||||
22729a9bd40f,
|
|
||||||
#
|
|
||||||
# Data from https://dfir.lu/blog/cloning-a-mifare-classic-1k-tag.html
|
|
||||||
925b158f796f,
|
|
||||||
fad63ecb5891,
|
|
||||||
bba840ba1c57,
|
|
||||||
cc6b3b3cd263,
|
|
||||||
6245e47352e6,
|
|
||||||
8ed41e8b8056,
|
|
||||||
2dd39a54e1f3,
|
|
||||||
6d4c5b3658d2,
|
|
||||||
1877ed29435a,
|
|
||||||
52264716efde,
|
|
||||||
961c0db4a7ed,
|
|
||||||
703140fd6d86,
|
|
||||||
157c9a513fa5,
|
|
||||||
e2a5dc8e066f,
|
|
||||||
#
|
|
||||||
# Data from a oyster card
|
|
||||||
374bf468607f,
|
|
||||||
bfc8e353af63,
|
|
||||||
15cafd6159f6,
|
|
||||||
62efd80ab715,
|
|
||||||
987a7f7f1a35,
|
|
||||||
c4104fa3c526,
|
|
||||||
4c961f23e6be,
|
|
||||||
67546972bc69,
|
|
||||||
f4cd5d4c13ff,
|
|
||||||
94414c1a07dc,
|
|
||||||
16551d52fd20,
|
|
||||||
9cb290282f7d,
|
|
||||||
77a84170b574,
|
|
||||||
ed646c83a4f3,
|
|
||||||
e703589db50b,
|
|
||||||
513c85d06cde,
|
|
||||||
95093f0b2e22,
|
|
||||||
543b01b27a95,
|
|
||||||
c6d375b99972,
|
|
||||||
ee4cc572b40e,
|
|
||||||
5106ca7e4a69,
|
|
||||||
c96bd1ce607f,
|
|
||||||
167a1be102e0,
|
|
||||||
a8d0d850a606,
|
|
||||||
a2abb693ce34,
|
|
||||||
7b296c40c486,
|
|
||||||
91f93a5564c9,
|
|
||||||
e10623e7a016,
|
|
||||||
b725f9cbf183,
|
|
||||||
#
|
|
||||||
# Data from FDi tag
|
|
||||||
8829da9daf76,
|
|
||||||
#
|
|
||||||
# Data from GitHub issue
|
|
||||||
0A7932DC7E65,
|
|
||||||
11428B5BCE06,
|
|
||||||
11428B5BCE07,
|
|
||||||
11428B5BCE08,
|
|
||||||
11428B5BCE09,
|
|
||||||
11428B5BCE0A,
|
|
||||||
11428B5BCE0F,
|
|
||||||
18971D893494,
|
|
||||||
25D60050BF6E,
|
|
||||||
3FA7217EC575,
|
|
||||||
44F0B5FBE344,
|
|
||||||
7B296F353C6B,
|
|
||||||
8553263F4FF0,
|
|
||||||
8E5D33A6ED51,
|
|
||||||
9F42971E8322,
|
|
||||||
C620318EF179,
|
|
||||||
D4FE03CE5B06,
|
|
||||||
D4FE03CE5B07,
|
|
||||||
D4FE03CE5B08,
|
|
||||||
D4FE03CE5B09,
|
|
||||||
D4FE03CE5B0A,
|
|
||||||
D4FE03CE5B0F,
|
|
||||||
E241E8AFCBAF,
|
|
||||||
#
|
|
||||||
# Data from forum post
|
|
||||||
123F8888F322,
|
|
||||||
050908080008,
|
|
||||||
#
|
|
||||||
# Data from hoist
|
|
||||||
4f9f59c9c875,
|
|
||||||
#
|
|
||||||
# Data from pastebin
|
|
||||||
66f3ed00fed7,
|
|
||||||
f7a39753d018,
|
|
||||||
#
|
|
||||||
# Data from https://pastebin.com/Z7pEeZif
|
|
||||||
386B4D634A65,
|
|
||||||
666E564F4A44,
|
|
||||||
564777315276,
|
|
||||||
476242304C53,
|
|
||||||
6A696B646631,
|
|
||||||
4D3248735131,
|
|
||||||
425A73484166,
|
|
||||||
57784A533069,
|
|
||||||
345547514B4D,
|
|
||||||
4C6B69723461,
|
|
||||||
4E4175623670,
|
|
||||||
4D5076656D58,
|
|
||||||
686A736A356E,
|
|
||||||
484A57696F4A,
|
|
||||||
6F4B6D644178,
|
|
||||||
744E326B3441,
|
|
||||||
70564650584F,
|
|
||||||
584F66326877,
|
|
||||||
6D4E334B6C48,
|
|
||||||
6A676C315142,
|
|
||||||
77494C526339,
|
|
||||||
623055724556,
|
|
||||||
356D46474348,
|
|
||||||
4E32336C6E38,
|
|
||||||
57734F6F6974,
|
|
||||||
436A46587552,
|
|
||||||
5544564E6E67,
|
|
||||||
6F506F493353,
|
|
||||||
31646241686C,
|
|
||||||
77646B633657,
|
|
||||||
#
|
|
||||||
# Data from TransPert
|
|
||||||
2031d1e57a3b,
|
|
||||||
53c11f90822a,
|
|
||||||
9189449ea24e,
|
|
||||||
#
|
|
||||||
# data from Github
|
|
||||||
410b9b40b872,
|
|
||||||
2cb1a90071c8,
|
|
||||||
#
|
|
||||||
# data from
|
|
||||||
8697389ACA26,
|
|
||||||
1AB23CD45EF6,
|
|
||||||
013889343891,
|
|
||||||
#
|
|
||||||
#
|
|
||||||
0000000018de,
|
|
||||||
16ddcb6b3f24,
|
|
||||||
#
|
|
||||||
# Data from https://pastebin.com/vwDRZW7d
|
|
||||||
EC0A9B1A9E06,--Vingcard Mifare 4k Staff card
|
|
||||||
6C94E1CED026,--Vingcard Mifare 4k Staff card
|
|
||||||
0F230695923F,--Vingcard Mifare 4k Staff card
|
|
||||||
0000014B5C31,--Vingcard Mifare 4k Staff card
|
|
||||||
#
|
|
||||||
BEDB604CC9D1,
|
|
||||||
B8A1F613CF3D,
|
|
||||||
B578F38A5C61,
|
|
||||||
B66AC040203A
|
|
||||||
6D0B6A2A0003
|
|
||||||
2E641D99AD5B
|
|
||||||
AD4FB33388BF,
|
|
||||||
69FB7B7CD8EE,
|
|
||||||
2A6D9205E7CA,
|
|
||||||
2a2c13cc242a,
|
|
||||||
27FBC86A00D0,
|
|
||||||
01FA3FC68349,
|
|
||||||
#
|
|
||||||
6D44B5AAF464,--Smart Rider. Western Australian Public Transport Cards
|
|
||||||
1717E34A7A8A,--Smart Rider. Western Australian Public Transport Cards
|
|
||||||
#
|
|
||||||
6B6579737472,--RFIDeas
|
|
||||||
#
|
|
||||||
484944204953,--HID MIFARE Classic 1k Key
|
|
||||||
204752454154,--HID MIFARE Classic 1k Key
|
|
||||||
3B7E4FD575AD,--HID MIFARE SO
|
|
||||||
11496F97752A,--HID MIFARE SO
|
|
||||||
#
|
|
||||||
415A54454B4D,--Luxeo/Aztek cashless vending
|
|
||||||
#
|
|
||||||
321958042333,--BQT
|
|
||||||
#
|
|
||||||
160A91D29A9C,--Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48
|
|
||||||
#
|
|
||||||
b7bf0c13066e,--Gallagher
|
|
||||||
#
|
|
||||||
# Boston, MA, USA Transit - MBTA Charlie Card
|
|
||||||
3060206f5b0a,-- charlie
|
|
||||||
5ec39b022f2b,-- charlie
|
|
||||||
3a09594c8587,-- charlie
|
|
||||||
f1b9f5669cc8,-- charlie
|
|
||||||
f662248e7e89,-- charlie
|
|
||||||
62387b8d250d,-- charlie
|
|
||||||
f238d78ff48f,-- charlie
|
|
||||||
9dc282d46217,-- charlie
|
|
||||||
afd0ba94d624,-- charlie
|
|
||||||
92ee4dc87191,-- charlie
|
|
||||||
b35a0e4acc09,-- charlie
|
|
||||||
756ef55e2507,-- charlie
|
|
||||||
447ab7fd5a6b,-- charlie
|
|
||||||
932b9cb730ef,-- charlie
|
|
||||||
1f1a0a111b5b,-- charlie
|
|
||||||
ad9e0a1ca2f7,-- charlie
|
|
||||||
d58023ba2bdc,-- charlie
|
|
||||||
62ced42a6d87,-- charlie
|
|
||||||
2548a443df28,-- charlie
|
|
||||||
2ed3b15e7c0f,-- charlie
|
|
||||||
#
|
|
||||||
60012e9ba3fa,
|
|
||||||
#
|
|
||||||
de1fcbec764b,
|
|
||||||
81bfbe8cacba,
|
|
||||||
bff123126c9b,
|
|
||||||
2f47741062a0,
|
|
||||||
b4166b0a27ea,
|
|
||||||
a170d9b59f95,
|
|
||||||
400bc9be8976,
|
|
||||||
d80511fc2ab4,
|
|
||||||
1fcef3005bcf,
|
|
||||||
bb467463acd6,
|
|
||||||
e67c8010502d,
|
|
||||||
ff58ba1b4478,
|
|
||||||
# Data from https://pastebin.com/Kz8xp4ev
|
|
||||||
fbf225dc5d58,
|
|
||||||
#
|
|
||||||
# Data https://pastebin.com/BEm6bdAE
|
|
||||||
# vingcard.txt
|
|
||||||
4708111c8604,
|
|
||||||
3d50d902ea48,
|
|
||||||
96a301bce267,
|
|
||||||
6700f10fec09,
|
|
||||||
7a09cc1db70a,
|
|
||||||
560f7cff2d81,
|
|
||||||
66b31e64ca4b,
|
|
||||||
9e53491f685b,
|
|
||||||
3a09911d860c,
|
|
||||||
8a036920ac0c,
|
|
||||||
361f69d2c462,
|
|
||||||
d9bcde7fc489,
|
|
||||||
0c03a720f208,
|
|
||||||
6018522fac02,
|
|
||||||
#
|
|
||||||
# Data from https://pastebin.com/4t2yFMgt
|
|
||||||
# Mifare technische Universität Graz TUG
|
|
||||||
D58660D1ACDE,
|
|
||||||
50A11381502C,
|
|
||||||
C01FC822C6E5,
|
|
||||||
0854BF31111E,
|
|
||||||
# More keys:
|
|
||||||
8a19d40cf2b5,
|
|
||||||
ae8587108640,
|
|
||||||
135b88a94b8b, SafLock standalone door locks.
|
|
||||||
#
|
|
||||||
# Russian Troika card
|
|
||||||
08B386463229,
|
|
||||||
0E8F64340BA4,
|
|
||||||
0F1C63013DBA,
|
|
||||||
2AA05ED1856F,
|
|
||||||
2B7F3253FAC5,
|
|
||||||
69A32F1C2F19,
|
|
||||||
73068F118C13,
|
|
||||||
9BECDF3D9273,
|
|
||||||
A73F5DC1D333,
|
|
||||||
A82607B01C0D,
|
|
||||||
AE3D65A3DAD4,
|
|
||||||
CD4C61C26E3D,
|
|
||||||
D3EAFB5DF46D,
|
|
||||||
E35173494A81,
|
|
||||||
FBC2793D540B,
|
|
||||||
5125974CD391,
|
|
||||||
ECF751084A80,
|
|
||||||
7545DF809202,
|
|
||||||
AB16584C972A,
|
|
||||||
7A38E3511A38,
|
|
||||||
C8454C154CB5,
|
|
||||||
04C297B91308,
|
|
||||||
EFCB0E689DB3,
|
|
||||||
07894FFEC1D6,
|
|
||||||
FBA88F109B32,
|
|
||||||
2FE3CB83EA43,
|
|
||||||
B90DE525CEB6,
|
|
||||||
1CC219E9FEC1,
|
|
||||||
A74332F74994,
|
|
||||||
764CD061F1E6,
|
|
||||||
8F79C4FD8A01,
|
|
||||||
CD64E567ABCD,
|
|
||||||
CE26ECB95252,
|
|
||||||
ABA208516740,
|
|
||||||
9868925175BA,
|
|
||||||
16A27AF45407,
|
|
||||||
372CC880F216,
|
|
||||||
3EBCE0925B2F,
|
|
||||||
73E5B9D9D3A4,
|
|
||||||
0DB520C78C1C,
|
|
||||||
70D901648CB9,
|
|
||||||
C11F4597EFB5,
|
|
||||||
B39D19A280DF,
|
|
||||||
403D706BA880,
|
|
||||||
7038CD25C408,
|
|
||||||
6B02733BB6EC,
|
|
||||||
EAAC88E5DC99,
|
|
||||||
4ACEC1205D75,
|
|
||||||
2910989B6880,
|
|
||||||
31C7610DE3B0,
|
|
||||||
5EFBAECEF46B,
|
|
||||||
F8493407799D,
|
|
||||||
6B8BD9860763,
|
|
||||||
D3A297DC2698,
|
|
||||||
#
|
|
||||||
# Keys from MifareClassicTool project
|
|
||||||
044CE1872BC3,
|
|
||||||
045CECA15535,
|
|
||||||
0BE5FAC8B06A,
|
|
||||||
0CE7CD2CC72B,
|
|
||||||
0EB23CC8110B,
|
|
||||||
0F01CEFF2742,
|
|
||||||
0F318130ED18,
|
|
||||||
114D6BE9440C,
|
|
||||||
18E3A02B5EFF,
|
|
||||||
19FC84A3784B,
|
|
||||||
1B61B2E78C75,
|
|
||||||
22052B480D11,
|
|
||||||
3367BFAA91DB,
|
|
||||||
3A8A139C20B4,
|
|
||||||
42E9B54E51AB,
|
|
||||||
46D78E850A7E,
|
|
||||||
4B609876BBA3,
|
|
||||||
518DC6EEA089,
|
|
||||||
6B07877E2C5C,
|
|
||||||
7259FA0197C6,
|
|
||||||
72F96BDD3714,
|
|
||||||
7413B599C4EA,
|
|
||||||
77DABC9825E1,
|
|
||||||
7A396F0D633D,
|
|
||||||
7A86AA203788,
|
|
||||||
8791B2CCB5C4,
|
|
||||||
8A8D88151A00,
|
|
||||||
8C97CD7A0E56,
|
|
||||||
8E26E45E7D65,
|
|
||||||
9D993C5D4EF4,
|
|
||||||
9EA3387A63C1,
|
|
||||||
A3FAA6DAFF67,
|
|
||||||
A7141147D430,
|
|
||||||
AAFB06045877,
|
|
||||||
ACFFFFFFFFFF,
|
|
||||||
AFCEF64C9913,
|
|
||||||
B27ADDFB64B0,
|
|
||||||
B81F2B0C2F66,
|
|
||||||
B9F8A7D83978,
|
|
||||||
BAFF3053B496,
|
|
||||||
BB52F8CCE07F,
|
|
||||||
BC2D1791DEC1,
|
|
||||||
BC4580B7F20B,
|
|
||||||
C65D4EAA645B,
|
|
||||||
C76BF71A2509,
|
|
||||||
D5524F591EED,
|
|
||||||
E328A1C7156D,
|
|
||||||
E4821A377B75,
|
|
||||||
E56AC127DD45,
|
|
||||||
EA0FD73CB149,
|
|
||||||
FC0001877BF7,
|
|
||||||
FD8705E721B0,
|
|
||||||
00ada2cd516d,
|
|
||||||
#
|
|
||||||
#
|
|
||||||
D3F7D3F7D3F7
|
|
||||||
##
|
|
||||||
237a4d0d9119,
|
|
||||||
0ed7846c2bc9,
|
|
||||||
FFFFD06F83E3,
|
|
||||||
FFFFAE82366C,
|
|
||||||
F89C86B2A961,
|
|
||||||
F83466888612,
|
|
||||||
ED3A7EFBFF56,
|
|
||||||
E96246531342,
|
|
||||||
E1DD284379D4,
|
|
||||||
DFED39FFBB76,
|
|
||||||
DB5181C92CBE,
|
|
||||||
CFC738403AB0,
|
|
||||||
BCFE01BCFE01,
|
|
||||||
BA28CFD15EE8,
|
|
||||||
B0699AD03D17,
|
|
||||||
AABBCC660429,
|
|
||||||
A4EF6C3BB692,
|
|
||||||
A2B2C9D187FB,
|
|
||||||
9B1DD7C030A1,
|
|
||||||
9AEDF9931EC1,
|
|
||||||
8F9B229047AC,
|
|
||||||
872B71F9D15A,
|
|
||||||
833FBD3CFE51,
|
|
||||||
5D293AFC8D7E,
|
|
||||||
5554AAA96321,
|
|
||||||
474249437569,
|
|
||||||
435330666666,
|
|
||||||
1A2B3C4D5E6F,
|
|
||||||
123456ABCDEF,
|
|
||||||
83BAB5ACAD62,
|
|
||||||
64E2283FCF5E,
|
|
||||||
64A2EE93B12B,
|
|
||||||
46868F6D5677,
|
|
||||||
40E5EA1EFC00,
|
|
||||||
37D4DCA92451,
|
|
||||||
2012053082AD,
|
|
||||||
2011092119F1,
|
|
||||||
200306202033,
|
|
||||||
1795902DBAF9,
|
|
||||||
17505586EF02,
|
|
||||||
022FE48B3072,
|
|
||||||
013940233313,
|
|
||||||
#
|
|
||||||
# Hotel Adina
|
|
||||||
9EBC3EB37130,
|
|
||||||
#
|
|
||||||
# mostlikely diverised individual keys.
|
|
||||||
# data from: https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c
|
|
||||||
491CDC863104,
|
|
||||||
A2F63A485632,
|
|
||||||
98631ED2B229,
|
|
||||||
19F1FFE02563,
|
|
||||||
563A22C01FC8, -- Argentina
|
|
||||||
43CA22C13091, -- Argentina
|
|
||||||
25094DF2C1BD, -- Argentina
|
|
||||||
#
|
|
||||||
# OMNITEC.ES HOTEL TIMECARD / MAINTENANCECARD
|
|
||||||
AFBECD120454,
|
|
||||||
#
|
|
||||||
# OMNITEC.ES HOTEL EMERGENCYCARD
|
|
||||||
842146108088,
|
|
||||||
#
|
|
||||||
# TAPCARD PUBLIC TRANSPORT LA
|
|
||||||
#
|
|
||||||
EA1B88DF0A76,
|
|
||||||
D1991E71E2C5,
|
|
||||||
05F89678CFCF,
|
|
||||||
D31463A7AB6D,
|
|
||||||
C38197C36420,
|
|
||||||
772219470B38,
|
|
||||||
1C1532A6F1BC,
|
|
||||||
FA38F70215AD,
|
|
||||||
E907470D31CC,
|
|
||||||
160F4B7AB806,
|
|
||||||
1D28C58BBE8A,
|
|
||||||
B3830B95CA34,
|
|
||||||
6A0E215D1EEB,
|
|
||||||
E41E6199318F,
|
|
||||||
C4F271F5F0B3,
|
|
||||||
1E352F9E19E5,
|
|
||||||
0E0E8C6D8EB6,
|
|
||||||
C342F825B01B,
|
|
||||||
CB911A1A1929,
|
|
||||||
E65B66089AFC,
|
|
||||||
B81846F06EDF,
|
|
||||||
37FC71221B46,
|
|
||||||
880C09CFA23C,
|
|
||||||
6476FA0746E7,
|
|
||||||
419A13811554,
|
|
||||||
2C60E904539C,
|
|
||||||
4ECCA6236400,
|
|
||||||
10F2BBAA4D1C,
|
|
||||||
4857DD68ECD9,
|
|
||||||
C6A76CB2F3B5,
|
|
||||||
E3AD9E9BA5D4,
|
|
||||||
6C9EC046C1A4,
|
|
||||||
#
|
|
||||||
# ROC HIGHSCHOOL ACCESSCARD
|
|
||||||
#
|
|
||||||
B021669B44BB,
|
|
||||||
B18CDCDE52B7,
|
|
||||||
A22647F422AE,
|
|
||||||
B268F7C9CA63,
|
|
||||||
A37A30004AC9,
|
|
||||||
B3630C9F11C8,
|
|
||||||
A4CDFF3B1848,
|
|
||||||
B42C4DFD7A90,
|
|
||||||
A541538F1416,
|
|
||||||
B5F454568271,
|
|
||||||
A6C028A12FBB,
|
|
||||||
B6323F550F54,
|
|
||||||
A7D71AC06DC2,
|
|
||||||
B7C344A36D88,
|
|
||||||
A844F4F52385,
|
|
||||||
B8457ACC5F5D,
|
|
||||||
A9A4045DCE77,
|
|
||||||
B9B8B7B6B5B3,
|
|
||||||
AA4D051954AC,
|
|
||||||
BA729428E808,
|
|
||||||
AB28A44AD5F5,
|
|
||||||
BB320A757099,
|
|
||||||
AC45AD2D620D,
|
|
||||||
BCF5A6B5E13F,
|
|
||||||
AD5645062534,
|
|
||||||
BDF837787A71,
|
|
||||||
AE43F36C1A9A,
|
|
||||||
BE7C4F6C7A9A,
|
|
||||||
5EC7938F140A,
|
|
||||||
82D58AA49CCB,
|
|
||||||
#
|
|
||||||
# MELONCARD
|
|
||||||
#
|
|
||||||
323334353637,
|
|
||||||
#
|
|
||||||
#
|
|
||||||
CEE3632EEFF5,
|
|
||||||
827ED62B31A7,
|
|
||||||
03EA4053C6ED,
|
|
||||||
C0BEEFEC850B,
|
|
||||||
F57F410E18FF,
|
|
||||||
0AF7DB99AEE4,
|
|
||||||
A7FB4824ACBF,
|
|
||||||
207FFED492FD,
|
|
||||||
1CFA22DBDFC3,
|
|
||||||
30FFB6B056F5,
|
|
||||||
39CF885474DD,
|
|
||||||
00F0BD116D70,
|
|
||||||
4CFF128FA3EF,
|
|
||||||
10F3BEBC01DF,
|
|
||||||
#
|
|
||||||
# Transportes Insular La Palma
|
|
||||||
#
|
|
||||||
0172066b2f03,
|
|
||||||
0000085f0000,
|
|
||||||
1a80b93f7107,
|
|
||||||
70172066b2f0,
|
|
||||||
b1a80c94f710,
|
|
||||||
0b0172066b2f,
|
|
||||||
0f1a81c95071,
|
|
||||||
f0f0172066b2,
|
|
||||||
1131a81d9507,
|
|
||||||
2f130172066b,
|
|
||||||
71171a82d951,
|
|
||||||
b2f170172066,
|
|
||||||
1711b1a82e96,
|
|
||||||
6b2f1b017206,
|
|
||||||
62711f1a83e9,
|
|
||||||
66b2f1f01720,
|
|
||||||
97271231a83f,
|
|
||||||
066b2f230172,
|
|
||||||
f97371271a84,
|
|
||||||
2066b2f27017,
|
|
||||||
50983712b1a8,
|
|
||||||
72066b2f2b01,
|
|
||||||
850984712f1a,
|
|
||||||
172066b2f2f0,
|
|
||||||
a85198481331,
|
|
||||||
0172066b2f33,
|
|
||||||
1a8619858137,
|
|
||||||
70172066b2f3,
|
|
||||||
b1a862985913,
|
|
||||||
3b0172066b2f,
|
|
||||||
3f1a87298691,
|
|
||||||
f3f0172066b2,
|
|
||||||
#
|
|
||||||
# Tehran ezpay
|
|
||||||
#
|
|
||||||
38A88AEC1C43
|
|
||||||
CBD2568BC7C6
|
|
||||||
7BCB4774EC8F
|
|
||||||
22ECE9316461
|
|
||||||
AE4B497A2527
|
|
||||||
EEC0626B01A1
|
|
||||||
2C71E22A32FE
|
|
||||||
91142568B22F
|
|
||||||
7D56759A974A
|
|
||||||
D3B1C7EA5C53
|
|
||||||
41C82D231497
|
|
||||||
0B8B21C692C2
|
|
||||||
604Ac8D87C7E
|
|
||||||
8E7B29460F12
|
|
||||||
BB3D7B11D224
|
|
||||||
#
|
|
||||||
# Chaco
|
|
||||||
#
|
|
||||||
b210cfa436d2
|
|
||||||
b8b1cfa646a8
|
|
||||||
a9f95891f0a4
|
|
||||||
#
|
|
||||||
# Keys from APK application "Scan Badge"
|
|
||||||
4A4C474F524D
|
|
||||||
444156494442
|
|
||||||
434143445649
|
|
||||||
434456495243
|
|
||||||
A00002000021
|
|
||||||
EF61A3D48E2A
|
|
||||||
A23456789123
|
|
||||||
010000000000
|
|
||||||
363119000001
|
|
||||||
A00003000084
|
|
||||||
675A32413770
|
|
||||||
395244733978
|
|
||||||
A0004A000036
|
|
||||||
2C9F3D45BA13
|
|
||||||
4243414F5250
|
|
||||||
DFE73BE48AC6
|
|
||||||
#
|
|
||||||
B069D0D03D17
|
|
||||||
000131B93F28
|
|
|
@ -1,123 +0,0 @@
|
||||||
# known cloners
|
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?id=2022
|
|
||||||
51243648,
|
|
||||||
000D8787,
|
|
||||||
19920427,
|
|
||||||
65857569, //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com)
|
|
||||||
# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77
|
|
||||||
05D73B9F,
|
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?=
|
|
||||||
89A69E60,
|
|
||||||
# ref lock
|
|
||||||
314159E0,
|
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115
|
|
||||||
AA55BBBB,
|
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376
|
|
||||||
A5B4C3D2,
|
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379
|
|
||||||
1C0B5848,
|
|
||||||
# http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075
|
|
||||||
00434343,
|
|
||||||
44B44CAE,
|
|
||||||
88661858,
|
|
||||||
# paxton bullit?
|
|
||||||
575F4F4B,
|
|
||||||
#
|
|
||||||
50520901,
|
|
||||||
# Default pwd, simple:
|
|
||||||
00000000,
|
|
||||||
11111111,
|
|
||||||
22222222,
|
|
||||||
33333333,
|
|
||||||
44444444,
|
|
||||||
55555555,
|
|
||||||
66666666,
|
|
||||||
77777777,
|
|
||||||
88888888,
|
|
||||||
99999999,
|
|
||||||
AAAAAAAA,
|
|
||||||
BBBBBBBB,
|
|
||||||
CCCCCCCC,
|
|
||||||
DDDDDDDD,
|
|
||||||
EEEEEEEE,
|
|
||||||
FFFFFFFF,
|
|
||||||
a0a1a2a3,
|
|
||||||
b0b1b2b3,
|
|
||||||
aabbccdd,
|
|
||||||
bbccddee,
|
|
||||||
ccddeeff,
|
|
||||||
50415353,
|
|
||||||
00000001,
|
|
||||||
00000002,
|
|
||||||
0000000a,
|
|
||||||
0000000b,
|
|
||||||
01020304,
|
|
||||||
02030405,
|
|
||||||
03040506,
|
|
||||||
04050607,
|
|
||||||
05060708,
|
|
||||||
06070809,
|
|
||||||
0708090A,
|
|
||||||
08090A0B,
|
|
||||||
090A0B0C,
|
|
||||||
0A0B0C0D,
|
|
||||||
0B0C0D0E,
|
|
||||||
0C0D0E0F,
|
|
||||||
01234567,
|
|
||||||
12345678,
|
|
||||||
10000000,
|
|
||||||
20000000,
|
|
||||||
30000000,
|
|
||||||
40000000,
|
|
||||||
50000000,
|
|
||||||
60000000,
|
|
||||||
70000000,
|
|
||||||
80000000,
|
|
||||||
90000000,
|
|
||||||
A0000000,
|
|
||||||
B0000000,
|
|
||||||
C0000000,
|
|
||||||
D0000000,
|
|
||||||
E0000000,
|
|
||||||
F0000000,
|
|
||||||
10101010,
|
|
||||||
01010101,
|
|
||||||
11223344,
|
|
||||||
22334455,
|
|
||||||
33445566,
|
|
||||||
44556677,
|
|
||||||
55667788,
|
|
||||||
66778899,
|
|
||||||
778899AA,
|
|
||||||
8899AABB,
|
|
||||||
99AABBCC,
|
|
||||||
AABBCCDD,
|
|
||||||
BBCCDDEE,
|
|
||||||
CCDDEEFF,
|
|
||||||
0CB7E7FC, //rfidler?
|
|
||||||
FABADA11, //china?
|
|
||||||
# 20 most common len==8
|
|
||||||
87654321,
|
|
||||||
12341234,
|
|
||||||
69696969,
|
|
||||||
12121212,
|
|
||||||
12344321,
|
|
||||||
1234ABCD,
|
|
||||||
11112222,
|
|
||||||
13131313,
|
|
||||||
10041004,
|
|
||||||
#
|
|
||||||
31415926, //pii
|
|
||||||
abcd1234,
|
|
||||||
20002000,
|
|
||||||
19721972,
|
|
||||||
aa55aa55, // amiboo
|
|
||||||
55aa55aa, // rev amiboo
|
|
||||||
4f271149, // seeds ul-ev1
|
|
||||||
07d7bb0b, // seeds ul-ev1
|
|
||||||
9636ef8f, // seeds ul-ev1
|
|
||||||
b5f44686, // seeds ul-ev1
|
|
||||||
9E3779B9, // TEA
|
|
||||||
C6EF3720, // TEA
|
|
||||||
7854794A, // xbox tea constant :)
|
|
||||||
F1EA5EED, // burtle
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
12
client/dictionaries/iclass_default_keys.dic
Normal file
12
client/dictionaries/iclass_default_keys.dic
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#
|
||||||
|
# iClass Default Keys
|
||||||
|
# -- iceman fork version --
|
||||||
|
# -- contribute to this list, sharing is caring --
|
||||||
|
#
|
||||||
|
AEA684A6DAB23278 # AA1
|
||||||
|
7665544332211000 # key1/Kc from PicoPass 2k documentation
|
||||||
|
0123456789ABCDEF # SAGEM
|
||||||
|
5b7c62c491c11b39 # from loclass demo file.
|
||||||
|
F0E1D2C3B4A59687 # Kd from PicoPass 2k documentation
|
||||||
|
5CBCF1DA45D5FB4F # PicoPass Default Exchange Key
|
||||||
|
31ad7ebd2f282168 # From HID multiclassSE reader
|
1022
client/dictionaries/mfc_default_keys.dic
Normal file
1022
client/dictionaries/mfc_default_keys.dic
Normal file
File diff suppressed because it is too large
Load diff
1000
client/dictionaries/mfc_keys_bmp_sorted.dic
Normal file
1000
client/dictionaries/mfc_keys_bmp_sorted.dic
Normal file
File diff suppressed because it is too large
Load diff
1000
client/dictionaries/mfc_keys_icbmp_sorted.dic
Normal file
1000
client/dictionaries/mfc_keys_icbmp_sorted.dic
Normal file
File diff suppressed because it is too large
Load diff
57
client/dictionaries/mfc_keys_mrzd_sorted.dic
Normal file
57
client/dictionaries/mfc_keys_mrzd_sorted.dic
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
010203040506
|
||||||
|
013940233313
|
||||||
|
022FE48B3072
|
||||||
|
123456789ABC
|
||||||
|
123456ABCDEF
|
||||||
|
17505586EF02
|
||||||
|
1795902DBAF9
|
||||||
|
1A2B3C4D5E6F
|
||||||
|
1A982C7E459A
|
||||||
|
200306202033
|
||||||
|
2011092119F1
|
||||||
|
2012053082AD
|
||||||
|
37D4DCA92451
|
||||||
|
40E5EA1EFC00
|
||||||
|
435330666666
|
||||||
|
46868F6D5677
|
||||||
|
474249437569
|
||||||
|
4D3A99C351DD
|
||||||
|
533CB6C723F6
|
||||||
|
5554AAA96321
|
||||||
|
587EE5F9350F
|
||||||
|
5A1B85FCE20A
|
||||||
|
5D293AFC8D7E
|
||||||
|
64A2EE93B12B
|
||||||
|
64E2283FCF5E
|
||||||
|
714C5C886E97
|
||||||
|
833FBD3CFE51
|
||||||
|
83BAB5ACAD62
|
||||||
|
872B71F9D15A
|
||||||
|
8F9B229047AC
|
||||||
|
8FD0A4F256E9
|
||||||
|
9AEDF9931EC1
|
||||||
|
9B1DD7C030A1
|
||||||
|
A0478CC39091
|
||||||
|
A0A1A2A3A4A5
|
||||||
|
A2B2C9D187FB
|
||||||
|
A4EF6C3BB692
|
||||||
|
AABBCC660429
|
||||||
|
AABBCCDDEEFF
|
||||||
|
ABCDEF123456
|
||||||
|
B0699AD03D17
|
||||||
|
B0B1B2B3B4B5
|
||||||
|
BA28CFD15EE8
|
||||||
|
BCFE01BCFE01
|
||||||
|
C0C1C2C3C4C5
|
||||||
|
CFC738403AB0
|
||||||
|
D0D1D2D3D4D5
|
||||||
|
D3F7D3F7D3F7
|
||||||
|
DB5181C92CBE
|
||||||
|
DFED39FFBB76
|
||||||
|
E1DD284379D4
|
||||||
|
E96246531342
|
||||||
|
ED3A7EFBFF56
|
||||||
|
F83466888612
|
||||||
|
F89C86B2A961
|
||||||
|
FFFFAE82366C
|
||||||
|
FFFFD06F83E3
|
|
@ -2,4 +2,5 @@
|
||||||
# Mifare Ultralight Default Keys
|
# Mifare Ultralight Default Keys
|
||||||
# -- iceman fork version --
|
# -- iceman fork version --
|
||||||
# -- contribute to this list, sharing is caring --
|
# -- contribute to this list, sharing is caring --
|
||||||
425245414B4D454946594F5543414E21 -- Sample Key (BREAKMEIFYOUCAN!)
|
#
|
||||||
|
425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!)
|
|
@ -1,57 +0,0 @@
|
||||||
010203040506,
|
|
||||||
013940233313,
|
|
||||||
022FE48B3072,
|
|
||||||
123456789ABC,
|
|
||||||
123456ABCDEF,
|
|
||||||
17505586EF02,
|
|
||||||
1795902DBAF9,
|
|
||||||
1A2B3C4D5E6F,
|
|
||||||
1A982C7E459A,
|
|
||||||
200306202033,
|
|
||||||
2011092119F1,
|
|
||||||
2012053082AD,
|
|
||||||
37D4DCA92451,
|
|
||||||
40E5EA1EFC00,
|
|
||||||
435330666666,
|
|
||||||
46868F6D5677,
|
|
||||||
474249437569,
|
|
||||||
4D3A99C351DD,
|
|
||||||
533CB6C723F6,
|
|
||||||
5554AAA96321,
|
|
||||||
587EE5F9350F,
|
|
||||||
5A1B85FCE20A,
|
|
||||||
5D293AFC8D7E,
|
|
||||||
64A2EE93B12B,
|
|
||||||
64E2283FCF5E,
|
|
||||||
714C5C886E97,
|
|
||||||
833FBD3CFE51,
|
|
||||||
83BAB5ACAD62,
|
|
||||||
872B71F9D15A,
|
|
||||||
8F9B229047AC,
|
|
||||||
8FD0A4F256E9,
|
|
||||||
9AEDF9931EC1,
|
|
||||||
9B1DD7C030A1,
|
|
||||||
A0478CC39091,
|
|
||||||
A0A1A2A3A4A5,
|
|
||||||
A2B2C9D187FB,
|
|
||||||
A4EF6C3BB692,
|
|
||||||
AABBCC660429,
|
|
||||||
AABBCCDDEEFF,
|
|
||||||
ABCDEF123456,
|
|
||||||
B0699AD03D17,
|
|
||||||
B0B1B2B3B4B5,
|
|
||||||
BA28CFD15EE8,
|
|
||||||
BCFE01BCFE01,
|
|
||||||
C0C1C2C3C4C5,
|
|
||||||
CFC738403AB0,
|
|
||||||
D0D1D2D3D4D5,
|
|
||||||
D3F7D3F7D3F7,
|
|
||||||
DB5181C92CBE,
|
|
||||||
DFED39FFBB76,
|
|
||||||
E1DD284379D4,
|
|
||||||
E96246531342,
|
|
||||||
ED3A7EFBFF56,
|
|
||||||
F83466888612,
|
|
||||||
F89C86B2A961,
|
|
||||||
FFFFAE82366C,
|
|
||||||
FFFFD06F83E3,
|
|
123
client/dictionaries/t55xx_default_pwds.dic
Normal file
123
client/dictionaries/t55xx_default_pwds.dic
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
# known cloners
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?id=2022
|
||||||
|
51243648
|
||||||
|
000D8787
|
||||||
|
19920427
|
||||||
|
65857569 //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com)
|
||||||
|
# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77
|
||||||
|
05D73B9F
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?=
|
||||||
|
89A69E60
|
||||||
|
# ref lock
|
||||||
|
314159E0
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115
|
||||||
|
AA55BBBB
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376
|
||||||
|
A5B4C3D2
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379
|
||||||
|
1C0B5848
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075
|
||||||
|
00434343
|
||||||
|
44B44CAE
|
||||||
|
88661858
|
||||||
|
# paxton bullit?
|
||||||
|
575F4F4B
|
||||||
|
#
|
||||||
|
50520901
|
||||||
|
# Default pwd, simple:
|
||||||
|
00000000
|
||||||
|
11111111
|
||||||
|
22222222
|
||||||
|
33333333
|
||||||
|
44444444
|
||||||
|
55555555
|
||||||
|
66666666
|
||||||
|
77777777
|
||||||
|
88888888
|
||||||
|
99999999
|
||||||
|
AAAAAAAA
|
||||||
|
BBBBBBBB
|
||||||
|
CCCCCCCC
|
||||||
|
DDDDDDDD
|
||||||
|
EEEEEEEE
|
||||||
|
FFFFFFFF
|
||||||
|
a0a1a2a3
|
||||||
|
b0b1b2b3
|
||||||
|
aabbccdd
|
||||||
|
bbccddee
|
||||||
|
ccddeeff
|
||||||
|
50415353
|
||||||
|
00000001
|
||||||
|
00000002
|
||||||
|
0000000a
|
||||||
|
0000000b
|
||||||
|
01020304
|
||||||
|
02030405
|
||||||
|
03040506
|
||||||
|
04050607
|
||||||
|
05060708
|
||||||
|
06070809
|
||||||
|
0708090A
|
||||||
|
08090A0B
|
||||||
|
090A0B0C
|
||||||
|
0A0B0C0D
|
||||||
|
0B0C0D0E
|
||||||
|
0C0D0E0F
|
||||||
|
01234567
|
||||||
|
12345678
|
||||||
|
10000000
|
||||||
|
20000000
|
||||||
|
30000000
|
||||||
|
40000000
|
||||||
|
50000000
|
||||||
|
60000000
|
||||||
|
70000000
|
||||||
|
80000000
|
||||||
|
90000000
|
||||||
|
A0000000
|
||||||
|
B0000000
|
||||||
|
C0000000
|
||||||
|
D0000000
|
||||||
|
E0000000
|
||||||
|
F0000000
|
||||||
|
10101010
|
||||||
|
01010101
|
||||||
|
11223344
|
||||||
|
22334455
|
||||||
|
33445566
|
||||||
|
44556677
|
||||||
|
55667788
|
||||||
|
66778899
|
||||||
|
778899AA
|
||||||
|
8899AABB
|
||||||
|
99AABBCC
|
||||||
|
AABBCCDD
|
||||||
|
BBCCDDEE
|
||||||
|
CCDDEEFF
|
||||||
|
0CB7E7FC # rfidler?
|
||||||
|
FABADA11 # china?
|
||||||
|
# 20 most common len==8
|
||||||
|
87654321
|
||||||
|
12341234
|
||||||
|
69696969
|
||||||
|
12121212
|
||||||
|
12344321
|
||||||
|
1234ABCD
|
||||||
|
11112222
|
||||||
|
13131313
|
||||||
|
10041004
|
||||||
|
#
|
||||||
|
31415926 # pii
|
||||||
|
abcd1234
|
||||||
|
20002000
|
||||||
|
19721972
|
||||||
|
aa55aa55 # amiboo
|
||||||
|
55aa55aa # rev amiboo
|
||||||
|
4f271149 # seeds ul-ev1
|
||||||
|
07d7bb0b # seeds ul-ev1
|
||||||
|
9636ef8f # seeds ul-ev1
|
||||||
|
b5f44686 # seeds ul-ev1
|
||||||
|
9E3779B9 # TEA
|
||||||
|
C6EF3720 # TEA
|
||||||
|
7854794A # xbox tea constant :)
|
||||||
|
F1EA5EED # burtle
|
|
@ -232,7 +232,7 @@ static int CmdEMVGPO(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("kK", "keep", "keep field ON for next command"),
|
arg_lit0("kK", "keep", "keep field ON for next command"),
|
||||||
arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"),
|
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"),
|
||||||
arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
|
arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
||||||
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
|
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
|
||||||
|
@ -398,7 +398,7 @@ static int CmdEMVAC(const char *Cmd) {
|
||||||
arg_lit0("kK", "keep", "keep field ON for next command"),
|
arg_lit0("kK", "keep", "keep field ON for next command"),
|
||||||
arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
|
arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
|
||||||
arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
|
arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
|
||||||
arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"),
|
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"),
|
||||||
arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
|
arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
||||||
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
|
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
|
||||||
|
@ -564,7 +564,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("kK", "keep", "keep field ON for next command"),
|
arg_lit0("kK", "keep", "keep field ON for next command"),
|
||||||
arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"),
|
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"),
|
||||||
arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
|
arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
||||||
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
|
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
|
||||||
|
@ -785,7 +785,7 @@ static int CmdEMVExec(const char *Cmd) {
|
||||||
arg_lit0("sS", "select", "activate field and select card."),
|
arg_lit0("sS", "select", "activate field and select card."),
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
|
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
|
||||||
arg_lit0("tT", "tlv", "TLV decode results."),
|
arg_lit0("tT", "tlv", "TLV decode results."),
|
||||||
arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
|
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."),
|
||||||
arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
|
arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
|
||||||
arg_rem("By default:", "Transaction type - MSD"),
|
arg_rem("By default:", "Transaction type - MSD"),
|
||||||
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
||||||
|
@ -1376,7 +1376,7 @@ static int CmdEMVScan(const char *Cmd) {
|
||||||
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
|
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
|
||||||
arg_lit0("tT", "tlv", "TLV decode results."),
|
arg_lit0("tT", "tlv", "TLV decode results."),
|
||||||
arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
|
arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
|
||||||
arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
|
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."),
|
||||||
arg_rem("By default:", "Transaction type - MSD"),
|
arg_rem("By default:", "Transaction type - MSD"),
|
||||||
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
|
||||||
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
|
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
#define BCD(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
|
#define BCD(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
|
||||||
-1)
|
-1)
|
||||||
|
@ -483,13 +485,12 @@ struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const char *relfname = "emv/capk.txt";
|
char *path;
|
||||||
|
if (searchFile(&path, RESOURCES_SUBDIR, "capk", ".txt", false) != PM3_SUCCESS) {
|
||||||
char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1];
|
return NULL;
|
||||||
strcpy(fname, get_my_executable_directory());
|
}
|
||||||
strcat(fname, relfname);
|
pk = emv_pk_get_ca_pk_from_file(path, rid, idx);
|
||||||
|
free(path);
|
||||||
pk = emv_pk_get_ca_pk_from_file(fname, rid, idx);
|
|
||||||
|
|
||||||
if (!pk)
|
if (!pk)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -401,11 +401,11 @@ static const struct emv_tag emv_tags[] = {
|
||||||
{ 0xdf811b, "Kernel Configuration", EMV_TAG_GENERIC, NULL },
|
{ 0xdf811b, "Kernel Configuration", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf811c, "Max Lifetime of Torn Transaction Log Record", EMV_TAG_GENERIC, NULL },
|
{ 0xdf811c, "Max Lifetime of Torn Transaction Log Record", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf811d, "Max Number of Torn Transaction Log Records", EMV_TAG_GENERIC, NULL },
|
{ 0xdf811d, "Max Number of Torn Transaction Log Records", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf811e, "Mag-stripe CVM Capability – CVM Required", EMV_TAG_GENERIC, NULL },
|
{ 0xdf811e, "Mag-stripe CVM Capability - CVM Required", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf811f, "Security Capability", EMV_TAG_GENERIC, NULL },
|
{ 0xdf811f, "Security Capability", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf8120, "Terminal Action Code – Default", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8120, "Terminal Action Code - Default", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf8121, "Terminal Action Code – Denial", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8121, "Terminal Action Code - Denial", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf8122, "Terminal Action Code – Online", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8122, "Terminal Action Code - Online", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf8123, "Reader Contactless Floor Limit", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8123, "Reader Contactless Floor Limit", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf8124, "Reader Contactless Transaction Limit (No On-device CVM)", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8124, "Reader Contactless Transaction Limit (No On-device CVM)", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf8125, "Reader Contactless Transaction Limit (On-device CVM)", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8125, "Reader Contactless Transaction Limit (On-device CVM)", EMV_TAG_GENERIC, NULL },
|
||||||
|
@ -415,7 +415,7 @@ static const struct emv_tag emv_tags[] = {
|
||||||
{ 0xdf8129, "Outcome Parameter Set", EMV_TAG_GENERIC, NULL },
|
{ 0xdf8129, "Outcome Parameter Set", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf812a, "DD Card (Track1)", EMV_TAG_GENERIC, NULL },
|
{ 0xdf812a, "DD Card (Track1)", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf812b, "DD Card (Track2)", EMV_TAG_GENERIC, NULL },
|
{ 0xdf812b, "DD Card (Track2)", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf812c, "Mag-stripe CVM Capability – No CVM Required", EMV_TAG_GENERIC, NULL },
|
{ 0xdf812c, "Mag-stripe CVM Capability - No CVM Required", EMV_TAG_GENERIC, NULL },
|
||||||
{ 0xdf812d, "Message Hold Time", EMV_TAG_GENERIC, NULL },
|
{ 0xdf812d, "Message Hold Time", EMV_TAG_GENERIC, NULL },
|
||||||
|
|
||||||
{ 0xff8101, "Torn Record", EMV_TAG_GENERIC, NULL },
|
{ 0xff8101, "Torn Record", EMV_TAG_GENERIC, NULL },
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "emv_tags.h"
|
#include "emv_tags.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
static const ApplicationDataElm ApplicationData[] = {
|
static const ApplicationDataElm ApplicationData[] = {
|
||||||
{0x82, "AIP"},
|
{0x82, "AIP"},
|
||||||
|
@ -303,13 +305,12 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// current path + file name
|
char *path;
|
||||||
const char *relfname = "emv/defparams.json";
|
if (searchFile(&path, RESOURCES_SUBDIR, "emv_defparams", ".json", false) != PM3_SUCCESS) {
|
||||||
char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1];
|
return false;
|
||||||
strcpy(fname, get_my_executable_directory());
|
}
|
||||||
strcat(fname, relfname);
|
root = json_load_file(path, 0, &error);
|
||||||
|
free(path);
|
||||||
root = json_load_file(fname, 0, &error);
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
PrintAndLogEx(ERR, "Load params: json error on line " _YELLOW_("%d") ": %s", error.line, error.text);
|
PrintAndLogEx(ERR, "Load params: json error on line " _YELLOW_("%d") ": %s", error.line, error.text);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -58,7 +58,13 @@ int ExecuteCryptoTests(bool verbose) {
|
||||||
res = mbedtls_entropy_self_test(verbose);
|
res = mbedtls_entropy_self_test(verbose);
|
||||||
if (res) TestFail = true;
|
if (res) TestFail = true;
|
||||||
|
|
||||||
res = mbedtls_timing_self_test(verbose);
|
// retry for CI (when resources too low)
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
res = mbedtls_timing_self_test(verbose);
|
||||||
|
if (!res)
|
||||||
|
break;
|
||||||
|
PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1);
|
||||||
|
}
|
||||||
if (res) TestFail = true;
|
if (res) TestFail = true;
|
||||||
|
|
||||||
res = mbedtls_ctr_drbg_self_test(verbose);
|
res = mbedtls_ctr_drbg_self_test(verbose);
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
// Name: Yubico U2F Root CA Serial 457200631
|
// Name: Yubico U2F Root CA Serial 457200631
|
||||||
// Issued: 2014-08-01
|
// Issued: 2014-08-01
|
||||||
|
// https://github.com/Yubico/developers.yubico.com/tree/master/static/U2F
|
||||||
#define YUBICO_CA \
|
#define YUBICO_CA \
|
||||||
"-----BEGIN CERTIFICATE-----\r\n" \
|
"-----BEGIN CERTIFICATE-----\r\n" \
|
||||||
"MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \
|
"MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \
|
||||||
|
|
|
@ -34,18 +34,23 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
// this define is needed for scandir/alphasort to work
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "pm3_cmd.h"
|
#include "pm3_cmd.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "proxmark3.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "scandir.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PATH_MAX_LENGTH 200
|
||||||
#ifndef ON_DEVICE
|
|
||||||
|
|
||||||
#define PATH_MAX_LENGTH 100
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief checks if a file exists
|
* @brief checks if a file exists
|
||||||
|
@ -98,9 +103,9 @@ static char *newfilenamemcopy(const char *preferredName, const char *suffix) {
|
||||||
|
|
||||||
int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) {
|
int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) {
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return PM3_EINVARG;
|
||||||
char *fileName = newfilenamemcopy(preferredName, suffix);
|
char *fileName = newfilenamemcopy(preferredName, suffix);
|
||||||
if (fileName == NULL) return 1;
|
if (fileName == NULL) return PM3_EMALLOC;
|
||||||
|
|
||||||
/* We should have a valid filename now, e.g. dumpdata-3.bin */
|
/* We should have a valid filename now, e.g. dumpdata-3.bin */
|
||||||
|
|
||||||
|
@ -121,9 +126,9 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si
|
||||||
|
|
||||||
int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) {
|
int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) {
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return PM3_EINVARG;
|
||||||
char *fileName = newfilenamemcopy(preferredName, ".eml");
|
char *fileName = newfilenamemcopy(preferredName, ".eml");
|
||||||
if (fileName == NULL) return 1;
|
if (fileName == NULL) return PM3_EMALLOC;
|
||||||
|
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
int blocks = datalen / blocksize;
|
int blocks = datalen / blocksize;
|
||||||
|
@ -166,9 +171,9 @@ out:
|
||||||
|
|
||||||
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) {
|
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) {
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return PM3_EINVARG;
|
||||||
char *fileName = newfilenamemcopy(preferredName, ".json");
|
char *fileName = newfilenamemcopy(preferredName, ".json");
|
||||||
if (fileName == NULL) return 1;
|
if (fileName == NULL) return PM3_EMALLOC;
|
||||||
|
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
|
@ -276,6 +281,19 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case jsfIclass: {
|
||||||
|
JsonSaveStr(root, "FileType", "iclass");
|
||||||
|
uint8_t csn[8] = {0};
|
||||||
|
memcpy(csn, data, 8);
|
||||||
|
JsonSaveBufAsHexCompact(root, "$.Card.CSN", csn, sizeof(csn));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < (datalen / 8); i++) {
|
||||||
|
char path[PATH_MAX_LENGTH] = {0};
|
||||||
|
sprintf(path, "$.blocks.%zu", i);
|
||||||
|
JsonSaveBufAsHexCompact(root, path, data + (i * 8), 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = json_dump_file(root, fileName, JSON_INDENT(2));
|
int res = json_dump_file(root, fileName, JSON_INDENT(2));
|
||||||
|
@ -293,11 +311,42 @@ out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) {
|
||||||
|
uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (fptr == NULL) {
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fkeys = fopen(fptr, "wb");
|
||||||
|
if (fkeys == NULL) {
|
||||||
|
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr);
|
||||||
|
|
||||||
|
for (i = 0; i < sectorsCnt; i++) {
|
||||||
|
num_to_bytes(e_sector[i].Key[0], 6, tmpKey);
|
||||||
|
fwrite(tmpKey, 1, 6, fkeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sectorsCnt; i++) {
|
||||||
|
num_to_bytes(e_sector[i].Key[1], 6, tmpKey);
|
||||||
|
fwrite(tmpKey, 1, 6, fkeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fkeys);
|
||||||
|
PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) {
|
int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) {
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return 1;
|
||||||
char *fileName = filenamemcopy(preferredName, suffix);
|
char *fileName = filenamemcopy(preferredName, suffix);
|
||||||
if (fileName == NULL) return 1;
|
if (fileName == NULL) return PM3_EINVARG;
|
||||||
|
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
|
@ -315,23 +364,24 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
|
||||||
|
|
||||||
if (fsize <= 0) {
|
if (fsize <= 0) {
|
||||||
PrintAndLogEx(FAILED, "error, when getting filesize");
|
PrintAndLogEx(FAILED, "error, when getting filesize");
|
||||||
retval = 1;
|
retval = PM3_EFILE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
||||||
if (!dump) {
|
if (!dump) {
|
||||||
PrintAndLogEx(FAILED, "error, cannot allocate memory");
|
PrintAndLogEx(FAILED, "error, cannot allocate memory");
|
||||||
retval = 2;
|
retval = PM3_EMALLOC;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytes_read = fread(dump, 1, fsize, f);
|
size_t bytes_read = fread(dump, 1, fsize, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
if (bytes_read != fsize) {
|
if (bytes_read != fsize) {
|
||||||
PrintAndLogEx(FAILED, "error, bytes read mismatch file size");
|
PrintAndLogEx(FAILED, "error, bytes read mismatch file size");
|
||||||
free(dump);
|
free(dump);
|
||||||
retval = 3;
|
retval = PM3_EFILE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,17 +398,66 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
|
||||||
*datalen = bytes_read;
|
*datalen = bytes_read;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
fclose(f);
|
|
||||||
free(fileName);
|
free(fileName);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) {
|
||||||
|
|
||||||
|
char *path;
|
||||||
|
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
|
FILE *f = fopen(path, "rb");
|
||||||
|
if (!f) {
|
||||||
|
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
|
||||||
|
free(path);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
// get filesize in order to malloc memory
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
if (fsize <= 0) {
|
||||||
|
PrintAndLogEx(FAILED, "error, when getting filesize");
|
||||||
|
fclose(f);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pdata = calloc(fsize, sizeof(uint8_t));
|
||||||
|
if (!pdata) {
|
||||||
|
PrintAndLogEx(FAILED, "error, cannot allocate memory");
|
||||||
|
fclose(f);
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_read = fread(*pdata, 1, fsize, f);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (bytes_read != fsize) {
|
||||||
|
PrintAndLogEx(FAILED, "error, bytes read mismatch file size");
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*datalen = bytes_read;
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
|
int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return PM3_EINVARG;
|
||||||
char *fileName = filenamemcopy(preferredName, ".eml");
|
char *fileName = filenamemcopy(preferredName, ".eml");
|
||||||
if (fileName == NULL) return 1;
|
if (fileName == NULL) return PM3_EMALLOC;
|
||||||
|
|
||||||
size_t counter = 0;
|
size_t counter = 0;
|
||||||
int retval = PM3_SUCCESS, hexlen = 0;
|
int retval = PM3_SUCCESS, hexlen = 0;
|
||||||
|
@ -384,7 +483,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
|
||||||
break;
|
break;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(FAILED, "File reading error.");
|
PrintAndLogEx(FAILED, "File reading error.");
|
||||||
retval = 2;
|
retval = PM3_EFILE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,9 +509,9 @@ out:
|
||||||
|
|
||||||
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) {
|
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) {
|
||||||
|
|
||||||
if (data == NULL) return 1;
|
if (data == NULL) return PM3_EINVARG;
|
||||||
char *fileName = filenamemcopy(preferredName, ".json");
|
char *fileName = filenamemcopy(preferredName, ".json");
|
||||||
if (fileName == NULL) return 1;
|
if (fileName == NULL) return PM3_EMALLOC;
|
||||||
|
|
||||||
*datalen = 0;
|
*datalen = 0;
|
||||||
json_t *root;
|
json_t *root;
|
||||||
|
@ -423,13 +522,13 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
root = json_load_file(fileName, 0, &error);
|
root = json_load_file(fileName, 0, &error);
|
||||||
if (!root) {
|
if (!root) {
|
||||||
PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text);
|
PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text);
|
||||||
retval = 2;
|
retval = PM3_ESOFT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_is_object(root)) {
|
if (!json_is_object(root)) {
|
||||||
PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName);
|
PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName);
|
||||||
retval = 3;
|
retval = PM3_ESOFT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +544,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
size_t sptr = 0;
|
size_t sptr = 0;
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (sptr + 16 > maxdatalen) {
|
if (sptr + 16 > maxdatalen) {
|
||||||
retval = 5;
|
retval = PM3_EMALLOC;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +566,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
size_t sptr = 0;
|
size_t sptr = 0;
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (sptr + 4 > maxdatalen) {
|
if (sptr + 4 > maxdatalen) {
|
||||||
retval = 5;
|
retval = PM3_EMALLOC;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +588,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
size_t sptr = 0;
|
size_t sptr = 0;
|
||||||
for (size_t i = 0; i < (maxdatalen / 4); i++) {
|
for (size_t i = 0; i < (maxdatalen / 4); i++) {
|
||||||
if (sptr + 4 > maxdatalen) {
|
if (sptr + 4 > maxdatalen) {
|
||||||
retval = 5;
|
retval = PM3_EMALLOC;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,6 +606,27 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
*datalen = sptr;
|
*datalen = sptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(ctype, "iclass")) {
|
||||||
|
size_t sptr = 0;
|
||||||
|
for (size_t i = 0; i < (maxdatalen / 8); i++) {
|
||||||
|
if (sptr + 8 > maxdatalen) {
|
||||||
|
retval = PM3_EMALLOC;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[30] = {0};
|
||||||
|
sprintf(path, "$.blocks.%zu", i);
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
JsonLoadBufAsHex(root, path, &udata[sptr], 8, &len);
|
||||||
|
if (!len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
sptr += len;
|
||||||
|
}
|
||||||
|
*datalen = sptr;
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName);
|
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName);
|
||||||
out:
|
out:
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
|
@ -516,10 +636,10 @@ out:
|
||||||
|
|
||||||
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) {
|
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) {
|
||||||
|
|
||||||
|
if (data == NULL) return PM3_EINVARG;
|
||||||
if (data == NULL) return 1;
|
char *path;
|
||||||
char *fileName = filenamemcopy(preferredName, ".dic");
|
if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS)
|
||||||
if (fileName == NULL) return 1;
|
return PM3_EFILE;
|
||||||
|
|
||||||
// t5577 == 4bytes
|
// t5577 == 4bytes
|
||||||
// mifare == 6 bytes
|
// mifare == 6 bytes
|
||||||
|
@ -537,9 +657,9 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
|
||||||
size_t counter = 0;
|
size_t counter = 0;
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
FILE *f = fopen(fileName, "r");
|
FILE *f = fopen(path, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
|
||||||
retval = PM3_EFILE;
|
retval = PM3_EFILE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -571,12 +691,98 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
|
||||||
counter += (keylen >> 1);
|
counter += (keylen >> 1);
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName);
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
|
||||||
|
|
||||||
if (datalen)
|
if (datalen)
|
||||||
*datalen = counter;
|
*datalen = counter;
|
||||||
out:
|
out:
|
||||||
free(fileName);
|
free(path);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) {
|
||||||
|
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
|
char *path;
|
||||||
|
if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS)
|
||||||
|
return PM3_EFILE;
|
||||||
|
|
||||||
|
// t5577 == 4bytes
|
||||||
|
// mifare == 6 bytes
|
||||||
|
// iclass == 8 bytes
|
||||||
|
// default to 6 bytes.
|
||||||
|
if (keylen != 4 && keylen != 6 && keylen != 8) {
|
||||||
|
keylen = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mem_size;
|
||||||
|
size_t block_size = 10 * keylen;
|
||||||
|
|
||||||
|
// double up since its chars
|
||||||
|
keylen <<= 1;
|
||||||
|
|
||||||
|
char line[255];
|
||||||
|
|
||||||
|
// allocate some space for the dictionary
|
||||||
|
*pdata = calloc(block_size, sizeof(uint8_t));
|
||||||
|
if (*pdata == NULL)
|
||||||
|
return PM3_EFILE;
|
||||||
|
|
||||||
|
mem_size = block_size;
|
||||||
|
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
if (!f) {
|
||||||
|
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
|
||||||
|
retval = PM3_EFILE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file
|
||||||
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
|
||||||
|
// check if we have enough space (if not allocate more)
|
||||||
|
if ((*keycnt * (keylen >> 1)) >= mem_size) {
|
||||||
|
|
||||||
|
mem_size += block_size;
|
||||||
|
*pdata = realloc(*pdata, mem_size);
|
||||||
|
|
||||||
|
if (*pdata == NULL) {
|
||||||
|
return PM3_EFILE;
|
||||||
|
} else {
|
||||||
|
memset(*pdata + (mem_size - block_size), 0, block_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add null terminator
|
||||||
|
line[keylen] = 0;
|
||||||
|
|
||||||
|
// smaller keys than expected is skipped
|
||||||
|
if (strlen(line) < keylen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// The line start with # is comment, skip
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!isxdigit(line[0])) {
|
||||||
|
PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t key = strtoull(line, NULL, 16);
|
||||||
|
|
||||||
|
num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1)));
|
||||||
|
|
||||||
|
(*keycnt)++;
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(path);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +818,211 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int filelist(const char *path, const char *ext, bool last, bool tentative) {
|
||||||
|
struct dirent **namelist;
|
||||||
|
int n;
|
||||||
|
|
||||||
#else //if we're on ARM
|
n = scandir(path, &namelist, NULL, alphasort);
|
||||||
|
if (n == -1) {
|
||||||
|
if (!tentative)
|
||||||
|
PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path);
|
||||||
|
for (uint16_t i = 0; i < n; i++) {
|
||||||
|
if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) {
|
||||||
|
PrintAndLogEx(NORMAL, "%s %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name);
|
||||||
|
}
|
||||||
|
free(namelist[i]);
|
||||||
|
}
|
||||||
|
free(namelist);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int searchAndList(const char *pm3dir, const char *ext) {
|
||||||
|
// display in same order as searched by searchFile
|
||||||
|
// try pm3 dirs in current workdir (dev mode)
|
||||||
|
if (get_my_executable_directory() != NULL) {
|
||||||
|
char script_directory_path[strlen(get_my_executable_directory()) + strlen(pm3dir) + 1];
|
||||||
|
strcpy(script_directory_path, get_my_executable_directory());
|
||||||
|
strcat(script_directory_path, pm3dir);
|
||||||
|
filelist(script_directory_path, ext, false, true);
|
||||||
|
}
|
||||||
|
// try pm3 dirs in user .proxmark3 (user mode)
|
||||||
|
const char *user_path = get_my_user_directory();
|
||||||
|
if (user_path != NULL) {
|
||||||
|
char script_directory_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1];
|
||||||
|
strcpy(script_directory_path, user_path);
|
||||||
|
strcat(script_directory_path, PM3_USER_DIRECTORY);
|
||||||
|
strcat(script_directory_path, pm3dir);
|
||||||
|
filelist(script_directory_path, ext, false, false);
|
||||||
|
}
|
||||||
|
// try pm3 dirs in pm3 installation dir (install mode)
|
||||||
|
const char *exec_path = get_my_executable_directory();
|
||||||
|
if (exec_path != NULL) {
|
||||||
|
char script_directory_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + 1];
|
||||||
|
strcpy(script_directory_path, exec_path);
|
||||||
|
strcat(script_directory_path, PM3_SHARE_RELPATH);
|
||||||
|
strcat(script_directory_path, pm3dir);
|
||||||
|
filelist(script_directory_path, ext, true, false);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname, bool silent) {
|
||||||
|
if ((foundpath == NULL) || (pm3dir == NULL) || (searchname == NULL)) return PM3_ESOFT;
|
||||||
|
// explicit absolute (/) or relative path (./) => try only to match it directly
|
||||||
|
char *filename = calloc(strlen(searchname) + 1, sizeof(char));
|
||||||
|
if (filename == NULL) return PM3_EMALLOC;
|
||||||
|
strcpy(filename, searchname);
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Searching %s", filename);
|
||||||
|
}
|
||||||
|
if (((strlen(filename) > 1) && (filename[0] == '/')) ||
|
||||||
|
((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) {
|
||||||
|
if (fileExists(filename)) {
|
||||||
|
*foundpath = filename;
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Found %s", *foundpath);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
|
||||||
|
// try implicit relative path
|
||||||
|
{
|
||||||
|
if (fileExists(filename)) {
|
||||||
|
*foundpath = filename;
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Found %s", *foundpath);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// try pm3 dirs in user .proxmark3 (user mode)
|
||||||
|
const char *user_path = get_my_user_directory();
|
||||||
|
if (user_path != NULL) {
|
||||||
|
char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
||||||
|
if (path == NULL)
|
||||||
|
goto out;
|
||||||
|
strcpy(path, user_path);
|
||||||
|
strcat(path, PM3_USER_DIRECTORY);
|
||||||
|
strcat(path, pm3dir);
|
||||||
|
strcat(path, filename);
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Searching %s", path);
|
||||||
|
}
|
||||||
|
if (fileExists(path)) {
|
||||||
|
free(filename);
|
||||||
|
*foundpath = path;
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Found %s", *foundpath);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else {
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// try pm3 dirs in current client workdir (dev mode)
|
||||||
|
const char *exec_path = get_my_executable_directory();
|
||||||
|
if ((exec_path != NULL) &&
|
||||||
|
((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) {
|
||||||
|
char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
||||||
|
if (path == NULL)
|
||||||
|
goto out;
|
||||||
|
strcpy(path, exec_path);
|
||||||
|
strcat(path, pm3dir);
|
||||||
|
strcat(path, filename);
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Searching %s", path);
|
||||||
|
}
|
||||||
|
if (fileExists(path)) {
|
||||||
|
free(filename);
|
||||||
|
*foundpath = path;
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Found %s", *foundpath);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else {
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// try pm3 dirs in current repo workdir (dev mode)
|
||||||
|
if ((exec_path != NULL) &&
|
||||||
|
((strcmp(TRACES_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(FIRMWARES_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(BOOTROM_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(FULLIMAGE_SUBDIR, pm3dir) == 0))) {
|
||||||
|
char *above = "../";
|
||||||
|
char *path = calloc(strlen(exec_path) + strlen(above) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
||||||
|
if (path == NULL)
|
||||||
|
goto out;
|
||||||
|
strcpy(path, exec_path);
|
||||||
|
strcat(path, above);
|
||||||
|
strcat(path, pm3dir);
|
||||||
|
strcat(path, filename);
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Searching %s", path);
|
||||||
|
}
|
||||||
|
if (fileExists(path)) {
|
||||||
|
free(filename);
|
||||||
|
*foundpath = path;
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Found %s", *foundpath);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else {
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// try pm3 dirs in pm3 installation dir (install mode)
|
||||||
|
{
|
||||||
|
char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
||||||
|
if (path == NULL)
|
||||||
|
goto out;
|
||||||
|
strcpy(path, exec_path);
|
||||||
|
strcat(path, PM3_SHARE_RELPATH);
|
||||||
|
strcat(path, pm3dir);
|
||||||
|
strcat(path, filename);
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Searching %s", path);
|
||||||
|
}
|
||||||
|
if (fileExists(path)) {
|
||||||
|
free(filename);
|
||||||
|
*foundpath = path;
|
||||||
|
if ((g_debugMode == 2) && (!silent)) {
|
||||||
|
PrintAndLogEx(INFO, "Found %s", *foundpath);
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
} else {
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(filename);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) {
|
||||||
|
if (foundpath == NULL)
|
||||||
|
return PM3_EINVARG;
|
||||||
|
char *filename = filenamemcopy(searchname, suffix);
|
||||||
|
if (filename == NULL) return PM3_EMALLOC;
|
||||||
|
int res = searchFinalFile(foundpath, pm3dir, filename, silent);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
if ((res == PM3_EFILE) && (!silent))
|
||||||
|
PrintAndLogEx(FAILED, "Error - can't find %s", filename);
|
||||||
|
free(filename);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
free(filename);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
|
@ -38,17 +38,16 @@
|
||||||
#ifndef FILEUTILS_H
|
#ifndef FILEUTILS_H
|
||||||
#define FILEUTILS_H
|
#define FILEUTILS_H
|
||||||
|
|
||||||
#ifndef ON_DEVICE
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "../ui.h"
|
#include "ui.h"
|
||||||
#include "../emv/emvjson.h"
|
#include "emv/emvjson.h"
|
||||||
#include "mifare/mifare4.h"
|
#include "mifare/mifare4.h"
|
||||||
|
#include "mifare/mifarehost.h"
|
||||||
#include "cmdhfmfu.h"
|
#include "cmdhfmfu.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -56,12 +55,20 @@ typedef enum {
|
||||||
jsfCardMemory,
|
jsfCardMemory,
|
||||||
jsfMfuMemory,
|
jsfMfuMemory,
|
||||||
jsfHitag,
|
jsfHitag,
|
||||||
|
jsfIclass,
|
||||||
// jsf14b,
|
// jsf14b,
|
||||||
// jsf15,
|
// jsf15,
|
||||||
// jsfLegic,
|
// jsfLegic,
|
||||||
// jsfT55xx,
|
// jsfT55xx,
|
||||||
} JSONFileType;
|
} JSONFileType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BIN = 0,
|
||||||
|
EML,
|
||||||
|
JSON,
|
||||||
|
DICTIONARY,
|
||||||
|
} DumpFileType_t;
|
||||||
|
|
||||||
int fileExists(const char *filename);
|
int fileExists(const char *filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +110,17 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
|
||||||
*/
|
*/
|
||||||
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen);
|
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen);
|
||||||
|
|
||||||
/** STUB
|
/**
|
||||||
|
* @brief Utility function to save a keydump.
|
||||||
|
*
|
||||||
|
* @param sectorsCnt the used sectors
|
||||||
|
* @param e_sector the keys in question
|
||||||
|
* @param fptr string pointer to the filename
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr);
|
||||||
|
|
||||||
|
/**
|
||||||
* @brief Utility function to load data from a binary file. This method takes a preferred name.
|
* @brief Utility function to load data from a binary file. This method takes a preferred name.
|
||||||
* E.g. dumpdata-15.bin
|
* E.g. dumpdata-15.bin
|
||||||
*
|
*
|
||||||
|
@ -112,10 +129,22 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
|
||||||
* @param data The data array to store the loaded bytes from file
|
* @param data The data array to store the loaded bytes from file
|
||||||
* @param maxdatalen the number of bytes that your data array has
|
* @param maxdatalen the number of bytes that your data array has
|
||||||
* @param datalen the number of bytes loaded from file
|
* @param datalen the number of bytes loaded from file
|
||||||
* @return 0 for ok, 1 for failz
|
* @return PM3_SUCCESS for ok, PM3_E* for failz
|
||||||
*/
|
*/
|
||||||
int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen);
|
int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to load data from a binary file. This method takes a preferred name.
|
||||||
|
* E.g. dumpdata-15.bin, tries to search for it, and allocated memory.
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param suffix the file suffix. Including the ".".
|
||||||
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
* @param datalen the number of bytes loaded from file
|
||||||
|
* @return PM3_SUCCESS for ok, PM3_E* for failz
|
||||||
|
*/
|
||||||
|
int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen);
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to load data from a textfile (EML). This method takes a preferred name.
|
* @brief Utility function to load data from a textfile (EML). This method takes a preferred name.
|
||||||
* E.g. dumpdata-15.txt
|
* E.g. dumpdata-15.txt
|
||||||
|
@ -139,10 +168,9 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen);
|
||||||
*/
|
*/
|
||||||
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen);
|
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name.
|
* @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name.
|
||||||
* E.g. default_keys.dic
|
* E.g. mfc_default_keys.dic
|
||||||
*
|
*
|
||||||
* @param preferredName
|
* @param preferredName
|
||||||
* @param data The data array to store the loaded bytes from file
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
@ -153,6 +181,17 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
*/
|
*/
|
||||||
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt);
|
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name.
|
||||||
|
* E.g. mfc_default_keys.dic
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param pdata A pointer to a pointer (for reverencing the loaded dictionary)
|
||||||
|
* @param keylen the number of bytes a key per row is
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to check and convert old mfu dump format to new
|
* @brief Utility function to check and convert old mfu dump format to new
|
||||||
*
|
*
|
||||||
|
@ -162,20 +201,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
|
||||||
*/
|
*/
|
||||||
int convertOldMfuDump(uint8_t **dump, size_t *dumplen);
|
int convertOldMfuDump(uint8_t **dump, size_t *dumplen);
|
||||||
|
|
||||||
#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args)
|
int searchAndList(const char *pm3dir, const char *ext);
|
||||||
#else
|
int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent);
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility function to print to console. This is used consistently within the library instead
|
|
||||||
* of printf, but it actually only calls printf. The reason to have this method is to
|
|
||||||
*make it simple to plug this library into proxmark, which has this function already to
|
|
||||||
* write also to a logfile. When doing so, just point this function to use PrintAndLog
|
|
||||||
* @param fmt
|
|
||||||
*/
|
|
||||||
#define PrintAndLogEx(level, format, args...) { }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //ON_DEVICE
|
|
||||||
|
|
||||||
#endif // FILEUTILS_H
|
#endif // FILEUTILS_H
|
|
@ -83,7 +83,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||||
ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t));
|
ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t));
|
||||||
if (!ctx->segments) {
|
if (!ctx->segments) {
|
||||||
PrintAndLogEx(ERR, "Out of memory");
|
PrintAndLogEx(ERR, "Out of memory");
|
||||||
return -1;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
ctx->num_segs = 0;
|
ctx->num_segs = 0;
|
||||||
seg = ctx->segments;
|
seg = ctx->segments;
|
||||||
|
@ -113,19 +113,19 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||||
if (filesz != memsz) {
|
if (filesz != memsz) {
|
||||||
PrintAndLogEx(ERR, "Error: PHDR file size does not equal memory size\n"
|
PrintAndLogEx(ERR, "Error: PHDR file size does not equal memory size\n"
|
||||||
"(DATA+BSS PHDRs do not make sense on ROM platforms!)");
|
"(DATA+BSS PHDRs do not make sense on ROM platforms!)");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
if (paddr < last_end) {
|
if (paddr < last_end) {
|
||||||
PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap");
|
PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
if (paddr < FLASH_START || (paddr + filesz) > flash_end) {
|
if (paddr < FLASH_START || (paddr + filesz) > flash_end) {
|
||||||
PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash");
|
PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) {
|
if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) {
|
||||||
PrintAndLogEx(ERR, "Error: Flash VMA segment is writable");
|
PrintAndLogEx(ERR, "Error: Flash VMA segment is writable");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
@ -133,12 +133,12 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||||
data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t));
|
data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t));
|
||||||
if (!data) {
|
if (!data) {
|
||||||
PrintAndLogEx(ERR, "Error: Out of memory");
|
PrintAndLogEx(ERR, "Error: Out of memory");
|
||||||
return -1;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
if (fseek(fd, offset, SEEK_SET) < 0 || fread(data, 1, filesz, fd) != filesz) {
|
if (fseek(fd, offset, SEEK_SET) < 0 || fread(data, 1, filesz, fd) != filesz) {
|
||||||
PrintAndLogEx(ERR, "Error while reading PHDR payload");
|
PrintAndLogEx(ERR, "Error while reading PHDR payload");
|
||||||
free(data);
|
free(data);
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t block_offset = paddr & (BLOCK_SIZE - 1);
|
uint32_t block_offset = paddr & (BLOCK_SIZE - 1);
|
||||||
|
@ -157,7 +157,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||||
if (!new_data) {
|
if (!new_data) {
|
||||||
PrintAndLogEx(ERR, "Error: Out of memory");
|
PrintAndLogEx(ERR, "Error: Out of memory");
|
||||||
free(data);
|
free(data);
|
||||||
return -1;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
memset(new_data, 0xff, new_length);
|
memset(new_data, 0xff, new_length);
|
||||||
memcpy(new_data, prev_seg->data, prev_seg->length);
|
memcpy(new_data, prev_seg->data, prev_seg->length);
|
||||||
|
@ -191,7 +191,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||||
last_end = paddr + filesz;
|
last_end = paddr + filesz;
|
||||||
phdr++;
|
phdr++;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity check segments and check for bootloader writes
|
// Sanity check segments and check for bootloader writes
|
||||||
|
@ -201,26 +201,26 @@ static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) {
|
||||||
|
|
||||||
if (seg->start & (BLOCK_SIZE - 1)) {
|
if (seg->start & (BLOCK_SIZE - 1)) {
|
||||||
PrintAndLogEx(ERR, "Error: Segment is not aligned");
|
PrintAndLogEx(ERR, "Error: Segment is not aligned");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
if (seg->start < FLASH_START) {
|
if (seg->start < FLASH_START) {
|
||||||
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
if (seg->start + seg->length > flash_end) {
|
if (seg->start + seg->length > flash_end) {
|
||||||
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
if (!can_write_bl && seg->start < BOOTLOADER_END) {
|
if (!can_write_bl && seg->start < BOOTLOADER_END) {
|
||||||
PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled");
|
PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled");
|
||||||
return -1;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) {
|
if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) {
|
||||||
PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds");
|
PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds");
|
||||||
return -1;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load an ELF file and prepare it for flashing
|
// Load an ELF file and prepare it for flashing
|
||||||
|
@ -230,11 +230,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
Elf32_Phdr *phdrs = NULL;
|
Elf32_Phdr *phdrs = NULL;
|
||||||
uint16_t num_phdrs;
|
uint16_t num_phdrs;
|
||||||
uint32_t flash_end = FLASH_START + flash_size;
|
uint32_t flash_end = FLASH_START + flash_size;
|
||||||
int res;
|
int res = PM3_EUNDEF;
|
||||||
|
|
||||||
fd = fopen(name, "rb");
|
fd = fopen(name, "rb");
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name);
|
PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name);
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,28 +243,34 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
|
|
||||||
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
||||||
PrintAndLogEx(ERR, "Error while reading ELF file header");
|
PrintAndLogEx(ERR, "Error while reading ELF file header");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident))
|
if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident))
|
||||||
|| le32(ehdr.e_version) != 1) {
|
|| le32(ehdr.e_version) != 1) {
|
||||||
PrintAndLogEx(ERR, "Not an ELF file or wrong ELF type");
|
PrintAndLogEx(ERR, "Not an ELF file or wrong ELF type");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (le16(ehdr.e_type) != ET_EXEC) {
|
if (le16(ehdr.e_type) != ET_EXEC) {
|
||||||
PrintAndLogEx(ERR, "ELF is not executable");
|
PrintAndLogEx(ERR, "ELF is not executable");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (le16(ehdr.e_machine) != EM_ARM) {
|
if (le16(ehdr.e_machine) != EM_ARM) {
|
||||||
PrintAndLogEx(ERR, "Wrong ELF architecture");
|
PrintAndLogEx(ERR, "Wrong ELF architecture");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!ehdr.e_phnum || !ehdr.e_phoff) {
|
if (!ehdr.e_phnum || !ehdr.e_phoff) {
|
||||||
PrintAndLogEx(ERR, "ELF has no PHDRs");
|
PrintAndLogEx(ERR, "ELF has no PHDRs");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
|
if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
|
||||||
// could be a structure padding issue...
|
// could be a structure padding issue...
|
||||||
PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail");
|
PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
num_phdrs = le16(ehdr.e_phnum);
|
num_phdrs = le16(ehdr.e_phnum);
|
||||||
|
@ -271,28 +278,31 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||||
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
|
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
|
||||||
if (!phdrs) {
|
if (!phdrs) {
|
||||||
PrintAndLogEx(ERR, "Out of memory");
|
PrintAndLogEx(ERR, "Out of memory");
|
||||||
|
res = PM3_EMALLOC;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) {
|
if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) {
|
||||||
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
||||||
|
res = PM3_EFILE;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
|
if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
|
||||||
|
res = PM3_EFILE;
|
||||||
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end);
|
res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end);
|
||||||
if (res < 0)
|
if (res != PM3_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
res = check_segs(ctx, can_write_bl, flash_end);
|
res = check_segs(ctx, can_write_bl, flash_end);
|
||||||
if (res < 0)
|
if (res != PM3_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
free(phdrs);
|
free(phdrs);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
ctx->filename = name;
|
ctx->filename = name;
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (phdrs)
|
if (phdrs)
|
||||||
|
@ -300,7 +310,7 @@ fail:
|
||||||
if (fd)
|
if (fd)
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
flash_free(ctx);
|
flash_free(ctx);
|
||||||
return -1;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the state of the proxmark, backwards compatible
|
// Get the state of the proxmark, backwards compatible
|
||||||
|
@ -326,22 +336,23 @@ static int get_proxmark_state(uint32_t *state) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd);
|
PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd);
|
||||||
return -1;
|
return PM3_EFATAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter the bootloader to be able to start flashing
|
// Enter the bootloader to be able to start flashing
|
||||||
static int enter_bootloader(char *serial_port_name) {
|
static int enter_bootloader(char *serial_port_name) {
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (get_proxmark_state(&state) < 0)
|
if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS)
|
||||||
return -1;
|
return ret;
|
||||||
|
|
||||||
/* Already in flash state, we're done. */
|
/* Already in flash state, we're done. */
|
||||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)
|
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
||||||
PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader..."));
|
PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader..."));
|
||||||
|
@ -364,15 +375,15 @@ static int enter_bootloader(char *serial_port_name) {
|
||||||
|
|
||||||
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
|
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
|
||||||
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
|
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found.");
|
PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found.");
|
||||||
return -1;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode");
|
PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode");
|
||||||
return -1;
|
return PM3_EFATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_for_ack(PacketResponseNG *ack) {
|
static int wait_for_ack(PacketResponseNG *ack) {
|
||||||
|
@ -383,9 +394,9 @@ static int wait_for_ack(PacketResponseNG *ack) {
|
||||||
ack->cmd,
|
ack->cmd,
|
||||||
(ack->cmd == CMD_NACK) ? "NACK" : ""
|
(ack->cmd == CMD_NACK) ? "NACK" : ""
|
||||||
);
|
);
|
||||||
return -1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flash_suggest_update_bootloader(void) {
|
static void flash_suggest_update_bootloader(void) {
|
||||||
|
@ -401,12 +412,15 @@ static void flash_suggest_update_flasher(void) {
|
||||||
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
|
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
uint32_t chipinfo = 0;
|
uint32_t chipinfo = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (enter_bootloader(serial_port_name) < 0)
|
ret = enter_bootloader(serial_port_name);
|
||||||
return -1;
|
if (ret != PM3_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (get_proxmark_state(&state) < 0)
|
ret = get_proxmark_state(&state);
|
||||||
return -1;
|
if (ret != PM3_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
|
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
|
||||||
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
|
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
|
||||||
|
@ -485,7 +499,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
||||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command")));
|
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command")));
|
||||||
flash_suggest_update_bootloader();
|
flash_suggest_update_bootloader();
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_block(uint32_t address, uint8_t *data, uint32_t length) {
|
static int write_block(uint32_t address, uint8_t *data, uint32_t length) {
|
||||||
|
@ -531,7 +545,7 @@ int flash_write(flash_file_t *ctx) {
|
||||||
|
|
||||||
if (write_block(baddr, data, block_size) < 0) {
|
if (write_block(baddr, data, block_size) < 0) {
|
||||||
PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks);
|
PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks);
|
||||||
return -1;
|
return PM3_EFATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data += block_size;
|
data += block_size;
|
||||||
|
@ -544,7 +558,7 @@ int flash_write(flash_file_t *ctx) {
|
||||||
PrintAndLogEx(NORMAL, " " _GREEN_("OK"));
|
PrintAndLogEx(NORMAL, " " _GREEN_("OK"));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// free a file context
|
// free a file context
|
||||||
|
@ -564,5 +578,5 @@ void flash_free(flash_file_t *ctx) {
|
||||||
int flash_stop_flashing(void) {
|
int flash_stop_flashing(void) {
|
||||||
SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0);
|
SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define FLASH_MAX_FILES 4
|
||||||
|
#define ONE_KB 1024
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *data;
|
void *data;
|
||||||
uint32_t start;
|
uint32_t start;
|
||||||
|
|
130
client/flasher.c
130
client/flasher.c
|
@ -1,130 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
||||||
// the license.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Flasher frontend tool
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "usart_defs.h"
|
|
||||||
#include "flash.h"
|
|
||||||
#include "comms.h"
|
|
||||||
#include "ui.h"
|
|
||||||
|
|
||||||
#define MAX_FILES 4
|
|
||||||
#define ONE_KB 1024
|
|
||||||
|
|
||||||
static void usage(char *argv0) {
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: %s <port> [-b] image.elf [image.elf...]", argv0);
|
|
||||||
PrintAndLogEx(NORMAL, " %s <port> -i\n", argv0);
|
|
||||||
PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)");
|
|
||||||
PrintAndLogEx(NORMAL, "\t-i\tProbe the connected Proxmark3 to retrieve its memory size");
|
|
||||||
PrintAndLogEx(NORMAL, "\nExamples:\n\t %s "SERIAL_PORT_EXAMPLE_H" -i", argv0);
|
|
||||||
PrintAndLogEx(NORMAL, "\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0);
|
|
||||||
#ifdef __linux__
|
|
||||||
PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on <DEVICE>',");
|
|
||||||
PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:");
|
|
||||||
PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md");
|
|
||||||
PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:");
|
|
||||||
PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux");
|
|
||||||
PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux");
|
|
||||||
PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int can_write_bl = 0;
|
|
||||||
int num_files = 0;
|
|
||||||
int res;
|
|
||||||
int ret = 0;
|
|
||||||
flash_file_t files[MAX_FILES];
|
|
||||||
char *filenames[MAX_FILES];
|
|
||||||
bool info = false;
|
|
||||||
memset(files, 0, sizeof(files));
|
|
||||||
|
|
||||||
session.supports_colors = false;
|
|
||||||
session.stdinOnTTY = isatty(STDIN_FILENO);
|
|
||||||
session.stdoutOnTTY = isatty(STDOUT_FILENO);
|
|
||||||
#if defined(__linux__) || (__APPLE__)
|
|
||||||
if (session.stdinOnTTY && session.stdoutOnTTY)
|
|
||||||
session.supports_colors = true;
|
|
||||||
#endif
|
|
||||||
session.help_dump_mode = false;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
usage(argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 2; i < argc; i++) {
|
|
||||||
if (argv[i][0] == '-') {
|
|
||||||
if (!strcmp(argv[i], "-b")) {
|
|
||||||
can_write_bl = 1;
|
|
||||||
} else if (!strcmp(argv[i], "-i")) {
|
|
||||||
info = true;
|
|
||||||
} else {
|
|
||||||
usage(argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
filenames[num_files] = argv[i];
|
|
||||||
num_files++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *serial_port_name = argv[1];
|
|
||||||
|
|
||||||
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
|
|
||||||
PrintAndLogEx(NORMAL, _GREEN_("Found"));
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t max_allowed = 0;
|
|
||||||
res = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed);
|
|
||||||
if (res < 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < num_files; ++i) {
|
|
||||||
res = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB);
|
|
||||||
if (res < 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing..."));
|
|
||||||
|
|
||||||
for (int i = 0; i < num_files; i++) {
|
|
||||||
res = flash_write(&files[i]);
|
|
||||||
if (res < 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
flash_free(&files[i]);
|
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
finish:
|
|
||||||
res = flash_stop_flashing();
|
|
||||||
if (res < 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
CloseProxmark();
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
PrintAndLogEx(SUCCESS, _BLUE_("All done."));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "Aborted on error.");
|
|
||||||
PrintAndLogEx(NORMAL, "\nHave a nice day!");
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -65,11 +65,13 @@ THE SOFTWARE.
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "crapto1/crapto1.h"
|
#include "crapto1/crapto1.h"
|
||||||
#include "parity.h"
|
#include "parity.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
#define NUM_BRUTE_FORCE_THREADS (num_CPUs())
|
#define NUM_BRUTE_FORCE_THREADS (num_CPUs())
|
||||||
#define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed
|
#define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed
|
||||||
#define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark
|
#define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark
|
||||||
#define TEST_BENCH_FILENAME "hardnested/bf_bench_data.bin"
|
#define TEST_BENCH_FILENAME "hardnested_bf_bench_data.bin"
|
||||||
//#define WRITE_BENCH_FILE
|
//#define WRITE_BENCH_FILE
|
||||||
|
|
||||||
// debugging options
|
// debugging options
|
||||||
|
@ -265,8 +267,12 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) {
|
||||||
#if defined (WRITE_BENCH_FILE)
|
#if defined (WRITE_BENCH_FILE)
|
||||||
static void write_benchfile(statelist_t *candidates) {
|
static void write_benchfile(statelist_t *candidates) {
|
||||||
|
|
||||||
printf("Writing brute force benchmark data...");
|
PrintAndLogEx(NORMAL, "Writing brute force benchmark data in " RESOURCES_SUBDIR " subdirectory...");
|
||||||
FILE *benchfile = fopen(TEST_BENCH_FILENAME, "wb");
|
FILE *benchfile = fopen(RESOURCES_SUBDIR TEST_BENCH_FILENAME, "wb");
|
||||||
|
if (benchfile == NULL) {
|
||||||
|
PrintAndLogEx(ERR, "Can't write " RESOURCES_SUBDIR TEST_BENCH_FILENAME", abort!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
fwrite(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile);
|
fwrite(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile);
|
||||||
for (uint32_t i = 0; i < nonces_to_bruteforce; i++) {
|
for (uint32_t i = 0; i < nonces_to_bruteforce; i++) {
|
||||||
fwrite(&(bf_test_nonce[i]), 1, sizeof(bf_test_nonce[i]), benchfile);
|
fwrite(&(bf_test_nonce[i]), 1, sizeof(bf_test_nonce[i]), benchfile);
|
||||||
|
@ -283,7 +289,7 @@ static void write_benchfile(statelist_t *candidates) {
|
||||||
fwrite(&(candidates->states[ODD_STATE][i]), 1, sizeof(uint32_t), benchfile);
|
fwrite(&(candidates->states[ODD_STATE][i]), 1, sizeof(uint32_t), benchfile);
|
||||||
}
|
}
|
||||||
fclose(benchfile);
|
fclose(benchfile);
|
||||||
printf("done.\n");
|
PrintAndLogEx(NORMAL, "Done");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -360,14 +366,17 @@ static bool read_bench_data(statelist_t *test_candidates) {
|
||||||
uint32_t num_states = 0;
|
uint32_t num_states = 0;
|
||||||
uint32_t states_read = 0;
|
uint32_t states_read = 0;
|
||||||
|
|
||||||
char bench_file_path[strlen(get_my_executable_directory()) + strlen(TEST_BENCH_FILENAME) + 1];
|
char *path;
|
||||||
strcpy(bench_file_path, get_my_executable_directory());
|
if (searchFile(&path, RESOURCES_SUBDIR, TEST_BENCH_FILENAME, "", false) != PM3_SUCCESS) {
|
||||||
strcat(bench_file_path, TEST_BENCH_FILENAME);
|
|
||||||
|
|
||||||
FILE *benchfile = fopen(bench_file_path, "rb");
|
|
||||||
if (benchfile == NULL) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE *benchfile = fopen(path, "rb");
|
||||||
|
if (benchfile == NULL) {
|
||||||
|
free(path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile);
|
bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile);
|
||||||
if (bytes_read != sizeof(nonces_to_bruteforce)) {
|
if (bytes_read != sizeof(nonces_to_bruteforce)) {
|
||||||
fclose(benchfile);
|
fclose(benchfile);
|
||||||
|
|
|
@ -1,81 +1,21 @@
|
||||||
# Hide full compilation line:
|
MYSRCPATHS =
|
||||||
ifneq ($(V),1)
|
MYINCLUDES = -I.
|
||||||
Q?=@
|
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE -Wno-unused-function
|
||||||
endif
|
MYDEFS = -DHAVE_STDINT_H
|
||||||
# To see full command lines, use make V=1
|
MYSRCS = \
|
||||||
|
|
||||||
include_HEADERS = jansson.h
|
|
||||||
nodist_include_HEADERS = jansson_config.h
|
|
||||||
|
|
||||||
LIB_A = libjansson.a
|
|
||||||
libjansson_la_SOURCES = \
|
|
||||||
dump.c \
|
dump.c \
|
||||||
error.c \
|
error.c \
|
||||||
hashtable.c \
|
hashtable.c \
|
||||||
hashtable.h \
|
|
||||||
hashtable_seed.c \
|
hashtable_seed.c \
|
||||||
jansson_private.h \
|
|
||||||
load.c \
|
load.c \
|
||||||
lookup3.h \
|
|
||||||
memory.c \
|
memory.c \
|
||||||
pack_unpack.c \
|
pack_unpack.c \
|
||||||
strbuffer.c \
|
strbuffer.c \
|
||||||
strbuffer.h \
|
|
||||||
strconv.c \
|
strconv.c \
|
||||||
utf.c \
|
utf.c \
|
||||||
utf.h \
|
|
||||||
path.c \
|
path.c \
|
||||||
value.c
|
value.c
|
||||||
libjansson_la_LDFLAGS = \
|
|
||||||
-no-undefined \
|
|
||||||
-export-symbols-regex '^json_' \
|
|
||||||
-version-info 15:0:11
|
|
||||||
|
|
||||||
|
LIB_A = libjansson.a
|
||||||
|
|
||||||
CFILES = $(filter %.c, $(libjansson_la_SOURCES))
|
include ../../Makefile.host
|
||||||
CMDOBJS = $(CFILES:%.c=%.o)
|
|
||||||
CLEAN = $(CMDOBJS)
|
|
||||||
|
|
||||||
platform = $(shell uname)
|
|
||||||
|
|
||||||
CC= gcc
|
|
||||||
CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function
|
|
||||||
|
|
||||||
LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS)
|
|
||||||
LIBS= $(SYSLIBS) $(MYLIBS)
|
|
||||||
DEFAULT_INCLUDES = -I.
|
|
||||||
DEFS = -DHAVE_STDINT_H
|
|
||||||
|
|
||||||
ifeq ($(platform),Darwin)
|
|
||||||
AR= /usr/bin/ar rcs
|
|
||||||
RANLIB= /usr/bin/ranlib
|
|
||||||
else
|
|
||||||
AR= ar rcs
|
|
||||||
RANLIB= ranlib
|
|
||||||
endif
|
|
||||||
RM= rm -f
|
|
||||||
TST= echo
|
|
||||||
|
|
||||||
SYSLDFLAGS=
|
|
||||||
SYSLIBS=
|
|
||||||
|
|
||||||
MYLIBS=
|
|
||||||
MYOBJS=
|
|
||||||
|
|
||||||
$(LIB_A): $(CMDOBJS)
|
|
||||||
$(info [=] AR $@)
|
|
||||||
$(Q)$(AR) $(LIB_A) $(CMDOBJS)
|
|
||||||
$(Q)$(RANLIB) $(LIB_A)
|
|
||||||
|
|
||||||
all: $(LIB_A)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)$(RM) $(CLEAN)
|
|
||||||
$(Q)$(RM) $(LIB_A)
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(info [-] CC $<)
|
|
||||||
$(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS)
|
|
||||||
|
|
||||||
.PHONY: all clean
|
|
||||||
|
|
||||||
|
|
|
@ -1,106 +1,27 @@
|
||||||
# Makefile for building Lua
|
MYSRCPATHS =
|
||||||
# See ../doc/readme.html for installation and customization instructions.
|
MYINCLUDES = -I.
|
||||||
|
# Lua lib is not ready for C99 style...
|
||||||
|
#MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
|
||||||
|
MYCFLAGS =
|
||||||
|
MYDEFS = -DLUA_COMPAT_ALL $(SYSCFLAGS)
|
||||||
|
MYSRCS = lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \
|
||||||
|
lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \
|
||||||
|
ltm.c lundump.c lvm.c lzio.c \
|
||||||
|
lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c \
|
||||||
|
lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c
|
||||||
|
|
||||||
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
|
SYSCFLAGS=
|
||||||
|
|
||||||
# Hide full compilation line:
|
LIB_A= liblua.a
|
||||||
ifneq ($(V),1)
|
|
||||||
Q?=@
|
|
||||||
endif
|
|
||||||
# To see full command lines, use make V=1
|
|
||||||
|
|
||||||
# Your platform. See PLATS for possible values.
|
# Your platform. See PLATS for possible values.
|
||||||
PLAT= none
|
PLAT= none
|
||||||
|
|
||||||
platform= $(shell uname)
|
|
||||||
|
|
||||||
CC= gcc
|
|
||||||
CFLAGS= -O3 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
|
|
||||||
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
|
||||||
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
|
||||||
|
|
||||||
ifeq ($(platform),Darwin)
|
|
||||||
AR= /usr/bin/ar rc
|
|
||||||
RANLIB= /usr/bin/ranlib
|
|
||||||
else
|
|
||||||
AR= ar rc
|
|
||||||
RANLIB= ranlib
|
|
||||||
endif
|
|
||||||
RM= rm -f
|
|
||||||
|
|
||||||
SYSCFLAGS=
|
|
||||||
SYSLDFLAGS=
|
|
||||||
SYSLIBS=
|
|
||||||
|
|
||||||
MYCFLAGS=
|
|
||||||
MYLDFLAGS=
|
|
||||||
MYLIBS=
|
|
||||||
MYOBJS=
|
|
||||||
|
|
||||||
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(info [-] CC $<)
|
|
||||||
$(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
|
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
|
||||||
|
|
||||||
LUA_A= liblua.a
|
|
||||||
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
|
|
||||||
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
|
|
||||||
ltm.o lundump.o lvm.o lzio.o
|
|
||||||
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
|
|
||||||
lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o
|
|
||||||
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
|
|
||||||
|
|
||||||
LUA_T= lua
|
|
||||||
LUA_O= lua.o
|
|
||||||
|
|
||||||
LUAC_T= luac
|
|
||||||
LUAC_O= luac.o
|
|
||||||
|
|
||||||
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
|
|
||||||
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
|
|
||||||
ALL_A= $(LUA_A)
|
|
||||||
|
|
||||||
# Targets start here.
|
|
||||||
default: $(PLAT)
|
default: $(PLAT)
|
||||||
|
|
||||||
all: $(ALL_T)
|
include ../../Makefile.host
|
||||||
|
|
||||||
o: $(ALL_O)
|
|
||||||
|
|
||||||
a: $(ALL_A)
|
|
||||||
|
|
||||||
$(LUA_A): $(BASE_O)
|
|
||||||
$(info [=] AR $@)
|
|
||||||
$(Q)$(AR) $@ $(BASE_O)
|
|
||||||
$(Q)$(RANLIB) $@
|
|
||||||
|
|
||||||
$(LUA_T): $(LUA_O) $(LUA_A)
|
|
||||||
$(info [=] LD $@)
|
|
||||||
$(Q)$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
|
|
||||||
|
|
||||||
$(LUAC_T): $(LUAC_O) $(LUA_A)
|
|
||||||
$(info [=] LD $@)
|
|
||||||
$(Q)$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(Q)$(RM) $(ALL_T) $(ALL_O)
|
|
||||||
|
|
||||||
depend:
|
|
||||||
$(info GEN DEPS)
|
|
||||||
$(Q)$(CC) $(CFLAGS) -MM l*.c
|
|
||||||
|
|
||||||
echo:
|
|
||||||
@echo "PLAT= $(PLAT)"
|
|
||||||
@echo "CC= $(CC)"
|
|
||||||
@echo "CFLAGS= $(CFLAGS)"
|
|
||||||
@echo "LDFLAGS= $(SYSLDFLAGS)"
|
|
||||||
@echo "LIBS= $(LIBS)"
|
|
||||||
@echo "AR= $(AR)"
|
|
||||||
@echo "RANLIB= $(RANLIB)"
|
|
||||||
@echo "RM= $(RM)"
|
|
||||||
|
|
||||||
# Convenience targets for popular platforms
|
# Convenience targets for popular platforms
|
||||||
ALL= all
|
ALL= all
|
||||||
|
@ -110,99 +31,32 @@ none:
|
||||||
@echo " $(PLATS)"
|
@echo " $(PLATS)"
|
||||||
|
|
||||||
aix:
|
aix:
|
||||||
$(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
|
$(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN"
|
||||||
|
|
||||||
ansi:
|
ansi:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
|
||||||
|
|
||||||
bsd:
|
bsd:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN"
|
||||||
|
|
||||||
freebsd:
|
freebsd:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX"
|
||||||
|
|
||||||
generic: $(ALL)
|
generic: $(ALL)
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -ltermcap -lncurses"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX"
|
||||||
|
|
||||||
macosx:
|
macosx:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX"
|
||||||
|
|
||||||
mingw:
|
mingw:
|
||||||
$(Q)$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
|
$(Q)$(MAKE) $(ALL)
|
||||||
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
|
|
||||||
"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
|
|
||||||
$(Q)$(MAKE) "LUAC_T=luac.exe" luac.exe
|
|
||||||
|
|
||||||
posix:
|
posix:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
|
||||||
|
|
||||||
solaris:
|
solaris:
|
||||||
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl"
|
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN"
|
||||||
|
|
||||||
# list targets that do not create files (but not all makes understand .PHONY)
|
|
||||||
.PHONY: all $(PLATS) default o a clean depend echo none
|
|
||||||
|
|
||||||
# DO NOT DELETE
|
|
||||||
|
|
||||||
lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
|
|
||||||
lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \
|
|
||||||
lvm.h
|
|
||||||
lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
|
|
||||||
lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
|
|
||||||
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
|
|
||||||
lstring.h ltable.h lvm.h
|
|
||||||
lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h
|
|
||||||
ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
|
|
||||||
ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \
|
|
||||||
lfunc.h lstring.h lgc.h ltable.h lvm.h
|
|
||||||
ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
|
|
||||||
lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \
|
|
||||||
lstring.h ltable.h lundump.h lvm.h
|
|
||||||
ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
|
|
||||||
lzio.h lmem.h lundump.h
|
|
||||||
lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \
|
|
||||||
lstate.h ltm.h lzio.h lmem.h
|
|
||||||
lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
|
|
||||||
lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
|
|
||||||
linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
|
|
||||||
liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \
|
|
||||||
lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
|
|
||||||
lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
|
|
||||||
ltm.h lzio.h lmem.h ldo.h lgc.h
|
|
||||||
loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \
|
|
||||||
lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h
|
|
||||||
lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
|
|
||||||
loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
|
|
||||||
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \
|
|
||||||
lstring.h lgc.h ltable.h
|
|
||||||
lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
|
|
||||||
ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \
|
|
||||||
ltable.h
|
|
||||||
lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
|
|
||||||
ltm.h lzio.h lstring.h lgc.h
|
|
||||||
lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
|
|
||||||
ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
|
|
||||||
ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
|
|
||||||
lmem.h lstring.h lgc.h ltable.h
|
|
||||||
lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
|
|
||||||
luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \
|
|
||||||
ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
|
|
||||||
lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
|
||||||
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
|
|
||||||
lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
|
|
||||||
lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
|
|
||||||
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
|
|
||||||
lzio.h
|
|
||||||
|
|
||||||
|
.PHONY: all $(PLATS) default clean depend none
|
||||||
|
|
|
@ -226,8 +226,8 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
|
||||||
reverse_arraybytes(dest, sizeof(dest));
|
reverse_arraybytes(dest, sizeof(dest));
|
||||||
memcpy(mac, dest, 4);
|
memcpy(mac, dest, 4);
|
||||||
//free(cc_nr);
|
//free(cc_nr);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]) {
|
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]) {
|
||||||
uint8_t *address_data;
|
uint8_t *address_data;
|
||||||
uint8_t div_key[8];
|
uint8_t div_key[8];
|
||||||
|
@ -245,7 +245,6 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke
|
||||||
reverse_arraybytes(dest, sizeof(dest));
|
reverse_arraybytes(dest, sizeof(dest));
|
||||||
memcpy(mac, dest, 4);
|
memcpy(mac, dest, 4);
|
||||||
free(address_data);
|
free(address_data);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ON_DEVICE
|
#ifndef ON_DEVICE
|
||||||
|
@ -267,8 +266,8 @@ int testMAC() {
|
||||||
PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:");
|
PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:");
|
||||||
printarr(" Calculated_MAC", calculated_mac, 4);
|
printarr(" Calculated_MAC", calculated_mac, 4);
|
||||||
printarr(" Correct_MAC ", correct_MAC, 4);
|
printarr(" Correct_MAC ", correct_MAC, 4);
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#ifndef CIPHER_H
|
#ifndef CIPHER_H
|
||||||
#define CIPHER_H
|
#define CIPHER_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]);
|
void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]);
|
||||||
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]);
|
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]);
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "util.h" // sprint_hex
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
|
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
|
@ -127,18 +127,21 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) {
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t reversebytes(uint8_t b) {
|
uint8_t reversebytes(uint8_t b) {
|
||||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverse_arraybytes(uint8_t *arr, size_t len) {
|
void reverse_arraybytes(uint8_t *arr, size_t len) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < len ; i++) {
|
for (i = 0; i < len ; i++) {
|
||||||
arr[i] = reversebytes(arr[i]);
|
arr[i] = reversebytes(arr[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) {
|
void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < len ; i++) {
|
for (i = 0; i < len ; i++) {
|
||||||
|
@ -160,23 +163,14 @@ void printarr(const char *name, uint8_t *arr, int len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void printvar(const char *name, uint8_t *arr, int len) {
|
void printvar(const char *name, uint8_t *arr, int len) {
|
||||||
int cx, i;
|
PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len));
|
||||||
size_t outsize = 40 + strlen(name) + len * 2;
|
|
||||||
char *output = calloc(outsize, sizeof(char));
|
|
||||||
cx = snprintf(output, outsize, "%s = ", name);
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, output);
|
|
||||||
free(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printarr_human_readable(const char *title, uint8_t *arr, int len) {
|
void printarr_human_readable(const char *title, uint8_t *arr, int len) {
|
||||||
int cx, i;
|
int cx = 0, i;
|
||||||
size_t outsize = 100 + strlen(title) + len * 4;
|
size_t outsize = 100 + strlen(title) + len * 4;
|
||||||
char *output = calloc(outsize, sizeof(char));
|
char *output = calloc(outsize, sizeof(char));
|
||||||
cx = snprintf(output, outsize, "\n\t%s\n", title);
|
PrintAndLogEx(NORMAL, "\n %s", title);
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (i % 16 == 0)
|
if (i % 16 == 0)
|
||||||
cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i);
|
cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i);
|
||||||
|
@ -211,9 +205,9 @@ static int testBitStream() {
|
||||||
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
|
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
|
||||||
PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]);
|
PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]);
|
||||||
}
|
}
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int testReversedBitstream() {
|
static int testReversedBitstream() {
|
||||||
|
@ -241,9 +235,9 @@ static int testReversedBitstream() {
|
||||||
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
|
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
|
||||||
PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]);
|
PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]);
|
||||||
}
|
}
|
||||||
return 1;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
return 0;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
|
|
|
@ -475,11 +475,11 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) {
|
||||||
memcpy(master_key, key64, 8);
|
memcpy(master_key, key64, 8);
|
||||||
|
|
||||||
if (memcmp(z_0, result, 4) != 0) {
|
if (memcmp(z_0, result, 4) != 0) {
|
||||||
PrintAndLogEx(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong.");
|
PrintAndLogEx(WARNING, _RED_("Failed to verify") "calculated master key (k_cus)! Something is wrong.");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
PrintAndLogEx(SUCCESS, "Key verified ok!\n");
|
PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!"));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -502,11 +502,19 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||||
for (i = 0 ; i * itemsize < dumpsize ; i++) {
|
for (i = 0 ; i * itemsize < dumpsize ; i++) {
|
||||||
memcpy(attack, dump + i * itemsize, itemsize);
|
memcpy(attack, dump + i * itemsize, itemsize);
|
||||||
errors += bruteforceItem(*attack, keytable);
|
errors += bruteforceItem(*attack, keytable);
|
||||||
|
if (errors)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(attack);
|
free(attack);
|
||||||
t1 = msclock() - t1;
|
t1 = msclock() - t1;
|
||||||
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000);
|
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000);
|
||||||
|
|
||||||
|
|
||||||
|
if (errors) {
|
||||||
|
PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Pick out the first 16 bytes of the keytable.
|
// Pick out the first 16 bytes of the keytable.
|
||||||
// The keytable is now in 16-bit ints, where the upper 8 bits
|
// The keytable is now in 16-bit ints, where the upper 8 bits
|
||||||
// indicate crack-status. Those must be discarded for the
|
// indicate crack-status. Those must be discarded for the
|
||||||
|
@ -516,8 +524,10 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||||
for (i = 0 ; i < 16 ; i++) {
|
for (i = 0 ; i < 16 ; i++) {
|
||||||
first16bytes[i] = keytable[i] & 0xFF;
|
first16bytes[i] = keytable[i] & 0xFF;
|
||||||
|
|
||||||
if (!(keytable[i] & CRACKED))
|
if (!(keytable[i] & CRACKED)) {
|
||||||
PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i);
|
PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
errors += calculateMasterKey(first16bytes, NULL);
|
errors += calculateMasterKey(first16bytes, NULL);
|
||||||
return errors;
|
return errors;
|
||||||
|
@ -530,37 +540,14 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int bruteforceFile(const char *filename, uint16_t keytable[]) {
|
int bruteforceFile(const char *filename, uint16_t keytable[]) {
|
||||||
FILE *f = fopen(filename, "rb");
|
|
||||||
if (!f) {
|
size_t dumplen = 0;
|
||||||
PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename);
|
uint8_t *dump = NULL;
|
||||||
return 1;
|
if (loadFile_safe(filename, "", (void **)&dump, &dumplen) != PM3_SUCCESS) {
|
||||||
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
uint8_t res = bruteforceDump(dump, dumplen, keytable);
|
||||||
long fsize = ftell(f);
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
|
|
||||||
if (fsize <= 0) {
|
|
||||||
PrintAndLogEx(ERR, "Error, when getting filesize");
|
|
||||||
fclose(f);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
|
||||||
if (!dump) {
|
|
||||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
|
||||||
fclose(f);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
size_t bytes_read = fread(dump, 1, fsize, f);
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
if (bytes_read < fsize) {
|
|
||||||
PrintAndLogEx(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t res = bruteforceDump(dump, fsize, keytable);
|
|
||||||
free(dump);
|
free(dump);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -582,39 +569,30 @@ int bruteforceFileNoKeys(const char *filename) {
|
||||||
// TEST CODE BELOW
|
// TEST CODE BELOW
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
static int _testBruteforce() {
|
static int _testBruteforce() {
|
||||||
int errors = 0;
|
|
||||||
if (true) {
|
|
||||||
// First test
|
|
||||||
PrintAndLogEx(INFO, "Testing crack from dumpfile...");
|
|
||||||
|
|
||||||
/**
|
PrintAndLogEx(INFO, "Testing crack from dumpfile...");
|
||||||
Expected values for the dumpfile:
|
|
||||||
High Security Key Table
|
|
||||||
|
|
||||||
00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1
|
/**
|
||||||
10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21
|
Expected values for the dumpfile:
|
||||||
20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2
|
High Security Key Table
|
||||||
30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C
|
|
||||||
40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6
|
|
||||||
50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42
|
|
||||||
60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95
|
|
||||||
70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB
|
|
||||||
|
|
||||||
**** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 ****
|
00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1
|
||||||
**/
|
10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21
|
||||||
uint16_t keytable[128] = {0};
|
20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2
|
||||||
|
30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C
|
||||||
|
40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6
|
||||||
|
50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42
|
||||||
|
60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95
|
||||||
|
70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB
|
||||||
|
|
||||||
//Test a few variants
|
**** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 ****
|
||||||
if (fileExists("iclass_dump.bin")) {
|
**/
|
||||||
errors |= bruteforceFile("iclass_dump.bin", keytable);
|
uint16_t keytable[128] = {0};
|
||||||
} else if (fileExists("loclass/iclass_dump.bin")) {
|
int errors = bruteforceFile("iclass_dump.bin", keytable);
|
||||||
errors |= bruteforceFile("loclass/iclass_dump.bin", keytable);
|
if (errors) {
|
||||||
} else if (fileExists("client/loclass/iclass_dump.bin")) {
|
PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!");
|
||||||
errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable);
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(ERR, "Error: The file iclass_dump.bin was not found!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue