Merge upstream branch 'master'

This commit is contained in:
Peter S. Hollander
2026-03-24 10:54:30 +00:00
196 changed files with 20998 additions and 2538 deletions
+5 -3
View File
@@ -7,12 +7,14 @@ on:
- 'docker/**'
- 'traces/**'
- '.vscode/**'
- '**.md'
pull_request:
paths-ignore:
- 'doc/**'
- 'docker/**'
- 'traces/**'
- '.vscode/**'
- '**.md'
jobs:
macos-make:
@@ -39,7 +41,7 @@ jobs:
run: brew tap RfidResearchGroup/proxmark3
- name: Install dependencies
run: brew install readline coreutils qt@5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl gd
run: brew install readline coreutils qt RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl gd
continue-on-error: true
- name: Install Python dependencies
@@ -80,7 +82,7 @@ jobs:
run: brew tap RfidResearchGroup/proxmark3
- name: Install dependencies
run: brew install readline coreutils qt@5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl gd
run: brew install readline coreutils qt RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl gd
continue-on-error: true
- name: Install Python dependencies
@@ -122,7 +124,7 @@ jobs:
run: brew tap RfidResearchGroup/proxmark3
- name: Install dependencies
run: brew install readline coreutils qt@5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl gd
run: brew install readline coreutils qt RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl gd
continue-on-error: true
- name: Install Python dependencies
+5 -4
View File
@@ -7,13 +7,14 @@ on:
- 'docker/**'
- 'traces/**'
- '.vscode/**'
- '**.md'
pull_request:
paths-ignore:
- 'doc/**'
- 'docker/**'
- 'traces/**'
- '.vscode/**'
- '**.md'
jobs:
ubuntu-make:
@@ -30,7 +31,7 @@ jobs:
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 liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
run: sudo apt-get install -yqq make build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qt6-base-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
@@ -60,7 +61,7 @@ jobs:
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 liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
run: sudo apt-get install -yqq make build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qt6-base-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
@@ -91,7 +92,7 @@ jobs:
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 liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
run: sudo apt-get install -yqq make build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qt6-base-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev libgd-dev
- name: Install Python dependencies
run: pip install -r tools/requirements.txt
+22 -17
View File
@@ -7,13 +7,14 @@ on:
- 'docker/**'
- 'traces/**'
- '.vscode/**'
- '**.md'
pull_request:
paths-ignore:
- 'doc/**'
- 'docker/**'
- 'traces/**'
- '.vscode/**'
- '**.md'
jobs:
proxspace:
@@ -46,7 +47,19 @@ jobs:
- name: ProxSpace initial startup
working-directory: C:\ProxSpace
run: ./runme64.bat -c "exit"
run: |
$maxAttempts = 3
$delay = 20
for ($i = 1; $i -le $maxAttempts; $i++) {
Write-Host "Attempt $i..."
./runme64.bat -c "exit"
if ($LASTEXITCODE -eq 0) {
./runme64.bat -c "pacman -Syu --noconfirm mingw-w64-x86_64-qt6-base"
exit 0
}
if ($i -lt $maxAttempts) { Start-Sleep -Seconds $delay }
}
exit 1
- uses: actions/checkout@v4
@@ -98,9 +111,9 @@ jobs:
steps:
- name: WSL setup
uses: Vampire/setup-wsl@v3
uses: Vampire/setup-wsl@v5
with:
distribution: Ubuntu-22.04
distribution: Ubuntu-24.04
update: "true"
additional-packages: git
ca-certificates
@@ -111,25 +124,17 @@ jobs:
libnewlib-dev
libbz2-dev
liblz4-dev
qtbase5-dev
qt6-base-dev
cmake
libpython3-dev
python3
python3-pip
python3-dev
libpython3-all-dev
libssl-dev
libgd-dev
- name: Install Python dependencies
- name: Install uv
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
curl -LsSf https://astral.sh/uv/install.sh | sh
install -m 0755 /root/.local/bin/uv /usr/local/bin/
install -m 0755 /root/.local/bin/uvx /usr/local/bin/
- name: Set git to use LF
shell: bash
run: |
+33 -7
View File
@@ -4,18 +4,44 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased]
- Added `-t` / `--timeout` option for `hf 15 sim` (@recursivenomad)
- Added `--aid` parameter to `hf seos` commands (@kormax)
- Added `hf iclass blacktears` command to perform an automated tearoff of block 1 to set non-secure page mode(@antiklesys)
- Changed wiegand encoding to use shared helpers and have unified parameters (--raw, --bin, --new, --wiegand, etc.) (@cindersocket)
- Added `hf gst read` command (@kormax)
- Added `hf gst info` command (@kormax)
- Added `hf 14b tearoff` - interactive ST25TB/SRx monotonic counter tear-off attack (@xNovyz)
- Fixed missing `WDT_HIT()` in `Get14443bAnswerFromTag()` DMA polling loop causing hardware watchdog reboot on SSC clock stall (@xNovyz)
- Added `hf vas info` command (@kormax)
- Changed `wiegand encode` / `wiegand decode` - added support for encoding and decoding the new 96-bit ASN.1 encoded format, `--bin` encoding, verbose PACS encoding output, and explicit rejection of raw/binary decodes above 96 bits (@cindersocket)
- Added Mifare Classic support to `hf gallagher` command (@pingu2211)
- Added `hf felica discnodes` command (@kormax)
- Added `hf mfp dump` command (@apply-science)
- Added `hf felica seacinfo` command (@kormax)
- Added `hf mfdes bruteisofid` and `hf mfdes selectisofid` commands (@kormax)
- Added DESFire AID values related to LEAF (@kormax)
- Added `dict`, `ascii`, `mad` presets for `hf mfdes bruteaid` (@kormax)
- Added tag loss detection & recovery into `hf mfdes bruteaid` (@kormax)
- Added --credit option for `hf iclass legrec` command to perform a credit key recovery. This is experimental and unfinished as it only partially works.(@antiklesys)
- Added hardening for all host binaries. Exact level of hardening depends on the OS (@doegox)
- Added `hf aliro read` command (@kormax)
- Added `hf aliro info` command (@kormax)
- Added Qt6 support for the client (@doegox)
## [Permafrost][2026-02-25]
## [Permafrost.4.21128][2026-02-25]
- Added standalone mode `HF_DOEGOX_AUTH0`: UL-C / UL-AES unlocker (@doegox)
- Fixed `lf t55xx wakeup` options parsing (@suut)
- Added `--` arg separator to client to pass following args to scripts (@doegox)
- Added `hf mfu cchk/aeschk` and options to `hf mf cauth/aesauth` (@doegox)
- Added support to inject card auth replies in `hf mfu sim` (@doegox)
- Added ntag22x_suncmac_recovery and mfulaes_mask_recovery scripts (@doegox)
- Added mfulc_counterfeit_recovery script and mfulc_des_brute tool (@np0 & @doegox)
- Fixed ISO14443-4 type B NDEF workflow + parsing (@team-orangeBlue)
- Added Snapmaker U1 filament spool KDF in `hf mf keygen` (@Foxushka)
- Replaced `hf mf bambukeys` with `hf mf keygen` with multiple KDFs support (@Foxushka)
- Fix `hf seos adf/pacs` handling of cards with different diversifier lengths and different ADF OIDs (@nvx)
- Fixed `hf seos adf/pacs` handling of cards with different diversifier lengths and different ADF OIDs (@nvx)
- Added `data qrcode` - to generate QR codes from inside the pm3 client (@iceman1001)
- Fix unicode on mingw/proxspace (@nvx)
- Fix `hf felica raw` - wrong length calculationes. Thanks @dxl for the solutions! (@iceman1001)
- Fixed unicode on mingw/proxspace (@nvx)
- Fixed `hf felica raw` - wrong length calculationes. Thanks @dxl for the solutions! (@iceman1001)
- Added basic QR code generation support. Thanks @mistial-dev for the idea! (@iceman1001)
- Added identification of NDEF/Open print tag record (@iceman1001)
- Added support for Bruce dump files [.rfid] (@iceman1001)
@@ -31,13 +57,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added Ultralight AES basic DataProtKey emulation support (@doegox)
- Changed `mem info` and how the signature handling is done (@iceman1001)
- Added `client/resources/pm3_generic_private_key.pem` in order to self-sign a modded device (@iceman1001)
- Fix `hf mfdes value --op clear` commands for clearing more than 0x80000000 values and getfilesettings mac mode (@merlokk)
- Fixed `hf mfdes value --op clear` commands for clearing more than 0x80000000 values and getfilesettings mac mode (@merlokk)
- Added ATR fingerprinting to `hf 14a/14b info` (@doegox)
- Added `Verkada 40-bit` format (@aaronmaxlevy)
- Added `hf seos write` command (@aaronjamt)
- Added `hf seos sim` command (@aaronjamt)
- Fix `hf mf staticnested` faild to find a KeyB (@xianglin1998)
- Fix errors(jansson) for MSYS2+UCRT compiler (@xianglin1998)
- Fixed `hf mf staticnested` faild to find a KeyB (@xianglin1998)
- Fixed errors(jansson) for MSYS2+UCRT compiler (@xianglin1998)
- Added Kaba evolo AIDs (@xtruan)
## [Phrack.4.20728][2025-09-11]
+16 -14
View File
@@ -29,19 +29,19 @@ ifneq (,$(DESTDIR))
endif
endif
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfc_card_only/% mfc_card_reader/% mfd_aes_brute/% mfulc_des_brute/% fpga_compress/% cryptorf/%
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
#all clean install uninstall check: %: hitag2crack/%
HOST_TARGETS=client mfc_card_only mfc_card_reader mfd_aes_brute mfulc_des_brute fpga_compress cryptorf
host: host/all
host/all: $(addsuffix /all,$(HOST_TARGETS))
host/clean: $(addsuffix /clean,$(HOST_TARGETS))
host/install: $(addsuffix /install,$(HOST_TARGETS))
host/uninstall: $(addsuffix /uninstall,$(HOST_TARGETS))
host/check: $(addsuffix /check,$(HOST_TARGETS))
clean: %: hitag2crack/%
find . -type d -name __pycache__ -exec rm -rfv \{\} +
define submake
$(MAKE) $(1)/$(2) || exit 1;
endef
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
HOST_TARGETS := client mfc_card_only mfc_card_reader mfd_aes_brute mfulc_des_brute fpga_compress cryptorf
TARGETS := bootrom armsrc recovery $(HOST_TARGETS)
all clean install uninstall check: %:
$(foreach target,$(TARGETS),$(call submake,$(target),$*))
host: host/all
host/all host/clean host/install host/uninstall host/check: %:
$(foreach target,$(HOST_TARGETS),$(call submake,$(target),$(notdir $*)))
INSTALLTOOLS=mfc/pm3_eml2lower.sh mfc/pm3_eml2upper.sh mfc/pm3_mfdread.py mfc/pm3_mfd2eml.py mfc/pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py
INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt sim014.bin sim014.sha512.txt
@@ -155,8 +155,6 @@ hitag2crack/check: FORCE
common/check: FORCE
$(info [*] CHECK $(patsubst %/check,%,$@))
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
check: common/check
$(info [*] ALL CHECKS DONE)
cryptorf/%: FORCE
$(info [*] MAKE $@)
@@ -193,6 +191,10 @@ recovery/%: FORCE cleanifplatformchanged
hitag2crack/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/hitag2crack $(patsubst hitag2crack/%,%,$@) DESTDIR=$(MYDESTDIR)
hitag2crack/clean: FORCE hitag2crack/_clean_pycache
hitag2crack/_clean_pycache:
find . -type d -name __pycache__ -exec rm -rfv \{\} +
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
.PHONY: all host clean install uninstall help _test bootrom fullimage recovery client mfc_card_only mfc_card_reader mfulc_des_brute mfd_aes_brute hitag2crack style miscchecks release FORCE udev accessrights cleanifplatformchanged
+75 -23
View File
@@ -68,22 +68,40 @@ export INSTALLSUDO
platform = $(shell uname)
DETECTED_OS=$(platform)
ifneq ($(findstring MINGW,$(platform)),)
IS_WINDOWS := 1
IS_MINGW := 1
endif
ifneq ($(findstring MSYS,$(platform)),)
IS_WINDOWS := 1
IS_MSYS := 1
endif
ifeq ($(platform),Darwin)
IS_DARWIN := 1
ifeq ($(shell uname -p),arm64)
IS_IOS := 1
else
IS_MACOS := 1
endif
endif
ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang version"), 1)
DETECTED_COMPILER = clang
else
DETECTED_COMPILER = gcc
endif
ifeq ($(platform),Darwin)
ifeq ($(shell uname -p),arm64)
# The platform is iOS
USE_BREW ?= 0
# iOS refuses to compile unless this is set
export IPHONEOS_DEPLOYMENT_TARGET=11.0
else
# M* macOS devices return arm
USE_BREW ?= 1
endif
ifdef IS_IOS
# The platform is iOS
USE_BREW ?= 0
# iOS refuses to compile unless this is set
export IPHONEOS_DEPLOYMENT_TARGET=11.0
endif
ifdef IS_MACOS
# M* macOS devices return arm
USE_BREW ?= 1
endif
ifdef IS_DARWIN
USE_MACPORTS ?= 0
AR= /usr/bin/ar rcs
RANLIB= /usr/bin/ranlib
@@ -108,12 +126,12 @@ ifeq ($(USE_MACPORTS),1)
endif
ifeq ($(DEBUG),1)
DEFCXXFLAGS = -g -O0 -pipe
DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe
DEFCXXFLAGS = -ggdb3 -O0 -pipe
DEFCFLAGS = -ggdb3 -O0 -fstrict-aliasing -pipe
DEFLDFLAGS =
else
DEFCXXFLAGS = -Wall -O3 -pipe
DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe
DEFCXXFLAGS = -Wall -Werror -O3 -pipe
DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe
DEFLDFLAGS =
endif
@@ -129,18 +147,18 @@ ifeq ($(SANITIZE),1)
endif
# Some more warnings we want as errors:
DEFCFLAGS += -Wbad-function-cast -Wredundant-decls -Wmissing-prototypes -Wchar-subscripts -Wshadow -Wundef -Wwrite-strings -Wunused -Wuninitialized -Wpointer-arith -Winline -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wmissing-declarations -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits -Wold-style-definition -Wcast-align -Wswitch-enum
# GCC 10 has issues with false positives on stringop-overflow, let's disable them for now (cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335)
# beware these flags didn't exist for GCC < 7
ifeq ($(shell expr $(CC_VERSION) \>= 10), 1)
# GCC 10 to 13 had issues with false positives on stringop-overflow (cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335)
ifeq ($(shell expr $(CC_VERSION) \>= 14), 1)
ifneq ($(DETECTED_COMPILER), clang)
DEFCFLAGS += -Wno-stringop-overflow -Wno-error=stringop-overflow
DEFCFLAGS += -Wstringop-overread -Wstringop-overflow
endif
endif
ifeq ($(platform),Darwin)
ifeq ($(shell uname -p),arm64)
# iOS will refuse to compile without the minimum target of iOS 11.0
DEFCFLAGS += -mios-version-min=11.0
endif
ifdef IS_IOS
# iOS will refuse to compile without the minimum target of iOS 11.0
DEFCFLAGS += -mios-version-min=11.0
endif
ifdef IS_DARWIN
# their readline has strict-prototype issues
DEFCFLAGS += -Wno-strict-prototypes
# some warnings about braced initializers on structs we want to ignore
@@ -149,6 +167,40 @@ else
DEFCFLAGS += -Wstrict-prototypes
endif
ifneq ($(NOHARDENING),1)
# Manual equivalents of -fhardened to avoid g++: warning: linker hardening options not enabled by -fhardened because other link options were specified on the command line
DEFCFLAGS += \
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong
ifeq ($(DETECTED_COMPILER), clang)
ifeq ($(shell expr $(CC_VERSION) \>= 16), 1)
DEFCFLAGS += -ftrivial-auto-var-init=zero
endif
else
ifeq ($(shell expr $(CC_VERSION) \>= 12), 1)
DEFCFLAGS += -ftrivial-auto-var-init=zero
endif
endif
ifndef IS_WINDOWS
ifndef IS_DARWIN
ifeq ($(ARCH),x86_64)
CFLAGS += -fcf-protection=full
endif
DEFCFLAGS += -fPIC
DEFCXXFLAGS += -fPIC
DEFLDFLAGS += -Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -pie
endif
endif
ifdef IS_DARWIN
DEFLDFLAGS += -Wl,-bind_at_load # equivalent of -z,now
DEFLDFLAGS += -Wl,-pie # ASLR
endif
ifeq ($(DETECTED_COMPILER), gcc)
DEFCFLAGS += -fstack-clash-protection
endif
endif
# Next ones are activated only if GCCEXTRA=1 or CLANGEXTRA=1
EXTRACFLAGS =
EXTRACFLAGS += -Wunused-parameter -Wno-error=unused-parameter
+2 -1
View File
@@ -38,7 +38,7 @@ The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the
| [Linux - Important notes on ModemManager](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating Proxmark3 Client Functionality](/doc/md/Use_of_Proxmark/1_Validation.md)|
| [macOS - Homebrew & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/macOS-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
| [macOS - MacPorts](/doc/md/Installation_Instructions/macOS-MacPorts-Installation-Instructions.md) | [Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
| [macOS - Setup and Build](/doc/md/Installation_Instructions/macOS-Compile-From-Source-Instructions.md) ||
| [macOS - Setup and Build](/doc/md/Installation_Instructions/macOS-Compile-From-Source-Instructions.md) |[Standalone Modes](/doc/standalone/)|
| [Windows - Setup and Build](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md) ||
| [Termux / Android - Setup and Build](/doc/termux_notes.md) ||
| [iOS - Setup and Build](/doc/md/Installation_Instructions/iOS-Installation-Instructions.md)
@@ -49,6 +49,7 @@ The Proxmark3 is the swiss-army tool of RFID, allowing for interactions with the
## Notes / helpful documents
| Notes |||
+1 -1
View File
@@ -190,7 +190,7 @@ showinfo:
# version_pm3.c should be checked on every time fullimage.stage1.elf should be remade
version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE
$(info [-] CHECK $@)
$(Q)$(CP) $< $@
$(Q)$(SH) ../tools/mkversion.sh $@ || $(CP) $< $@
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(info [-] GEN $@)
+63
View File
@@ -5,6 +5,9 @@
# Table of Contents
- [Standalone Modes](#standalone-modes)
- [Table of Contents](#table-of-contents)
- [What are standalone modes?](#what-are-standalone-modes)
- [Individual mode documentation](#individual-mode-documentation)
- [Developing Standalone Modes](#developing-standalone-modes)
- [Implementing a standalone mode](#implementing-a-standalone-mode)
- [Naming your standalone mode](#naming-your-standalone-mode)
- [Update MAKEFILE.HAL](#update-makefilehal)
@@ -14,7 +17,67 @@
- [Submitting your code](#submitting-your-code)
Standalone modes run directly on the Proxmark3 device without a connected host computer.
See [Developing Standalone Modes](#developing-standalone-modes) for how to build your own.
> Only one (1) mode can be compiled into the firmware at a time (except via [DANKARMULTI](../../doc/standalone/dankarmulti.md)).
## Individual Mode Documentation
### LF (Low Frequency — 125 kHz) Standalone Modes
| Mode ID | Document | Description | Hardware |
|---------|----------|-------------|----------|
| LF_SAMYRUN | [SamyRun](../../doc/standalone/lf_samyrun.md) | HID26 read/clone/simulate (Samy Kamkar) | Generic |
| LF_EM4100EMUL | [EM4100 Emulator](../../doc/standalone/lf_em4100emul.md) | Simulate predefined EM4100 tag IDs | Generic |
| LF_EM4100RSWB | [EM4100 RSWB](../../doc/standalone/lf_em4100rswb.md) | Read/simulate/write/brute EM4100 (4 slots) | RDV4 (flash) |
| LF_EM4100RSWW | [EM4100 RSWW](../../doc/standalone/lf_em4100rsww.md) | Read/simulate/write/wipe/validate EM4100 | RDV4 (flash) |
| LF_EM4100RWC | [EM4100 RWC](../../doc/standalone/lf_em4100rwc.md) | Read/simulate/clone EM4100 (16 slots) | RDV4 (flash) |
| LF_HIDBRUTE | [HID Corporate Brute](../../doc/standalone/lf_hidbrute.md) | HID Corporate 1000 card number bruteforce | Generic |
| LF_HIDFCBRUTE | [HID FC Brute](../../doc/standalone/lf_hidfcbrute.md) | HID facility code bruteforce (0255) | RDV4 (flash) |
| LF_ICEHID | [IceHID Collector](../../doc/standalone/lf_icehid.md) | Multi-format LF credential collector to flash | RDV4 (flash) |
| LF_MULTIHID | [MultiHID](../../doc/standalone/lf_multihid.md) | HID 26-bit multi-card simulator | Generic |
| LF_NEDAP_SIM | [Nedap Simulator](../../doc/standalone/lf_nedap_sim.md) | Nedap RFID simple tag simulator | Generic |
| LF_NEXID | [NexID Collector](../../doc/standalone/lf_nexid.md) | Nexwatch credential collector to flash | RDV4 (flash) |
| LF_PROXBRUTE | [ProxBrute](../../doc/standalone/lf_proxbrute.md) | HID ProxII card number bruteforce | Generic |
| LF_PROX2BRUTE | [Prox2Brute](../../doc/standalone/lf_prox2brute.md) | HID ProxII bruteforce v2 (faster, configurable) | Generic |
| LF_THAREXDE | [Tharexde EM4x50](../../doc/standalone/lf_tharexde.md) | EM4x50 simulate/read/collect | RDV4 (flash) |
| LF_SKELETON | [Skeleton Template](../../doc/standalone/lf_skeleton.md) | Development template for new LF modes | Generic |
### HF (High Frequency — 13.56 MHz) Standalone Modes
| Mode ID | Document | Description | Hardware |
|---------|----------|-------------|----------|
| HF_14ASNIFF | [14A Sniffer](../../doc/standalone/hf_14asniff.md) | ISO14443A passive sniffer to flash | RDV4 (flash) |
| HF_14BSNIFF | [14B Sniffer](../../doc/standalone/hf_14bsniff.md) | ISO14443B passive sniffer to flash | RDV4 (flash) |
| HF_15SNIFF | [15693 Sniffer](../../doc/standalone/hf_15sniff.md) | ISO15693 sniffer to flash | RDV4 (flash) |
| HF_15SIM | [15693 Simulator](../../doc/standalone/hf_15sim.md) | ISO15693 dump and simulate | RDV4 (flash) |
| HF_AVEFUL | [Aveful UL Reader](../../doc/standalone/hf_aveful.md) | MIFARE Ultralight read and emulate | Generic |
| HF_BOG | [BogitoRun Auth Sniffer](../../doc/standalone/hf_bog.md) | 14A sniff with ULC/ULEV1/NTAG auth capture | RDV4 (flash) |
| HF_CARDHOPPER | [CardHopper Relay](../../doc/standalone/hf_cardhopper.md) | Long-range 14A relay over serial/IP | RDV4 (BT) |
| HF_COLIN | [VIGIKPWN](../../doc/standalone/hf_colin.md) | MIFARE Classic ultra-fast sniff/sim/clone | RDV4 (flash) |
| HF_CRAFTBYTE | [CraftByte UID Stealer](../../doc/standalone/hf_craftbyte.md) | Scan and emulate ISO14443A UIDs | Generic |
| HF_DOEGOX_AUTH0 | [UL-C/UL-AES Unlocker](../../doc/standalone/hf_doegox_auth0.md) | Unlock password-protected Ultralight tags | Generic |
| HF_EMVPNG | [EMV Visa Reader/Emulator](../../doc/standalone/hf_emvpng.md) | Read Visa EMV cards and emulate transactions | RDV4 (flash) |
| HF_ICECLASS | [IceClass iCLASS](../../doc/standalone/hf_iceclass.md) | iCLASS multi-mode: sim/dump/attack/config | RDV4 (flash) |
| HF_LEGIC | [Legic Prime Reader](../../doc/standalone/hf_legic.md) | Read and simulate Legic Prime tags | Generic |
| HF_LEGICSIM | [Legic Prime Simulator](../../doc/standalone/hf_legicsim.md) | Simulate Legic Prime dumps from flash (15 slots) | RDV4 (flash) |
| HF_MATTYRUN | [MattyRun MFC Clone](../../doc/standalone/hf_mattyrun.md) | MIFARE Classic key check, dump, and emulate | Generic |
| HF_MFCSIM | [MFC Simulator](../../doc/standalone/hf_mfcsim.md) | Simulate MIFARE Classic 1K from flash (15 slots) | RDV4 (flash) |
| HF_MSDSAL | [MSD Visa Reader](../../doc/standalone/hf_msdsal.md) | Read and emulate Visa MSD cards | Generic |
| HF_REBLAY | [Reblay BT Relay](../../doc/standalone/hf_reblay.md) | ISO14443A relay over Bluetooth | RDV4 (BT) |
| HF_ST25_TEAROFF | [ST25TB Tear-off](../../doc/standalone/hf_st25_tearoff.md) | ST25TB store/restore with counter tear-off | RDV4 (flash) |
| HF_TCPRST | [IKEA Rothult](../../doc/standalone/hf_tcprst.md) | IKEA Rothult ST25TA master key dump/emulation | Generic |
| HF_TMUDFORD | [ISO15693 UID Emulator](../../doc/standalone/hf_tmudford.md) | Read and emulate ISO15693 UIDs | Generic |
| HF_UNISNIFF | [Universal Sniffer](../../doc/standalone/hf_unisniff.md) | Multi-protocol sniffer (14A/14B/15/iCLASS) | RDV4 (flash) |
| HF_YOUNG | [Young MFC Sniff/Sim](../../doc/standalone/hf_young.md) | MIFARE sniff/simulation with 2-bank storage | Generic |
### Multi-Mode Loader
| Mode ID | Document | Description |
|---------|----------|-------------|
| DANKARMULTI | [Dankarmulti Loader](../../doc/standalone/dankarmulti.md) | Combine multiple standalone modes into one firmware image |
# Developing Standalone Modes
This contains functionality for different StandAlone modes. The fullimage will be built given the correct compiler flags used. Build targets for these files are contained in `Makefile.inc` and `Makefile.hal`
If you want to implement a new standalone mode, you need to implement the methods provided in `standalone.h`.
+16 -3
View File
@@ -101,19 +101,19 @@ uint8_t g_tearoff_skip = 0;
int tearoff_hook(void) {
if (g_tearoff_enabled) {
if (g_tearoff_delay_us == 0) {
Dbprintf(_RED_("No tear-off delay configured!"));
if (g_dbglevel >= DBG_ERROR) Dbprintf(_RED_("No tear-off delay configured!"));
g_tearoff_enabled = false;
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
}
if (g_tearoff_skip > 0) {
Dbprintf(_GREEN_("Tear-off skipped!"));
if (g_dbglevel >= DBG_INFO) Dbprintf(_GREEN_("Tear-off skipped!"));
g_tearoff_skip--;
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
}
SpinDelayUsPrecision(g_tearoff_delay_us);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
g_tearoff_enabled = false;
if (g_dbglevel >= DBG_ERROR) Dbprintf(_YELLOW_("Tear-off triggered!"));
if (g_dbglevel >= DBG_INFO) Dbprintf(_YELLOW_("Tear-off triggered!"));
return PM3_ETEAROFF;
} else {
return PM3_SUCCESS; // SUCCESS = the hook didn't do anything
@@ -1744,6 +1744,10 @@ static void PacketReceived(PacketCommandNG *packet) {
setHf14bConfig(&c);
break;
}
case CMD_HF_ISO14443B_ST25TB_TEAROFF: {
ST25TB_TearOff(packet->data.asBytes);
break;
}
case CMD_HF_CRYPTORF_SIM : {
// simulate_crf_tag();
break;
@@ -2439,6 +2443,15 @@ static void PacketReceived(PacketCommandNG *packet) {
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
uint8_t *mem = BigBuf_get_addr();
// sanity checks
if (payload->bytes_in_packet > sizeof(payload->data) ||
payload->idx > BigBuf_get_size() ||
payload->idx + payload->bytes_in_packet > BigBuf_get_size()) {
reply_ng(CMD_SMART_UPLOAD, PM3_EOVFLOW, NULL, 0);
break;
}
memcpy(mem + payload->idx, payload->data, payload->bytes_in_packet);
uint8_t a = 0, b = 0;
+20
View File
@@ -161,8 +161,17 @@ void ulaes_cmac8(uint8_t *cmac, uint8_t *mac) {
}
void append_cmac(uint8_t *d, size_t n) {
// sanity check
if (n > PM3_CMD_DATA_SIZE) {
return;
}
uint8_t mac[16] = {0};
uint8_t cmd_mac[2 + n];
memset(cmd_mac, 0, sizeof(cmd_mac));
cmd_mac[0] = g_secure_session.counter & 0xFF;
cmd_mac[1] = (g_secure_session.counter >> 8) & 0xFF;
memcpy(cmd_mac + 2, d, n);
@@ -177,19 +186,30 @@ void append_cmac(uint8_t *d, size_t n) {
}
int verify_cmac(uint8_t *d, size_t n, bool verify_crc) {
// sanity check
if (n > PM3_CMD_DATA_SIZE) {
return PM3_EOVFLOW;
}
// n = data size without cmac and without crc
uint8_t chk_d[n + ULAES_CMAC8_SIZE + 2];
memcpy(chk_d, d, n);
memset(chk_d + n, 0, sizeof(chk_d) - n);
append_cmac(chk_d, n);
if (memcmp(chk_d + n, d + n, ULAES_CMAC8_SIZE) != 0) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("CMAC response error.");
}
return PM3_ECRC;
}
if (verify_crc) {
AddCrc14A(chk_d, n + ULAES_CMAC8_SIZE);
if (memcmp(chk_d + n + ULAES_CMAC8_SIZE, d + n + ULAES_CMAC8_SIZE, 2) != 0) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("CRC response error.");
+9
View File
@@ -600,6 +600,15 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
if ((communication_settings & MAC_VERIFY) == MAC_VERIFY) {
if (*nbytes < key_macing_length(key)) {
*nbytes = -1;
res = NULL;
#ifdef WITH_DEBUG
Dbprintf("No room for MAC!");
#endif
break;
}
*nbytes -= key_macing_length(key);
if (*nbytes == 0) {
+158 -79
View File
@@ -77,7 +77,7 @@ static uint32_t iso18092_get_timeout(void) {
static uint8_t frameSpace[FELICA_MAX_RF_FRAME_SIZE];
//structure to hold incoming NFC frame, used for ISO/IEC 18092-compatible frames
static struct {
typedef struct {
enum {
STATE_UNSYNCD,
STATE_TRYING_SYNC,
@@ -88,15 +88,25 @@ static struct {
} state;
uint16_t shiftReg; //for synchronization and offset calculation
uint16_t shiftRegInv; // sync search helper while polarity is unknown
int posCnt;
bool crc_ok;
int rem_len;
uint16_t len;
uint8_t byte_offset;
uint8_t polarity;
uint8_t *framebytes;
//should be enough. maxlen is 255, 254 for data, 2 for sync, 2 for crc
// 0,1 -> SYNC, 2 - len, 3-(len+1)->data, then crc
} FelicaFrame;
} felica_frame_t;
enum {
FELICA_POLARITY_UNKNOWN = 0,
FELICA_POLARITY_NORMAL = 1,
FELICA_POLARITY_INVERTED = 2
};
static felica_frame_t FelicaFrame;
//b2 4d is SYNC, 45645 in 16-bit notation, 10110010 01001101 binary. Frame will not start filling until this is shifted in
//bit order in byte -reverse, I guess? [((bt>>0)&1),((bt>>1)&1),((bt>>2)&1),((bt>>3)&1),((bt>>4)&1),((bt>>5)&1),((bt>>6)&1),((bt>>7)&1)] -at least in the mode that I read those in
@@ -104,111 +114,139 @@ static struct {
# define SYNC_16BIT 0xB24D
#endif
static void FelicaFrameReset(void) {
FelicaFrame.state = STATE_UNSYNCD;
FelicaFrame.posCnt = 0;
FelicaFrame.crc_ok = false;
FelicaFrame.byte_offset = 0;
static void FelicaFrameReset(felica_frame_t *f) {
f->state = STATE_UNSYNCD;
f->posCnt = 0;
f->shiftReg = 0;
f->shiftRegInv = 0;
f->crc_ok = false;
f->rem_len = 0;
f->len = 0;
f->byte_offset = 0;
f->polarity = FELICA_POLARITY_UNKNOWN;
}
static void FelicaFrameinit(uint8_t *data) {
FelicaFrame.framebytes = data;
FelicaFrameReset();
static void FelicaFrameinit(felica_frame_t *f, uint8_t *data) {
f->framebytes = data;
FelicaFrameReset(f);
}
//shift byte into frame, reversing it at the same time
static void shiftInByte(uint8_t bt) {
static void shiftInByte(felica_frame_t *f, uint8_t bt) {
uint8_t j;
for (j = 0; j < FelicaFrame.byte_offset; j++) {
FelicaFrame.framebytes[FelicaFrame.posCnt] = (FelicaFrame.framebytes[FelicaFrame.posCnt] << 1) + (bt & 1);
for (j = 0; j < f->byte_offset; j++) {
f->framebytes[f->posCnt] = (f->framebytes[f->posCnt] << 1) + (bt & 1);
bt >>= 1;
}
FelicaFrame.posCnt++;
FelicaFrame.rem_len--;
for (j = FelicaFrame.byte_offset; j < 8; j++) {
FelicaFrame.framebytes[FelicaFrame.posCnt] = (FelicaFrame.framebytes[FelicaFrame.posCnt] << 1) + (bt & 1);
f->posCnt++;
f->rem_len--;
for (j = f->byte_offset; j < 8; j++) {
f->framebytes[f->posCnt] = (f->framebytes[f->posCnt] << 1) + (bt & 1);
bt >>= 1;
}
}
static void Process18092Byte(uint8_t bt) {
static void Process18092Byte(felica_frame_t *f, uint8_t bt) {
switch (FelicaFrame.state) {
switch (f->state) {
case STATE_UNSYNCD: {
// almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not always the case
if (bt > 0) {
FelicaFrame.shiftReg = reflect8(bt);
FelicaFrame.state = STATE_TRYING_SYNC;
uint8_t btr = reflect8(bt);
f->shiftReg = btr;
f->shiftRegInv = (uint8_t)~btr;
f->polarity = FELICA_POLARITY_UNKNOWN;
f->state = STATE_TRYING_SYNC;
}
break;
}
case STATE_TRYING_SYNC: {
uint8_t bt_norm = bt;
uint8_t bt_inv = (uint8_t)~bt;
if (bt == 0) {
// desync
FelicaFrame.shiftReg = bt;
FelicaFrame.state = STATE_UNSYNCD;
} else {
for (uint8_t i = 0; i < 8; i++) {
bool sync_normal = (f->shiftReg == SYNC_16BIT);
bool sync_inverted = (f->shiftRegInv == SYNC_16BIT);
for (uint8_t i = 0; i < 8; i++) {
if (sync_normal || sync_inverted) {
bool use_inverted = sync_inverted;
uint8_t shift_bt = use_inverted ? bt_inv : bt_norm;
if (FelicaFrame.shiftReg == SYNC_16BIT) {
// SYNC done!
FelicaFrame.state = STATE_GET_LENGTH;
FelicaFrame.framebytes[0] = 0xb2;
FelicaFrame.framebytes[1] = 0x4d;
FelicaFrame.byte_offset = i;
// SYNC done!
f->state = STATE_GET_LENGTH;
f->framebytes[0] = 0xb2;
f->framebytes[1] = 0x4d;
f->framebytes[2] = 0x00;
f->byte_offset = i;
f->polarity = use_inverted ? FELICA_POLARITY_INVERTED : FELICA_POLARITY_NORMAL;
// shift in remaining byte, slowly...
for (uint8_t j = i; j < 8; j++) {
FelicaFrame.framebytes[2] = (FelicaFrame.framebytes[2] << 1) + (bt & 1);
bt >>= 1;
}
FelicaFrame.posCnt = 2;
if (i == 0) {
break;
}
// shift in remaining byte, slowly...
for (uint8_t j = i; j < 8; j++) {
f->framebytes[2] = (f->framebytes[2] << 1) + (shift_bt & 1);
shift_bt >>= 1;
}
FelicaFrame.shiftReg = (FelicaFrame.shiftReg << 1) + (bt & 1);
bt >>= 1;
f->posCnt = 2;
return;
}
//that byte was last byte of sync
if (FelicaFrame.shiftReg == SYNC_16BIT) {
//Force SYNC on next byte
FelicaFrame.state = STATE_GET_LENGTH;
FelicaFrame.framebytes[0] = 0xb2;
FelicaFrame.framebytes[1] = 0x4d;
FelicaFrame.byte_offset = 0;
FelicaFrame.posCnt = 1;
}
f->shiftReg = (f->shiftReg << 1) + (bt_norm & 1);
f->shiftRegInv = (f->shiftRegInv << 1) + (bt_inv & 1);
bt_norm >>= 1;
bt_inv >>= 1;
}
// that byte was last byte of sync
if (f->shiftReg == SYNC_16BIT || f->shiftRegInv == SYNC_16BIT) {
bool use_inverted = (f->shiftRegInv == SYNC_16BIT);
// Force SYNC on next byte
f->state = STATE_GET_LENGTH;
f->framebytes[0] = 0xb2;
f->framebytes[1] = 0x4d;
f->framebytes[2] = 0x00;
f->byte_offset = 0;
f->posCnt = 1;
f->polarity = use_inverted ? FELICA_POLARITY_INVERTED : FELICA_POLARITY_NORMAL;
}
break;
}
case STATE_GET_LENGTH: {
shiftInByte(bt);
FelicaFrame.rem_len = FelicaFrame.framebytes[2] - 1;
FelicaFrame.len = FelicaFrame.framebytes[2] + 4; //with crc and sync
FelicaFrame.state = STATE_GET_DATA;
if (f->polarity == FELICA_POLARITY_INVERTED) {
bt = (uint8_t)~bt;
}
shiftInByte(f, bt);
if (f->framebytes[2] == 0 || (f->framebytes[2] + 4 > FELICA_MAX_RF_FRAME_SIZE)) {
// invalid frame length, drop frame and start over.
FelicaFrameReset(f);
break;
}
f->rem_len = f->framebytes[2] - 1;
f->len = f->framebytes[2] + 4; //with crc and sync
f->state = STATE_GET_DATA;
break;
}
case STATE_GET_DATA: {
shiftInByte(bt);
if (FelicaFrame.rem_len <= 0) {
FelicaFrame.state = STATE_GET_CRC;
FelicaFrame.rem_len = 2;
if (f->polarity == FELICA_POLARITY_INVERTED) {
bt = (uint8_t)~bt;
}
shiftInByte(f, bt);
if (f->rem_len <= 0) {
f->state = STATE_GET_CRC;
f->rem_len = 2;
}
break;
}
case STATE_GET_CRC: {
shiftInByte(bt);
if (FelicaFrame.rem_len <= 0) {
FelicaFrame.rem_len = 0;
if (f->polarity == FELICA_POLARITY_INVERTED) {
bt = (uint8_t)~bt;
}
shiftInByte(f, bt);
if (f->rem_len <= 0) {
f->rem_len = 0;
// skip sync 2bytes. IF ok, residue should be 0x0000
FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2);
FelicaFrame.state = STATE_FULL;
f->crc_ok = check_crc(CRC_FELICA, f->framebytes + 2, f->len - 2);
f->state = STATE_FULL;
}
break;
}
@@ -278,6 +316,14 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
return 3;
}
// 4. frame too short to contain IDm + PMm (need 4 header + 8 + 8 = 20 bytes)
if (FelicaFrame.len < 20) {
if (g_dbglevel >= DBG_DEBUG) {
Dbprintf("Error: Frame length smaller than 20, got %u", FelicaFrame.len);
}
return 4;
}
// copy UID
// idm 8
if (card) {
@@ -438,10 +484,12 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
// if (g_dbglevel >= DBG_DEBUG) { Dbprintf("WaitForFelicaReply Start"); }
uint32_t c = 0;
uint16_t crc_fail_normal = 0;
uint16_t crc_fail_inverted = 0;
// power, no modulation
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
FelicaFrameReset();
FelicaFrameReset(&FelicaFrame);
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@@ -457,17 +505,42 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
Process18092Byte(b);
Process18092Byte(&FelicaFrame, b);
felica_frame_t *received = NULL;
if (FelicaFrame.state == STATE_FULL) {
if (FelicaFrame.crc_ok) {
received = &FelicaFrame;
} else {
if (FelicaFrame.polarity == FELICA_POLARITY_INVERTED) {
crc_fail_inverted++;
} else {
crc_fail_normal++;
}
FelicaFrameReset(&FelicaFrame);
}
}
if (received != NULL) {
if (maxbytes && received->len > maxbytes) {
if (g_dbglevel >= DBG_DEBUG) {
Dbprintf("FeliCa RX frame dropped (len %u > max %u)", received->len, maxbytes);
}
FelicaFrameReset(&FelicaFrame);
continue;
}
if (g_dbglevel >= DBG_DEBUG && received->polarity == FELICA_POLARITY_INVERTED) {
DbpString("FeliCa RX decoded using inverted polarity fallback");
}
felica_nexttransfertime = MAX(
felica_nexttransfertime,
(GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME);
LogTrace(
FelicaFrame.framebytes,
FelicaFrame.len,
received->framebytes,
received->len,
((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER - timeout,
((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER,
NULL,
@@ -475,9 +548,15 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
);
return true;
} else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) {
} else if (
c++ > timeout
&& (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)
) {
// if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD");
if (g_dbglevel >= DBG_DEBUG && (crc_fail_normal || crc_fail_inverted)) {
Dbprintf("FeliCa RX timeout, CRC fails normal=%u inverted=%u", crc_fail_normal, crc_fail_inverted);
}
return false;
}
@@ -497,7 +576,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
#endif
// allocate command receive buffer
BigBuf_free();
FelicaFrameinit(BigBuf_calloc(FELICA_MAX_RF_FRAME_SIZE));
FelicaFrameinit(&FelicaFrame, BigBuf_calloc(FELICA_MAX_RF_FRAME_SIZE));
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
// iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card
@@ -710,7 +789,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
Process18092Byte(dist);
Process18092Byte(&FelicaFrame, dist);
if ((dist >= 178) && (++trigger_cnt > triggersToSkip)) {
Dbprintf("triggers To skip kicked %d", dist);
@@ -734,7 +813,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
NULL,
isReaderFrame
);
FelicaFrameReset();
FelicaFrameReset(&FelicaFrame);
}
}
}
@@ -822,7 +901,7 @@ void felica_sim_lite(const uint8_t *uid) {
uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
// frtm = GetCountSspClk();
Process18092Byte(dist);
Process18092Byte(&FelicaFrame, dist);
if (FelicaFrame.state == STATE_FULL) {
@@ -859,10 +938,10 @@ void felica_sim_lite(const uint8_t *uid) {
listenmode = false;
}
// clear frame
FelicaFrameReset();
FelicaFrameReset(&FelicaFrame);
} else {
// frame invalid, clear it out to allow for the next one
FelicaFrameReset();
FelicaFrameReset(&FelicaFrame);
}
}
}
@@ -878,7 +957,7 @@ void felica_sim_lite(const uint8_t *uid) {
// switch back
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD);
FelicaFrameReset();
FelicaFrameReset(&FelicaFrame);
listenmode = true;
curlen = 0;
curresp = NULL;
+4
View File
@@ -630,6 +630,10 @@ int FpgaGetCurrent(void) {
return downloaded_bitstream;
}
void FpgaResetBitstream(void) {
downloaded_bitstream = FPGA_BITSTREAM_UNKNOWN;
}
// Turns off the antenna,
// log message
// if HF, Disable SSC DMA
+1
View File
@@ -172,6 +172,7 @@ void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, uint16_t len);
void Fpga_print_status(void);
int FpgaGetCurrent(void);
void FpgaResetBitstream(void);
void SetAdcMuxFor(uint32_t whichGpio);
// extern and generel turn off the antenna method
+25 -10
View File
@@ -272,9 +272,12 @@ void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_
}
out:
if (dataout && dataoutlen)
if (dataout && dataoutlen) {
memcpy(dataout, mac_responses, *dataoutlen);
}
FpgaResetBitstream();
switch_off();
BigBuf_free_keep_EM();
}
@@ -815,15 +818,15 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
}
if (simulationMode == ICLASS_SIM_MODE_FULL_GLITCH) {
//Jam the read based on the last SIO block
// jam the read based on the last SIO block
uint8_t *sr_or_sio = emulator + (current_page * page_size) + (6 * 8);
if (memcmp(emulator + (current_page * page_size) + (5 * 8), ff_data, PICOPASS_BLOCK_SIZE) == 0) { //SR card
if (block == 16) { //SR cards use a standard legth SIO
//update block 6 byte 1 from 03 to A3
if (memcmp(emulator + (current_page * page_size) + (5 * 8), ff_data, PICOPASS_BLOCK_SIZE) == 0) { // SR card
if (block == 16) { // SR cards use a standard legth SIO
// update block 6 byte 1 from 03 to A3
sr_or_sio[0] |= 0xA0;
goto send;
}
} else { //For SE cards we have to account for different SIO lengths depending if a standard or custom key is used
} else { // for SE cards we have to account for different SIO lengths depending if a standard or custom key is used
if (block == (5 + ((sr_or_sio[1] + 12) / 8))) {
goto send;
}
@@ -921,6 +924,7 @@ send:
DbpString("button pressed");
}
return button_pressed;
}
@@ -2746,6 +2750,9 @@ void iClass_Recover(iclass_recover_req_t *msg) {
uint32_t start_time = 0;
uint8_t read_check_cc[] = { 0x10 | ICLASS_CMD_READCHECK, 0x18 }; //block 24 with credit key
uint8_t read_check_cc2[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; //block 2 -> to check Kd macs
if (msg->credit_recovery == true) {
read_check_cc[0] = 0x80 | ICLASS_CMD_READCHECK; //still block 24 but with debit key
}
/* iclass_mac_table is a series of weak macs, those weak macs correspond to the different combinations of the last 3 bits of each key byte. */
@@ -2788,7 +2795,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
}
//Step0 Card Select Routine
eof_time = 0; //reset eof time
res = select_iclass_tag(&hdr, false, &eof_time, shallow_mod);
res = select_iclass_tag(&hdr, msg->credit_recovery, &eof_time, shallow_mod);
if (res) {
status_message = 1; //card select successful
card_select = true;
@@ -2796,14 +2803,16 @@ void iClass_Recover(iclass_recover_req_t *msg) {
//Step 0A - The read_check_cc block has to be in AA2, set it by checking the card configuration
read_check_cc[1] = hdr.conf.app_limit + 1; //first block of AA2
if (msg->credit_recovery == true) {
read_check_cc[1] = hdr.conf.app_limit - 1; //last block of AA1
}
//Step1 Authenticate with AA1 using trace
if (card_select) {
memcpy(original_mac, msg->req.key, 8);
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
res = authenticate_iclass_tag(&msg->req, &hdr, &start_time, &eof_time, mac1);
if (res) {
status_message = 2; //authentication with AA1 macs successful
status_message = 2; //authentication with AA1(AA2 if credit recovery) macs successful
card_auth = true;
}
}
@@ -2852,7 +2861,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
set_tracing(false); // disable tracing to prevent crashes - set to true for debugging
// Step0 Card Select Routine
eof_time = 0; // reset eof time
res = select_iclass_tag(&hdr, false, &eof_time, shallow_mod);
res = select_iclass_tag(&hdr, msg->credit_recovery, &eof_time, shallow_mod);
if (res) {
status_message = 1; // card select successful
card_select = true;
@@ -2923,6 +2932,9 @@ void iClass_Recover(iclass_recover_req_t *msg) {
uint8_t wb[9] = {0};
uint8_t blockno = 3;
if (msg->credit_recovery == true) {
blockno = 4;
}
wb[0] = blockno;
memcpy(wb + 1, genkeyblock, 8);
doMAC_N(wb, sizeof(wb), div_key2, mac2);
@@ -3072,6 +3084,9 @@ fast_restore:
uint8_t mac2[4] = {0};
uint8_t wb[9] = {0};
uint8_t blockno = 3;
if (msg->credit_recovery == true) {
blockno = 4;
}
wb[0] = blockno;
bool reverted = false;
uint8_t revert_retries = 0;
+28 -6
View File
@@ -852,11 +852,20 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
uint32_t rx_samples = 0;
uint16_t checker = 12000;
// loop and listen
while (BUTTON_PRESS() == false) {
WDT_HIT();
LED_A_ON();
if (checker-- == 0) {
if (data_available()) {
break;
}
checker = 12000;
}
register int readBufDataP = data - dma->buf;
register int dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
if (readBufDataP <= dmaBufDataP) {
@@ -1436,6 +1445,11 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
}
break;
}
case 15: { // MIFARE Plus
rATQA[0] = 0x44;
sak = 0x20;
break;
}
default: {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
return false;
@@ -2615,7 +2629,7 @@ int EmGetCmd(uint8_t *received, uint16_t received_max_len, uint16_t *len, uint8_
if (flip == 3) {
if (data_available()) {
Dbprintf("----------- " _GREEN_("Breaking / Data") " ----------");
return false;
return 1;
}
flip = 0;
}
@@ -2624,7 +2638,7 @@ int EmGetCmd(uint8_t *received, uint16_t received_max_len, uint16_t *len, uint8_
if (checker-- == 0) {
if (BUTTON_PRESS()) {
Dbprintf("----------- " _GREEN_("Button pressed, user aborted") " ----------");
return false;
return 1;
}
flip++;
@@ -4582,6 +4596,14 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
int received_aid_len = receivedCmd[5 + offset];
uint8_t *received_aid = &receivedCmd[6 + offset];
// Validate claimed AID length against actual received frame length
if ((6 + offset + received_aid_len) > len) {
dynamic_response_info.response[1 + offset] = 0x6A;
dynamic_response_info.response[2 + offset] = 0x80; // Wrong data
dynamic_response_info.response_n = 3 + offset;
break;
}
// aid enumeration flag
if ((flags & FLAG_ENUMERATE_AID) == FLAG_ENUMERATE_AID) {
Dbprintf("Received AID (%d):", received_aid_len);
@@ -4590,8 +4612,8 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
if ((received_aid_len == aid_len) && (memcmp(aid, received_aid, aid_len) == 0)) { // Evaluate the AID sent by the Reader to the AID supplied
// AID Response will be parsed here
memcpy(dynamic_response_info.response + 1 + offset, selectaid_response, selectaid_response_len + 1 + offset);
dynamic_response_info.response_n = selectaid_response_len + 2;
memcpy(dynamic_response_info.response + 1 + offset, selectaid_response, selectaid_response_len);
dynamic_response_info.response_n = selectaid_response_len + 1 + offset;
} else { // Any other SELECT FILE command will return with a Not Found
dynamic_response_info.response[1 + offset] = 0x6A;
dynamic_response_info.response[2 + offset] = 0x82;
@@ -4611,8 +4633,8 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
case 0xCA: { // GET DATA
if (sentCount == 0) {
// APDU Command will just be parsed here
memcpy(dynamic_response_info.response + 1 + offset, getdata_response, getdata_response_len + 2);
dynamic_response_info.response_n = selectaid_response_len + 1 + offset;
memcpy(dynamic_response_info.response + 1 + offset, getdata_response, getdata_response_len);
dynamic_response_info.response_n = getdata_response_len + 1 + offset;
} else {
finished = true;
break;
+478 -9
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -49,6 +49,7 @@ int read_14b_srx_block(uint8_t blocknr, uint8_t *block);
int iso14443b_select_srx_card(iso14b_card_select_t *card);
void SniffIso14443b(void);
void SendRawCommand14443B(iso14b_raw_cmd_t *p);
void ST25TB_TearOff(const uint8_t *data);
void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing);
// 14b config
+218 -92
View File
File diff suppressed because it is too large Load Diff

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