Merge pull request #64 from RfidResearchGroup/master

Rebase
This commit is contained in:
mwalker33 2021-03-04 16:22:23 +11:00 committed by GitHub
commit d8984626db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
273 changed files with 29981 additions and 9303 deletions

View file

@ -22,14 +22,14 @@ assignees: doegox, iceman1001
# OS compilation and tests
```bash
make clean && make -j PLATFORM=PM3OTHER && tools/pm3test.sh
make clean && make -j PLATFORM=PM3RDV4 && tools/pm3test.sh
make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && tools/pm3test.sh
make install; pushd /tmp; proxmark3 -c 'data load em4x05.pm3;lf search 1'; popd; make uninstall
make clean && make -j PLATFORM=PM3OTHER && tools/pm3_tests.sh
make clean && make -j PLATFORM=PM3RDV4 && tools/pm3_tests.sh
make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && tools/pm3_tests.sh
make install; pushd /tmp; proxmark3 -c 'data load -f em4x05.pm3;lf search 1'; popd; make uninstall
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3OTHER && PM3BIN=./proxmark3 ../../tools/pm3test.sh client )
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 && PM3BIN=./proxmark3 ../../tools/pm3test.sh client )
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && PM3BIN=./proxmark3 ../../tools/pm3test.sh client )
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3OTHER && PM3BIN=./proxmark3 ../../tools/pm3_tests.sh client )
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 && PM3BIN=./proxmark3 ../../tools/pm3_tests.sh client )
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && PM3BIN=./proxmark3 ../../tools/pm3_tests.sh client )
```
- [ ] RPI Zero

133
.github/workflows/macos.yml vendored Normal file
View file

@ -0,0 +1,133 @@
name: MacOS Build and Test
on: [push, pull_request]
jobs:
macos-make:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Set Git http.postBuffer to something high
run: git config --global http.postBuffer 524288000
- name: Handle homebrew quirks
run: rm -rf /usr/local/bin/2to3
- name: Update brew repos
run: brew update
continue-on-error: true
- name: Tap RfidResearchGroup/proxmark3
run: brew tap RfidResearchGroup/proxmark3
- name: Install dependencies
run: brew install readline qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: make clean
run: make clean
- name: Build
env:
V: 1
run: make
- name: Test
run: make check
macos-make-btaddon:
if: always()
needs: [macos-make]
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Set Git http.postBuffer to something high
run: git config --global http.postBuffer 524288000
- name: Handle homebrew quirks
run: rm -rf /usr/local/bin/2to3
- name: Update brew repos
run: brew update
continue-on-error: true
- name: Tap RfidResearchGroup/proxmark3
run: brew tap RfidResearchGroup/proxmark3
- name: Install dependencies
run: brew install readline qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: make clean
run: make clean
- name: Build
env:
V: 1
PLATFORM_EXTRAS: BTADDON
run: make
- name: Test
run: make check
macos-cmake:
if: always()
needs: [macos-make, macos-make-btaddon]
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Set Git http.postBuffer to something high
run: git config --global http.postBuffer 524288000
- name: Handle homebrew quirks
run: rm -rf /usr/local/bin/2to3
- name: Update brew repos
run: brew update
continue-on-error: true
- name: Tap RfidResearchGroup/proxmark3
run: brew tap RfidResearchGroup/proxmark3
- name: Install dependencies
run: brew install readline qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: Prepare Build Folders
run: mkdir -p client/build
- name: Initiate cmake environment
run: cmake ..
working-directory: client/build/
- name: Build
env:
VERBOSE: 1
run: make
working-directory: client/build/
- name: Test
env:
CHECKARGS: "--clientbin ./client/build/proxmark3"
run: make client/check

106
.github/workflows/ubuntu.yml vendored Normal file
View file

@ -0,0 +1,106 @@
name: Ubuntu Build and Test
on: [push, pull_request]
jobs:
ubuntu-make:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Update apt repos
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: make clean
run: make clean
- name: Build
env:
V: 1
run: make
- name: Test
run: make check
ubuntu-make-btaddon:
if: always()
needs: [ubuntu-make]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Update apt repos
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: make clean
run: make clean
- name: Build
env:
V: 1
PLATFORM_EXTRAS: BTADDON
run: make
- name: Test
run: make check
ubuntu-cmake:
if: always()
needs: [ubuntu-make, ubuntu-make-btaddon]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Update apt repos
run: sudo apt-get update
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: Prepare Build Folders
run: mkdir -p client/build
- name: Initiate cmake environment
run: cmake ..
working-directory: client/build/
- name: Build
env:
VERBOSE: 1
run: make
working-directory: client/build/
- name: Test
env:
CHECKARGS: "--clientbin ./client/build/proxmark3"
run: make client/check

152
.github/workflows/windows.yml vendored Normal file
View file

@ -0,0 +1,152 @@
name: Windows Build and Test
on: [push, pull_request]
jobs:
proxspace:
runs-on: windows-latest
defaults:
run:
shell: pwsh
env:
PATH: C:/ProxSpace/msys2/mingw64/bin;C:/ProxSpace/msys2/usr/local/bin;C:/ProxSpace/msys2/usr/bin;C:/ProxSpace/msys2/bin
MSYSTEM: MINGW64
steps:
- name: ProxSpace download
run: Invoke-WebRequest "https://github.com/Gator96100/ProxSpace/archive/master.zip" -outfile "C:\proxspace.zip" -Passthru
- name: ProxSpace extract
run: Expand-Archive -LiteralPath "C:\proxspace.zip" -DestinationPath "C:\"
- name: ProxSpace delete zip
run: Remove-Item "C:\proxspace.zip"
- name: ProxSpace rename folder
run: Get-ChildItem -Path "C:\ProxSpace-*" | Rename-Item -NewName (Split-Path C:\ProxSpace -Leaf)
- name: ProxSpace version
run: |
$psversion = (Select-String -Pattern 'PSVERSION=' -SimpleMatch -Path "C:\ProxSpace\msys2\ps\09-proxspace_setup.post").Line.Split("""")[1]
Write-Host "ProxSpace version: $psversion"
- name: ProxSpace initial startup
working-directory: C:\ProxSpace
run: ./runme64.bat -c "exit"
- uses: actions/checkout@v2
- name: make clean
run: make clean
- name: Build
run: make V=1
- name: Test
run: make check
- name: make clean
run: make clean
- name: Build btaddon
run: make V=1 PLATFORM_EXTRAS=BTADDON
- name: Test btaddon
run: make check
- name: make clean
run: make clean
- name: Prepare cmake build folders
run: mkdir -p client/build
- name: Initiate cmake environment
run: cmake -G"MSYS Makefiles" ..
working-directory: client/build/
- name: Build cmake
run: make VERBOSE=1
working-directory: client/build/
- name: Test cmake
run: make client/check CHECKARGS="--clientbin ./client/build/proxmark3"
wsl:
runs-on: windows-latest
defaults:
run:
shell: wsl-bash {0}
steps:
- name: WSL setup
uses: Vampire/setup-wsl@v1
with:
distribution: Ubuntu-20.04
update: "true"
additional-packages: git
ca-certificates
build-essential
pkg-config
libreadline-dev
gcc-arm-none-eabi
libnewlib-dev
libbz2-dev
qtbase5-dev
cmake
libpython3-dev
python3
python3-pip
python3-dev
libpython3-all-dev
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install ansicolors sslcrypto
- name: WSL QT fix
run: sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
- name: Set git to use LF
shell: bash
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@v2
- name: make clean
run: make clean
- name: Build
run: make V=1
- name: Test
run: make check
- name: make clean
run: make clean
- name: Build btaddon
run: make V=1 PLATFORM_EXTRAS=BTADDON
- name: Test btaddon
run: make check
- name: make clean
run: make clean
- name: Prepare cmake build folders
run: mkdir -p client/build
- name: Initiate cmake environment
run: cmake ..
working-directory: client/build/
- name: Build cmake
run: make VERBOSE=1
working-directory: client/build/
- name: Test cmake
run: make client/check CHECKARGS="--clientbin ./client/build/proxmark3"

13
.gitignore vendored
View file

@ -33,6 +33,7 @@ version.c
*.json.bak
*.pyc
*.bmp
originalitysig.csv
# new build file for add-ons.
Makefile.platform
@ -71,6 +72,7 @@ tools/cryptorf/cm
tools/cryptorf/sm
tools/cryptorf/sma
tools/cryptorf/sma_multi
tools/mf_nonce_brute/mf_nonce_brute
fpga/*
!fpga/tests
@ -93,18 +95,21 @@ client/traces/*
client/dumps/*
*.ice
*.new
tools/mf_nonce_brute/mf_nonce_brute
tools/andrew/*
tools/jtag_openocd/openocd_configuration
ppls patches/*
*- Copy.*
/EF_*
client/lualibs/mfc_default_keys.lua
client/lualibs/pm3_cmd.lua
# recompiled
fpga_version_info.c
# log / history
.proxmark3/*
# .tmp files are created during compilation
*.tmp
# VSCode files
!.vscode/templates/*.json
!.vscode/extensions.json
!.vscode/tasks.json

10
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,10 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"ms-vscode.cpptools",
"austin.code-gnu-global",
"marus25.cortex-debug",
"augustocdias.tasks-shell-input"
]
}

145
.vscode/setup.sh vendored Executable file
View file

@ -0,0 +1,145 @@
#!/bin/bash
###############################
# Linux #
# Uncomment to override #
###############################
#export SerialPort="/dev/ttyACM0"
#export DebuggerPath="/usr/bin/gdb"
#export JLinkServerPath="/opt/SEGGER/JLink/JLinkGDBServerCLExe"
###############################
# WSL #
# Uncomment to override #
###############################
#export SerialPort="/dev/ttyS4"
#export DebuggerPath="/usr/bin/gdb"
#export JLinkServerPath="/mnt/c/Program Files (x86)/SEGGER/JLink/JLinkGDBServerCL.exe"
###############################
# ProxSpace #
# Uncomment to override #
###############################
#export SerialPort="COM5"
#export JLinkServerPath="C:/Program Files (x86)/SEGGER/JLink/JLinkGDBServerCL.exe"
#Debugging on 256KB systems is not recommended
#This option does not override PLATFORM_SIZE
export DeviceMem="512"
VSCODEPATH=$(dirname "$0")
function print_config {
echo "Updating with following configuration:"
echo "SerialPort: $SerialPort"
echo "DebuggerPath: $DebuggerPath"
echo "JLinkServerPath: $JLinkServerPath"
}
function setup_serial_port {
if [ -z "$SerialPort" ]; then
pm3list=$($VSCODEPATH/../pm3 --list 2>/dev/null)
#Use first port listed
export SerialPort=$(echo $pm3list | head -n 1 | cut -c 4-)
if [ -z "$SerialPort" ]; then
echo >&2 "[!!] No serial port found, please set SerialPort manually"
exit 1
fi
fi
}
function setup_gdb_linux {
if [ -z "$DebuggerPath" ]; then
export DebuggerPath="/usr/bin/gdb"
fi
if [ ! -x "$DebuggerPath" ]; then
echo >&2 "[!!] gdb not found, please set DebuggerPath manually"
exit 1
fi
}
function setup_jlink_linux {
if [ -z "$JLinkServerPath" ]; then
export JLinkServerPath="/opt/SEGGER/JLink/JLinkGDBServerCLExe"
fi
if [ ! -x "$JLinkServerPath" ]; then
echo >&2 "[!!] JLinkGDBServerCLExe not found, please set JLinkServerPath manually"
exit 1
fi
}
function setup_jlink_wsl {
if [ -z "$JLinkServerPath" ]; then
export JLinkServerPath="/mnt/c/Program Files (x86)/SEGGER/JLink/JLinkGDBServerCL.exe"
fi
if [ ! -x "$JLinkServerPath" ]; then
echo >&2 "[!!] JLinkGDBServerCL.exe not found, please set JLinkServerPath manually"
exit 1
fi
}
function setup_jlink_ps {
if [ -z "$JLinkServerPath" ]; then
export JLinkServerPath="c:/Program Files (x86)/SEGGER/JLink/JLinkGDBServerCL.exe"
fi
jlinkpath=$(cygpath "$JLinkServerPath")
if [ ! -x "$jlinkpath" ]; then
echo >&2 "[!!] JLinkGDBServerCL.exe not found, please set JLinkServerPath manually"
exit 1
fi
}
function setup_wsl {
setup_serial_port
setup_gdb_linux
setup_jlink_wsl
print_config
envsubst '${SerialPort} ${DebuggerPath} ${JLinkServerPath} ${DeviceMem}' <"$VSCODEPATH/templates/launch_wsl.json" > "$VSCODEPATH/launch.json"
}
function setup_linux {
setup_serial_port
setup_gdb_linux
setup_jlink_linux
print_config
envsubst '${SerialPort} ${DebuggerPath} ${JLinkServerPath} ${DeviceMem}' <"$VSCODEPATH/templates/launch_linux.json" > "$VSCODEPATH/launch.json"
}
function setup_ps {
setup_serial_port
setup_jlink_ps
export DebuggerPath="Using ProxSpace gbd"
print_config
envsubst '${SerialPort} ${JLinkServerPath} ${DeviceMem}' <"$VSCODEPATH/templates/launch_ps.json" > "$VSCODEPATH/launch.json"
}
if [ -f "$VSCODEPATH/launch.json" ]; then
read -p "Existing configuration found, do you want to override it? " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
rm "$VSCODEPATH/launch.json.bak" 2> /dev/null
mv "$VSCODEPATH/launch.json" "$VSCODEPATH/launch.json.bak" 2> /dev/null
else
echo >&2 "[!!] user abort"
exit 1
fi
fi
HOSTOS=$(uname | awk '{print toupper($0)}')
if [ "$HOSTOS" = "LINUX" ]; then
if uname -a|grep -q Microsoft; then
setup_wsl
else
setup_linux
fi
elif [ "$HOSTOS" = "DARWIN" ]; then
echo >&2 "[!!] MacOS not supported, sorry!"
exit 1
elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then
setup_ps
else
echo >&2 "[!!] Host OS not recognized, abort: $HOSTOS"
exit 1
fi

101
.vscode/tasks.json vendored
View file

@ -2,23 +2,20 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"windows": {
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PATH": "${workspaceFolder}/../../msys2/mingw64/bin;${workspaceFolder}/../../msys2/usr/local/bin;${workspaceFolder}/../../msys2/usr/bin;${workspaceFolder}/../../msys2/bin",
"MSYSTEM": "MINGW64"
}
}
},
"tasks": [
{
"label": "all: Make & run",
"type": "shell",
"command": "make -j && ./pm3",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": [
"$gcc"
],
@ -31,18 +28,6 @@
"label": "choose: Make",
"type": "shell",
"command": "make ${input:componentType} -j",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": [
"$gcc"
],
@ -52,18 +37,6 @@
"label": "client: Debug: make",
"type": "shell",
"command": "make client -j DEBUG=1",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": [
"$gcc"
],
@ -73,18 +46,6 @@
"label": "client: Debug: clean & make",
"type": "shell",
"command": "make client/clean && make client -j DEBUG=1",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": [
"$gcc"
],
@ -94,55 +55,27 @@
"label": "fullimage: Make & Flash",
"type": "shell",
"command": "make fullimage && ./pm3-flash-fullimage",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": []
},
{
"label": "BOOTROM: Make & Flash",
"type": "shell",
"command": "make bootrom && ./pm3-flash-bootrom",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": []
},
{
"label": "Run client",
"type": "shell",
"command": "./pm3",
"windows": {
"options": {
"cwd": "${workspaceFolder}/../..",
"shell": {
"executable": "${workspaceFolder}/../../runme64.bat",
"args": [
"-c \"cd ${workspaceFolderBasename} &&"
],
}
}
},
"problemMatcher": []
},{
"label": "fullimage: clean & make debug",
"type": "shell",
"command": "make armsrc/clean && make armsrc/all DEBUG_ARM=1",
"problemMatcher": [
"$gcc"
],
"group": "build",
}
],
"inputs": [

View file

@ -5,34 +5,11 @@
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "${cwd}/client/proxmark3",
//"processId": "${command:pickProcess}",
"processId": "${input:ProcessID}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"windows": {
"processId": "${input:ProcessIDWindows}",
"miDebuggerPath": "${workspaceFolder}/../../msys2/mingw64/bin/gdb.exe",
"externalConsole": true,//for ProxSpace externalConsole=true is required, because the internal cosole stops updating after a while
"environment": [{
"name": "PATH","value": "${workspaceFolder}/../../msys2/mingw64/bin;${workspaceFolder}/../../msys2/usr/local/bin;${workspaceFolder}/../../msys2/usr/bin;${workspaceFolder}/../../msys2/bin"
}]
}
},{
"name": "(gdb) Build & Launch",
"name": "Client: (gdb) Build & Launch",
"type": "cppdbg",
"request": "launch",
"program": "${cwd}/client/proxmark3",
"args": ["/dev/ttyACM0"],
"args": ["${SerialPort}"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@ -46,15 +23,36 @@
}
],
"preLaunchTask": "client: Debug: clean & make",
"miDebuggerPath": "/usr/bin/gdb",
"windows": {
"args": ["COM5"],
"miDebuggerPath": "${workspaceFolder}/../../msys2/mingw64/bin/gdb.exe",
"externalConsole": true,//for ProxSpace externalConsole=true is required, because the internal cosole stops updating after a while
"environment": [{
"name": "PATH","value": "${workspaceFolder}/../../msys2/mingw64/bin;${workspaceFolder}/../../msys2/usr/local/bin;${workspaceFolder}/../../msys2/usr/bin;${workspaceFolder}/../../msys2/bin"
}]
}
"miDebuggerPath": "${DebuggerPath}"
},{
"name": "Client: (gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "${cwd}/client/proxmark3",
//"processId": "${command:pickProcess}",
"processId": "${input:ProcessID}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},{
"name": "Firmware: (J-Link) Build & Launch",
"type": "cortex-debug",
"request": "launch",
"cwd": "${workspaceRoot}",
"preLaunchTask": "fullimage: clean & make debug",
"executable": "${workspaceRoot}/armsrc/obj/fullimage.elf",
"serverpath": "${JLinkServerPath}",
"servertype": "jlink",
"device": "AT91SAM7S${DeviceMem}",
"interface": "jtag",
"serialNumber": "", //If you have more than one J-Link probe, add the serial number here.
"runToMain": false,
"armToolchainPath": "/usr/bin/"
}
],
"inputs": [
@ -67,14 +65,6 @@
"command": "pgrep -n proxmark3",
}
},{
"id": "ProcessIDWindows",
"type": "command",
"command": "shellCommand.execute",
"args": {
"command": "${workspaceFolder}/../../runme64.bat -c \"cat /proc/$(pgrep -n proxmark3)/winpid\"",
}
}
]
}

49
.vscode/templates/launch_ps.json vendored Normal file
View file

@ -0,0 +1,49 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PATH": "${workspaceFolder}/../../msys2/mingw64/bin;${workspaceFolder}/../../msys2/usr/local/bin;${workspaceFolder}/../../msys2/usr/bin;${workspaceFolder}/../../msys2/bin",
"MSYSTEM": "MINGW64"
}
},
"configurations": [
{
"name": "Client: (gdb) Build & Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceFolder}",
"program": "${cwd}/client/proxmark3",
"args": ["${SerialPort}"],
"stopAtEntry": false,
"externalConsole": true,//for ProxSpace externalConsole=true is required, because the internal cosole stops updating after a while
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "client: Debug: clean & make",
"miDebuggerPath": "${workspaceFolder}/../../msys2/mingw64/bin/gdb.exe"
},{
"name": "Firmware: (J-Link) Build & Launch",
"type": "cortex-debug",
"request": "launch",
"cwd": "${workspaceRoot}",
"preLaunchTask": "fullimage: clean & make debug",
"executable": "${workspaceRoot}/armsrc/obj/fullimage.elf",
"serverpath": "${JLinkServerPath}",
"servertype": "jlink",
"device": "AT91SAM7S${DeviceMem}",
"interface": "jtag",
"serialNumber": "", //If you have more than one J-Link probe, add the serial number here.
"runToMain": false,
"armToolchainPath": "${workspaceFolder}/../../msys2/mingw64/bin"
}
]
}

70
.vscode/templates/launch_wsl.json vendored Normal file
View file

@ -0,0 +1,70 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Client: (gdb) Build & Launch",
"type": "cppdbg",
"request": "launch",
"program": "${cwd}/client/proxmark3",
"args": ["${SerialPort}"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "client: Debug: clean & make",
"miDebuggerPath": "${DebuggerPath}"
},{
"name": "Client: (gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "${cwd}/client/proxmark3",
//"processId": "${command:pickProcess}",
"processId": "${input:ProcessID}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},{
"name": "Firmware: (J-Link) Build & Launch",
"type": "cortex-debug",
"request": "launch",
"cwd": "${workspaceRoot}",
"preLaunchTask": "fullimage: clean & make debug",
"executable": "${workspaceRoot}/armsrc/obj/fullimage.elf",
"serverpath": "${JLinkServerPath}",
"servertype": "jlink",
"device": "AT91SAM7S${DeviceMem}",
"interface": "jtag",
"serialNumber": "", //If you have more than one J-Link probe, add the serial number here.
"runToMain": false,
"armToolchainPath": "/usr/bin/"
}
],
"inputs": [
{
// Using Extension "Tasks Shell Input" https://marketplace.visualstudio.com/items?itemName=augustocdias.tasks-shell-input
"id": "ProcessID",
"type": "command",
"command": "shellCommand.execute",
"args": {
"command": "pgrep -n proxmark3",
}
}
]
}

View file

@ -3,29 +3,67 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Added a script to dump originality signatures from MFU EV1s and NTAGs (@aveao)
- Added parsing of EF_CardAccess to display PACE algorithm, version and parameter in `hf emrtd info` (@aveao)
- Change, numerous commands more uses cliparser (@tcprst, @iceman1001)
- Added more originality public keys (@anon)
- Added `hf 14a info` - now also verify MFC Ev1 signatures (@iceman1001)
- Added `LF_THAREXDE` standalone mode which simulates and reads EM4x50 cards (@tharexde)
- Added `hf jooki` commands (@iceman1001)
- Changed `lf hid clone` - also accepts binary wiegand (@iceman1001)
- Changed `wiegand encode` - format param is now optional, w/o it will try encode all formats (@iceman1001)
- Fix cppchecker warnings (@iceman1001)
- Added `trace list -t mf` - now can use external dictionary keys file (@McEloff)
- Fix `lf gallagher read` - now correctly decodes card data
- Add support to `lf gallagher clone` and `lf gallagher sim` for writing specific card region, facility, card & issue numbers (@DarkMatterMatt)
- Added support for older vid/pid detection (@Gator96100)
- Added `hf mfdes bruteaid` - proper bruteforce of DESFire AID when no reading of files is possible (@craftbyte)
- Added support for bidirectional communication for `lf em 4x50 sim` (@tharexde)
- Change `PLATFORM=PM3OTHER` to `PLATFORM=PM3GENERIC` (@iceman1001)
- Added `tools/hitag2crack/crack5opencl`, an optimized version of `crack5gpu` (@matrix)
- Fixed Makefile to account for changes when running on Apple Silicon (@tcprst)
- Added support for debugging ARM with JTAG & VSCode (@Gator96100)
- Added MFUL "Gen1b" suport to `hf_mfu_setuid.lua` (@iceman1001)
- Added possibility to get bargraph in `lf tune` and `hf tune` (@iceman1001, @doegox)
- Added `hf emrtd` ePassport dumping and parsing (@aveao)
- Added `aidsearch` to `hf 14b info` (@iceman1001)
- Added `ICE_STATE_DUMP_SIM` - standalone mode for dumping/simming one iClass tag (@iconicsec)
- Added `lf em 4x50 eview` - show uploaded EM4x50 data in emul memory (@tharexde)
- Fix `data rawdemod` parsing for psk2 and user defined clock (@cyberpunk-re)
- Added `hf iclass encode` - encode a wiegand binary to a encrypted credential (@iceman1001)
- Changed `recoverpk.py` - now tests more ECDSA curves (@doegox)
- Added `hf 14a apdufuzz`- a naive apdu cla/ins/p1p2/len fuzzer (@iceman1001)
- Improved `hf 14a apdufuzz/apdufind` to find hidden APDUs (@ikarus23)
- Fix mixed up INC/DEC in MIFARE protocol defs (@vortixdev)
- Added `lf em 4x70 info` - new support for ID48 transponders (@cmolson)
- Fix multiple coverity scan issues (@iceman1001)
- Added a SIO item (@iceman1001)
- Fix `lf hid brute` - param (@iceman1001)
- Changed `lf em` layouts (@iceman1001)
- Change many commands to cliparser (@iceman1001, @tcprst, ...)
- Fix issue #844 - `lf t55xx config` => recompute block0 (@cyberpunk-re)
- EM4x50: changed cli parameter from w (word) to d (data) (@tharexde)
- EM4x50: new function 4x50 login: authenticate against tag (@tharexde)
- EM4x50: new function 4x50 brute: guess password within a given password range (@tharexde)
- EM4x50: new function 4x50 chk: try passwords from dictionary (without option -> T55xx default dictionary or -f user dictionary) (@tharexde)
- EM4x50: new function 4x50 reader: read data from tag (configured data -> standard read mode), incl. option -@ (@tharexde)
- EM4x50: new function 4x50 sim: simulate dump from file or emulator/flash (@tharexde)
- EM4x50: new function 4x50 restore: restore dump file (bin, eml, json) onto tag (@tharexde)
- EM4x50: new function 4x50 esave: dump em4x50 content in emulator memory to file (bin + eml + json) (@tharexde)
- EM4x50: new function 4x50 eload: upload em4x50 file content (bin, eml, json) to emulator memory (@tharexde)
- EM4x50: added LED signals (@tharexde)
- EM4x50: added json format for 4x50 dump (@tharexde)
- EM4x50: relocated write requests in function 4x50 wipe from device to client (@tharexde)
- EM4x50: renamed 4x50_write_password to 4x50 writepwd (@tharexde)
- EM4x50: all hex input parameters now have to be given in lsb format (output is still msb + lsb) (@tharexde)
- EM4x50: changed cli parameter from a (address) to b (block) (@tharexde)
- EM4x50: switched to cliparser for all functions (@tharexde)
- EM4x50: stabilized and accelerated tag detection (@tharexde)
- EM4x50: removed global tag structure on device side (@tharexde)
- Change `lf em 4x50` - changed cli parameter from w (word) to d (data) (@tharexde)
- Added `lf em 4x50 login` - authenticate against tag (@tharexde)
- Added `lf em 4x50 brute` - guess password within a given password range (@tharexde)
- Added `lf em 4x50 chk` - try passwords from dictionary (without option -> T55xx default dictionary or -f user dictionary) (@tharexde)
- Added `lf em 4x50 reader` - read data from tag (configured data -> standard read mode), incl. option -@ (@tharexde)
- Added `lf em 4x50 sim` - simulate dump from file or emulator/flash (@tharexde)
- Added `lf em 4x50 restore` - restore dump file (bin, eml, json) onto tag (@tharexde)
- Added `lf em 4x50 esave` - dump em4x50 content in emulator memory to file (bin + eml + json) (@tharexde)
- Added `lf em 4x50 eload` - upload em4x50 file content (bin, eml, json) to emulator memory (@tharexde)
- Changed EM4x50 - added LED signals (@tharexde)
- Change `lf em 4x50 dump` - now support json format (@tharexde)
- Change `lf em 4x50 wipe` - relocated write requests from device to client (@tharexde)
- Renamed `lf em 4x50 write_passwordd` -> `writepwd` (@tharexde)
- Change `lf em 4x50` - all hex input parameters now have to be given in lsb format (output is still msb + lsb) (@tharexde)
- Change `lf em 4x50` - changed cli parameter from a (address) to b (block) (@tharexde)
- Change `lf em 4x50` - now supports cliparser (@tharexde)
- Change EM4x50 - stabilized and accelerated tag detection (@tharexde)
- Change EM4x50 - removed global tag structure on device side (@tharexde)
- Fix `hf 15 sim` - Added basic response to GET_SYSTEM_INFO and READBLOCK requests in order to fix iso15693 tag sim (@cyberpunk-re)
- Added `mf mfu sim t 7 n <numreads>` - MFU emulation now supports automatic exit after <num> blocks read. (@cyberpunk-re)
- Added T55xx Guide to assist in learning how to use the T55xx chip (@mwalker33)
- Fix 'hf iclass wrbl' - dealing with tags in unsecured vs secured pagemode now is correct (@iceman1001)
- Fix `hf iclass wrbl` - dealing with tags in unsecured vs secured pagemode now is correct (@iceman1001)
- Change many commands to cliparser (@iceman1001, @tcprst, @mwalker33,...)
- ...
- Change `hf iclass chk/lookup/loclass` speedups (@iceman1001)

View file

@ -46,7 +46,7 @@ ifneq (,$(INSTALLTOOLS))
endif
ifneq (,$(INSTALLSIMFW))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
$(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
$(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),client/resources/$(fw)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
endif
ifeq ($(platform),Linux)
$(Q)$(MKDIR) $(DESTDIR)$(UDEV_PREFIX)
@ -169,7 +169,7 @@ help:
@echo "+ fpga_compress - Make tools/fpga_compress"
@echo
@echo "+ style - Apply some automated source code formatting rules"
@echo "+ cliparser - Generate cliparser TODO
@echo "+ cliparser - Generate cliparser TODO"
@echo "+ check - Run offline tests. Set CHECKARGS to pass arguments to the test script"
@echo "+ .../check - Run offline tests against specific target. See above."
@echo "+ miscchecks - Detect various encoding issues in source code"

View file

@ -57,6 +57,11 @@ else
RANLIB= ranlib
endif
# For detection of Apple Silicon
ifeq ($(platform),Darwin)
BREW_PREFIX = $(shell brew --prefix)
endif
ifeq ($(DEBUG),1)
DEFCXXFLAGS = -g -O0 -pipe
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
@ -66,6 +71,11 @@ else
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
DEFLDFLAGS =
endif
ifeq ($(DEBUG_ARM),1)
APP_CFLAGS += -g
SKIP_COMPRESSION=1
endif
# Next ones are activated only if SANITIZE=1
ifeq ($(SANITIZE),1)
DEFCFLAGS += -g -fsanitize=address -fno-omit-frame-pointer

View file

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

111
README.md
View file

@ -1,15 +1,18 @@
# RRG / Iceman repo - Proxmark3
# RRG / Iceman - Proxmark3
| Releases | Coverity | Contributors |
| ------------------- | -------------------:| -------------------:|
| [![Latest release](https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| ![GitHub contributors](https://img.shields.io/github/contributors/rfidresearchgroup/proxmark3) |
| Actions OSX CI | Actions Ubuntu CI | Windows CI |
| ------------------- | -------------------:| -------------------:|
| ![MacOS Build and Test](https://github.com/RfidResearchGroup/proxmark3/workflows/MacOS%20Build%20and%20Test/badge.svg?branch=master) | ![Ubuntu Build and Test](https://github.com/RfidResearchGroup/proxmark3/workflows/Ubuntu%20Build%20and%20Test/badge.svg?branch=master) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) |
| Releases | Linux & OSX CI | Windows CI | Coverity | Contributors |
| ------------------- |:-------------------:| -------------------:| -------------------:| -------------------:|
| [![Latest release](https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://api.travis-ci.com/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.com/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| ![GitHub contributors](https://img.shields.io/github/contributors/rfidresearchgroup/proxmark3) |
# PROXMARK INSTALLATION AND OVERVIEW
# PROXMARK3 INSTALLATION AND OVERVIEW
| FAQ's & Updates | Installation | Use of the Proxmark |
| ------------------- |:-------------------:| -------------------:|
@ -36,10 +39,25 @@
|[Notes on Color usage](/doc/colors_notes.md)|[Makefile vs CMake](/doc/md/Development/Makefile-vs-CMake.md)|[Notes on Cloner guns](/doc/cloner_notes.md)|
|[Notes on cliparser usage](/doc/cliparser.md)|[Notes on clocks](/doc/clocks.md)||
## Build for non-RDV4 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)
## Build for Proxmark3 RDV4
See the instruction links in the tables above to build, flash and run for your Proxmark3 RDV4 device.
## Build for generic Proxmark3 platforms
In order to build this repo for generic Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)
With generic Proxmark3 platforms we mean:
- RDV1
- RDV2
- RDV3 easy
- Proxmark Evolution (needs extra care)
- Radiowar black PCB version
- Ryscorp green PCB version
- Ryscorp Pm3Pro
- VX
- numerous Chinese adapted versions of the RDV3 easy (kkmoon, pisworks etc)
> ⚠ **Note**: About flash memory size of other Proxmark3 platforms. You need to keep a eye on how large your ARM chip built-in flash memory is. With 512kb you are fine but if its 256kb you need to compile this repo with even less functionality. When running the `./pm3-flash-all` you can see which size your device have if you have the bootloader from this repo installed. Otherwise you will find the size reported in the start message when running the Proxmark3 client `./pm3`.
## What has changed?
@ -49,7 +67,9 @@ On the hardware side:
* added smart card module
* added FPC connector
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) which we try to keep updated.
## Development
@ -57,13 +77,13 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
This repo compiles nicely on
- Proxspace v3.x
- [latest release v3.7.1](https://github.com/Gator96100/ProxSpace/releases)
- [latest release v3.8](https://github.com/Gator96100/ProxSpace/releases)
- Windows/mingw environment with Qt5.6.1 & GCC 4.9
- Ubuntu 16.04 -> 20.04
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora, Debian
- Rasbian
- Android / Termux
- Mac OS X / Homebrew
- Mac OS X / Homebrew / Apple Silicon
- WSL1 (Windows subsystem linux) on Windows 10
- Docker container
- [ RRG / Iceman repo based ubuntu 18.04 container ](https://hub.docker.com/r/secopsconsult/proxmark3)
@ -72,26 +92,22 @@ This repo compiles nicely on
Hardware to run client on
- PC
- Android
- Raspberry Pi & Raspberry Pi Zero
- Raspberry Pi, Raspberry Pi Zero
- Nvidia Jetson Nano
## Precompiled binaries
We don't maintain any precompiled binaries in this repo. There is community effort over at the Proxmark3 forum where @gator96100 has set up a google drive with many mingw binaries which is up-to-date. We link to these files here as to make it easier for users.
If you are having troubles with these files, contact the package maintainer @gator96100 and read the [sticky thread at forum](http://www.proxmark.org/forum/viewtopic.php?pid=24763#p24763) where known issues has been documented.
We don't maintain any precompiled binaries in this repo. There is community effort over at the Proxmark3 forum where [@gator96100](https://github.com/gator96100) has set up a AWS bucket with precompiled Proxspace (Mingw) binaries which is recompiled every night and with that also up-to-date. We link to these files here as to make it easier for users.
_If you use his pre-compiled Proxspace binaries do consider buy him a coffee for his efforts. Remember nothing says thank you as good as a donation._
Ref:
For Proxmark3 RDV4
- [Precompiled builds for RDV40 dedicated x86](https://drive.google.com/open?id=13zUs-aiQkYaSl5KWrBtuW5IWCoHJPsue)
- [Precompiled builds for RDV40 dedicated x64](https://drive.google.com/open?id=1SyPB8t5Vo8O0Lh7PjNm3Kv-mO4BNbxjX)
If you are having troubles with these files, contact the package maintainer [@gator96100](https://github.com/gator96100) and read the [homepage of his proxmark builds](https://www.proxmarkbuilds.org/) or read the [sticky thread at forum](http://www.proxmark.org/forum/viewtopic.php?pid=24763#p24763) where known issues has been documented with regards to the precompiled builds.
For Proxmark3 RDV4 with blueshark addon
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x86](https://drive.google.com/open?id=1TqWYctkRvkLshQ1ZRBHPLDzYHR-asuMO)
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x64](https://drive.google.com/open?id=17ful7u2QyYmMQzQzc5fAf8nJvyoDJfSL)
### Proxmark3 RDV4 devices
- [Precompiled builds for RDV40 dedicated x64](https://www.proxmarkbuilds.org/#rdv40-64/)
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x64](https://www.proxmarkbuilds.org/#rdv40_bt-64/)
Generice Proxmark3 devices (non RDV4), for Proxmark3 Easy, RDV1, RDV2, RDV3, etc etc
- [Precompiled builds for RRG / Iceman repository x86](https://drive.google.com/open?id=1PI3Xr1mussPBPnYGu4ZjWzGPARK4N7JR)
- [Precompiled builds for RRG / Iceman repository x64](https://drive.google.com/open?id=1uX9RtYGinuFrpHybu4xq_BE3HrobI20e)
### Generic Proxmark3 devices
- [Precompiled builds for RRG / Iceman repository x64](https://www.proxmarkbuilds.org/#rrg_other-64/)
## Roadmap
@ -103,28 +119,40 @@ We usually merge your contributions fast since we do like the idea of getting a
## Issues & Troubleshooting
Please search the [issues](https://github.com/rfidresearchgroup/proxmark3/issues) page here and see if your issue is listed in the first instance.
Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
Read the [Troubleshooting guide](/doc/md/Installation_Instructions/Troubleshooting.md) to weed out most known problems.
Next place to visit is the [Proxmark Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :) You will find many blogposts, youtube videos, tweets, reddit
Next place to visit is the [Proxmark3 Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :)
You will find many blogposts, youtube videos, tweets, reddit
### Offical channels
- [RFID Hacking community discord server](https://discord.gg/QfPvGFRQxH)
- [Proxmark3 IRC channel](http://webchat.freenode.net/?channels=#proxmark3)
- [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/)
- [Twitter](https://twitter.com/proxmark3/)
- [Proxmark3 community discord server](https://discord.gg/zjxc8ZB)
_no slack channel_
- [Proxmark3 Twitter](https://twitter.com/proxmark3/)
- [Proxmark3 forum](http://www.proxmark.org/forum/index.php)
- _no slack channel_
Iceman has quite a few videos on his [youtube channel](https://www.youtube.com/c/ChrisHerrmann1001)
### Youtube channels
Iceman has quite a few videos on his channel and Quentyn has risen up the last year with good informative videos. We suggest you check them out and smash that subscribe buttons!
- [Iceman channel](https://www.youtube.com/c/ChrisHerrmann1001)
- [Quentyn Taylor](https://www.youtube.com/channel/UCL91C3IZDv3wfj2ABhdRIrw)
- [Hacker warehouse channel](https://www.youtube.com/channel/UCimS6P854cQ23j6c_xst7EQ)
_if you think of some more good youtube channels to be on this list, let us know!_
## Cheat sheet
Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md)
You can enjoy a [command cheat sheet](/doc/cheatsheet.md) and we are trying to keep it updated.
[Thanks to Alex Dib!](https://github.com/scund00r)
## 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)
To all distro, package maintainers, we tried to make your life easier.
`make install` is now available and if you want to know more.
- [Notes for maintainers](/doc/md/Development/Maintainers.md)
## Why didn't you base it on official Proxmark3 Master?
@ -132,14 +160,9 @@ The separation from official Proxmark3 repo gives us a lot of freedom to create
## Proxmark3 GUI
The official PM3-GUI from Gaucho will not work.
The new [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) will work more or less. Change is needed in order to show helptext when client isn't connected to a device. We don't know how active the maintainers.
The official PM3-GUI from Gaucho will not work. Not to mention is quite old and not maintained any longer.
## The end
- July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001)
- updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish)
- updated 2019 [@doegox](https://mobile.twitter.com/doegox)
The new [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) will work more or less. Change is needed in order to show helptext when client isn't connected to a device. We don't know how active the maintainers are. There has been brought to our attention that there is quite a few Chinese Windows GUI available. Usually you find them on alibaba / taobao ads but we have no idea which fw/client they are compatible with. Proceed with caution if you decide to go down that road.
# Donations

View file

@ -64,8 +64,12 @@ clone_script:
WSLExec "WSL update..." "sudo apt-get update 1>/dev/null"
WSLExec "WSL upgrade..." "sudo apt-get upgrade -y 1>/dev/null"
WSLExec "WSL cleanup..." "sudo apt-get auto-remove -y 1>/dev/null"
WSLExec "WSL install..." "sudo apt-get -y install --reinstall --no-install-recommends git ca-certificates build-essential pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev qtbase5-dev cmake 1>/dev/null"
WSLExec "WSL install..." "sudo apt-get -y install --reinstall --no-install-recommends git ca-certificates build-essential pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev qtbase5-dev cmake libpython3-dev python3 python3-pip python3-dev libpython3-all-dev 1>/dev/null"
WSLExec "WSL QT fix..." "sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5"
WSLExec "WSL install python dependencies..." "sudo python3 -m pip install --upgrade pip 1>/dev/null"
WSLExec "WSL install pip..." "sudo python3 -m pip install setuptools 1>/dev/null"
WSLExec "WSL install pip continue..." "sudo python3 -m pip install ansicolors sslcrypto 1>/dev/null"
Add-AppveyorMessage -Message "WSL setup took $(([System.Environment]::TickCount-$WSLInstallTime) / 1000) sec" -Category Information
New-Item -ItemType "file" -Path "C:\WSL-Finished.txt" -Force | Out-Null
}
@ -279,7 +283,7 @@ build_script:
cd $env:proxspace_path
./runme64.bat -c "yes | pacman -Sc > /dev/null 2>&1"
Remove-Item -Recurse -Force -Path "$env:proxspace_cache_path" -ErrorAction SilentlyContinue
Move-Item -Path "$env:proxspace_path\msys2\var\cache" -Destination "$env:proxspace_cache_path" -Force

View file

@ -217,8 +217,12 @@ $(OBJDIR)/fullimage.data.o: $(OBJDIR)/fullimage.data.bin.z
$(Q)$(OBJCOPY) -O elf32-littlearm -I binary -B arm --rename-section .data=compressed_data $^ $@
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o
ifeq (,$(findstring WITH_NO_COMPRESSION,$(APP_CFLAGS)))
$(info [=] LD $@)
$(Q)$(CC) $(CROSS_LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^
else
$(Q)$(CP) $(OBJDIR)/fullimage.stage1.elf $@
endif
tarbin: $(OBJS)
$(info TAR $@)

View file

@ -35,6 +35,9 @@ define KNOWN_STANDALONE_DEFINITIONS
| LF_SAMYRUN | HID26 read/clone/sim |
| | - Samy Kamkar |
+----------------------------------------------------------+
| LF_THAREXDE | Simulate/read EM4x50 tags |
| (RDV4 only) | storing in flashmem |
+----------------------------------------------------------+
| HF_14ASNIFF | 14a sniff to flashmem |
| (RDV4 only) | |
+----------------------------------------------------------+
@ -67,10 +70,10 @@ define KNOWN_STANDALONE_DEFINITIONS
+----------------------------------------------------------+
endef
STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN
STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE
STANDALONE_MODES += HF_14ASNIFF HF_AVEFUL HF_BOG HF_COLIN HF_ICECLASS HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_TCPRST HF_YOUNG
STANDALONE_MODES_REQ_SMARTCARD :=
STANDALONE_MODES_REQ_FLASH := LF_ICEHID HF_14ASNIFF HF_BOG HF_COLIN HF_ICECLASS
STANDALONE_MODES_REQ_FLASH := LF_ICEHID LF_THAREXDE HF_14ASNIFF HF_BOG HF_COLIN HF_ICECLASS
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)

View file

@ -73,3 +73,7 @@ endif
ifneq (,$(findstring WITH_STANDALONE_HF_ICECLASS,$(APP_CFLAGS)))
SRC_STANDALONE = hf_iceclass.c
endif
# WITH_STANDALONE_LF_THAREXDE
ifneq (,$(findstring WITH_STANDALONE_LF_THAREXDE,$(APP_CFLAGS)))
SRC_STANDALONE = lf_tharexde.c
endif

View file

@ -68,11 +68,11 @@ uint16_t get_ev1_version(iso14a_card_select_t card, uint8_t *version) {
return mifare_sendcmd(MIFARE_ULEV1_VERSION, NULL, 0, version, NULL, NULL);
}
uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *response) {
uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *signature) {
uint8_t cmd[4] = {MIFARE_ULEV1_READSIG, 0x00, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(response, NULL);
return ReaderReceive(signature, NULL);
}
uint16_t get_ev1_counter(iso14a_card_select_t card, uint8_t counter, uint8_t *response) {
@ -114,7 +114,6 @@ int get_block_count(iso14a_card_select_t card, uint8_t version[], uint16_t versi
else if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0E", 7) == 0) { block_count = MAX_ULEV1b_BLOCKS; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0E", 7) == 0) { block_count = MAX_ULEV1b_BLOCKS; }
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { block_count = MAX_ULEV1b_BLOCKS; } // Mikron JSC Russia EV1 41 pages tag
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { block_count = MAX_UL_BLOCKS; }
else if (version[2] == 0x03) { block_count = MAX_ULEV1a_BLOCKS; }
}
}
@ -191,7 +190,7 @@ void RunMod(void) {
read_successful = false;
break;
}
// We're skipping 14 blocks (56 bytes) here, as that "[...] has version/signature/counter data here" according to comments on hf_mfu_dumptoemulator
// We're skipping 14 blocks (56 bytes) here, as that "[...] has version/signature/counter data here" according to comments on data_mfu_bin2eml
// When converting a bin, it's almost all 0 other than one 0x0F byte, and functionality seems to be unaffected if that byte is set to 0x00.
emlSetMem_xt(dataout, 14 + i, 1, 4);
Dbhexdump(4, dataout, 0);

View file

@ -37,15 +37,19 @@
#define ICE_STATE_ATTACK 2
#define ICE_STATE_READER 3
#define ICE_STATE_CONFIGCARD 4
#define ICE_STATE_DUMP_SIM 5
#define HF_ICLASS_NUM_MODES 6
// ====================================================
// Select which standalone function to be active.
// 4 possiblities. Uncomment the one you wanna use.
// 5 possiblities. Uncomment the one you wanna use.
#define ICE_USE ICE_STATE_FULLSIM
//#define ICE_USE ICE_STATE_ATTACK
//#define ICE_USE ICE_STATE_READER
//#define ICE_USE ICE_STATE_CONFIGCARD
//#define ICE_USE ICE_STATE_DUMP_SIM
// ====================================================
@ -53,6 +57,8 @@
#define NUM_CSNS 9
#define MAC_RESPONSES_SIZE (16 * NUM_CSNS)
#define HF_ICLASS_FULLSIM_ORIG_BIN "iceclass-orig.bin"
#define HF_ICALSSS_READSIM_TEMP_BIN "iceclass-temp.bin"
#define HF_ICALSSS_READSIM_TEMP_MOD_BIN "iceclass-temp-mod.bin"
#define HF_ICLASS_FULLSIM_MOD "iceclass-modified"
#define HF_ICLASS_FULLSIM_MOD_BIN HF_ICLASS_FULLSIM_MOD".bin"
#define HF_ICLASS_FULLSIM_MOD_EML HF_ICLASS_FULLSIM_MOD".eml"
@ -141,20 +147,33 @@ static void download_instructions(uint8_t t) {
DbpString("2. " _YELLOW_("mem spiffs dump h"));
break;
}
case ICE_STATE_DUMP_SIM: {
DbpString("The found tag will be dumped to " HF_ICALSSS_READSIM_TEMP_BIN);
DbpString("1. " _YELLOW_("mem spiffs tree"));
DbpString("2. " _YELLOW_("mem spiffs dump h"));
break;
}
}
}
// Save to flash if file doesn't exist.
// Write over file if size of flash file is less than new datalen
static void save_to_flash(uint8_t *data, uint16_t datalen) {
static void save_to_flash(uint8_t *data, uint16_t datalen, char *filename) {
rdv40_spiffs_lazy_mount();
char fn[SPIFFS_OBJ_NAME_LEN];
sprintf(fn, "iclass-%02X%02X%02X%02X%02X%02X%02X%02X.bin",
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]
);
if (filename == NULL) {
sprintf(fn, "iclass-%02X%02X%02X%02X%02X%02X%02X%02X.bin",
data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]
);
} else {
int fnlen = MIN(strlen(filename), SPIFFS_OBJ_NAME_LEN);
// if the given name len longer than buffer allows, cut it down to size
memcpy(fn, filename, fnlen);
}
int res;
if (exists_in_spiffs(fn) == false) {
@ -400,13 +419,180 @@ static int reader_dump_mode(void) {
}
}
switch_off();
save_to_flash(card_data, (start_block + dumped) * 8);
save_to_flash(card_data, (start_block + dumped) * 8, NULL);
Dbprintf("%u bytes saved", (start_block + dumped) * 8);
}
DbpString("-=[ exiting " _CYAN_("`read & dump`") " mode ]=-");
return PM3_SUCCESS;
}
static int dump_sim_mode(void) {
DbpString("this mode has no tracelog");
if (have_aa2())
DbpString("dumping of " _YELLOW_("AA2 enabled"));
for (;;) {
BigBuf_free();
uint8_t *card_data = BigBuf_malloc(ICLASS_16KS_SIZE);
memset(card_data, 0xFF, ICLASS_16KS_SIZE);
if (BUTTON_PRESS()) {
DbpString("button pressed");
break;
}
// setup authenticate AA1
iclass_auth_req_t auth = {
.use_raw = false,
.use_elite = false,
.use_credit_key = false,
.do_auth = true,
.send_reply = false,
};
memcpy(auth.key, legacy_aa1_key, sizeof(auth.key));
Iso15693InitReader();
set_tracing(false);
picopass_hdr *hdr = (picopass_hdr *)card_data;
// select tag.
uint32_t eof_time = 0;
bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
if (res == false) {
switch_off();
continue;
}
// sanity check of CSN.
if (hdr->csn[7] != 0xE0 && hdr->csn[6] != 0x12) {
switch_off();
continue;
}
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
// get 3 config bits
uint8_t type = (hdr->conf.chip_config & 0x10) >> 2;
type |= (hdr->conf.mem_config & 0x80) >> 6;
type |= (hdr->conf.mem_config & 0x20) >> 5;
Dbprintf(_GREEN_("%s") ", dumping...", card_types[type]);
uint8_t pagemap = get_pagemap(hdr);
uint8_t app1_limit, app2_limit, start_block;
// tags configured for NON SECURE PAGE, acts different
if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) {
app1_limit = card_app2_limit[type];
app2_limit = 0;
start_block = 3;
} else {
app1_limit = hdr->conf.app_limit;
app2_limit = card_app2_limit[type];
start_block = 5;
res = authenticate_iclass_tag(&auth, hdr, &start_time, &eof_time, NULL);
if (res == false) {
switch_off();
Dbprintf(_RED_("failed AA1 auth") ", skipping ");
continue;
}
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
}
uint16_t dumped = 0;
// main read loop
for (uint16_t i = start_block; i <= app1_limit; i++) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) {
dumped++;
}
}
if (pagemap != PICOPASS_NON_SECURE_PAGEMODE && have_aa2()) {
// authenticate AA2
auth.use_raw = false;
auth.use_credit_key = true;
memcpy(auth.key, aa2_key, sizeof(auth.key));
res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time);
if (res) {
// sanity check of CSN.
if (hdr->csn[7] != 0xE0 && hdr->csn[6] != 0x12) {
switch_off();
continue;
}
res = authenticate_iclass_tag(&auth, hdr, &start_time, &eof_time, NULL);
if (res) {
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
for (uint16_t i = app1_limit + 1; i <= app2_limit; i++) {
if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) {
dumped++;
}
}
} else {
DbpString(_RED_("failed AA2 auth"));
}
} else {
DbpString(_RED_("failed selecting AA2"));
// sanity check of CSN.
if (hdr->csn[7] != 0xE0 && hdr->csn[6] != 0x12) {
switch_off();
continue;
}
}
}
switch_off();
char *temp_file = HF_ICALSSS_READSIM_TEMP_BIN;
save_to_flash(card_data, (start_block + dumped) * 8, temp_file);
Dbprintf("%u bytes saved", (start_block + dumped) * 8);
if (((start_block + dumped) * 8) > 0) {
break; //switch to sim mode
}
}
rdv40_spiffs_lazy_mount();
SpinOff(0);
uint8_t *emul = BigBuf_get_EM_addr();
uint32_t fsize = size_in_spiffs(HF_ICALSSS_READSIM_TEMP_BIN);
int res = rdv40_spiffs_read_as_filetype(HF_ICALSSS_READSIM_TEMP_BIN, emul, fsize, RDV40_SPIFFS_SAFETY_SAFE);
rdv40_spiffs_lazy_unmount();
if (res == SPIFFS_OK) {
Dbprintf("loaded " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN) " (%u bytes)", fsize);
}
Dbprintf("simming " _GREEN_(HF_ICALSSS_READSIM_TEMP_BIN));
iclass_simulate(ICLASS_SIM_MODE_FULL, 0, false, NULL, NULL, NULL);
LED_B_ON();
rdv40_spiffs_lazy_mount();
res = rdv40_spiffs_write(HF_ICALSSS_READSIM_TEMP_BIN, emul, fsize, RDV40_SPIFFS_SAFETY_SAFE);
rdv40_spiffs_lazy_unmount();
LED_B_OFF();
if (res == SPIFFS_OK) {
Dbprintf("wrote emulator memory to " _GREEN_(HF_ICALSSS_READSIM_TEMP_MOD_BIN));
} else {
Dbprintf(_RED_("error") " writing "HF_ICALSSS_READSIM_TEMP_MOD_BIN" to flash ( %d )", res);
}
DbpString("-=[ exiting " _CYAN_("`dump & sim`") " mode ]=-");
return PM3_SUCCESS;
}
static int config_sim_mode(void) {
uint8_t *emul = BigBuf_get_EM_addr();
@ -436,7 +622,7 @@ void RunMod(void) {
uint8_t mode = ICE_USE;
uint8_t *bb = BigBuf_get_EM_addr();
if (bb[0] > 0 && bb[0] < 5) {
if (bb[0] > 0 && bb[0] < HF_ICLASS_NUM_MODES) {
mode = bb[0];
}
@ -512,6 +698,16 @@ void RunMod(void) {
if (mode == ICE_STATE_CONFIGCARD)
config_sim_mode();
mode = ICE_STATE_NONE;
break;
}
case ICE_STATE_DUMP_SIM: {
DbpString("-=[ enter " _CYAN_("`dump & sim`") " mode, read 1 card and sim it ]=-");
res = dump_sim_mode();
if (res == PM3_SUCCESS) {
download_instructions(mode);
}
mode = ICE_STATE_NONE;
break;
}

View file

@ -248,11 +248,9 @@ void RunMod(void) {
dynamic_response_info.response[0] = receivedCmd[0];
if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
memcpy(dynamic_response_info.response + 1, ndef, 31);
dynamic_response_info.response_n = 32;
} else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x63;
dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3;
@ -260,14 +258,12 @@ void RunMod(void) {
memcpy(verify_pwd + 5, receivedCmd + 6, 16);
DbpString("Reader sent password: ");
Dbhexdump(16, verify_pwd + 5, 0);
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3;
gotkey = true;
state = STATE_DUMP;
} else {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3;
@ -321,7 +317,7 @@ void RunMod(void) {
LED_B_ON();
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL);
if (apdulen > 0) {
if (apdulen > 2) {
DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]"));
Dbhexdump(apdusLen[i], apdus[i], false);
DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]"));
@ -429,11 +425,9 @@ void RunMod(void) {
dynamic_response_info.response[0] = receivedCmd[0];
if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
memcpy(dynamic_response_info.response + 1, ndef, 31);
dynamic_response_info.response_n = 32;
} else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x63;
dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3;
@ -441,12 +435,10 @@ void RunMod(void) {
memcpy(verify_pwd + 5, receivedCmd + 6, 16);
DbpString("Reader sent password: ");
Dbhexdump(16, verify_pwd + 5, 0);
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3;
} else {
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3;

View file

@ -21,19 +21,19 @@
#include "commonutil.h"
#define MAX_IND 16 // 4 LEDs - 2^4 combinations
#define CLOCK 64 //for 125kHz
#define LF_CLOCK 64 // for 125kHz
// low & high - array for storage IDs. Its length must be equal.
// Predefined IDs must be stored in low[].
static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
static uint8_t *bba, slots_count;
static uint8_t slots_count;
static int buflen;
void ModInfo(void) {
DbpString(" LF EM4100 simulator standalone mode");
}
static uint64_t ReversQuads(uint64_t bits) {
static uint64_t rev_quads(uint64_t bits) {
uint64_t result = 0;
for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
@ -41,32 +41,40 @@ static uint64_t ReversQuads(uint64_t bits) {
return result >> 24;
}
static void FillBuff(uint8_t bit) {
memset(bba + buflen, bit, CLOCK / 2);
buflen += (CLOCK / 2);
memset(bba + buflen, bit ^ 1, CLOCK / 2);
buflen += (CLOCK / 2);
static void fill_buff(uint8_t bit) {
uint8_t *bba = BigBuf_get_addr();
memset(bba + buflen, bit, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
}
static void ConstructEM410xEmulBuf(uint64_t id) {
static void construct_EM410x_emul(uint64_t id) {
int i, j, binary[4], parity[4];
int i, j;
int binary[4] = {0, 0, 0, 0};
int parity[4] = {0, 0, 0, 0};
buflen = 0;
for (i = 0; i < 9; i++)
FillBuff(1);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
fill_buff(1);
for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2;
for (j = 0; j < 4; j++)
FillBuff(binary[j]);
FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
fill_buff(binary[j]);
fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++)
parity[j] ^= binary[j];
}
for (j = 0; j < 4; j++)
FillBuff(parity[j]);
FillBuff(0);
fill_buff(parity[j]);
fill_buff(0);
}
static void LED_Slot(int i) {
@ -85,14 +93,14 @@ void RunMod(void) {
int selected = 0; //selected slot after start
slots_count = ARRAYLEN(low);
bba = BigBuf_get_addr();
for (;;) {
WDT_HIT();
if (data_available()) break;
SpinDelay(100);
SpinUp(100);
LED_Slot(selected);
ConstructEM410xEmulBuf(ReversQuads(low[selected]));
construct_EM410x_emul(rev_quads(low[selected]));
SimulateTagLowFrequency(buflen, 0, true);
selected = (selected + 1) % slots_count;
}

View file

@ -53,8 +53,8 @@
#include "flashmem.h"
#endif
#define LF_CLOCK 64 //for 125kHz
#define LF_RWSB_T55XX_TYPE 1 //Tag type: 0 - T5555, 1-T55x7
#define LF_CLOCK 64 // for 125kHz
#define LF_RWSB_T55XX_TYPE 1 // Tag type: 0 - T5555, 1-T55x7
#define LF_RWSB_UNKNOWN_RESULT 0
#define LF_RWSB_BRUTE_STOPED 1
@ -76,14 +76,13 @@ static int bruteforceSpeed[] = {10, 12, 14, 16};
// In high[] must be nulls
static uint64_t low[] = {0, 0, 0, 0};
static uint32_t high[] = {0, 0, 0, 0};
static uint8_t *bba;
static int buflen;
void ModInfo(void) {
DbpString(" LF EM4100 read/sim/write/brute mode");
}
static uint64_t ReversQuads(uint64_t bits) {
static uint64_t rev_quads(uint64_t bits) {
uint64_t result = 0;
for (int i = 0; i < 16; i++) {
result += ((bits >> (60 - 4 * i)) & 0xf) << (4 * i);
@ -91,33 +90,39 @@ static uint64_t ReversQuads(uint64_t bits) {
return result >> 24;
}
static void FillBuff(uint8_t bit) {
static void fill_buff(uint8_t bit) {
uint8_t *bba = BigBuf_get_addr();
memset(bba + buflen, bit, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
}
static void ConstructEM410xEmulBuf(uint64_t id) {
bba = BigBuf_get_addr();
int i, j, binary[4], parity[4];
static void construct_EM410x_emul(uint64_t id) {
int i, j;
int binary[4] = {0, 0, 0, 0};
int parity[4] = {0, 0, 0, 0};
buflen = 0;
for (i = 0; i < 9; i++)
FillBuff(1);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
fill_buff(1);
for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2;
for (j = 0; j < 4; j++)
FillBuff(binary[j]);
FillBuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
fill_buff(binary[j]);
fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++)
parity[j] ^= binary[j];
}
for (j = 0; j < 4; j++)
FillBuff(parity[j]);
FillBuff(0);
fill_buff(parity[j]);
fill_buff(0);
}
static void LED_Update(int mode, int slot) {
@ -188,8 +193,8 @@ static uint64_t PackEmID(uint64_t original, int newCardNum) {
buf &= ~(1 << i);
}
buf |= (newCardNum & 0xFFFF) << 1;
buf |= oddparity32((buf >> 1) & 0xFFF) & 1;
buf |= (evenparity32((buf >> 13) & 0xFFF) & 1) << 25;
buf |= oddparity32((buf >> 1) & 0xFFF);
buf |= (evenparity32((buf >> 13) & 0xFFF)) << 25;
uint32_t cardnumNew = (buf >> 1) & 0xFFFF;
uint32_t fcNew = (buf >> 17) & 0xFF;
@ -197,7 +202,6 @@ static uint64_t PackEmID(uint64_t original, int newCardNum) {
return buf;
}
static void PrintFcAndCardNum(uint64_t lowData) {
// Calculate Facility Code and Card Number from high and low
uint32_t fc = (lowData >> 17) & 0xFF;
@ -222,7 +226,7 @@ static int BruteEMTag(uint64_t originalCard, int slot) {
cardnum = cardnum + direction;
uint64_t currentCard = PackEmID(originalCard, cardnum);
Dbprintf("[=] >> Simulating card id %"PRIx64" <<", currentCard);
ConstructEM410xEmulBuf(ReversQuads(currentCard));
construct_EM410x_emul(rev_quads(currentCard));
SimulateTagLowFrequencyEx(buflen, 0, 1, bruteforceSpeed[bruteforceSpeedCurrent] * 10000);
int button_pressed = BUTTON_CLICKED(1000);
@ -267,7 +271,7 @@ static int ExecuteMode(int mode, int slot) {
return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_SIM:
Dbprintf("[=] >> Sim mode started <<");
ConstructEM410xEmulBuf(ReversQuads(low[slot]));
construct_EM410x_emul(rev_quads(low[slot]));
SimulateTagLowFrequency(buflen, 0, 1);
return LF_RWSB_UNKNOWN_RESULT;
case LF_RWSB_MODE_WRITE:
@ -310,7 +314,6 @@ void RunMod() {
int slot = 0;
mode = SwitchMode(mode, slot);
bba = BigBuf_get_addr();
for (;;) {
WDT_HIT();
if (data_available()) break;

View file

@ -41,7 +41,7 @@
// In high[] must be nulls
static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static uint8_t *bba, slots_count;
static uint8_t slots_count;
static int buflen;
void ModInfo(void) {
@ -56,7 +56,8 @@ static uint64_t rev_quads(uint64_t bits) {
return result >> 24;
}
static void fillbuff(uint8_t bit) {
static void fill_buff(uint8_t bit) {
uint8_t *bba = BigBuf_get_addr();
memset(bba + buflen, bit, LF_CLOCK / 2);
buflen += (LF_CLOCK / 2);
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
@ -66,29 +67,29 @@ static void fillbuff(uint8_t bit) {
static void construct_EM410x_emul(uint64_t id) {
int i, j;
int binary[4] = {0};
int parity[4] = {0};
int binary[4] = {0, 0, 0, 0};
int parity[4] = {0, 0, 0, 0};
buflen = 0;
for (i = 0; i < 9; i++)
fillbuff(1);
fill_buff(1);
for (i = 0; i < 10; i++) {
for (j = 3; j >= 0; j--, id /= 2)
binary[j] = id % 2;
for (j = 0; j < 4; j++)
fillbuff(binary[j]);
fill_buff(binary[j]);
fillbuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
fill_buff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
for (j = 0; j < 4; j++)
parity[j] ^= binary[j];
}
for (j = 0; j < 4; j++)
fillbuff(parity[j]);
fill_buff(parity[j]);
fillbuff(0);
fill_buff(0);
}
static void led_slot(int i) {
@ -138,7 +139,6 @@ void RunMod(void) {
// 3 - write to T5555 tag
uint8_t state = 0;
slots_count = ARRAYLEN(low);
bba = BigBuf_get_addr();
led_slot(selected);
for (;;) {

View file

@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// Tharexde, 2020
// tharexde, 2021
//
// 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
@ -8,10 +8,12 @@
// main code for EM4x50 simulator and collector aka THAREXDE
//-----------------------------------------------------------------------------
#include <inttypes.h>
#include "ticks.h"
#include "standalone.h"
#include "proxmark3_arm.h"
#include "appmain.h"
#include "BigBuf.h"
#include "commonutil.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
@ -19,68 +21,75 @@
#include "../em4x50.h"
/*
* `lf_tharexde` simulates hardcoded words/blocks, reads words of standard read
* mode of EM4x50 tags and stores them in internal flash.
* `lf_tharexde` simulates EM4x50 dumps uploaded to flash, reads words
* transmitted by EM4x50 tags in standard read mode and stores them in
* internal flash.
* It requires RDV4 hardware (for flash and battery).
*
* On entering stand-alone mode, this module will start reading/record EM4x50 data.
* Every found / collected data will be written/appended to the logfile in flash
* as a text string.
* On entering stand-alone mode, this module will start simulating EM4x50 data.
* Data is read from eml dump file uploaded to flash memory (lf_em4x50_simulate.eml).
* If reader sends password different from dump file password, it is saved in
* file lf_em4x50_passwords.log in flash memory.
*
* On switching to read/record mode by pressing pm3 button, module will start
* reading EM4x50 data. Each collected data set will be written/appended to the
* logfile in flash (lf_em4x50_collect.log) as a text string.
*
* LEDs:
* - LED A: simulating
* - LED B: reading / record
* - LED C: writing to flash
* - LED A blinking: no simulation data or read error
* - LED B: reading/recording
* - LED D: unmounting/sync'ing flash (normally < 100ms)
*
* To upload input file (eml format) to flash:
* - mem spiffs load f <filename> o lf_em4x50_simulate.eml
*
* To retrieve password file from flash:
* - mem spiffs dump o lf_em4x50_passwords.log f <filename>
*
* To retrieve log file from flash:
*
* 1. mem spiffs dump o lf_em4x50collect.log f lf_em4x50collect.log
* Copies log file from flash to your client.
*
* 2. exit the Proxmark3 client
*
* 3. more lf_tharexdecollect.log
* - mem spiffs dump o lf_em4x50_collect.log f <filename>
*
* This module emits debug strings during normal operation -- so try it out in
* the lab connected to PM3 client before taking it into the field.
*
* To delete the log file from flash:
* To delete the input file from flash:
* - mem spiffs remove lf_em4x50_simulate.eml
*
* 1. mem spiffs remove lf_tharexdecollect.log
* To delete the log file from flash:
* - mem spiffs remove lf_em4x50_passwords.log
*
* To delete the log file from flash:
* - mem spiffs remove lf_em4x50_collect.log
*/
#define STATE_SIM 0
#define STATE_READ 1
#define STATE_BRUTE 2
#define EM4X50_TAG_WORD 45
#define EM4X50_PWD_SPEED 27
#define LF_EM4X50SIMULATE_INPUTFILE "lf_em4x50simulate.eml"
#define LF_EM4X50COLLECT_LOGFILE "lf_em4x50collect.log"
#define LF_EM4X50BRUTE_INPUTFILE "lf_em4x50brute.eml"
#define LF_EM4X50BRUTE_LOGFILE "lf_em4x50brute.log"
#define STATE_SIM 0
#define STATE_READ 1
#define LF_EM4X50_INPUTFILE_SIM "lf_em4x50_simulate.eml"
#define LF_EM4X50_LOGFILE_SIM "lf_em4x50_passwords.log"
#define LF_EM4X50_LOGFILE_COLLECT "lf_em4x50_collect.log"
#define MAX_NO_PWDS_TO_SAVE 50
bool input_exists;
bool log_exists;
uint32_t gPassword;
static void LoadDataInstructions(const char *inputfile) {
Dbprintf("");
Dbprintf("To load datafile into flash and display it:");
Dbprintf(_YELLOW_("1.") " edit inputfile %s", inputfile);
Dbprintf(_YELLOW_("2.") " start proxmark3 client");
Dbprintf(_YELLOW_("3.") " mem spiffs load f %s o %s", inputfile, inputfile);
Dbprintf(_YELLOW_("4.") " start standalone mode");
Dbprintf("To load datafile to flash and display it:");
Dbprintf("1. edit input file %s", inputfile);
Dbprintf("2. start proxmark3 client");
Dbprintf("3. mem spiffs load f <filename> o %s", inputfile);
Dbprintf("4. start standalone mode");
}
static void DownloadLogInstructions(const char *logfile) {
Dbprintf("");
Dbprintf("To get the logfile from flash and display it:");
Dbprintf(_YELLOW_("1.") " mem spiffs dump o %s f %s", logfile, logfile);
Dbprintf(_YELLOW_("2.") " exit proxmark3 client");
Dbprintf(_YELLOW_("3.") " cat %s", logfile);
Dbprintf("1. mem spiffs dump o %s f <filename>", logfile);
Dbprintf("2. exit proxmark3 client");
Dbprintf("3. cat <filename>");
}
static int get_input_data_from_file(uint32_t *words, char *inputfile) {
static bool get_input_data_from_file(uint32_t *tag, char *inputfile) {
size_t now = 0;
@ -88,92 +97,92 @@ static int get_input_data_from_file(uint32_t *words, char *inputfile) {
uint32_t size = size_in_spiffs(inputfile);
uint8_t *mem = BigBuf_malloc(size);
Dbprintf(_YELLOW_("found input file %s"), inputfile);
rdv40_spiffs_read_as_filetype(inputfile, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
now = size / 9;
for (int i = 0; i < now; i++)
for (int j = 0; j < 4; j++)
words[i] |= (hex2int(mem[2 * j + 9 * i]) << 4 | hex2int(mem[2 * j + 1 + 9 * i])) << ((3 - j) * 8);
for (int i = 0; i < now; i++) {
for (int j = 0; j < 4; j++) {
tag[i] |= (hex2int(mem[2 * j + 9 * i]) << 4 | hex2int(mem[2 * j + 1 + 9 * i])) << ((3 - j) * 8);
}
}
Dbprintf(_YELLOW_("read data from input file"));
Dbprintf(_YELLOW_("read tag data from input file"));
} else {
Dbprintf(_RED_("no input file %s"), inputfile);
}
BigBuf_free();
return (now > 0) ? now : 0;
return ((now == EM4X50_NO_WORDS) && (tag[EM4X50_DEVICE_SERIAL] != tag[EM4X50_DEVICE_ID]));
}
static void append(const char *filename, uint8_t *entry, size_t entry_len) {
LED_D_ON();
if (log_exists == false) {
rdv40_spiffs_write(filename, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE);
log_exists = true;
} else {
if (exists_in_spiffs(filename)) {
rdv40_spiffs_append(filename, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE);
} else {
rdv40_spiffs_write(filename, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE);
}
}
static void save_pwds(uint32_t *pwdlist, size_t no_pwd) {
uint8_t entry[10] = {0};
if (no_pwd > 0) {
Dbprintf("");
for (int i = 0; i < no_pwd; i++) {
sprintf((char *)entry, "%08"PRIx32"\n", pwdlist[i]);
append(LF_EM4X50_LOGFILE_SIM, entry, strlen((char *)entry));
Dbprintf("received password: %08"PRIx32"", pwdlist[i]);
}
}
LED_D_OFF();
}
void ModInfo(void) {
DbpString(_YELLOW_(" LF EM4x50 sim/collector/bruteforce mode") " - a.k.a tharexde");
DbpString(_YELLOW_(" LF EM4x50 sim/collector mode") " - a.k.a tharexde");
}
void RunMod(void) {
bool state_change = true;//, password_found = false;
int pwd_found = false;
uint8_t state = STATE_SIM;
// declarations for simulating
uint32_t words[33] = {0x0};
uint32_t pwd = 0x0;
uint32_t passwords[2] = {0x0};
size_t now = 0;
// declarations for reading
int no_words = 0;
//uint32_t words[EM4X50_TAG_WORD];
uint8_t entry[81];
bool state_change = true, read_ok = false;
int no_words = 0, command = 0, no_pwd = 0;
uint8_t entry[400], state = STATE_SIM;
uint32_t tag[EM4X50_NO_WORDS] = {0x0}, pwdlist[MAX_NO_PWDS_TO_SAVE];
rdv40_spiffs_lazy_mount();
StandAloneMode();
Dbprintf(_YELLOW_("Standalone mode THAREXDE started"));
for (;;) {
WDT_HIT();
if (data_available()) break;
if (data_available()) {
break;
}
// press button - toggle between SIM, READ and BRUTE
// press button - toggle between SIM and READ
// hold button - exit
int button_pressed = BUTTON_CLICKED(1000);
if (button_pressed == BUTTON_SINGLE_CLICK) {
SpinUp(100);
switch (state) {
case STATE_SIM:
// save and display passwords
save_pwds(pwdlist, no_pwd);
state = STATE_READ;
break;
case STATE_READ:
state = STATE_BRUTE;
break;
case STATE_BRUTE:
state = STATE_SIM;
break;
default:
break;
}
state_change = true;
} else if (button_pressed == BUTTON_HOLD) {
SpinDown(100);
break;
}
@ -181,170 +190,102 @@ void RunMod(void) {
if (state_change) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
// initialize simulation mode
LEDsoff();
LED_A_ON();
Dbprintf("");
Dbprintf(_YELLOW_("switched to EM4x50 simulating mode"));
now = get_input_data_from_file(words, LF_EM4X50SIMULATE_INPUTFILE);
if (now > 0) {
Dbprintf(_YELLOW_("simulating %i blocks"), now);
for (int i = 0; i < now; i++)
Dbprintf("%2i -> %lx", i + 1, words[i]);
read_ok = get_input_data_from_file(tag, LF_EM4X50_INPUTFILE_SIM);
if (read_ok) {
Dbprintf(_YELLOW_("tag data ok"));
} else {
Dbprintf(_RED_("error in input data"));
Dbprintf(_RED_("error in tag data"));
LoadDataInstructions(LF_EM4X50_INPUTFILE_SIM);
}
LED_D_OFF();
gLogin = false;
gPassword = reflect32(tag[0]);
gWritePasswordProcess = false;
command = EM4X50_COMMAND_STANDARD_READ;
no_pwd = 0;
memset(pwdlist, 0, sizeof(pwdlist));
em4x50_setup_sim();
state_change = false;
}
em4x50_sim_send_listen_window();
for (int i = 0; i < now; i++) {
em4x50_sim_send_listen_window();
em4x50_sim_send_word(words[i]);
// if no data or read error -> blink
if (read_ok == false) {
LED(LED_A, 200);
SpinDelay(200);
}
em4x50_handle_commands(&command, tag);
// check if new password was found
if (gPassword != reflect32(tag[EM4X50_DEVICE_PASSWORD])) {
if (no_pwd < MAX_NO_PWDS_TO_SAVE) {
pwdlist[no_pwd] = gPassword;
no_pwd++;
}
gPassword = reflect32(tag[EM4X50_DEVICE_PASSWORD]);
}
// if timeout (e.g. no reader field) continue with standard read
// mode and reset former authentication
if (command == PM3_ETIMEOUT) {
command = EM4X50_COMMAND_STANDARD_READ;
gLogin = false;
LED_D_OFF();
}
} else if (state == STATE_READ) {
if (state_change) {
// initialize read mode
LEDsoff();
LED_B_ON();
Dbprintf("");
Dbprintf(_YELLOW_("switched to EM4x50 reading mode"));
memset(entry, 0, sizeof(entry));
memset(words, 0, sizeof(words));
log_exists = exists_in_spiffs(LF_EM4X50COLLECT_LOGFILE);
em4x50_setup_read();
state_change = false;
}
no_words = em4x50_standalone_read(words);
no_words = 0;
memset(tag, 0, sizeof(tag));
standard_read(&no_words, tag);
if (no_words > 0) {
memset(entry, 0, sizeof(entry));
sprintf((char *)entry, "found new EM4x50 tag:");
Dbprintf("%s", entry);
strcat((char *)entry, "\n");
append(LF_EM4X50COLLECT_LOGFILE, entry, strlen((char *)entry));
sprintf((char *)entry, "found EM4x50 tag:\n");
for (int i = 0; i < no_words; i++) {
sprintf((char *)entry, " %2i -> 0x%08"PRIx32"", i + 1, words[i]);
Dbprintf("%s", entry);
strcat((char *)entry, "\n");
append(LF_EM4X50COLLECT_LOGFILE, entry, strlen((char *)entry));
sprintf((char *)entry + strlen((char *)entry), "%08"PRIx32"\n", tag[i]);
}
}
} else if (state == STATE_BRUTE) {
if (state_change) {
LEDsoff();
LED_C_ON();
Dbprintf("");
Dbprintf(_YELLOW_("switched to EM4x50 brute force mode"));
log_exists = exists_in_spiffs(LF_EM4X50BRUTE_LOGFILE);
now = get_input_data_from_file(passwords, LF_EM4X50BRUTE_INPUTFILE);
if (now == 2) {
// print some information
int no_iter = passwords[1] - passwords[0] + 1;
int dur_s = no_iter / EM4X50_PWD_SPEED;
int dur_h = dur_s / 3600;
int dur_m = (dur_s - dur_h * 3600) / 60;
dur_s -= dur_h * 3600 + dur_m * 60;
//iterprint = no_iter/10;
Dbprintf(_YELLOW_("trying %i passwords in range [0x%08x, 0x%08x]"),
no_iter, passwords[0], passwords[1]);
Dbprintf(_YELLOW_("estimated duration: %ih%im%is"),
dur_h, dur_m, dur_s);
} else {
Dbprintf(_RED_("error in input data"));
break;
}
state_change = false;
}
pwd_found = em4x50_standalone_brute(passwords[0], passwords[1], &pwd);
if (pwd_found == PM3_ETIMEOUT) {
// timeout -> no EM4x50 tag on reader?
Dbprintf(_YELLOW_("timeout - no EM4x50 tag detected"));
} else if (pwd_found == true) {
// password found -> write to logfile
sprintf((char *)entry, "password found: 0x%08"PRIx32, pwd);
Dbprintf(_YELLOW_("%s"), entry);
strcat((char *)entry, "\n");
append(LF_EM4X50BRUTE_LOGFILE, entry, strlen((char *)entry));
break;
} else {
if (pwd == passwords[1] + 1) {
// finished without success -> write to logfile
sprintf((char *)entry, "no password found");
Dbprintf(_YELLOW_("%s"), entry);
strcat((char *)entry, "\n");
append(LF_EM4X50BRUTE_LOGFILE, entry, strlen((char *)entry));
} else {
// stopped -> write to logfile
sprintf((char *)entry, "stopped search - last password: 0x%08"PRIx32, pwd);
Dbprintf(_YELLOW_("%s"), entry);
strcat((char *)entry, "\n");
append(LF_EM4X50BRUTE_LOGFILE, entry, strlen((char *)entry));
// replace start password by last tested password in
// inputfile (spiffs) so that brute forcing process will
// be continued when envoking brute force mode again
sprintf((char *)entry, "%08"PRIx32"\n%08"PRIx32"\n", pwd, passwords[1]);
rdv40_spiffs_write(LF_EM4X50BRUTE_INPUTFILE,
entry,
strlen((char *)entry),
RDV40_SPIFFS_SAFETY_SAFE);
}
break;
Dbprintf("%s", entry);
sprintf((char *)entry + strlen((char *)entry), "\n");
append(LF_EM4X50_LOGFILE_COLLECT, entry, strlen((char *)entry));
}
}
// reset timer
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0
AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero
AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer
}
if (state == STATE_READ) {
DownloadLogInstructions(LF_EM4X50COLLECT_LOGFILE);
} else if (state == STATE_BRUTE) {
LoadDataInstructions(LF_EM4X50BRUTE_INPUTFILE);
DownloadLogInstructions(LF_EM4X50BRUTE_LOGFILE);
DownloadLogInstructions(LF_EM4X50_LOGFILE_COLLECT);
} else {
LoadDataInstructions(LF_EM4X50SIMULATE_INPUTFILE);
// save and display passwords
save_pwds(pwdlist, no_pwd);
DownloadLogInstructions(LF_EM4X50_LOGFILE_SIM);
}
LED_D_ON();
@ -352,8 +293,8 @@ void RunMod(void) {
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
Dbprintf("");
Dbprintf(_YELLOW_("[=] Standalone mode THAREXDE stopped"));
}

View file

@ -50,7 +50,7 @@
#include "crc16.h"
#ifdef WITH_LCD
#include "LCD.h"
#include "LCD_disabled.h"
#endif
#ifdef WITH_SMARTCARD
@ -257,6 +257,9 @@ void ReadMem(int addr) {
/* osimage version information is linked in, cf commonutil.h */
/* bootrom version information is pointed to from _bootphase1_version_pointer */
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, __data_src_start__;
#ifdef WITH_NO_COMPRESSION
extern char *_bootrom_end, _bootrom_start, __os_size__;
#endif
static void SendVersion(void) {
char temp[PM3_CMD_DATA_SIZE - 12]; /* Limited data payload in USB packets */
char VersionString[PM3_CMD_DATA_SIZE - 12] = { '\0' };
@ -295,9 +298,11 @@ static void SendVersion(void) {
strncat(VersionString, "\n ", sizeof(VersionString) - strlen(VersionString) - 1);
}
}
#ifndef WITH_NO_COMPRESSION
// Send Chip ID and used flash memory
uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
uint32_t compressed_data_section_size = common_area.arg1;
#endif
struct p {
uint32_t id;
@ -308,7 +313,11 @@ static void SendVersion(void) {
struct p payload;
payload.id = *(AT91C_DBGU_CIDR);
#ifdef WITH_NO_COMPRESSION
payload.section_size = (uint32_t)&_bootrom_end - (uint32_t)&_bootrom_start + (uint32_t)&__os_size__;
#else
payload.section_size = text_and_rodata_section_size + compressed_data_section_size;
#endif
payload.versionstr_len = strlen(VersionString) + 1;
memcpy(payload.versionstr, VersionString, payload.versionstr_len);
@ -1136,7 +1145,7 @@ static void PacketReceived(PacketCommandNG *packet) {
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
em4x50_sim((uint8_t *)packet->data.asBytes);
em4x50_sim((uint32_t *)packet->data.asBytes);
break;
}
case CMD_LF_EM4X50_READER: {
@ -1170,6 +1179,26 @@ static void PacketReceived(PacketCommandNG *packet) {
em4x70_info((em4x70_data_t *)packet->data.asBytes);
break;
}
case CMD_LF_EM4X70_WRITE: {
em4x70_write((em4x70_data_t *)packet->data.asBytes);
break;
}
case CMD_LF_EM4X70_UNLOCK: {
em4x70_unlock((em4x70_data_t *)packet->data.asBytes);
break;
}
case CMD_LF_EM4X70_AUTH: {
em4x70_auth((em4x70_data_t *)packet->data.asBytes);
break;
}
case CMD_LF_EM4X70_WRITEPIN: {
em4x70_write_pin((em4x70_data_t *)packet->data.asBytes);
break;
}
case CMD_LF_EM4X70_WRITEKEY: {
em4x70_write_key((em4x70_data_t *)packet->data.asBytes);
break;
}
#endif
#ifdef WITH_ISO15693
@ -1637,10 +1666,6 @@ static void PacketReceived(PacketCommandNG *packet) {
iClass_ReadBlock(packet->data.asBytes);
break;
}
case CMD_HF_ICLASS_AUTH: { //check
iClass_Authentication(packet->data.asBytes);
break;
}
case CMD_HF_ICLASS_CHKKEYS: {
iClass_Authentication_fast(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
break;

View file

@ -242,7 +242,6 @@ void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfire
}
}
static void xor(const uint8_t *ivect, uint8_t *data, const size_t len);
static size_t key_macing_length(desfirekey_t key);
// iceman, see memxor inside string.c, dest/src swapped..
@ -264,20 +263,20 @@ void cmac_generate_subkeys(desfirekey_t key) {
mifare_cypher_blocks_chained(NULL, key, ivect, l, kbs, MCD_RECEIVE, MCO_ENCYPHER);
bool xor = false;
bool txor = false;
// Used to compute CMAC on complete blocks
memcpy(key->cmac_sk1, l, kbs);
xor = l[0] & 0x80;
txor = l[0] & 0x80;
lsl(key->cmac_sk1, kbs);
if (xor)
if (txor)
key->cmac_sk1[kbs - 1] ^= R;
// Used to compute CMAC on the last block if non-complete
memcpy(key->cmac_sk2, key->cmac_sk1, kbs);
xor = key->cmac_sk1[0] & 0x80;
txor = key->cmac_sk1[0] & 0x80;
lsl(key->cmac_sk2, kbs);
if (xor)
if (txor)
key->cmac_sk2[kbs - 1] ^= R;
}

File diff suppressed because it is too large Load diff

View file

@ -13,10 +13,11 @@
#include "../include/em4x50.h"
int em4x50_standalone_read(uint32_t *words);
int em4x50_standalone_brute(uint32_t start, uint32_t stop, uint32_t *pwd);
bool em4x50_sim_send_listen_window(void);
bool em4x50_sim_send_word(uint32_t word);
void em4x50_setup_read(void);
int standard_read(int *now, uint32_t *words);
void em4x50_setup_sim(void);
void em4x50_handle_commands(int *command, uint32_t *tag);
void em4x50_info(em4x50_data_t *etd);
void em4x50_write(em4x50_data_t *etd);
@ -24,7 +25,7 @@ void em4x50_writepwd(em4x50_data_t *etd);
void em4x50_read(em4x50_data_t *etd);
void em4x50_brute(em4x50_data_t *etd);
void em4x50_login(uint32_t *password);
void em4x50_sim(uint8_t *filename);
void em4x50_sim(uint32_t *password);
void em4x50_reader(void);
void em4x50_chk(uint8_t *filename);

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,16 @@ typedef struct {
uint8_t data[32];
} em4x70_tag_t;
typedef enum {
RISING_EDGE,
FALLING_EDGE
} edge_detection_t;
void em4x70_info(em4x70_data_t *etd);
void em4x70_write(em4x70_data_t *etd);
void em4x70_unlock(em4x70_data_t *etd);
void em4x70_auth(em4x70_data_t *etd);
void em4x70_write_pin(em4x70_data_t *etd);
void em4x70_write_key(em4x70_data_t *etd);
#endif /* EM4x70_H */

View file

@ -408,9 +408,9 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
// Tag CSN
uint8_t *modulated_response = NULL;
int modulated_response_size = 0;
int modulated_response_size;
uint8_t *trace_data = NULL;
int trace_data_size = 0;
int trace_data_size;
// Respond SOF -- takes 1 bytes
uint8_t *resp_sof = BigBuf_malloc(1);
@ -498,10 +498,9 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
bool button_pressed = false;
uint8_t cmd, options, block;
int len = 0;
int len, kc_attempt = 0;
bool exit_loop = false;
bool using_kc = false;
int kc_attempt = 0;
while (exit_loop == false) {
WDT_HIT();
@ -1364,7 +1363,9 @@ static bool select_iclass_tag_ex(picopass_hdr *hdr, bool use_credit_key, uint32_
return false;
memcpy(hdr->epurse, resp, sizeof(hdr->epurse));
*status |= FLAG_ICLASS_CC;
if (status)
*status |= FLAG_ICLASS_CC;
} else {
@ -1469,16 +1470,9 @@ void ReaderIClass(uint8_t flags) {
switch_off();
}
// used with function select_and_auth (cmdhficlass.c)
// which needs to authenticate before doing more things like read/write
// selects and authenticate to a card, sends back div_key and mac to client.
void iClass_Authentication(uint8_t *msg) {
}
bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out) {
uint8_t cmd_check[9] = { ICLASS_CMD_CHECK };
uint8_t div_key[8] = {0};
uint8_t mac[4] = {0};
uint8_t resp_auth[4] = {0};
uint8_t ccnr[12] = {0};
@ -1495,6 +1489,8 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint
memcpy(cmd_check + 1, payload->key, 8);
} else {
uint8_t div_key[8] = {0};
if (payload->use_raw)
memcpy(div_key, payload->key, 8);
else
@ -1792,7 +1788,7 @@ static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac,
uint8_t resp[10] = {0};
uint32_t eof_time = 0, start_time = 0;
bool isOK = iclass_send_cmd_with_retries(write, sizeof(write), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time);
bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time);
if (isOK == false) {
return false;
}
@ -1833,7 +1829,7 @@ void iClass_WriteBlock(uint8_t *msg) {
// select tag.
uint32_t eof_time = 0;
picopass_hdr hdr = {0};
bool res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time);
uint8_t res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time);
if (res == false) {
goto out;
}

View file

@ -16,7 +16,7 @@
#include "pm3_cmd.h"
void SniffIClass(uint8_t jam_search_len, uint8_t *jam_search_string);
void ReaderIClass(uint8_t arg0);
void ReaderIClass(uint8_t flags);
void iClass_WriteBlock(uint8_t *msg);
void iClass_Dump(uint8_t *msg);
@ -29,7 +29,6 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_t *datain, uint8_t *dataout, uint16_t *dataoutlen);
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain);
void iClass_Authentication(uint8_t *bytes);
bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out);
void iClass_ReadBlock(uint8_t *msg);

View file

@ -133,35 +133,30 @@ static hf14a_config hf14aconfig = { 0, 0, 0, 0, 0 } ;
void printHf14aConfig(void) {
DbpString(_CYAN_("HF 14a config"));
Dbprintf(" [a] Anticol override....%i %s%s%s",
hf14aconfig.forceanticol,
(hf14aconfig.forceanticol == 0) ? "( " _GREEN_("No") " ) follow standard " : "",
(hf14aconfig.forceanticol == 1) ? "( " _RED_("Yes") " ) always do anticol" : "",
(hf14aconfig.forceanticol == 2) ? "( " _RED_("Yes") " ) always skip anticol" : ""
Dbprintf(" [a] Anticol override....%s%s%s",
(hf14aconfig.forceanticol == 0) ? _GREEN_("std") " : follow standard " : "",
(hf14aconfig.forceanticol == 1) ? _RED_("force") " : always do anticol" : "",
(hf14aconfig.forceanticol == 2) ? _RED_("skip") " : always skip anticol" : ""
);
Dbprintf(" [b] BCC override........%i %s%s%s",
hf14aconfig.forcebcc,
(hf14aconfig.forcebcc == 0) ? "( " _GREEN_("No") " ) follow standard" : "",
(hf14aconfig.forcebcc == 1) ? "( " _RED_("Yes") " ) always do CL2" : "",
(hf14aconfig.forcebcc == 2) ? "( " _RED_("Yes") " ) always use card BCC" : ""
Dbprintf(" [b] BCC override........%s%s%s",
(hf14aconfig.forcebcc == 0) ? _GREEN_("std") " : follow standard" : "",
(hf14aconfig.forcebcc == 1) ? _RED_("fix") " : fix bad BCC" : "",
(hf14aconfig.forcebcc == 2) ? _RED_("ignore") " : ignore bad BCC, always use card BCC" : ""
);
Dbprintf(" [2] CL2 override........%i %s%s%s",
hf14aconfig.forcecl2,
(hf14aconfig.forcecl2 == 0) ? "( " _GREEN_("No") " ) follow standard" : "",
(hf14aconfig.forcecl2 == 1) ? "( " _RED_("Yes") " ) always do CL2" : "",
(hf14aconfig.forcecl2 == 2) ? "( " _RED_("Yes") " ) always skip CL2" : ""
Dbprintf(" [2] CL2 override........%s%s%s",
(hf14aconfig.forcecl2 == 0) ? _GREEN_("std") " : follow standard" : "",
(hf14aconfig.forcecl2 == 1) ? _RED_("force") " : always do CL2" : "",
(hf14aconfig.forcecl2 == 2) ? _RED_("skip") " : always skip CL2" : ""
);
Dbprintf(" [3] CL3 override........%i %s%s%s",
hf14aconfig.forcecl3,
(hf14aconfig.forcecl3 == 0) ? "( " _GREEN_("No") " ) follow standard" : "",
(hf14aconfig.forcecl3 == 1) ? "( " _RED_("Yes") " ) always do CL3" : "",
(hf14aconfig.forcecl3 == 2) ? "( " _RED_("Yes") " ) always skip CL3" : ""
Dbprintf(" [3] CL3 override........%s%s%s",
(hf14aconfig.forcecl3 == 0) ? _GREEN_("std") " : follow standard" : "",
(hf14aconfig.forcecl3 == 1) ? _RED_("force") " : always do CL3" : "",
(hf14aconfig.forcecl3 == 2) ? _RED_("skip") " : always skip CL3" : ""
);
Dbprintf(" [r] RATS override.......%i %s%s%s",
hf14aconfig.forcerats,
(hf14aconfig.forcerats == 0) ? "( " _GREEN_("No") " ) follow standard " : "",
(hf14aconfig.forcerats == 1) ? "( " _RED_("Yes") " ) always do RATS" : "",
(hf14aconfig.forcerats == 2) ? "( " _RED_("Yes") " ) always skip RATS" : ""
Dbprintf(" [r] RATS override.......%s%s%s",
(hf14aconfig.forcerats == 0) ? _GREEN_("std") " : follow standard " : "",
(hf14aconfig.forcerats == 1) ? _RED_("force") " : always do RATS" : "",
(hf14aconfig.forcerats == 2) ? _RED_("skip") " : always skip RATS" : ""
);
}
@ -921,18 +916,25 @@ bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *len) {
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
(void)b;
uint16_t check = 0;
uint8_t flip = 0;
uint16_t checker = 0;
for (;;) {
if (check == 4000) {
// if (BUTTON_PRESS() || data_available())
WDT_HIT();
if (flip == 3) {
if (data_available())
return false;
flip = 0;
}
if (checker >= 3000) {
if (BUTTON_PRESS())
return false;
check = 0;
WDT_HIT();
flip++;
checker = 0;
}
++check;
++checker;
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -1340,7 +1342,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data, uint8_t
LED_A_ON();
// main loop
//for (;;) {
bool finished = false;
bool button_pushed = BUTTON_PRESS();
while (!button_pushed && !finished) {

View file

@ -129,7 +129,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time);
RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time);
void RAMFUNC SniffIso14443a(uint8_t param);
void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data, uint8_t numReads);
void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data, uint8_t exitAfterNReads);
bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages);
bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *len);
void iso14443a_antifuzz(uint32_t flags);

View file

@ -1201,7 +1201,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
if (Handle14443bSamplesFromTag(ci, cq)) {
*eof_time = dma_start_time + (samples) - DELAY_TAG_TO_ARM; // end of EOF
*eof_time = GetCountSspClkDelta(dma_start_time) - (DELAY_TAG_TO_ARM * 128); // end of EOF
if (Demod.len > Demod.max_len) {
ret = -2; // overflow
@ -1209,7 +1209,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
break;
}
if (samples > timeout && Demod.state < DEMOD_PHASE_REF_TRAINING) {
if (((GetCountSspClkDelta(dma_start_time) >> 7) > timeout) && Demod.state < DEMOD_PHASE_REF_TRAINING) {
ret = -1;
break;
}
@ -1225,7 +1225,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
- (Demod.len * (8 + 2)) // time for byte transfers
- (12) // time for SOF transfer
- (12); // time for EOF transfer
LogTrace(Demod.output, Demod.len, (sof_time * 4), (*eof_time * 4), NULL, false);
LogTrace(Demod.output, Demod.len, sof_time, *eof_time, NULL, false);
}
return Demod.len;
}
@ -1400,7 +1400,7 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void
CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, iso14b_timeout, &eof_time);
FpgaDisableTracing();
uint8_t *data_bytes = (uint8_t *) rxdata;

View file

@ -1602,7 +1602,7 @@ void ReaderIso15693(uint32_t parameter) {
reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0);
} else {
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
//start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
// we should do a better check than this
if (recvlen >= 12) {
@ -1686,7 +1686,7 @@ void SimTagIso15693(uint8_t *uid) {
enum { NO_FIELD, IDLE, ACTIVATED, SELECTED, HALTED } chip_state = NO_FIELD;
bool button_pressed = false;
int vHf = 0; // in mV
int vHf; // in mV
bool exit_loop = false;
while (exit_loop == false) {
@ -1719,7 +1719,6 @@ void SimTagIso15693(uint8_t *uid) {
int cmd_len = GetIso15693CommandFromReader(cmd, sizeof(cmd), &reader_eof_time);
if (cmd_len < 0) {
button_pressed = true;
exit_loop = true;
break;
}
@ -1727,7 +1726,7 @@ void SimTagIso15693(uint8_t *uid) {
if ((cmd_len >= 5) && (cmd[0] & ISO15_REQ_INVENTORY) && (cmd[1] == ISO15_CMD_INVENTORY)) {
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
// Build INVENTORY command
uint8_t resp_inv[CMD_INV_RESP] = {0};
@ -1743,30 +1742,30 @@ void SimTagIso15693(uint8_t *uid) {
resp_inv[7] = uid[2];
resp_inv[8] = uid[1];
resp_inv[9] = uid[0];
// CRC
AddCrc15(resp_inv, 10);
CodeIso15693AsTag(resp_inv, CMD_INV_RESP);
tosend_t *ts = get_tosend();
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
LogTrace_ISO15693(resp_inv, CMD_INV_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
chip_state = SELECTED;
}
// GET_SYSTEM_INFO
if ((cmd[1] == ISO15_CMD_SYSINFO)) {
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
// Build GET_SYSTEM_INFO command
uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0};
resp_sysinfo[0] = 0; // Response flags.
resp_sysinfo[1] = 0x0F; // Information flags (0x0F - DSFID, AFI, Mem size, IC)
// 64-bit UID
resp_sysinfo[2] = uid[7];
resp_sysinfo[3] = uid[6];
@ -1776,42 +1775,42 @@ void SimTagIso15693(uint8_t *uid) {
resp_sysinfo[7] = uid[2];
resp_sysinfo[8] = uid[1];
resp_sysinfo[9] = uid[0];
resp_sysinfo[10] = 0; // DSFID
resp_sysinfo[11] = 0; // AFI
resp_sysinfo[12] = 0x1B; // Memory size.
resp_sysinfo[13] = 0x03; // Memory size.
resp_sysinfo[14] = 0x01; // IC reference.
// CRC
AddCrc15(resp_sysinfo, 15);
CodeIso15693AsTag(resp_sysinfo, CMD_SYSINFO_RESP);
tosend_t *ts = get_tosend();
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
LogTrace_ISO15693(resp_sysinfo, CMD_SYSINFO_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
}
// READ_BLOCK
if ((cmd[1] == ISO15_CMD_READ)) {
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
// Build GET_SYSTEM_INFO command
uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0};
resp_readblock[0] = 0; // Response flags.
resp_readblock[1] = 0; // Block data.
resp_readblock[2] = 0; // Block data.
resp_readblock[3] = 0; // Block data.
resp_readblock[4] = 0; // Block data.
// CRC
AddCrc15(resp_readblock, 5);
CodeIso15693AsTag(resp_readblock, CMD_READBLOCK_RESP);
tosend_t *ts = get_tosend();
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
@ -1845,9 +1844,8 @@ void BruteforceIso15693Afi(uint32_t speed) {
int datalen = 5;
uint32_t eof_time = 0;
uint32_t start_time = GetCountSspClk();
int recvlen = SendDataTag(data, datalen, true, speed, recv, sizeof(recv), 0, ISO15693_READER_TIMEOUT, &eof_time);
start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
uint32_t start_time = eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
WDT_HIT();

View file

@ -154,7 +154,7 @@ t55xx_configurations_t T55xx_Timing = {
{ 29 * 8, 17 * 8, 15 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0
{ 29 * 8, 17 * 8, 15 * 8, 31 * 8, 15 * 8, 47 * 8, 63 * 8 } // 1 of 4
#else
// PM3OTHER or like offical repo
// PM3GENERIC or like official repo
{ 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Default Fixed
{ 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref.
{ 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0
@ -1009,7 +1009,7 @@ void CmdFSKsimTAGEx(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t cl
WDT_HIT();
Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, STT: %d, n: %d", fchigh, fclow, clk, separator, n);
Dbprintf("FSK simulating with rf/%d, fc high %d, fc low %d, STT %d, n %d", clk, fchigh, fclow, separator, n);
if (ledcontrol) LED_A_ON();
SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles);
@ -1122,10 +1122,10 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c
WDT_HIT();
Dbprintf("Simulating with clk: %d, invert: %d, encoding: %s (%d), separator: %d, n: %d"
Dbprintf("ASK simulating with rf/%d, invert %d, encoding %s (%d), separator %d, n %d"
, clk
, invert
, (encoding == 2) ? "BI" : (encoding == 1) ? "ASK" : "RAW"
, (encoding == 2) ? "ASK/BI" : (encoding == 1) ? "ASK/MAN" : "RAW/MAN"
, encoding
, separator
, n
@ -1176,7 +1176,7 @@ void CmdPSKsimTAG(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, u
WDT_HIT();
Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d", carrier, clk, invert, n);
Dbprintf("PSK simulating with rf/%d, fc/%d, invert %d, n %d", clk, carrier, invert, n);
if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol);
@ -1220,7 +1220,7 @@ void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size,
WDT_HIT();
Dbprintf("Simulating with clk: %d, invert: %d, separator: %d, n: %d"
Dbprintf("NRZ simulating with rf/%d, invert %d, separator %d, n %d"
, clk
, invert
, separator
@ -1251,20 +1251,13 @@ int lf_hid_watch(int findone, uint32_t *high, uint32_t *low) {
BigBuf_Clear_keep_EM();
int res = PM3_SUCCESS;
uint16_t interval = 0;
while (BUTTON_PRESS() == false) {
for (;;) {
WDT_HIT();
// cancel w usb command.
if (interval == 4000) {
if (data_available()) {
res = PM3_EOPABORTED;
break;
}
interval = 0;
} else {
interval++;
if (data_available() || BUTTON_PRESS()) {
res = PM3_EOPABORTED;
break;
}
DoAcquisition_default(-1, false);
@ -1360,20 +1353,13 @@ int lf_awid_watch(int findone, uint32_t *high, uint32_t *low) {
LFSetupFPGAForADC(LF_DIVISOR_125, true);
int res = PM3_SUCCESS;
uint16_t interval = 0;
while (BUTTON_PRESS() == false) {
for (;;) {
WDT_HIT();
// cancel w usb command.
if (interval == 4000) {
if (data_available()) {
res = PM3_EOPABORTED;
break;
}
interval = 0;
} else {
interval++;
if (data_available() || BUTTON_PRESS()) {
res = PM3_EOPABORTED;
break;
}
DoAcquisition_default(-1, false);
@ -1465,19 +1451,12 @@ int lf_em410x_watch(int findone, uint32_t *high, uint64_t *low) {
LFSetupFPGAForADC(LF_DIVISOR_125, true);
int res = PM3_SUCCESS;
uint16_t interval = 0;
while (BUTTON_PRESS() == false) {
for (;;) {
WDT_HIT();
// cancel w usb command.
if (interval == 4000) {
if (data_available()) {
res = PM3_EOPABORTED;
break;
}
interval = 0;
} else {
interval++;
if (data_available() || BUTTON_PRESS()) {
res = PM3_EOPABORTED;
break;
}
DoAcquisition_default(-1, false);
@ -1541,20 +1520,13 @@ int lf_io_watch(int findone, uint32_t *high, uint32_t *low) {
LFSetupFPGAForADC(LF_DIVISOR_125, true);
int res = PM3_SUCCESS;
uint16_t interval = 0;
while (BUTTON_PRESS() == false) {
for (;;) {
WDT_HIT();
// cancel w usb command.
if (interval == 4000) {
if (data_available()) {
res = PM3_EOPABORTED;
break;
}
interval = 0;
} else {
interval++;
if (data_available() || BUTTON_PRESS()) {
res = PM3_EOPABORTED;
break;
}
DoAcquisition_default(-1, false);

View file

@ -73,11 +73,11 @@ void printSamples(void) {
void setSamplingConfig(sample_config *sc) {
// decimation (1-8) how many bits of adc sample value to save
if (sc->decimation > 0 && sc->decimation < 8)
if (sc->decimation > 0 && sc->decimation < 9)
config.decimation = sc->decimation;
// bits per sample (1-8)
if (sc->bits_per_sample > 0 && sc->bits_per_sample < 8)
if (sc->bits_per_sample > 0 && sc->bits_per_sample < 9)
config.bits_per_sample = sc->bits_per_sample;
//
@ -515,7 +515,7 @@ void doCotagAcquisition(void) {
if (BUTTON_PRESS())
break;
if (checker == 4000) {
if (data_available())
break;

View file

@ -662,9 +662,11 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
// Return 1 if the nonce is invalid else return 0
static int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) & \
(oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) & \
(oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))) ? 1 : 0;
return (
(oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) && \
(oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) && \
(oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))
) ? 1 : 0;
}
void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
@ -696,7 +698,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
LED_C_ON();
for (uint16_t i = 0; i <= PM3_CMD_DATA_SIZE - 4; i += 4) {
while (num_nonces < PM3_CMD_DATA_SIZE / 4) {
// Test if the action was cancelled
if (BUTTON_PRESS()) {
@ -746,18 +748,14 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
continue;
}
num_nonces++;
// Save the tag nonce (nt)
buf[i] = answer[0];
buf[i + 1] = answer[1];
buf[i + 2] = answer[2];
buf[i + 3] = answer[3];
memcpy(buf + num_nonces * 4, answer, 4);
num_nonces++;
}
LED_C_OFF();
LED_B_ON();
reply_old(CMD_ACK, isOK, cuid, num_nonces - 1, buf, sizeof(buf));
reply_old(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));
LED_B_OFF();
if (DBGLEVEL >= 3) DbpString("AcquireNonces finished");
@ -826,7 +824,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
if (!have_uid) { // need a full select cycle to get the uid first
iso14a_card_select_t card_info;
if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (ALL)");
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Can't select card (ALL)");
continue;
}
switch (card_info.uidlen) {
@ -845,7 +843,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
have_uid = true;
} else { // no need for anticollision. We can directly select the card
if (!iso14443a_fast_select_card(uid, cascade_levels)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (UID)");
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Can't select card (UID)");
continue;
}
}
@ -855,7 +853,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
uint32_t nt1;
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Auth1 error");
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Auth1 error");
continue;
}
@ -866,7 +864,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
CHK_TIMEOUT();
if (len != 4) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireNonces: Auth2 error len=%d", len);
if (DBGLEVEL >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Auth2 error len=%d", len);
continue;
}
@ -1015,7 +1013,8 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
}
}
davg = (davg + (rtr - 1) / 2) / (rtr - 1);
if (rtr > 1)
davg = (davg + (rtr - 1) / 2) / (rtr - 1);
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time);
@ -2714,8 +2713,8 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) {
//
// Tear-off attack against MFU.
// - Moebius et al
void MifareU_Otp_Tearoff(uint8_t arg0, uint32_t tearoff_time, uint8_t *datain) {
uint8_t blockNo = arg0;
void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) {
uint8_t blockNo = blno;
uint8_t data_fullwrite[4] = {0x00};
uint8_t data_testwrite[4] = {0x00};
memcpy(data_fullwrite, datain, 4);

View file

@ -63,6 +63,6 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain);
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
// Tear-off test for MFU
void MifareU_Otp_Tearoff(uint8_t arg0, uint32_t arg1, uint8_t *datain);
void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain);
void MifareU_Counter_Tearoff(uint8_t counter, uint32_t tearoff_time, uint8_t *datain);
#endif

View file

@ -68,9 +68,12 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
// send X byte basic commands
int mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
uint8_t dcmd[data_size + 3];
dcmd[0] = cmd;
memcpy(dcmd + 1, data, data_size);
if (data_size > 0)
memcpy(dcmd + 1, data, data_size);
AddCrc14A(dcmd, data_size + 1);
ReaderTransmit(dcmd, sizeof(dcmd), timing);
int len = ReaderReceive(answer, answer_parity);

View file

@ -14,14 +14,16 @@
#include "proxmark3_arm.h"
#include "appmain.h"
#ifndef WITH_NO_COMPRESSION
#include "lz4.h"
#endif
#include "BigBuf.h"
#include "string.h"
extern struct common_area common_area;
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
#ifndef WITH_NO_COMPRESSION
static void uncompress_data_section(void) {
int avail_in;
memcpy(&avail_in, &__data_src_start__, sizeof(int));
@ -35,6 +37,7 @@ static void uncompress_data_section(void) {
// save the size of the compressed data section
common_area.arg1 = avail_in;
}
#endif
void __attribute__((section(".startos"))) Vector(void);
void Vector(void) {
@ -48,12 +51,20 @@ void Vector(void) {
}
common_area.flags.osimage_present = 1;
/* Set up data segment: Copy from flash to ram */
#ifdef WITH_NO_COMPRESSION
char *data_src = &__data_src_start__;
char *data_dst = &__data_start__;
char *data_end = &__data_end__;
while (data_dst < data_end) *data_dst++ = *data_src++;
#else
uncompress_data_section();
#endif
/* Set up (that is: clear) BSS. */
char *dst = &__bss_start__;
char *end = &__bss_end__;
while (dst < end) *dst++ = 0;
char *bss_dst = &__bss_start__;
char *bss_end = &__bss_end__;
while (bss_dst < bss_end) *bss_dst++ = 0;
AppMain();
}

View file

@ -121,7 +121,7 @@ uint16_t usart_rxdata_available(void) {
uint32_t usart_read_ng(uint8_t *data, size_t len) {
if (len == 0) return 0;
uint32_t nbBytesRcv = 0;
uint32_t bytes_rcv = 0;
uint32_t try = 0;
// uint32_t highest_observed_try = 0;
// Empirical max try observed: 3000000 / USART_BAUD_RATE
@ -146,7 +146,7 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) {
}
len -= packetSize;
while (packetSize--) {
data[nbBytesRcv++] = us_rxfifo[us_rxfifo_low++];
data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++];
if (us_rxfifo_low == sizeof(us_rxfifo))
us_rxfifo_low = 0;
}
@ -157,7 +157,7 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) {
}
// highest_observed_try = MAX(highest_observed_try, try);
// Dbprintf_usb("Dbg USART max observed try %i", highest_observed_try);
return nbBytesRcv;
return bytes_rcv;
}
// transfer from device to client

View file

@ -32,7 +32,7 @@ find_package(PkgConfig)
if (NOT SKIPQT EQUAL 1)
if(APPLE AND EXISTS /usr/local/opt/qt5)
# Homebrew installs Qt5 (up to at least 5.11.0) in
# /usr/local/qt5. Ensure that it can be found by CMake
# /usr/local/opt/qt5. Ensure that it can be found by CMake
# since it is not in the default /usr/local prefix.
# Add it to PATHS so that it doesn't override the
# CMAKE_PREFIX_PATH environment variable.
@ -40,6 +40,16 @@ if (NOT SKIPQT EQUAL 1)
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
endif(APPLE AND EXISTS /usr/local/opt/qt5)
if(APPLE AND EXISTS /opt/homebrew/opt/qt5)
# Homebrew on Apple Silicon installs Qt5 in
# /opt/homebrew/opt/qt5. Ensure that it can be found by CMake
# since it is not in the default /usr/local prefix.
# Add it to PATHS so that it doesn't override the
# CMAKE_PREFIX_PATH environment variable.
# QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
# e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /opt/homebrew/opt/qt5)
endif(APPLE AND EXISTS /opt/homebrew/opt/qt5)
set(QT_PACKAGELIST
Qt5Core
Qt5Widgets
@ -77,12 +87,12 @@ endif (EMBED_READLINE OR EMBED_BZIP2)
if (NOT SKIPREADLINE EQUAL 1)
if (APPLE)
find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH)
find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH)
find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include /opt/homebrew/opt/readline/include NO_DEFAULT_PATH)
find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib /opt/homebrew/opt/readline/lib NO_DEFAULT_PATH)
endif (APPLE)
if (EMBED_READLINE)
ExternalProject_Add(ncurses
URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz
URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz
PREFIX deps/ncurses
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib
@ -94,7 +104,7 @@ if (NOT SKIPREADLINE EQUAL 1)
ExternalProject_Add_StepTargets(ncurses configure build install)
ExternalProject_Add(readline
URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz
URL ftp://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz
PREFIX deps/readline
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
@ -228,9 +238,11 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdhf15.c
${PM3_ROOT}/client/src/cmdhfcryptorf.c
${PM3_ROOT}/client/src/cmdhfepa.c
${PM3_ROOT}/client/src/cmdhfemrtd.c
${PM3_ROOT}/client/src/cmdhffelica.c
${PM3_ROOT}/client/src/cmdhffido.c
${PM3_ROOT}/client/src/cmdhficlass.c
${PM3_ROOT}/client/src/cmdhfjooki.c
${PM3_ROOT}/client/src/cmdhflegic.c
${PM3_ROOT}/client/src/cmdhflist.c
${PM3_ROOT}/client/src/cmdhflto.c

View file

@ -17,8 +17,7 @@ vpath %.dic dictionaries
OBJDIR = obj
ifeq ($(platform),Darwin)
# cf brew info qt: qt not symlinked anymore
PKG_CONFIG_ENV := PKG_CONFIG_PATH=/usr/local/opt/qt/lib/pkgconfig
PKG_CONFIG_ENV := PKG_CONFIG_PATH=$(BREW_PREFIX)/opt/qt/lib/pkgconfig
endif
###################
@ -115,21 +114,6 @@ STATICLIBS += $(HARDNESTEDLIB)
LDLIBS +=$(HARDNESTEDLIBLD)
INCLUDES += $(HARDNESTEDLIBINC)
## Jansson
ifneq ($(SKIPJANSSONSYSTEM),1)
JANSSONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags jansson 2>/dev/null)
JANSSONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs jansson 2>/dev/null)
ifneq ($(JANSSONLDLIBS),)
JANSSONLIB =
JANSSONLIBLD = $(JANSSONLDLIBS)
JANSSONLIBINC = $(JANSSONINCLUDES)
JANSSON_FOUND = 1
endif
endif
STATICLIBS += $(JANSSONLIB)
LDLIBS += $(JANSSONLIBLD)
INCLUDES += $(JANSSONLIBINC)
## Lua
ifneq ($(SKIPLUASYSTEM),1)
LUAINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags lua5.2 2>/dev/null)
@ -145,6 +129,22 @@ STATICLIBS += $(LUALIB)
LDLIBS += $(LUALIBLD)
INCLUDES += $(LUALIBINC)
## Jansson
# Jansson section needs to be after Lua to avoid interferences on macOS if a locally incompatible Lua was available, see PR 1155
ifneq ($(SKIPJANSSONSYSTEM),1)
JANSSONINCLUDES = $(shell $(PKG_CONFIG_ENV) pkg-config --cflags jansson 2>/dev/null)
JANSSONLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs jansson 2>/dev/null)
ifneq ($(JANSSONLDLIBS),)
JANSSONLIB =
JANSSONLIBLD = $(JANSSONLDLIBS)
JANSSONLIBINC = $(JANSSONINCLUDES)
JANSSON_FOUND = 1
endif
endif
STATICLIBS += $(JANSSONLIB)
LDLIBS += $(JANSSONLIBLD)
INCLUDES += $(JANSSONLIBINC)
## mbed TLS
# system library cannot be used because it is compiled by default without CMAC support
STATICLIBS += $(MBEDTLSLIB)
@ -278,8 +278,8 @@ CXXINCLUDES += $(QTINCLUDES)
## Readline
ifneq ($(SKIPREADLINE),1)
ifeq ($(platform),Darwin)
LDLIBS += -L/usr/local/opt/readline/lib
INCLUDES += -I/usr/local/opt/readline/include
LDLIBS += -L$(BREW_PREFIX)/opt/readline/lib
INCLUDES += -I$(BREW_PREFIX)/opt/readline/include
endif
LDLIBS += -lreadline
READLINE_FOUND = 1
@ -469,10 +469,12 @@ SRCS = aiddesfire.c \
cmdhf15.c \
cmdhfcryptorf.c \
cmdhfepa.c \
cmdhfemrtd.c \
cmdhffelica.c \
cmdhffido.c \
cmdhficlass.c \
cmdhflegic.c \
cmdhfjooki.c \
cmdhflist.c \
cmdhflto.c \
cmdhfmf.c \

View file

@ -106,6 +106,7 @@ add_library(pm3rrg_rdv4 SHARED
${PM3_ROOT}/client/src/cmdhf15.c
${PM3_ROOT}/client/src/cmdhfcryptorf.c
${PM3_ROOT}/client/src/cmdhfepa.c
${PM3_ROOT}/client/src/cmdhfemrtd.c
${PM3_ROOT}/client/src/cmdhffelica.c
${PM3_ROOT}/client/src/cmdhffido.c
${PM3_ROOT}/client/src/cmdhficlass.c
@ -126,9 +127,11 @@ add_library(pm3rrg_rdv4 SHARED
${PM3_ROOT}/client/src/cmdlfawid.c
${PM3_ROOT}/client/src/cmdlfcotag.c
${PM3_ROOT}/client/src/cmdlfdestron.c
${PM3_ROOT}/client/src/cmdlfem4x.c
${PM3_ROOT}/client/src/cmdlfem.c
${PM3_ROOT}/client/src/cmdlfem410x.c
${PM3_ROOT}/client/src/cmdlfem4x05.c
${PM3_ROOT}/client/src/cmdlfem4x50.c
${PM3_ROOT}/client/src/cmdlfem4x70.c
${PM3_ROOT}/client/src/cmdlffdxb.c
${PM3_ROOT}/client/src/cmdlfgallagher.c
${PM3_ROOT}/client/src/cmdlfguard.c

View file

@ -74,13 +74,13 @@ static bool OpenPm3(void) {
jint Console(JNIEnv *env, jobject instance, jstring cmd_) {
if (!conn.run) {
if (OpenPm3() && TestProxmark() == PM3_SUCCESS) {
if (OpenPm3() && TestProxmark(session.current_device) == PM3_SUCCESS) {
LOGD("Connected to device");
PrintAndLogEx(SUCCESS, "Connected to device");
} else {
LOGD("Failed to connect to device");
PrintAndLogEx(ERR, "Failed to connect to device");
CloseProxmark();
CloseProxmark(session.current_device);
}
}
@ -110,10 +110,10 @@ jboolean IsClientRunning(JNIEnv *env, jobject instance) {
* */
jboolean TestPm3(JNIEnv *env, jobject instance) {
if (open() == false) {
CloseProxmark();
CloseProxmark(session.current_device);
return false;
}
bool ret = (TestProxmark() == PM3_SUCCESS);
bool ret = (TestProxmark(session.current_device) == PM3_SUCCESS);
return (jboolean)(ret);
}
@ -121,7 +121,7 @@ jboolean TestPm3(JNIEnv *env, jobject instance) {
* stop pm3 client
* */
void ClosePm3(JNIEnv *env, jobject instance) {
CloseProxmark();
CloseProxmark(session.current_device);
}
/*

View file

@ -3,4 +3,4 @@
mem load -f mfc_default_keys --mfc
mem load -f t55xx_default_pwds --t55xx
mem load -f iclass_default_keys --iclass
lf t55xx deviceconfig z p
lf t55xx deviceconfig -z -p

View file

@ -14,10 +14,18 @@ add_library(pm3rrg_rdv4_amiibo STATIC
if (NOT TARGET pm3rrg_rdv4_mbedtls)
include(mbedtls.cmake)
endif()
target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE
m
pm3rrg_rdv4_mbedtls)
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE ../../include ../../common)
target_include_directories(pm3rrg_rdv4_amiibo INTERFACE amiitool)
target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3)
set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool
../../common
../../include
../src
jansson)
target_include_directories(pm3rrg_rdv4_amiibo INTERFACE amiitool)

View file

@ -1,5 +1,5 @@
MYSRCPATHS =
MYINCLUDES = -I. -I.. -I../jansson -I../../../common -I../../../common/mbedtls -I../../../include
MYINCLUDES = -I. -I.. -I../../../common -I../../../common/mbedtls -I../../../include -I../../src -I../../../include -I../jansson
MYCFLAGS =
MYDEFS =
MYSRCS = \

View file

@ -9,6 +9,7 @@
#include "md.h"
#include "aes.h"
#include "commonutil.h"
#include "../src/fileutils.h"
#define HMAC_POS_DATA 0x008
#define HMAC_POS_TAG 0x1B4
@ -131,24 +132,29 @@ void nfc3d_amiibo_pack(const nfc3d_amiibo_keys *amiiboKeys, const uint8_t *plain
nfc3d_amiibo_internal_to_tag(cipher, tag);
}
bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys, const char *path) {
FILE *f = fopen(path, "rb");
if (!f) {
bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys) {
#define amiboo_key_fn "key_retail.bin"
uint8_t *dump = NULL;
size_t bytes_read = 0;
if (loadFile_safe(amiboo_key_fn, "", (void **)&dump, &bytes_read) != PM3_SUCCESS) {
PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", amiboo_key_fn);
return false;
}
size_t len = fread(amiiboKeys, sizeof(*amiiboKeys), 1, f);
fclose(f);
if (len != sizeof(*amiiboKeys)) {
if (bytes_read != sizeof(*amiiboKeys)) {
free(dump);
return false;
}
if ((amiiboKeys->data.magicBytesSize > 16) ||
(amiiboKeys->tag.magicBytesSize > 16)) {
if ((amiiboKeys->data.magicBytesSize > 16) || (amiiboKeys->tag.magicBytesSize > 16)) {
free(dump);
return false;
}
memcpy(amiiboKeys, dump, bytes_read);
free(dump);
return true;
}

View file

@ -25,7 +25,7 @@ typedef struct {
bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys *amiiboKeys, const uint8_t *tag, uint8_t *plain);
void nfc3d_amiibo_pack(const nfc3d_amiibo_keys *amiiboKeys, const uint8_t *plain, uint8_t *tag);
bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys, const char *path);
bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys);
void nfc3d_amiibo_copy_app_data(const uint8_t *src, uint8_t *dst);
#endif

View file

@ -33,15 +33,6 @@ void amiitool_usage(void) {
);
}
static bool LoadAmiikey(nfc3d_amiibo_keys keys, char *keyfile) {
if (!nfc3d_amiibo_load_keys(&keys, keyfile)) {
PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile);
return false;
}
return true;
}
int main(int argc, char **argv) {
self = argv[0];

View file

@ -830,7 +830,7 @@ static void arg_date_errorfn(
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);
@ -846,11 +846,11 @@ static void arg_date_errorfn(
struct tm tm;
char buff[200];
fprintf(fp, "illegal timestamp format \"%s\"\n", argval);
fprintf(fp, "[!] illegal timestamp format \"%s\"\n", argval);
memset(&tm, 0, sizeof(tm));
arg_strptime("1999-12-31 23:59:59", "%F %H:%M:%S", &tm);
strftime(buff, sizeof(buff), parent->format, &tm);
printf("correct format is \"%s\"\n", buff);
printf("[+] correct format is \"%s\"\n", buff);
break;
}
}
@ -1442,7 +1442,7 @@ static void arg_dbl_errorfn(
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);
@ -1455,7 +1455,7 @@ static void arg_dbl_errorfn(
break;
case EBADDOUBLE:
fprintf(fp, "invalid argument \"%s\" to option ", argval);
fprintf(fp, "[!] invalid argument \"%s\" to option ", argval);
arg_print_option(fp, shortopts, longopts, datatype, "\n");
break;
}
@ -1805,7 +1805,7 @@ static void arg_file_errorfn(
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);
@ -1818,7 +1818,7 @@ static void arg_file_errorfn(
break;
default:
fprintf(fp, "unknown error at \"%s\"\n", argval);
fprintf(fp, "[!] unknown error at \"%s\"\n", argval);
}
}
@ -2136,7 +2136,7 @@ static void arg_int_errorfn(
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);
@ -2149,7 +2149,7 @@ static void arg_int_errorfn(
break;
case EBADINT:
fprintf(fp, "invalid argument \"%s\" to option ", argval);
fprintf(fp, "[!] invalid argument \"%s\" to option ", argval);
arg_print_option(fp, shortopts, longopts, datatype, "\n");
break;
@ -2394,7 +2394,7 @@ static void arg_u64_errorfn(
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);
@ -2407,7 +2407,7 @@ static void arg_u64_errorfn(
break;
case EBADINT:
fprintf(fp, "invalid argument \"%s\" to option ", argval);
fprintf(fp, "[!] invalid argument \"%s\" to option ", argval);
arg_print_option(fp, shortopts, longopts, datatype, "\n");
break;
@ -2554,18 +2554,18 @@ static void arg_lit_errorfn(
switch (errorcode) {
case EMINCOUNT:
fprintf(fp, "%s: missing option ", progname);
fprintf(fp, "[!] %s: missing option ", progname);
arg_print_option(fp, shortopts, longopts, datatype, "\n");
fprintf(fp, "\n");
break;
case EMAXCOUNT:
fprintf(fp, "%s: extraneous option ", progname);
fprintf(fp, "[!] %s: extraneous option ", progname);
arg_print_option(fp, shortopts, longopts, datatype, "\n");
break;
}
ARG_TRACE(("%s:errorfn(%p, %p, %d, %s, %s)\n", __FILE__, parent, fp,
ARG_TRACE(("[!] %s:errorfn(%p, %p, %d, %s, %s)\n", __FILE__, parent, fp,
errorcode, argval, progname));
}
@ -2859,7 +2859,7 @@ static void arg_rex_errorfn(struct arg_rex *parent,
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);
@ -3790,7 +3790,7 @@ static void arg_str_errorfn(
/* make argval NULL safe */
argval = argval ? argval : "";
fprintf(fp, "%s: ", progname);
fprintf(fp, "[!] %s: ", progname);
switch (errorcode) {
case EMINCOUNT:
fputs("missing option ", fp);

View file

@ -118,7 +118,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
if (nerrors > 0) {
/* Display the error details contained in the arg_end struct.*/
arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName);
PrintAndLogEx(WARNING, "Try '%s --help' for more information.\n", ctx->programName);
PrintAndLogEx(WARNING, "Try " _YELLOW_("'%s --help'") " for more information.\n", ctx->programName);
fflush(stdout);
return 3;
}
@ -269,15 +269,19 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
return 0;
}
// hexstr -> u64, w optional len input and default value fallback.
// 0 = failed
// 1 = OK
// 3 = optional param - not set
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def) {
uint64_t rv = 0;
uint8_t data[8];
int datalen = 0;
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), &datalen);
if (res == 0 && datalen > 0) {
for (uint8_t i = 0; i < datalen; i++) {
uint8_t d[8];
int dlen = 0;
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &dlen);
if (res == 0 && dlen > 0) {
for (uint8_t i = 0; i < dlen; i++) {
rv <<= 8;
rv |= data[i];
rv |= d[i];
}
} else {
rv = def;
@ -285,4 +289,56 @@ uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_
return rv;
}
// hexstr -> u64, w optional len input and default value fallback.
// 0 = failed
// 1 = OK
// 2 = wrong len param, use default
// 3 = optional param, if fail, use default.
int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional) {
int n = 0;
uint8_t d[nlen];
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &n);
if (res == 0 && n == nlen) {
uint64_t rv = 0;
for (uint8_t i = 0; i < n; i++) {
rv <<= 8;
rv |= d[i];
}
*out = rv;
return 1;
} else if (res == 0 && n) {
*out = def;
return 2;
} else if (res == 0 && n == 0 && optional) {
*out = def;
return 3;
}
return 0;
}
int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out) {
return arg_get_u32_hexstr_def_nlen(ctx, paramnum, def, out, 4, false);
}
int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out, uint8_t nlen, bool optional) {
int n = 0;
uint8_t d[nlen];
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), d, sizeof(d), &n);
if (res == 0 && n == nlen) {
uint32_t rv = 0;
for (uint8_t i = 0; i < n; i++) {
rv <<= 8;
rv |= d[i];
}
*out = rv;
return 1;
} else if (res == 0 && n) {
*out = def;
return 2;
} else if (res == 0 && n == 0 && optional) {
*out = def;
return 3;
}
return 0;
}

View file

@ -68,4 +68,13 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def);
int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional);
int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out);
int arg_get_u32_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out, uint8_t nlen, bool optional);
#define CP_SUCCESS_OPTIONAL 1
#define CP_SUCCESS 0
#define CP_ENOPARAM -1
#define CP_WRONGLEN -2
#endif

View file

@ -143,7 +143,7 @@ bitslice_test_nonces_t bitslice_test_nonces_NOSIMD;
bitslice_test_nonces_t bitslice_test_nonces_dispatch;
#if defined (_WIN32)
#define malloc_bitslice(x) __builtin_assume_aligned(_aligned_malloc((x), MAX_BITSLICES/8), MAX_BITSLICES/8)
#define malloc_bitslice(x) __builtin_assume_aligned(_aligned_malloc((x), MAX_BITSLICES / 8), MAX_BITSLICES / 8)
#define free_bitslice(x) _aligned_free(x)
#elif defined (__APPLE__)
static void *malloc_bitslice(size_t x) {
@ -156,7 +156,7 @@ static void *malloc_bitslice(size_t x) {
}
#define free_bitslice(x) free(x)
#else
#define malloc_bitslice(x) memalign(MAX_BITSLICES/8, (x))
#define malloc_bitslice(x) memalign(MAX_BITSLICES / 8, (x))
#define free_bitslice(x) free(x)
#endif
@ -559,6 +559,10 @@ void SetSIMDInstr(SIMDExecInstr instr) {
static SIMDExecInstr GetSIMDInstr(void) {
SIMDExecInstr instr;
#if defined(COMPILER_HAS_SIMD)
__builtin_cpu_init();
#endif
#if defined(COMPILER_HAS_SIMD_AVX512)
if (__builtin_cpu_supports("avx512f"))
instr = SIMD_AVX512;

View file

@ -465,7 +465,8 @@ float brute_force_benchmark(void) {
free(test_candidates[0].states[ODD_STATE]);
free(test_candidates[0].states[EVEN_STATE]);
test_candidates[0].len[ODD_STATE] = 0;
test_candidates[0].len[EVEN_STATE] = 0;
return bf_rate;
}

View file

@ -25,7 +25,7 @@
typedef struct guess_sum_a8 {
float prob;
uint64_t num_states;
uint8_t sum_a8_idx;
uint16_t sum_a8_idx;
} guess_sum_a8_t;
typedef struct noncelistentry {
@ -40,7 +40,7 @@ typedef struct noncelist {
guess_sum_a8_t sum_a8_guess[NUM_SUMS];
bool sum_a8_guess_dirty;
float expected_num_brute_force;
uint8_t BitFlips[0x400];
uint16_t BitFlips[0x400];
uint32_t *states_bitarray[2];
uint32_t num_states_bitarray[2];
bool all_bitflips_dirty[2];

View file

@ -372,10 +372,11 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
count[odd_even] = count_states(test_bitarray[odd_even]);
if (count[odd_even] != 1 << 24) {
printf("Writing %u possible %s states for bitflip property %03x (%d (%1.2f%%) states eliminated)\n",
printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
count[odd_even],
odd_even == EVEN_STATE ? "even" : "odd",
bitflip, (1 << 24) - count[odd_even],
bitflip,
(1 << 24) - count[odd_even],
(float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
#ifndef TEST_RUN
write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even], count[odd_even]);
@ -399,10 +400,11 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
}
count[odd_even] = count_states(test_bitarray_2nd);
if (count[odd_even] != 1 << 24) {
printf("Writing %u possible %s states for bitflip property %03x (%d (%1.2f%%) states eliminated)\n",
printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
count[odd_even],
odd_even == EVEN_STATE ? "even" : "odd",
bitflip | BITFLIP_2ND_BYTE, (1 << 24) - count[odd_even],
bitflip | BITFLIP_2ND_BYTE,
(1 << 24) - count[odd_even],
(float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
#ifndef TEST_RUN
write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
@ -484,10 +486,11 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
count[odd_even] = count_states(test_not_bitarray[odd_even]);
if (count[odd_even] != 1 << 24) {
printf("Writing %u possible %s states for bitflip property %03x (%d (%1.2f%%) states eliminated)\n",
printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
count[odd_even],
odd_even == EVEN_STATE ? "even" : "odd",
bitflip | 0x100, (1 << 24) - count[odd_even],
bitflip | 0x100,
(1 << 24) - count[odd_even],
(float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
#ifndef TEST_RUN
write_bitflips_file(odd_even, bitflip | 0x100, sum_a0, test_not_bitarray[odd_even], count[odd_even]);
@ -511,10 +514,11 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
}
count[odd_even] = count_states(test_bitarray_2nd);
if (count[odd_even] != 1 << 24) {
printf("Writing %u possible %s states for bitflip property %03x (%d (%1.2f%%) states eliminated)\n",
printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
count[odd_even],
odd_even == EVEN_STATE ? "even" : "odd",
bitflip | 0x100 | BITFLIP_2ND_BYTE, (1 << 24) - count[odd_even],
bitflip | 0x100 | BITFLIP_2ND_BYTE,
(1 << 24) - count[odd_even],
(float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
#ifndef TEST_RUN
write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
@ -532,7 +536,6 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
free_bitarray(test_not_bitarray[EVEN_STATE]);
free_bitarray(test_bitarray[ODD_STATE]);
free_bitarray(test_bitarray[EVEN_STATE]);
exit(0);
}

View file

@ -1283,4 +1283,13 @@ AABAFFCC7612
17D071403C20
#
534F4C415249
534f4c303232
534f4c303232
#
# Nespresso, smart card
# key-gen algo, these keys are for one card
ff9a84635bd2
6f30126ee7e4
6039abb101bb
f1a1239a4487
#
b882fd4a9f78

View file

@ -8,6 +8,7 @@
43464F494D48504E4C4359454E528841 #NHIF
6AC292FAA1315B4D858AB3A3D7D5933A
404142434445464748494a4b4c4d4e4f
3112B738D8862CCD34302EB299AAB456 # Gallagher AES (https://pastebin.com/GkbGLz8r)
00112233445566778899aabbccddeeff
2b7e151628aed2a6abf7158809cf4f3c
fbeed618357133667c85e08f7236a8de
@ -43,4 +44,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
404142434445464748494a4b4c4d4e4f
303132333435363738393a3b3c3d3e3f
9CABF398358405AE2F0E2B3D31C99A8A # Default key
605F5E5D5C5B5A59605F5E5D5C5B5A59 # access control
605F5E5D5C5B5A59605F5E5D5C5B5A59 # access control

View file

@ -27,6 +27,8 @@ A5B4C3D2
00434343
44B44CAE
88661858
# MKF fobs
E9920427
# paxton bullit?
575F4F4B
#

View file

@ -32,4 +32,4 @@ rm $2
echo "hf mf eclr" >> $2
echo "hf mf eload" $1 >> $2
echo "hf mf ekeyprn" >> $2
echo "hf mf sim u" `cat $1.eml | (read -n 8 uid; echo $uid)` >> $2
echo "hf mf sim -u" `cat $1.eml | (read -n 8 uid; echo $uid)` >> $2

View file

@ -6,7 +6,7 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Martin Holst Swende'
version = 'v1.0.2'
version = 'v1.0.3'
desc = [[
This script takes a dumpfile from 'hf mf dump' and converts it to a format that can be used
by the emulator
@ -46,7 +46,7 @@ end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
print('[!!] ERROR:', err)
core.clearCommandBuffer()
return nil, err
end
@ -115,8 +115,7 @@ local function main(args)
local dumpdata = readdump(infile)
-- The hex-data is now in ascii-format,
if dumpdata == NIL then return oops('Dumpfle not loaded') end
if dumpdata == nil then return oops('Dumpfle not loaded') end
-- But first, check the uid
local uid = string.sub(dumpdata, 1, 8)
@ -124,8 +123,7 @@ local function main(args)
-- Format some linebreaks
dumpdata = convert_to_emulform(dumpdata)
if dumpdata == NIL then return oops('Dumpfle not loaded') end
if dumpdata == nil then return oops('Dumpfle not loaded') end
local outfile = io.open(output, 'w')
if outfile == nil then
@ -134,7 +132,7 @@ local function main(args)
outfile:write(dumpdata:lower())
io.close(outfile)
print(('Wrote an emulator-dump to the file %s'):format(output))
print(('[+] Wrote an emulator-dump to the file %s'):format(output))
end

View file

@ -7,7 +7,7 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Martin Holst Swende'
version = 'v1.0.2'
version = 'v1.0.3'
desc =[[
This script takes a dumpfile and produces a html based dump, which is a
bit more easily analyzed.
@ -45,7 +45,7 @@ end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
print('[!!] ERROR:', err)
core.clearCommandBuffer()
return nil, err
end
@ -76,7 +76,7 @@ local function main(args)
local filename, err = dumplib.convert_bin_to_html(input,output, 16)
if err then return oops(err) end
print(('Wrote a HTML dump to the file %s'):format(filename))
print(('[+] Wrote a HTML dump to the file %s'):format(filename))
end
--[[

View file

@ -5,7 +5,7 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Iceman'
version = 'v1.0.2'
version = 'v1.0.3'
desc =[[
This script takes an dumpfile in EML (ASCII) format and converts it to the PM3 dumpbin file to be used with `hf mf restore`
]]
@ -40,7 +40,7 @@ end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
print('[!!] ERROR:', err)
core.clearCommandBuffer()
return nil, err
end
@ -82,7 +82,7 @@ local function main(args)
local filename, err = dumplib.convert_eml_to_bin(input,output)
if err then return oops(err) end
ExitMsg(('Wrote a BIN dump to the file %s'):format(filename))
ExitMsg(('[+] Wrote a BIN dump to the file %s'):format(filename))
end
main(args)

View file

@ -7,7 +7,7 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Martin Holst Swende'
version = 'v1.0.2'
version = 'v1.0.3'
desc = [[
This script takes a dumpfile on EML (ASCII) format and produces a html based dump, which is a
bit more easily analyzed.
@ -44,7 +44,7 @@ end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
print('[!!] ERROR:', err)
core.clearCommandBuffer()
return nil, err
end
@ -75,7 +75,7 @@ local function main(args)
local filename, err = dumplib.convert_eml_to_html(input,output)
if err then return oops(err) end
print(('Wrote a HTML dump to the file %s'):format(filename))
print(('[+] Wrote a HTML dump to the file %s'):format(filename))
end
--[[

View file

@ -6,16 +6,16 @@ local ansicolors = require('ansicolors')
copyright = ''
author = "Martin Holst Swende \n @Marshmellow \n @iceman"
version = 'v1.0.2'
version = 'v1.0.4'
desc =[[
This script takes a dumpfile from 'hf mfu dump' and converts it to a format that can be used
by the emulator
]]
example = [[
script run hf_mfu_dumptoemulator -i dumpdata-foobar.bin
script run data_mfu_bin2eml -i dumpdata-foobar.bin
]]
usage = [[
script run hf_mfu_dumptoemulator [-i <file>] [-o <file>]
script run data_mfu_bin2eml [-i <file>] [-o <file>]
]]
arguments = [[
-h This help
@ -43,7 +43,7 @@ end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
print('[!!] ERROR:', err)
core.clearCommandBuffer()
return nil, err
end
@ -133,7 +133,7 @@ local function main(args)
outfile:write(dumpdata:lower())
io.close(outfile)
print(('Wrote an emulator-dump to the file %s'):format(output))
print(('[+] Wrote an emulator-dump to the file %s'):format(output))
end
--[[

View file

@ -582,14 +582,14 @@ function writeToTag(tag)
-- write pm3-buffer to Tag
for i=1, WriteBytes do
if (i > 7) then
cmd = ("hf legic wrbl o %02x d %s "):format(i-1, padString(bytes[i]))
cmd = ("hf legic wrbl -o %d -d %s "):format(i-1, padString(bytes[i]))
print(acgreen..cmd..acoff)
core.console(cmd)
core.clearCommandBuffer()
elseif (i == 7) then
if (writeDCF) then
-- write DCF in reverse order (requires 'mosci-patch')
cmd = ('hf legic wrbl o 05 d %s%s'):format(padString(bytes[i-1]), padString(bytes[i]))
cmd = ('hf legic wrbl -o 5 -d %s%s'):format(padString(bytes[i-1]), padString(bytes[i]))
print(acgreen..cmd..acoff)
core.console(cmd)
core.clearCommandBuffer()
@ -704,13 +704,32 @@ function writeFile(bytes, filename)
return true
end
function getRandomTempName()
local upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local lowerCase = "abcdefghijklmnopqrstuvwxyz"
local characterSet = upperCase .. lowerCase
local keyLength = 8
local output = ""
for i = 1, keyLength do
local rand = math.random(#characterSet)
output = output .. string.sub(characterSet, rand, rand)
end
output = "hf-legic-temp-" .. output
return output
end
---
-- read from pm3 into virtual-tag
function readFromPM3()
local tag, bytes, infile
--infile="legic.temp"
infile=os.tmpname()
core.console("hf legic dump f "..infile)
infile=getRandomTempName()
core.console("hf legic dump -f "..infile)
tag=readFile(infile..".bin")
os.remove(infile)
os.remove(infile..".bin")

View file

@ -456,7 +456,7 @@ local function writeToTag(plainBytes)
-- write data to file
if (writeOutputBytes(bytes, "hf-legic-UID-dump.bin")) then
-- write pm3-buffer to Tag
cmd = ('hf legic restore f hf-legic-UID-dump')
cmd = ('hf legic restore -f hf-legic-UID-dump')
core.console(cmd)
end
end
@ -530,13 +530,13 @@ local function main(args)
res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:"
res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc, -2)
res = res .."\nyou may load the new file with:"
res = res ..ansicolors.yellow.."hf legic eload f "..outfile..ansicolors.reset
res = res ..ansicolors.yellow.."hf legic eload -f "..outfile..ansicolors.reset
res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC"
res = res .."\nafter writing this dump to a tag!"
res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3, Segment-Header0..3"
res = res .."\ne.g. (based on Segment00 of the data from "..infile.."):"
res = res .."\n"
res = res ..ansicolors.yellow.."hf legic crc d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." u "..newcrc.." c 8"..ansicolors.reset
res = res ..ansicolors.yellow.."hf legic crc -d "..bytes[1]..bytes[2]..bytes[3]..bytes[4]..bytes[23]..bytes[24]..bytes[25]..bytes[26].." --mcc "..newcrc.." -t 8"..ansicolors.reset
-- this can not be calculated without knowing the new MCD, MSN0..2
print(res)
end

View file

@ -99,7 +99,7 @@ local function nested(key,sak)
else
print("I don't know how many sectors there are on this type of card, defaulting to 16")
end
local cmd = string.format('hf mf nested %d 0 A %s d', typ, key)
local cmd = string.format('hf mf nested -t %d -b 0 --keya -k %s --dumpkeys', typ, key)
core.console(cmd)
end
@ -123,7 +123,7 @@ local function dump_tag(uid, numsectors)
local dumpfile = 'hf-mf-'..uid..'-dump'
local dmp = ('hf mf dump %s f %s'):format(typ, dumpfile)
local dmp = ('hf mf dump -t %s -f %s'):format(typ, dumpfile)
core.console(dmp)
-- Save the global args, those are *our* arguments

View file

@ -14,7 +14,7 @@ This script will generate 'hf mf wrbl' commands for each block to format a Mifar
Alla datablocks gets 0x00
As default the script sets the keys A/B to 0xFFFFFFFFFFFF
and the access bytes will become 0x78,0x77,0x88
The GDB will become 0x00
The GPB will become 0x00
The script will skip the manufactoring block 0.
]]
@ -169,7 +169,7 @@ local function main(args)
GetCardInfo()
-- Show info
print( string.format('Estimating number of blocks: %d', numBlocks))
print( string.format('Estimating number of blocks: %d', numBlocks + 1))
print( string.format('Old key: %s', OldKey))
print( string.format('New key: %s', NewKey))
print( string.format('New Access: %s', Accessbytes))

View file

@ -147,7 +147,7 @@ local function main(args)
--Trying to find the other keys
if useNested then
core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
core.console( ('hf mf nested -t 1 -b 0 --keya -k %s --dumpkeys'):format(keyA) )
end
core.clearCommandBuffer()

View file

@ -496,7 +496,7 @@ local function main(args)
err = LoadEmulator(uid, blocks)
if err then return oops(err) end
core.clearCommandBuffer()
print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..'\" <--')
print('The simulation is now prepared.\n --> run \"hf mf sim -u '..uid..'\" <--')
end
end
main(args)

View file

@ -99,10 +99,10 @@ local function main(args)
local command = ''
if mftype == 'mfc' then
command = 'hf 14a sim t 1 u %014x'
command = 'hf 14a sim -t 1 -u %014x'
msg('Bruteforcing Mifare Classic card numbers')
elseif mftype == 'mfu' then
command = 'hf 14a sim t 2 u %014x'
command = 'hf 14a sim -t 2 -u %014x'
msg('Bruteforcing Mifare Ultralight card numbers')
else
return print(usage)

View file

@ -44,8 +44,8 @@ arguments = [[
-c read magic configuration
-u UID (14 hexsymbols), set UID on tag
-t tag type to impersonate
1 = UL_EV1 48k
2 = UL_EV1 128k
1 = UL EV1 48b
2 = UL EV1 128b
3 = NTAG 210
4 = NTAG 212
5 = NTAG 213 (true)
@ -60,7 +60,7 @@ arguments = [[
-p password (8 hexsymbols), set password on tag.
-a pack ( 4 hexsymbols), set pack on tag.
-s signature data (64 hexsymbols), set signature data on tag.
-o OTP data (8 hexsymbols), set one-time-pad data on tag.
-o OTP data (8 hexsymbols), set `One-Time Programmable` data on tag.
-v version data (16 hexsymbols), set version data on tag.
-w wipe tag. You can specify password if the tag has been locked down. Fills tag with zeros and put default values for NTAG213 (like -t 5)
-k pwd to use with the wipe option

View file

@ -4,26 +4,32 @@ local ansicolors = require('ansicolors')
copyright = ''
author = "Iceman"
version = 'v1.0.2'
version = 'v1.0.3'
desc = [[
This script tries to set UID on a mifare Ultralight magic card which either
- answers to chinese backdoor commands
- brickable magic tag (must write in one session)
It defaults to GEN1A type of uid changeable card.
]]
example = [[
-- backdoor magic tag
-- backdoor magic tag (gen1a)
script run hf_mfu_setuid -u 11223344556677
-- brickable magic tag
-- backdoor magic tag (gen1b)
script run hf_mfu_setuid -b -u 11223344556677
-- brickable magic tag (gen2)
script run hf_mfu_setuid -2 -u 11223344556677
]]
usage = [[
script run hf_mfu_setuid [-h] [-b] [-u <uid>]
script run hf_mfu_setuid [-h] [-b] [-2] [-u <uid>]
]]
arguments = [[
-h : this help
-u <UID> : UID (14 hexsymbols)
-b : write to brickable magic tag
-b : write to magic tag GEN1B
-2 : write to brickable magic tag GEN2
]]
local DEBUG = true
@ -65,23 +71,33 @@ local function help()
end
--
--- Set UID on magic command enabled
function magicUID(b0, b1, b2)
function magicUID(b0, b1, b2, isgen1a)
print('Using backdoor Magic tag function')
if isgen1a then
print('Using backdoor Magic tag (gen1a) function')
else
print('Using backdoor Magic tag (gen1b) function')
end
-- write block 0
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
if isgen1a then
core.console('hf 14a raw -k -a 43')
end
core.console('hf 14a raw -c -a A200'..b0)
-- write block 1
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
if isgen1a then
core.console('hf 14a raw -k -a 43')
end
core.console('hf 14a raw -c -a A201'..b1)
-- write block 2
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
if isgen1a then
core.console('hf 14a raw -k -a 43')
end
core.console('hf 14a raw -c -a A202'..b2)
end
--
@ -113,10 +129,11 @@ function main(args)
local tagtype = 1
-- Read the parameters
for o, a in getopt.getopt(args, 'hu:b') do
for o, a in getopt.getopt(args, 'hu:b2') do
if o == 'h' then return help() end
if o == 'u' then uid = a end
if o == 'b' then tagtype = 2 end
if o == '2' then tagtype = 3 end
end
-- uid string checks
@ -137,10 +154,11 @@ function main(args)
core.clearCommandBuffer()
if tagtype == 2 then
if tagtype == 3 then
brickableUID(block0, block1, block2)
else
magicUID(block0, block1, block2)
local is_gen1a = (tagtype == 1)
magicUID(block0, block1, block2, is_gen1a)
end
--halt

View file

@ -1,9 +1,10 @@
local getopt = require('getopt')
local ansicolors = require('ansicolors')
local utils = require('utils')
copyright = 'Copyright (c) 2019 IceSQL AB. All rights reserved.'
author = 'Christian Herrmann'
version = 'v1.0.1'
version = 'v1.0.3'
desc = [[
This script initialize a Proxmark3 RDV4.0 with
- uploading dictionary files to flashmem
@ -82,10 +83,14 @@ function main(args)
-- T55x7 Device configuration
print('Configure T55XX device side to match RDV4')
print(dash)
core.console('lf t55xx deviceconfig r 0 a 29 b 17 c 15 d 47 e 15 p')
core.console('lf t55xx deviceconfig r 1 a 29 b 17 c 18 d 50 e 15 p')
core.console('lf t55xx deviceconfig r 2 a 29 b 17 c 18 d 40 e 15 p')
core.console('lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p')
core.console('lf t55xx deviceconfig --r0 -a 29 -b 17 -c 15 -d 47 -e 15 -p')
utils.Sleep(1)
core.console('lf t55xx deviceconfig --r1 -a 29 -b 17 -c 18 -d 50 -e 15 -p')
utils.Sleep(1)
core.console('lf t55xx deviceconfig --r2 -a 29 -b 17 -c 18 -d 40 -e 15 -p')
utils.Sleep(1)
core.console('lf t55xx deviceconfig --r3 -a 29 -b 17 -c 15 -d 31 -e 15 -f 47 -g 63 -p')
utils.Sleep(1)
print('')
print('')

View file

@ -0,0 +1,212 @@
local getopt = require('getopt')
local utils = require('utils')
local ac = require('ansicolors')
copyright = ''
author = "Christian Herrmann"
version = 'v1.0.2'
desc = [[
Perform bulk EM410x enrollment of T5577 RFID tags. It keeps track of last card id used.
If called with -s, this value resets "session".
if press <enter> it defaults to Y, which writes a ID.
Any other input char will exit the script.
You can supply a password, which will set the config block / block 7 on the T5577.
The verify option will issue a 'lf em 410x reader' command, so you can manually verify
that the write worked.
]]
example = [[
-- resets and start enrolling EM410x id 11CC334455
script run lf_em4100_bulk.lua -s 11CC334455
-- continue enrolling from where last iteration
script run lf_em4100_bulk.lua -c
-- reset and start enrolling from 11223344,
-- protecting the tag with password 010203
-- and verify the em id write.
script run lf_em4100_bulk.lua -s 1122334455 -p 01020304 -v
]]
usage = [[
script run lf_en4100_bulk.lua [-h] [-c] [-p password] [-s <start cn>] [-v]
]]
arguments = [[
-h : this help
-c : continue from last card number used
-p : Password protecting the T5577.
-s : starting card number
-v : verify write by executing a `lf em 410x reader`
]]
-- Some globals
local DEBUG = false
local ENROLL_STATUS_FN = 'lf_em4100_status.txt'
---
-- A debug printout-function
local function dbg(args)
if not DEBUG then return end
if type(args) == 'table' then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
print('###', args)
end
end
---
-- This is only meant to be used when errors occur
local function oops(err)
print('ERROR:', err)
core.clearCommandBuffer()
return nil, errr
end
---
-- Usage help
local function help()
print(copyright)
print(author)
print(version)
print(desc)
print(ac.cyan..'Usage'..ac.reset)
print(usage)
print(ac.cyan..'Arguments'..ac.reset)
print(arguments)
print(ac.cyan..'Example usage'..ac.reset)
print(example)
end
---
-- Exit message
local function exitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
---
--
local function readfile()
local f = io.open(ENROLL_STATUS_FN, "r")
if f == nil then
return nil, string.format("Could not read file %s", ENROLL_STATUS_FN)
end
local t = f:read("*all")
f:close()
local cn_hi = tonumber(t:sub(1, 2), 16)
local cn_low = tonumber(t:sub(3, 10), 16)
print(('Using EM4100 ID '..ac.green..'%02X%08X'..ac.reset..' from `'..ac.yellow..'%s'..ac.reset..'`'):format(cn_hi, cn_low, ENROLL_STATUS_FN))
return cn_hi, cn_low
end
---
--
local function writefile(cn_hi, cn_low)
local f = io.open(ENROLL_STATUS_FN, "w")
if f == nil then
return nil, string.format("Could not write to file %s", ENROLL_STATUS_FN)
end
f:write(("%02X%08X\n"):format(cn_hi, cn_low))
f:close()
print(('Wrote EM4100 ID '..ac.green..'%02X%08X'..ac.reset..' to `'..ac.yellow..'%s'..ac.reset..'`'):format(cn_hi, cn_low, ENROLL_STATUS_FN))
return true, 'Ok'
end
---
-- main
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
print()
if #args == 0 then return help() end
local shall_verify = false
local shall_continue = false
local got_pwd = false
local startid = ''
local ipwd = ''
for o, a in getopt.getopt(args, 'cp:s:hv') do
if o == 'h' then return help() end
if o == 'c' then shall_continue = true end
if o == 's' then startid = a end
if o == 'p' then
ipwd = a
got_pwd = true
end
if o == 'v' then shall_verify = true end
end
-- if reset/start over, check -s
if not shall_continue then
if startid == nil then return oops('empty card number string') end
if #startid == 0 then return oops('empty card number string') end
if #startid ~= 10 then return oops('card number wrong length. Must be 5 hex bytes') end
end
if got_pwd then
if ipwd == nil then return oops('empty password') end
if #ipwd == 0 then return oops('empty password') end
if #ipwd ~= 8 then return oops('password wrong length. Must be 4 hex bytes') end
end
core.console('clear')
print(ac.red..'disable hints for less output'..ac.reset)
core.console('pref set hint --off')
print('')
local hi = tonumber(startid:sub(1, 2), 16)
local low = tonumber(startid:sub(3, 10), 16)
local pwd = tonumber(ipwd, 16)
if got_pwd then
print(('Will protect T5577 with password '..ac.green..'%08X'..ac.reset):format(pwd))
end
if shall_verify then
print('Will verify write afterwards')
end
if shall_continue then
print('Continue enrolling from last save')
hi, low = readfile()
else
print('reset & starting enrolling from refresh')
end
local template = 'EM4100 ID '..ac.green..'%02X%08X'..ac.reset
for i = low, low + 10000, 1 do
print('')
print( string.rep('--',20) )
local msg = (template):format(hi, i)
local ans = utils.input(msg, 'y'):lower()
if ans == 'y' then
core.console( ('lf em 410x clone --id %02X%08X'):format(hi, i) )
-- print ( ('lf em 410x clone --id %02X%08X'):format(hi, i) )
if got_pwd then
core.console('lf t55 detect')
core.console(('lf t55 protect -n %08x'):format(pwd))
end
if shall_verify then
core.console('lf em 410x reader')
end
else
print(ac.red..'User aborted'..ac.reset)
low = i
break
end
end
writefile(hi, low)
print('enabling hints again')
core.console('pref set hint --on')
end
main(args)

View file

@ -0,0 +1,104 @@
local getopt = require('getopt')
local lib14a = require('read14a')
local cmds = require('commands')
local ansicolors = require('ansicolors')
copyright = 'Copyright 2021 A. Ozkal, released under GPLv2+.'
author = 'Ave'
version = 'v1.0.0'
desc = [[
This script attempts to grab signatures from an NTAG or MFULEV1 card and print it in a machine parsable way
]]
example = [[
script run ntag_getsig
]]
usage = [[
script run ntag_getsig [-h]
]]
arguments = [[
-h : This help
]]
local function help()
print(author)
print(version)
print(desc)
print(ansicolors.cyan..'Usage'..ansicolors.reset)
print(usage)
print(ansicolors.cyan..'Arguments'..ansicolors.reset)
print(arguments)
print(ansicolors.cyan..'Example usage'..ansicolors.reset)
print(example)
end
-- Used to send raw data to the firmware to subsequently forward the data to the card.
-- from mifareplus.lua
local function sendRaw(rawdata, crc, power)
-- print(("<sent>: %s"):format(rawdata))
local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW
if crc then
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
end
if power then
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
end
local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
arg1 = flags, -- Send raw
arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata
data = rawdata
}
local ignore_response = false
local result, err = command:sendMIX(ignore_response)
if result then
--unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned
local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result)
returned_bytes = string.sub(data, 1, arg1 * 2)
if #returned_bytes > 0 then
-- print(("<recvd>: %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings
return returned_bytes
else
return nil
end
else
print("Error sending the card raw data.")
return nil
end
end
---
-- The main entry point
function main(args)
-- Read the parameters
for o, a in getopt.getopt(args, 'h') do
if o == 'h' then return help() end
end
local tag, err = lib14a.read(true, false)
if not err then
local sig = sendRaw("3C00", true, true)
local ver = sendRaw("60", true, false)
if sig and ver then -- if false, that's a fail right there
sig = string.sub(sig, 0, -5)
ver = string.sub(ver, 0, -5)
local text = tag.name..","..ver..","..tag.uid..","..sig
print(text)
local filename = "originalitysig.csv"
local outfile = io.open(filename, "a")
if outfile ~= nil then
outfile:write(text.."\n")
io.close(outfile)
else
print(ansicolors.red.."Couldn't open file originalitysig.csv."..ansicolors.reset)
end
else
print(ansicolors.red.."Read FAILED."..ansicolors.reset)
end
end
end
main(args)

View file

@ -7,11 +7,11 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Iceman'
version = 'v1.0.3'
version = 'v1.0.4'
desc = [[
This script will load several traces files in current working directory/traces/ folder and do
"data load"
"lf search 1 u"
"lf search -1u"
The following tracefiles will be loaded:
em*.pm3
@ -109,7 +109,7 @@ local function main(args)
end
p.close();
local cmdLFSEARCH = 'lf search 1 u'
local cmdLFSEARCH = 'lf search -1u'
-- main loop
io.write('Starting to test traces > ')

View file

@ -4749,14 +4749,14 @@
"application": "Security and Access Control",
"company": "PEC (New Zealand) Ltd.",
"mad": "0x4811",
"service_provider": "Cardax",
"service_provider": "Cardax / Gallagher",
"system_integrator": ""
},
{
"application": "Security and Access Control",
"company": "PEC (New Zealand) Ltd.",
"mad": "0x4812",
"service_provider": "Cardax",
"service_provider": "Cardax / Gallagher",
"system_integrator": ""
},
{
@ -6096,6 +6096,13 @@
"service_provider": "CDVI",
"system_integrator": "CDVI"
},
{
"application": "(access control and security) VIGIK",
"company": "NORALSY",
"mad": "0x4980",
"service_provider": "NORALSY",
"system_integrator": "NORALSY"
},
{
"application": "Card Administratin, cardholder adminstration, access control & security, company services, miscellaneous applications",
"company": "Ministry of Defense",

View file

@ -36,7 +36,7 @@ static int openAIDFile(json_t **root, bool verbose) {
goto out;
}
if (verbose) PrintAndLogEx(SUCCESS, "Loaded file (%s) OK. %zu records.", path, json_array_size(*root));
PrintAndLogEx(DEBUG, "Loaded file " _YELLOW_("%s") " " _GREEN_("%zu") " records ( " _GREEN_("ok") " )", path, json_array_size(*root));
out:
free(path);
return retval;
@ -145,22 +145,22 @@ int PrintAIDDescription(json_t *xroot, char *aid, bool verbose) {
const char *description = jsonStrGet(elm, "Description");
const char *type = jsonStrGet(elm, "Type");
if (!verbose) {
PrintAndLogEx(SUCCESS, "AID %s | %s | %s", vaid, vendor, name);
if (verbose == false) {
PrintAndLogEx(SUCCESS, "AID : " _YELLOW_("%s") " | %s | %s", vaid, vendor, name);
} else {
PrintAndLogEx(SUCCESS, "Input AID: %s", aid);
PrintAndLogEx(SUCCESS, "Input AID..... " _YELLOW_("%s"), aid);
if (aid)
PrintAndLogEx(SUCCESS, "Found AID: %s", vaid);
PrintAndLogEx(SUCCESS, "Found AID..... " _YELLOW_("%s"), vaid);
if (vendor)
PrintAndLogEx(SUCCESS, "Vendor: %s", vendor);
PrintAndLogEx(SUCCESS, "Vendor........ " _YELLOW_("%s"), vendor);
if (type)
PrintAndLogEx(SUCCESS, "Type: %s", type);
PrintAndLogEx(SUCCESS, "Type.......... " _YELLOW_("%s"), type);
if (name)
PrintAndLogEx(SUCCESS, "Name: %s", name);
PrintAndLogEx(SUCCESS, "Name.......... " _YELLOW_("%s"), name);
if (country)
PrintAndLogEx(SUCCESS, "Country: %s", country);
PrintAndLogEx(SUCCESS, "Country....... %s", country);
if (description)
PrintAndLogEx(SUCCESS, "Description: %s", description);
PrintAndLogEx(SUCCESS, "Description... %s", description);
}
out:

File diff suppressed because it is too large Load diff

View file

@ -769,22 +769,22 @@ static int CmdBiphaseDecodeRaw(const char *Cmd) {
int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) {
//ask raw demod GraphBuffer first
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
size_t size = getFromGraphBuf(BitStream);
uint8_t bs[MAX_DEMOD_BUF_LEN];
size_t size = getFromGraphBuf(bs);
if (size == 0) {
PrintAndLogEx(DEBUG, "DEBUG: no data in graphbuf");
return PM3_ESOFT;
}
int startIdx = 0;
//invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
int errCnt = askdemod_ext(BitStream, &size, &clk, &invert, maxErr, 0, 0, &startIdx);
int errCnt = askdemod_ext(bs, &size, &clk, &invert, maxErr, 0, 0, &startIdx);
if (errCnt < 0 || errCnt > maxErr) {
PrintAndLogEx(DEBUG, "DEBUG: no data or error found %d, clock: %d", errCnt, clk);
return PM3_ESOFT;
}
//attempt to Biphase decode BitStream
errCnt = BiphaseRawDecode(BitStream, &size, &offset, invert);
errCnt = BiphaseRawDecode(bs, &size, &offset, invert);
if (errCnt < 0) {
if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: Error BiphaseRawDecode: %d", errCnt);
return PM3_ESOFT;
@ -795,7 +795,7 @@ int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) {
}
//success set DemodBuffer and return
setDemodBuff(BitStream, size, 0);
setDemodBuff(bs, size, 0);
setClockGrid(clk, startIdx + clk * offset / 2);
if (g_debugMode || verbose) {
PrintAndLogEx(DEBUG, "Biphase Decoded using offset %d | clock %d | #errors %d | start index %d\ndata\n", offset, clk, errCnt, (startIdx + clk * offset / 2));
@ -1428,7 +1428,7 @@ static int CmdRawDemod(const char *Cmd) {
else if (str_startswith(Cmd, "am")) ans = Cmdaskmandemod(Cmd + 2);
else if (str_startswith(Cmd, "ar")) ans = Cmdaskrawdemod(Cmd + 2);
else if (str_startswith(Cmd, "nr") || Cmd[0] == 'n') ans = CmdNRZrawDemod(Cmd + 2);
else if (str_startswith(Cmd, "p1") || Cmd[0] == 'p') ans = CmdPSK1rawDemod(Cmd + 2);
else if (str_startswith(Cmd, "p1")) ans = CmdPSK1rawDemod(Cmd + 2);
else if (str_startswith(Cmd, "p2")) ans = CmdPSK2rawDemod(Cmd + 2);
else PrintAndLogEx(WARNING, "Unknown modulation entered - see help ('h') for parameter structure");
@ -1576,7 +1576,7 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose) {
uint32_t n = end - start;
if (n <= 0 || n > pm3_capabilities.bigbuf_size - 1)
if (n == 0 || n > pm3_capabilities.bigbuf_size - 1)
n = pm3_capabilities.bigbuf_size - 1;
if (verbose)

View file

@ -11,7 +11,7 @@
#include <ctype.h>
#include "cmdparser.h" // command_t
#include "cliparser.h"
#include "pmflash.h"
#include "pmflash.h" // rdv40validation_t
#include "fileutils.h" // saveFile
#include "comms.h" // getfromdevice
#include "cmdflashmemspiffs.h" // spiffs commands
@ -26,6 +26,123 @@
static int CmdHelp(const char *Cmd);
//-------------------------------------------------------------------------------------
// RRG Public RSA Key
#define RRG_RSA_KEY_LEN 128
// public key Exponent E
#define RRG_RSA_E "010001"
// public key modulus N
#define RRG_RSA_N "E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF" \
"4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F" \
"9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \
"DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
// Following example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c)
// private key - Exponent D
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
"66CA472BC44D253102F8B4A9D3BFA750" \
"91386C0077937FE33FA3252D28855837" \
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
"DF79C5CE07EE72C7F123142198164234" \
"CABB724CF78B8173B9F880FC86322407" \
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
"071513A1E85B5DFA031F21ECAE91A34D"
// prime P
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
"2C01CAD19EA484A87EA4377637E75500" \
"FCB2005C5C7DD6EC4AC023CDA285D796" \
"C3D9E75E1EFC42488BB4F1D13AC30A57"
// prime Q
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
"910E4168387E3C30AA1E00C339A79508" \
"8452DD96A9A5EA5D9DCA68DA636032AF"
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
"3C94D22288ACD763FD8E5600ED4A702D" \
"F84198A5F06C2E72236AE490C93F07F8" \
"3CC559CD27BC2D1CA488811730BB5725"
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
"D8AAEA56749EA28623272E4F7D0592AF" \
"7C1F1313CAC9471B5C523BFE592F517B" \
"407A1BD76C164B93DA2D32A383E58357"
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
"F38D18D2B2F0E2DD275AA977E2BF4411" \
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
"A74206CEC169D74BF5A8C50D6F48EA08"
int rdv4_get_signature(rdv40_validation_t *out) {
if (out == NULL) {
return PM3_EINVARG;
}
clearCommandBuffer();
SendCommandNG(CMD_FLASHMEM_INFO, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply");
return PM3_ETIMEOUT;
}
uint8_t isok = resp.oldarg[0] & 0xFF;
if (isok == false) {
PrintAndLogEx(FAILED, "fail reading from flashmemory");
return PM3_EFLASH;
}
//rdv40_validation_t mem;
memcpy(out, (rdv40_validation_t *)resp.data.asBytes, sizeof(rdv40_validation_t));
return PM3_SUCCESS;
}
// validate signature
int rdv4_validate(rdv40_validation_t *mem) {
// Flash ID hash (sha1)
uint8_t sha_hash[20] = {0};
mbedtls_sha1(mem->flashid, sizeof(mem->flashid), sha_hash);
// set up RSA
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
rsa.len = RRG_RSA_KEY_LEN;
mbedtls_mpi_read_string(&rsa.N, 16, RRG_RSA_N);
mbedtls_mpi_read_string(&rsa.E, 16, RRG_RSA_E);
// Verify (public key)
int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, mem->signature);
mbedtls_rsa_free(&rsa);
if (is_verified == 0) {
return PM3_SUCCESS;
}
return PM3_EFAILED;
}
static int rdv4_sign_write(uint8_t *signature, uint8_t slen){
// save to mem
clearCommandBuffer();
PacketResponseNG resp;
SendCommandOLD(CMD_FLASHMEM_WRITE, FLASH_MEM_SIGNATURE_OFFSET, FLASH_MEM_SIGNATURE_LEN, 0, signature, slen);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
} else {
if (!resp.oldarg[0]) {
PrintAndLogEx(FAILED, "Writing signature ( "_RED_("fail") ")");
} else {
PrintAndLogEx(SUCCESS, "Writing signature ( "_GREEN_("ok") " ) at offset %u", FLASH_MEM_SIGNATURE_OFFSET);
return PM3_SUCCESS;
}
}
return PM3_EFAILED;
}
static int CmdFlashmemSpiBaudrate(const char *Cmd) {
CLIParserContext *ctx;
@ -344,23 +461,14 @@ static int CmdFlashMemInfo(const char *Cmd) {
// shall_write = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
clearCommandBuffer();
SendCommandNG(CMD_FLASHMEM_INFO, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply");
return PM3_ETIMEOUT;
}
uint8_t isok = resp.oldarg[0] & 0xFF;
if (isok == false) {
PrintAndLogEx(FAILED, "failed");
return PM3_EFLASH;
}
// validate signature here
// validate signature data
rdv40_validation_t mem;
memcpy(&mem, (rdv40_validation_t *)resp.data.asBytes, sizeof(rdv40_validation_t));
int res = rdv4_get_signature(&mem);
if (res != PM3_SUCCESS) {
return res;
}
res = rdv4_validate(&mem);
// Flash ID hash (sha1)
uint8_t sha_hash[20] = {0};
@ -369,7 +477,6 @@ static int CmdFlashMemInfo(const char *Cmd) {
// print header
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------");
// PrintAndLogEx(INFO, "-----------------------------------------------------------------");
PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid)));
PrintAndLogEx(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash)));
PrintAndLogEx(NORMAL, "");
@ -378,69 +485,16 @@ static int CmdFlashMemInfo(const char *Cmd) {
PrintAndLogEx(INFO, " %s", sprint_hex_inrow(mem.signature + (i * 32), 32));
}
//-------------------------------------------------------------------------------
// RRG Public RSA Key
//
// public key Exponent E
#define RSA_E "010001"
// public key modulus N
#define RSA_N "E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF" \
"4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F" \
"9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \
"DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
//-------------------------------------------------------------------------------
// Example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c)
//
// private key Exponent D
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
"66CA472BC44D253102F8B4A9D3BFA750" \
"91386C0077937FE33FA3252D28855837" \
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
"DF79C5CE07EE72C7F123142198164234" \
"CABB724CF78B8173B9F880FC86322407" \
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
"071513A1E85B5DFA031F21ECAE91A34D"
// prime P
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
"2C01CAD19EA484A87EA4377637E75500" \
"FCB2005C5C7DD6EC4AC023CDA285D796" \
"C3D9E75E1EFC42488BB4F1D13AC30A57"
// prime Q
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
"910E4168387E3C30AA1E00C339A79508" \
"8452DD96A9A5EA5D9DCA68DA636032AF"
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
"3C94D22288ACD763FD8E5600ED4A702D" \
"F84198A5F06C2E72236AE490C93F07F8" \
"3CC559CD27BC2D1CA488811730BB5725"
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
"D8AAEA56749EA28623272E4F7D0592AF" \
"7C1F1313CAC9471B5C523BFE592F517B" \
"407A1BD76C164B93DA2D32A383E58357"
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
"F38D18D2B2F0E2DD275AA977E2BF4411" \
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
"A74206CEC169D74BF5A8C50D6F48EA08"
#define KEY_LEN 128
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
rsa.len = KEY_LEN;
rsa.len = RRG_RSA_KEY_LEN;
mbedtls_mpi_read_string(&rsa.N, 16, RSA_N);
mbedtls_mpi_read_string(&rsa.E, 16, RSA_E);
// add public key
mbedtls_mpi_read_string(&rsa.N, 16, RRG_RSA_N);
mbedtls_mpi_read_string(&rsa.E, 16, RRG_RSA_E);
// add private key
mbedtls_mpi_read_string(&rsa.D, 16, RSA_D);
mbedtls_mpi_read_string(&rsa.P, 16, RSA_P);
mbedtls_mpi_read_string(&rsa.Q, 16, RSA_Q);
@ -448,8 +502,6 @@ static int CmdFlashMemInfo(const char *Cmd) {
mbedtls_mpi_read_string(&rsa.DQ, 16, RSA_DQ);
mbedtls_mpi_read_string(&rsa.QP, 16, RSA_QP);
bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA Public key") " --------------");
@ -466,48 +518,35 @@ static int CmdFlashMemInfo(const char *Cmd) {
PrintAndLogEx(INFO, " %.64s", str_pk + 64);
PrintAndLogEx(INFO, " %.64s", str_pk + 128);
PrintAndLogEx(INFO, " %.64s", str_pk + 192);
PrintAndLogEx(NORMAL, "");
const char *msgkey = "RSA key validation... ";
if (is_keyok)
PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgkey);
else
PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgkey);
//
uint8_t from_device[KEY_LEN];
uint8_t sign[KEY_LEN];
bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0);
PrintAndLogEx(
(is_keyok) ? SUCCESS : FAILED,
"RSA key validation... ( %s )",
(is_keyok) ? _GREEN_("ok") : _RED_("fail")
);
// to be verified
memcpy(from_device, mem.signature, KEY_LEN);
uint8_t from_device[RRG_RSA_KEY_LEN];
memcpy(from_device, mem.signature, RRG_RSA_KEY_LEN);
// to be signed (all zeros
memset(sign, 0, KEY_LEN);
// to be signed
uint8_t sign[RRG_RSA_KEY_LEN];
memset(sign, 0, RRG_RSA_KEY_LEN);
// Signing (private key)
if (shall_sign) {
int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign);
const char *msgsign = "RSA signing.......... ";
if (is_signed == 0)
PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgsign);
else
PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgsign);
PrintAndLogEx(
(is_signed == 0) ? SUCCESS : FAILED,
"RSA signing.......... ( %s )",
(is_signed == 0) ? _GREEN_("ok") : _RED_("fail")
);
if (shall_write) {
// save to mem
clearCommandBuffer();
SendCommandOLD(CMD_FLASHMEM_WRITE, FLASH_MEM_SIGNATURE_OFFSET, FLASH_MEM_SIGNATURE_LEN, 0, sign, sizeof(sign));
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
} else {
if (!resp.oldarg[0])
PrintAndLogEx(FAILED, "Writing signature failed");
else
PrintAndLogEx(SUCCESS, "Writing signature ok [offset: %u]", FLASH_MEM_SIGNATURE_OFFSET);
}
rdv4_sign_write(sign, RRG_RSA_KEY_LEN);
}
PrintAndLogEx(INFO, "Signed");
for (int i = 0; i < (sizeof(sign) / 32); i++) {
@ -517,14 +556,15 @@ static int CmdFlashMemInfo(const char *Cmd) {
// Verify (public key)
int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device);
const char *msgverify = "RSA verification..... ";
if (is_verified == 0)
PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgverify);
else
PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgverify);
mbedtls_rsa_free(&rsa);
PrintAndLogEx(
(is_verified == 0) ? SUCCESS : FAILED,
"RSA verification..... ( %s )",
(is_verified == 0) ? _GREEN_("ok") : _RED_("fail")
);
PrintAndLogEx(NORMAL, "");
mbedtls_rsa_free(&rsa);
return PM3_SUCCESS;
}

View file

@ -12,6 +12,7 @@
#define CMDFLASHMEM_H__
#include "common.h"
#include "pmflash.h" // rdv40validation_t
typedef enum {
DICTIONARY_NONE = 0,
@ -21,5 +22,6 @@ typedef enum {
} Dictionary_t;
int CmdFlashMem(const char *Cmd);
int rdv4_get_signature(rdv40_validation_t *out);
int rdv4_validate(rdv40_validation_t *mem);
#endif

View file

@ -14,17 +14,18 @@
#include "cmdhf.h"
#include <ctype.h> // tolower
#include "cmdparser.h" // command_t
#include "cliparser.h" // parse
#include "cliparser.h" // parse
#include "comms.h" // clearCommandBuffer
#include "lfdemod.h" // computeSignalProperties
#include "cmdhf14a.h" // ISO14443-A
#include "cmdhf14b.h" // ISO14443-B
#include "cmdhf15.h" // ISO15693
#include "cmdhfepa.h"
#include "cmdhfemrtd.h" // eMRTD
#include "cmdhflegic.h" // LEGIC
#include "cmdhficlass.h" // ICLASS
#include "cmdhfjooki.h" // MFU based Jooki
#include "cmdhfmf.h" // CLASSIC
#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc
#include "cmdhfmfp.h" // Mifare Plus
@ -46,50 +47,20 @@
static int CmdHelp(const char *Cmd);
static int usage_hf_search(void) {
PrintAndLogEx(NORMAL, "Usage: hf search");
PrintAndLogEx(NORMAL, "Will try to find a HF read out of the unknown tag.");
PrintAndLogEx(NORMAL, "Continues to search for all different HF protocols");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - This help");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_hf_sniff(void) {
PrintAndLogEx(NORMAL, "The high frequency sniffer will assign all available memory on device for sniffed data");
PrintAndLogEx(NORMAL, "Use " _YELLOW_("'data samples'")" command to download from device, and " _YELLOW_("'data plot'")" to look at it");
PrintAndLogEx(NORMAL, "Press button to quit the sniffing.\n");
PrintAndLogEx(NORMAL, "Usage: hf sniff <skip pairs> <skip triggers>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - This help");
PrintAndLogEx(NORMAL, " <skip pairs> - skip sample pairs");
PrintAndLogEx(NORMAL, " <skip triggers> - skip number of triggers");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf sniff"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf sniff 1000 0"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_hf_tune(void) {
PrintAndLogEx(NORMAL, "Continuously measure HF antenna tuning.");
PrintAndLogEx(NORMAL, "Press button or `enter` to interrupt.");
PrintAndLogEx(NORMAL, "Usage: hf tune [h] [<iter>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - This help");
PrintAndLogEx(NORMAL, " <iter> - number of iterations (default: 0=infinite)");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf tune 1"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
int CmdHFSearch(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_search();
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf search",
"Will try to find a HF read out of the unknown tag.\n"
"Continues to search for all different HF protocols.",
"hf search"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
int res = PM3_ESOFT;
@ -141,7 +112,7 @@ int CmdHFSearch(const char *Cmd) {
PROMPT_CLEARLINE;
PrintAndLogEx(INPLACE, " Searching for LEGIC tag...");
if (IfPm3Legicrf()) {
if (readLegicUid(false) == PM3_SUCCESS) {
if (readLegicUid(false, false) == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC Prime tag") " found\n");
res = PM3_SUCCESS;
}
@ -189,18 +160,51 @@ int CmdHFSearch(const char *Cmd) {
PROMPT_CLEARLINE;
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, _RED_("No known/supported 13.56 MHz tags found"));
res = PM3_ESOFT;
}
DropField();
return res;
}
int CmdHFTune(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_tune();
int iter = param_get32ex(Cmd, 0, 0, 10);
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf tune",
"Continuously measure HF antenna tuning.\n"
"Press button or <Enter> to interrupt.",
"hf tune\n"
"hf tune --mix"
);
void *argtable[] = {
arg_param_begin,
arg_u64_0("n", "iter", "<dec>", "number of iterations (default: 0=infinite)"),
arg_lit0(NULL, "bar", "bar style"),
arg_lit0(NULL, "mix", "mixed style"),
arg_lit0(NULL, "value", "values style"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
uint32_t iter = arg_get_u32_def(ctx, 1, 0);
bool is_bar = arg_get_lit(ctx, 2);
bool is_mix = arg_get_lit(ctx, 3);
bool is_value = arg_get_lit(ctx, 4);
CLIParserFree(ctx);
if ((is_bar + is_mix + is_value) > 1) {
PrintAndLogEx(ERR, "Select only one output style");
return PM3_EINVARG;
}
barMode_t style = session.bar_mode;
if (is_bar)
style = STYLE_BAR;
if (is_mix)
style = STYLE_MIXED;
if (is_value)
style = STYLE_VALUE;
PrintAndLogEx(INFO, "Measuring HF antenna, click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit");
PacketResponseNG resp;
@ -214,6 +218,12 @@ int CmdHFTune(const char *Cmd) {
}
mode[0] = 2;
uint32_t max = 0xFFFF;
bool first = true;
print_progress(0, max, style);
// loop forever (till button pressed) if iter = 0 (default)
for (uint8_t i = 0; iter == 0 || i < iter; i++) {
if (kbd_enter_pressed()) {
@ -224,15 +234,23 @@ int CmdHFTune(const char *Cmd) {
if (!WaitForResponseTimeout(CMD_MEASURE_ANTENNA_TUNING_HF, &resp, 1000)) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF measure, aborting");
return PM3_ETIMEOUT;
break;
}
if ((resp.status == PM3_EOPABORTED) || (resp.length != sizeof(uint16_t))) {
PrintAndLogEx(NORMAL, "");
break;
}
uint16_t volt = resp.data.asDwords[0] & 0xFFFF;
PrintAndLogEx(INPLACE, " %u mV / %2u V", volt, (uint16_t)(volt / 1000));
if (first) {
max = (volt * 1.03);
first = false;
}
if (volt > max) {
max = (volt * 1.03);
}
print_progress(volt, max, style);
}
mode[0] = 3;
@ -241,7 +259,7 @@ int CmdHFTune(const char *Cmd) {
PrintAndLogEx(WARNING, "Timeout while waiting for Proxmark HF shutdown, aborting");
return PM3_ETIMEOUT;
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "\x1b%c[2K\r", 30);
PrintAndLogEx(INFO, "Done.");
return PM3_SUCCESS;
}
@ -251,16 +269,31 @@ int CmdHFTune(const char *Cmd) {
// Takes all available bigbuff memory
// data sample to download? Not sure what we can do with the data.
int CmdHFSniff(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_sniff();
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf sniff",
"The high frequency sniffer will assign all available memory on device for sniffed data.\n"
"Use `data samples` to download from device and `data plot` to visualize it.\n"
"Press button to quit the sniffing.",
"hf sniff\n"
"hf sniff --sp 1000 --st 0 -> skip 1000 pairs, skip 0 triggers"
);
void *argtable[] = {
arg_param_begin,
arg_u64_0(NULL, "sp", "<dec>", "skip sample pairs"),
arg_u64_0(NULL, "st", "<dec>", "skip number of triggers"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
struct {
uint32_t samplesToSkip;
uint32_t triggersToSkip;
} PACKED params;
params.samplesToSkip = param_get32ex(Cmd, 0, 0, 10);
params.triggersToSkip = param_get32ex(Cmd, 1, 0, 10);
params.samplesToSkip = arg_get_u32_def(ctx, 1, 0);
params.triggersToSkip = arg_get_u32_def(ctx, 2, 0);
CLIParserFree(ctx);
clearCommandBuffer();
SendCommandNG(CMD_HF_SNIFF, (uint8_t *)&params, sizeof(params));
@ -357,31 +390,33 @@ int CmdHFPlot(const char *Cmd) {
static command_t CommandTable[] = {
{"--------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("High Frequency") " -----------------------"},
{"14a", CmdHF14A, AlwaysAvailable, "{ ISO14443A RFIDs... }"},
{"14b", CmdHF14B, AlwaysAvailable, "{ ISO14443B RFIDs... }"},
{"15", CmdHF15, AlwaysAvailable, "{ ISO15693 RFIDs... }"},
// {"cryptorf", CmdHFCryptoRF, AlwaysAvailable, "{ CryptoRF RFIDs... }"},
{"epa", CmdHFEPA, AlwaysAvailable, "{ German Identification Card... }"},
{"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / FeliCa RFIDs... }"},
{"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"},
{"iclass", CmdHFiClass, AlwaysAvailable, "{ ICLASS RFIDs... }"},
{"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"},
{"lto", CmdHFLTO, AlwaysAvailable, "{ LTO Cartridge Memory RFIDs... }"},
{"mf", CmdHFMF, AlwaysAvailable, "{ MIFARE RFIDs... }"},
{"mfp", CmdHFMFP, AlwaysAvailable, "{ MIFARE Plus RFIDs... }"},
{"mfu", CmdHFMFUltra, AlwaysAvailable, "{ MIFARE Ultralight RFIDs... }"},
{"mfdes", CmdHFMFDes, AlwaysAvailable, "{ MIFARE Desfire RFIDs... }"},
{"st", CmdHF_ST, AlwaysAvailable, "{ ST Rothult RFIDs... }"},
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
{"14a", CmdHF14A, AlwaysAvailable, "{ ISO14443A RFIDs... }"},
{"14b", CmdHF14B, AlwaysAvailable, "{ ISO14443B RFIDs... }"},
{"15", CmdHF15, AlwaysAvailable, "{ ISO15693 RFIDs... }"},
// {"cryptorf", CmdHFCryptoRF, AlwaysAvailable, "{ CryptoRF RFIDs... }"},
{"epa", CmdHFEPA, AlwaysAvailable, "{ German Identification Card... }"},
{"emrtd", CmdHFeMRTD, AlwaysAvailable, "{ Machine Readable Travel Document... }"},
{"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / FeliCa RFIDs... }"},
{"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"},
{"jooki", CmdHF_Jooki, AlwaysAvailable, "{ Jooki RFIDs... }"},
{"iclass", CmdHFiClass, AlwaysAvailable, "{ ICLASS RFIDs... }"},
{"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"},
{"lto", CmdHFLTO, AlwaysAvailable, "{ LTO Cartridge Memory RFIDs... }"},
{"mf", CmdHFMF, AlwaysAvailable, "{ MIFARE RFIDs... }"},
{"mfp", CmdHFMFP, AlwaysAvailable, "{ MIFARE Plus RFIDs... }"},
{"mfu", CmdHFMFUltra, AlwaysAvailable, "{ MIFARE Ultralight RFIDs... }"},
{"mfdes", CmdHFMFDes, AlwaysAvailable, "{ MIFARE Desfire RFIDs... }"},
{"st", CmdHF_ST, AlwaysAvailable, "{ ST Rothult RFIDs... }"},
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
{"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"},
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
{"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"},
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
{"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, "Generic HF Sniff"},
{NULL, NULL, NULL, NULL}
};

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,7 @@ int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
int CmdHF14ASim(const char *Cmd); // used by hf mfu sim
int hf14a_getconfig(hf14a_config *config);
int hf14a_setconfig(hf14a_config *config);
int hf14a_setconfig(hf14a_config *config, bool verbose);
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
const char *getTagInfo(uint8_t uid);
int Hf14443_4aGetCardData(iso14a_card_select_t *card);

View file

@ -24,8 +24,11 @@
#include "protocols.h" // definitions of ISO14B/7816 protocol
#include "emv/apduinfo.h" // GetAPDUCodeDescription
#include "mifare/ndef.h" // NDEFRecordsDecodeAndPrint
#include "aidsearch.h"
#define MAX_14B_TIMEOUT 40542464U // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
#define TIMEOUT 2000
#define APDU_TIMEOUT 2000
// iso14b apdu input frame length
static uint16_t apdu_frame_length = 0;
@ -34,21 +37,6 @@ bool apdu_in_framing_enable = true;
static int CmdHelp(const char *Cmd);
static int usage_hf_14b_write_srx(void) {
PrintAndLogEx(NORMAL, "Usage: hf 14b [h] sriwrite <1|2> <block> <data>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " <1|2> 1 = SRIX4K , 2 = SRI512");
PrintAndLogEx(NORMAL, " <block> (hex) block number depends on tag, special block == FF");
PrintAndLogEx(NORMAL, " <data> hex bytes of data to be written");
PrintAndLogEx(NORMAL, "Example:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b sriwrite 1 7F 11223344"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b sriwrite 1 FF 11223344"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b sriwrite 2 15 11223344"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14b sriwrite 2 FF 11223344"));
return PM3_SUCCESS;
}
static int switch_off_field_14b(void) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_DISCONNECT, 0, 0, NULL, 0);
@ -63,6 +51,103 @@ static uint16_t get_sw(uint8_t *d, uint8_t n) {
return d[n] * 0x0100 + d[n + 1];
}
static void hf14b_aid_search(bool verbose) {
int elmindx = 0;
json_t *root = AIDSearchInit(verbose);
if (root == NULL) {
switch_off_field_14b();
return;
}
PrintAndLogEx(INFO, "-------------------- " _CYAN_("AID Search") " --------------------");
bool found = false;
bool leave_signal_on = true;
bool activate_field = true;
for (elmindx = 0; elmindx < json_array_size(root); elmindx++) {
if (kbd_enter_pressed()) {
break;
}
json_t *data = AIDSearchGetElm(root, elmindx);
uint8_t vaid[200] = {0};
int vaidlen = 0;
if (!AIDGetFromElm(data, vaid, sizeof(vaid), &vaidlen) || !vaidlen)
continue;
// COMPUTE APDU
uint8_t apdu_data[PM3_CMD_DATA_SIZE] = {0};
int apdu_len = 0;
sAPDU apdu = (sAPDU) {0x00, 0xa4, 0x04, 0x00, vaidlen, vaid};
if (APDUEncodeS(&apdu, false, 0x00, apdu_data, &apdu_len)) {
PrintAndLogEx(ERR, "APDU encoding error.");
return;
}
PrintAndLogEx(DEBUG, ">>>> %s", sprint_hex(apdu_data, apdu_len));
int resultlen = 0;
uint8_t result[1024] = {0};
int res = exchange_14b_apdu(apdu_data, apdu_len, activate_field, leave_signal_on, result, sizeof(result), &resultlen, -1);
activate_field = false;
if (res)
continue;
uint16_t sw = get_sw(result, resultlen);
uint8_t dfname[200] = {0};
size_t dfnamelen = 0;
if (resultlen > 3) {
struct tlvdb *tlv = tlvdb_parse_multi(result, resultlen);
if (tlv) {
// 0x84 Dedicated File (DF) Name
const struct tlv *dfnametlv = tlvdb_get_tlv(tlvdb_find_full(tlv, 0x84));
if (dfnametlv) {
dfnamelen = dfnametlv->len;
memcpy(dfname, dfnametlv->value, dfnamelen);
}
tlvdb_free(tlv);
}
}
if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) {
if (sw == 0x9000) {
if (verbose) PrintAndLogEx(SUCCESS, "Application ( " _GREEN_("ok") " )");
} else {
if (verbose) PrintAndLogEx(WARNING, "Application ( " _RED_("blocked") " )");
}
PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose);
if (dfnamelen) {
if (dfnamelen == vaidlen) {
if (memcmp(dfname, vaid, vaidlen) == 0) {
if (verbose) PrintAndLogEx(INFO, "(DF) Name found and equal to AID");
} else {
PrintAndLogEx(INFO, "(DF) Name not equal to AID: %s :", sprint_hex(dfname, dfnamelen));
PrintAIDDescriptionBuf(root, dfname, dfnamelen, verbose);
}
} else {
PrintAndLogEx(INFO, "(DF) Name not equal to AID: %s :", sprint_hex(dfname, dfnamelen));
PrintAIDDescriptionBuf(root, dfname, dfnamelen, verbose);
}
} else {
if (verbose) PrintAndLogEx(INFO, "(DF) Name not found");
}
if (verbose) PrintAndLogEx(SUCCESS, "----------------------------------------------------");
found = true;
}
}
switch_off_field_14b();
if (verbose == false && found)
PrintAndLogEx(INFO, "----------------------------------------------------");
}
static bool wait_cmd_14b(bool verbose, bool is_select) {
PacketResponseNG resp;
@ -102,8 +187,7 @@ static bool wait_cmd_14b(bool verbose, bool is_select) {
(crc) ? _GREEN_("ok") : _RED_("fail")
);
} else if (len == 0) {
if (verbose)
PrintAndLogEx(INFO, "no response from tag");
PrintAndLogEx(INFO, "no response from tag");
} else {
PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len));
}
@ -187,7 +271,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14b raw",
"Sends raw bytes to card ",
"Sends raw bytes to card",
"hf 14b raw -cks --data 0200a40400 -> standard select\n"
"hf 14b raw -ck --sr --data 0200a40400 -> SRx select\n"
"hf 14b raw -ck --cts --data 0200a40400 -> C-ticket select\n"
@ -200,7 +284,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
arg_lit0(NULL, "sr", "activate field, use SRx ST select"),
arg_lit0(NULL, "cts", "activate field, use ASK C-ticket select"),
arg_lit0("c", "crc", "calculate and append CRC"),
arg_lit0("r", "noresponse", "do not read response from card"),
arg_lit0(NULL, "noresponse", "do not read response from card"),
arg_int0("t", "timeout", "<dec>", "timeout in ms"),
arg_lit0("v", "verbose", "verbose"),
arg_strx0("d", "data", "<hex>", "data, bytes to send"),
@ -244,18 +328,20 @@ static int CmdHF14BCmdRaw(const char *Cmd) {
}
CLIParserFree(ctx);
uint32_t time_wait = 0;
if (user_timeout > 0) {
#define MAX_14B_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
flags |= ISO14B_SET_TIMEOUT;
if (user_timeout > MAX_14B_TIMEOUT) {
user_timeout = MAX_14B_TIMEOUT;
uint32_t max_timeout = user_timeout;
if (max_timeout > MAX_14B_TIMEOUT) {
max_timeout = MAX_14B_TIMEOUT;
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
}
time_wait = 13560000 / 1000 / (8 * 16) * user_timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
time_wait = ((13560000 / 1000 / (8 * 16)) * max_timeout); // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
if (verbose)
PrintAndLogEx(INFO, "using timeout %u", user_timeout);
PrintAndLogEx(INFO, "using timeout %u", max_timeout);
}
if (keep_field_on == 0)
@ -308,8 +394,7 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
if (card == NULL)
return false;
int status = 0;
int status;
PacketResponseNG resp;
clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0);
@ -628,12 +713,12 @@ static void print_ct_general_info(void *vcard) {
memcpy(&card, (iso14b_cts_card_select_t *)vcard, sizeof(iso14b_cts_card_select_t));
uint32_t uid32 = (card.uid[0] | card.uid[1] << 8 | card.uid[2] << 16 | card.uid[3] << 24);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "ASK C-Ticket");
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s") " ( " _YELLOW_("%010u") " )", sprint_hex(card.uid, sizeof(card.uid)), uid32);
PrintAndLogEx(SUCCESS, " Product Code: %02X", card.pc);
PrintAndLogEx(SUCCESS, " Facility Code: %02X", card.fc);
PrintAndLogEx(NORMAL, "");
}
// iceman, calypso?
@ -649,7 +734,7 @@ static void print_ct_general_info(void *vcard) {
// 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c])
// 14b get and print Full Info (as much as we know)
static bool HF14B_Std_Info(bool verbose) {
static bool HF14B_Std_Info(bool verbose, bool do_aid_search) {
bool is_success = false;
@ -670,14 +755,21 @@ static bool HF14B_Std_Info(bool verbose) {
int status = resp.oldarg[0];
switch (status) {
case 0:
case 0: {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "-------------------- " _CYAN_("Tag information") " --------------------");
PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen));
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
print_atqb_resp(card.atqb, card.cid);
if (do_aid_search) {
hf14b_aid_search(verbose);
}
is_success = true;
break;
}
case -1:
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
break;
@ -693,7 +785,7 @@ static bool HF14B_Std_Info(bool verbose) {
}
// SRx get and print full info (needs more info...)
static bool HF14B_ST_Info(bool verbose) {
static bool HF14B_ST_Info(bool verbose, bool do_aid_search) {
clearCommandBuffer();
PacketResponseNG resp;
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0, NULL, 0);
@ -711,6 +803,10 @@ static bool HF14B_ST_Info(bool verbose) {
return false;
print_st_general_info(card.uid, card.uidlen);
if (do_aid_search) {
hf14b_aid_search(verbose);
}
return true;
}
@ -724,13 +820,15 @@ static int CmdHF14Binfo(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("s", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"),
arg_lit0("v", "verbose", "verbose"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool verbose = arg_get_lit(ctx, 1);
bool do_aid_search = arg_get_lit(ctx, 1);
bool verbose = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
return infoHF14B(verbose);
return infoHF14B(verbose, do_aid_search);
}
static bool HF14B_st_reader(bool verbose) {
@ -1025,56 +1123,78 @@ static int CmdHF14BWriteSri(const char *Cmd) {
* Special block FF = otp_lock_reg block.
* Data len 4 bytes-
*/
char cmdp = tolower(param_getchar(Cmd, 0));
uint8_t blockno = -1;
uint8_t data[4] = {0x00};
bool isSrix4k = true;
char str[30];
memset(str, 0x00, sizeof(str));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_write_srx();
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14b sriwrite",
"Write data to a SRI512 | SRIX4K block",
"hf 14b sriwrite --4k -b 100 -d 11223344\n"
"hf 14b sriwrite --4k --sb -d 11223344 --> special block write\n"
"hf 14b sriwrite --512 -b 15 -d 11223344\n"
"hf 14b sriwrite --512 --sb -d 11223344 --> special block write\n"
);
if (cmdp == '2')
isSrix4k = false;
//blockno = param_get8(Cmd, 1);
if (param_gethex(Cmd, 1, &blockno, 2)) {
PrintAndLogEx(WARNING, "block number must include 2 HEX symbols");
return 0;
void *argtable[] = {
arg_param_begin,
arg_int0("b", "block", "<dec>", "block number"),
arg_str1("d", "data", "<hex>", "4 hex bytes"),
arg_lit0(NULL, "512", "target SRI 512 tag"),
arg_lit0(NULL, "4k", "target SRIX 4k tag"),
arg_lit0(NULL, "sb", "special block write at end of memory (0xFF)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int blockno = arg_get_int_def(ctx, 1, -1);
int dlen = 0;
uint8_t data[4] = {0,0,0,0};
int res = CLIParamHexToBuf(arg_get_str(ctx, 2), data, sizeof(data), &dlen);
if (res) {
CLIParserFree(ctx);
return PM3_EINVARG;
}
if (isSrix4k) {
if (blockno > 0x7f && blockno != 0xff) {
PrintAndLogEx(FAILED, "block number out of range");
return PM3_ESOFT;
}
} else {
if (blockno > 0x0f && blockno != 0xff) {
PrintAndLogEx(FAILED, "block number out of range");
return PM3_ESOFT;
}
bool use_sri512 = arg_get_lit(ctx, 3);
bool use_srix4k = arg_get_lit(ctx, 4);
bool special = arg_get_lit(ctx, 5);
CLIParserFree(ctx);
if (dlen != sizeof(data)) {
PrintAndLogEx(FAILED, "data must be 4 hex bytes, got %d", dlen);
return PM3_EINVARG;
}
if (param_gethex(Cmd, 2, data, 8)) {
PrintAndLogEx(WARNING, "data must include 8 HEX symbols");
return PM3_ESOFT;
if (use_sri512 + use_srix4k > 1) {
PrintAndLogEx(FAILED, "Select only one card type");
return PM3_EINVARG;
}
if (blockno == 0xff) {
if (use_srix4k && blockno > 0x7F) {
PrintAndLogEx(FAILED, "block number out of range, max 127 (0x7F)");
return PM3_EINVARG;
}
if (use_sri512 && blockno > 0x0F) {
PrintAndLogEx(FAILED, "block number out of range, max 15 (0x0F)");
return PM3_EINVARG;
}
// special block at end of memory
if (special) {
blockno = 0xFF;
PrintAndLogEx(SUCCESS, "[%s] Write special block %02X [ " _YELLOW_("%s")" ]",
(isSrix4k) ? "SRIX4K" : "SRI512",
(use_srix4k) ? "SRIX4K" : "SRI512",
blockno,
sprint_hex(data, 4)
sprint_hex(data, sizeof(data))
);
} else {
PrintAndLogEx(SUCCESS, "[%s] Write block %02X [ " _YELLOW_("%s")" ]",
(isSrix4k) ? "SRIX4K" : "SRI512",
(use_srix4k) ? "SRIX4K" : "SRI512",
blockno,
sprint_hex(data, 4)
sprint_hex(data, sizeof(data))
);
}
char str[36];
memset(str, 0x00, sizeof(str));
sprintf(str, "--sr -c --data %02x%02x%02x%02x%02x%02x", ISO14443B_WRITE_BLK, blockno, data[0], data[1], data[2], data[3]);
return CmdHF14BCmdRaw(str);
}
@ -1414,7 +1534,7 @@ static int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card) {
return PM3_SUCCESS;
}
static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) {
static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout, int user_timeout) {
*chainingout = false;
if (activateField) {
@ -1429,16 +1549,27 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool
if (chainingin)
flags = ISO14B_SEND_CHAINING;
uint32_t time_wait = 0;
if (user_timeout > 0) {
flags |= ISO14B_SET_TIMEOUT;
if (user_timeout > MAX_14B_TIMEOUT) {
user_timeout = MAX_14B_TIMEOUT;
PrintAndLogEx(INFO, "set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
}
time_wait = (uint32_t)((13560000 / 1000 / (8 * 16)) * user_timeout); // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
}
// "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes
// https://stackoverflow.com/questions/32994936/safe-max-java-card-apdu-data-command-and-respond-size
// here length PM3_CMD_DATA_SIZE=512
if (datain)
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, (datainlen & 0xFFFF), 0, datain, datainlen & 0xFFFF);
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, (datainlen & 0xFFFF), time_wait, datain, datainlen & 0xFFFF);
else
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, 0, 0, NULL, 0);
SendCommandMIX(CMD_HF_ISO14443B_COMMAND, ISO14B_APDU | flags, 0, time_wait, NULL, 0);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, MAX(APDU_TIMEOUT, user_timeout))) {
uint8_t *recv = resp.data.asBytes;
int rlen = resp.oldarg[0];
uint8_t res = resp.oldarg[1];
@ -1488,7 +1619,7 @@ static int handle_14b_apdu(bool chainingin, uint8_t *datain, int datainlen, bool
return PM3_SUCCESS;
}
static int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout) {
*dataoutlen = 0;
bool chaining = false;
int res;
@ -1505,7 +1636,7 @@ static int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field
bool chainBlockNotLast = ((clen + vlen) < datainlen);
*dataoutlen = 0;
res = handle_14b_apdu(chainBlockNotLast, &datain[clen], vlen, v_activate_field, dataout, maxdataoutlen, dataoutlen, &chaining);
res = handle_14b_apdu(chainBlockNotLast, &datain[clen], vlen, v_activate_field, dataout, maxdataoutlen, dataoutlen, &chaining, user_timeout);
if (res) {
if (leave_signal_on == false)
switch_off_field_14b();
@ -1534,7 +1665,7 @@ static int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field
} else {
res = handle_14b_apdu(false, datain, datainlen, activate_field, dataout, maxdataoutlen, dataoutlen, &chaining);
res = handle_14b_apdu(false, datain, datainlen, activate_field, dataout, maxdataoutlen, dataoutlen, &chaining, user_timeout);
if (res != PM3_SUCCESS) {
if (leave_signal_on == false) {
switch_off_field_14b();
@ -1545,7 +1676,7 @@ static int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field
while (chaining) {
// I-block with chaining
res = handle_14b_apdu(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining);
res = handle_14b_apdu(false, NULL, 0, false, &dataout[*dataoutlen], maxdataoutlen, dataoutlen, &chaining, user_timeout);
if (res != PM3_SUCCESS) {
if (leave_signal_on == false) {
switch_off_field_14b();
@ -1593,6 +1724,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
arg_lit0("e", "extended", "make extended length apdu if `m` parameter included"),
arg_int0("l", "le", "<int>", "Le apdu parameter if `m` parameter included"),
arg_strx1(NULL, "hex", "<hex>", "<APDU | data> if `m` parameter included"),
arg_int0(NULL, "timeout", "<dec>", "timeout in ms"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -1652,6 +1784,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
// len = data + PCB(1b) + CRC(2b)
CLIGetHexBLessWithReturn(ctx, 8, data, &datalen, 1 + 2);
}
int user_timeout = arg_get_int_def(ctx, 9, -1);
CLIParserFree(ctx);
PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s",
@ -1669,7 +1802,7 @@ static int CmdHF14BAPDU(const char *Cmd) {
PrintAndLogEx(WARNING, "can't decode APDU.");
}
int res = exchange_14b_apdu(data, datalen, activate_field, leave_signal_on, data, PM3_CMD_DATA_SIZE, &datalen);
int res = exchange_14b_apdu(data, datalen, activate_field, leave_signal_on, data, PM3_CMD_DATA_SIZE, &datalen, user_timeout);
if (res != PM3_SUCCESS) {
return res;
}
@ -1708,7 +1841,7 @@ static int CmdHF14BNdef(const char *Cmd) {
uint8_t aSELECT_AID[80];
int aSELECT_AID_n = 0;
param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
int res = exchange_14b_apdu(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
int res = exchange_14b_apdu(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
if (res) {
goto out;
}
@ -1734,7 +1867,7 @@ static int CmdHF14BNdef(const char *Cmd) {
uint8_t aSELECT_FILE_NDEF[30];
int aSELECT_FILE_NDEF_n = 0;
param_gethex_to_eol("00a4000c020001", 0, aSELECT_FILE_NDEF, sizeof(aSELECT_FILE_NDEF), &aSELECT_FILE_NDEF_n);
res = exchange_14b_apdu(aSELECT_FILE_NDEF, aSELECT_FILE_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
res = exchange_14b_apdu(aSELECT_FILE_NDEF, aSELECT_FILE_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
if (res)
goto out;
@ -1749,7 +1882,7 @@ static int CmdHF14BNdef(const char *Cmd) {
uint8_t aREAD_NDEF[30];
int aREAD_NDEF_n = 0;
param_gethex_to_eol("00b0000002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n);
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
if (res) {
goto out;
}
@ -1768,7 +1901,7 @@ static int CmdHF14BNdef(const char *Cmd) {
aREAD_NDEF_n = 0;
param_gethex_to_eol("00b00002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n);
aREAD_NDEF[4] = offset;
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
res = exchange_14b_apdu(aREAD_NDEF, aREAD_NDEF_n, activate_field, keep_field_on, response, sizeof(response), &resplen, -1);
if (res) {
goto out;
}
@ -1816,14 +1949,14 @@ int CmdHF14B(const char *Cmd) {
}
// get and print all info known about any known 14b tag
int infoHF14B(bool verbose) {
int infoHF14B(bool verbose, bool do_aid_search) {
// try std 14b (atqb)
if (HF14B_Std_Info(verbose))
if (HF14B_Std_Info(verbose, do_aid_search))
return 1;
// try ST 14b
if (HF14B_ST_Info(verbose))
if (HF14B_ST_Info(verbose, do_aid_search))
return 1;
// try unknown 14b read commands (to be identified later)

View file

@ -15,6 +15,8 @@
int CmdHF14B(const char *Cmd);
int infoHF14B(bool verbose);
int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout);
int infoHF14B(bool verbose, bool do_aid_search);
int readHF14B(bool verbose);
#endif

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