Merge pull request #3 from RfidResearchGroup/master

Update from master
This commit is contained in:
mwalker33 2019-08-12 10:28:24 +10:00 committed by GitHub
commit a72c11dec0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
515 changed files with 10448 additions and 5771 deletions

1
.gitignore vendored
View file

@ -39,6 +39,7 @@ client/ui/ui_overlays.h
hardnested_stats.txt hardnested_stats.txt
proxmark3 proxmark3
flasher flasher
!flasher/
lua lua
luac luac
fpga_compress fpga_compress

View file

@ -8,22 +8,18 @@ compiler: gcc
matrix: matrix:
include: include:
- os: osx - os: osx
osx_image: xcode9.2 # OS X 10.13 osx_image: xcode11
- os: linux - os: linux
dist: xenial dist: xenial
sudo: required sudo: required
before_install: addons:
## Install ARM toolchain on Linux. apt:
## add our homebrew tap for MacOS packages:
## Note: all dependencies on MacOS should be resolved by the brew install command - gcc-arm-none-eabi
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - libnewlib-dev
sudo apt-get update -qq; homebrew:
sudo apt-get install -y gcc-arm-none-eabi libnewlib-dev; taps: RfidResearchGroup/proxmark3
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew update;
brew tap RfidResearchGroup/proxmark3;
fi
install: install:
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
@ -34,8 +30,6 @@ install:
make all; make all;
fi fi
before_script:
script: script:
## start and run a test script ## start and run a test script
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then

27
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,27 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "make clean && make all -j$(nproc --all)",
"problemMatcher": [
"$gcc"
]
},
{
"label": "flash fullimage",
"type": "shell",
"command": "./flash-fullimage.sh",
"problemMatcher": []
},
{
"label": "FLASH BOOTROM",
"type": "shell",
"command": "./flash-bootrom.sh",
"problemMatcher": []
}
]
}

View file

@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Rework hitag2 read/write help (@ViRb3)
- Add 'lf nedap' - encoding / decoding (anon)
- Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox)
- Add VSCode tasks (@ViRb3)
- Better warn user of hardcoded hitag info (@ViRb3)
- Format and docs hitag (@ViRb3)
- Fix hitag password write offset by 1 (@ViRb3)
- Fix momentarily flash read/write of dicts (@doegox/@cjbrigato)
- Add some more default keys (@anon)
- Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox)
- Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox)
- Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001)
- Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001)
- Add FPGA LF adc path (@anon)
- Add ECC support / check for NID_secp128r1 (@pwpiwi)
- Add some more default keys (ollibolli)
- Fix T55x7 Downlink timings backward compatible (@mwalker33) - Fix T55x7 Downlink timings backward compatible (@mwalker33)
- Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox) - Add proper Makefile halting when using incompatible STANDALONE and PLATFORM vars (@doegox)
- Add T55x7 Downlink mode support (@mwalker33) - Add T55x7 Downlink mode support (@mwalker33)
@ -152,7 +168,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Change `lf indala demod` - refactoring (@iceman1001) - Change `lf indala demod` - refactoring (@iceman1001)
- Change - handling fault bit markers (7) and partial nibbles in hex printing (@doegox) - Change - handling fault bit markers (7) and partial nibbles in hex printing (@doegox)
- Change - printing of fault bit markers (7) using a dot (@doegox) - Change - printing of fault bit markers (7) using a dot (@doegox)
- Change `sc upgrade` - firmware file integrity check (@piwi) - Change `sc upgrade` - firmware file integrity check (@pwpiwi)
- Fix `data rawdemod am` - last bit was missing (@doegox) - Fix `data rawdemod am` - last bit was missing (@doegox)
- Fix `hf 15 dump f` - also selects tag first (@iceman1001) - Fix `hf 15 dump f` - also selects tag first (@iceman1001)
- Fix `hf iclass clone` - missing fileclose (@iceman1001) - Fix `hf iclass clone` - missing fileclose (@iceman1001)
@ -160,8 +176,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Change `lf hitag sim` - loads bin/eml/json (@iceman1001) - Change `lf hitag sim` - loads bin/eml/json (@iceman1001)
- Change `lf hitag reader 21` - saves in bin/eml/json (@iceman1001) - Change `lf hitag reader 21` - saves in bin/eml/json (@iceman1001)
- Change `lf hitag` - refactoring (@iceman1001) - Change `lf hitag` - refactoring (@iceman1001)
- Change `lf hitag` - refactoring (@piwi) - Change `lf hitag` - refactoring (@pwpiwi)
- Fix `lf hitag` - generic fix for missing clock init (@piwi) - Fix `lf hitag` - generic fix for missing clock init (@pwpiwi)
- Fix fsk sim operations on deviceside - avoid division by zero (@doegox) - Fix fsk sim operations on deviceside - avoid division by zero (@doegox)
- Fix `hf mf fchk` - condition always false (@doegox) - Fix `hf mf fchk` - condition always false (@doegox)
- Fix `lf t55xx recoverpw` - shift as u32 (@doegox) - Fix `lf t55xx recoverpw` - shift as u32 (@doegox)
@ -290,7 +306,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (@merlokk) - Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (@merlokk)
- Added to proxmark ability to execute commands from stdin (pipe) (@merlokk) - Added to proxmark ability to execute commands from stdin (pipe) (@merlokk)
- Added new standalone mode "HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN" (@cjbrigato) - Added new standalone mode "HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN" (@cjbrigato)
- Added to `hf 14a apdu` - exchange apdu via iso1443-4 (@merlokk) - Added to `hf 14a apdu` - exchange apdu via iso14443-4 (@merlokk)
- Added to `hf 14a apdu` - apdu and tlv results parser (@merlokk) - Added to `hf 14a apdu` - apdu and tlv results parser (@merlokk)
- Added `hf emv` commands (@merlokk) - Added `hf emv` commands (@merlokk)
- lots of bug fixes (many many) - lots of bug fixes (many many)

View file

@ -31,9 +31,9 @@ endif
-include Makefile.platform -include Makefile.platform
-include .Makefile.options.cache -include .Makefile.options.cache
include common/Makefile.hal include common_arm/Makefile.hal
all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/%
mfkey/%: FORCE mfkey/%: FORCE
$(info [*] MAKE $@) $(info [*] MAKE $@)
@ -41,10 +41,13 @@ mfkey/%: FORCE
nonce2key/%: FORCE nonce2key/%: FORCE
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) $(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@)
fpga_compress/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@)
bootrom/%: FORCE cleanifplatformchanged bootrom/%: FORCE cleanifplatformchanged
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) $(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@)
armsrc/%: FORCE cleanifplatformchanged armsrc/%: FORCE cleanifplatformchanged fpga_compress/%
$(info [*] MAKE $@) $(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) $(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@)
client/%: FORCE client/%: FORCE
@ -55,7 +58,7 @@ recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/%
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) $(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@)
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites) FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nounce2key style checks FORCE udev accessrights cleanifplatformchanged .PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged
help: help:
@echo "Multi-OS Makefile" @echo "Multi-OS Makefile"
@ -73,7 +76,8 @@ help:
@echo @echo
@echo "+ client - Make only the OS-specific host client" @echo "+ client - Make only the OS-specific host client"
@echo "+ mfkey - Make tools/mfkey" @echo "+ mfkey - Make tools/mfkey"
@echo "+ nounce2key - Make tools/nounce2key" @echo "+ nonce2key - Make tools/nonce2key"
@echo "+ fpga_compress - Make tools/fpga_compress"
@echo @echo
@echo "+ style - Apply some automated source code formatting rules" @echo "+ style - Apply some automated source code formatting rules"
@echo "+ checks - Detect various encoding issues in source code" @echo "+ checks - Detect various encoding issues in source code"
@ -93,6 +97,8 @@ mfkey: mfkey/all
nonce2key: nonce2key/all nonce2key: nonce2key/all
fpga_compress: fpga_compress/all
flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL) flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<) $(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<)
@ -145,7 +151,7 @@ style:
# Make sure astyle is installed # Make sure astyle is installed
@which astyle >/dev/null || ( echo "Please install 'astyle' package first" ; exit 1 ) @which astyle >/dev/null || ( echo "Please install 'astyle' package first" ; exit 1 )
# Remove spaces & tabs at EOL, add LF at EOF if needed on *.c, *.h, *.cpp. *.lua, *.py, *.pl, Makefile # Remove spaces & tabs at EOL, add LF at EOF if needed on *.c, *.h, *.cpp. *.lua, *.py, *.pl, Makefile
find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \
-exec perl -pi -e 's/[ \t]+$$//' {} \; \ -exec perl -pi -e 's/[ \t]+$$//' {} \; \
-exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \ -exec sh -c "tail -c1 {} | xxd -p | tail -1 | grep -q -v 0a$$" \; \
-exec sh -c "echo >> {}" \; -exec sh -c "echo >> {}" \;
@ -158,11 +164,11 @@ style:
# Detecting weird codepages and tabs. # Detecting weird codepages and tabs.
checks: checks:
find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \ find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" -or -name "*.v" \) \
-exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \; -exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \;
find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" \) \ find . \( -name "*.[ch]" -or \( -name "*.cpp" -and -not -name "*.moc.cpp" \) -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "*.md" -or -name "*.txt" -or -name "*.awk" -or -name "*.v" \) \
-exec grep -lP '\t' {} \; -exec grep -lP '\t' {} \;
# to remove tabs within lines, one can try with vi: :set tabstop=4 :set et|retab # to remove tabs within lines, one can try with: vi $file -c ':set tabstop=4' -c ':set et|retab' -c ':wq'
# Dummy target to test for GNU make availability # Dummy target to test for GNU make availability
_test: _test:

View file

@ -10,6 +10,9 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "BigBuf.h" #include "BigBuf.h"
#include "string.h"
#include "dbprint.h"
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces. // BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
// Also used to hold various smaller buffers and the Mifare Emulator Memory. // Also used to hold various smaller buffers and the Mifare Emulator Memory.
// declare it as uint32_t to achieve alignment to 4 Byte boundary // declare it as uint32_t to achieve alignment to 4 Byte boundary

View file

@ -12,10 +12,7 @@
#ifndef __BIGBUF_H #ifndef __BIGBUF_H
#define __BIGBUF_H #define __BIGBUF_H
#include <stdbool.h> // for bool #include "common.h"
#include "proxmark3.h"
#include "string.h"
#include "ticks.h"
#define BIGBUF_SIZE 40000 #define BIGBUF_SIZE 40000
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
@ -43,4 +40,5 @@ void set_tracelen(uint32_t value);
bool get_tracing(void); bool get_tracing(void);
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length); uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
#endif /* __BIGBUF_H */ #endif /* __BIGBUF_H */

View file

@ -9,10 +9,6 @@
#ifndef __LCD_H #ifndef __LCD_H
#define __LCD_H #define __LCD_H
#include "proxmark3.h"
#include "apps.h"
#include "fonts.h"
// The resolution of the LCD // The resolution of the LCD
#define LCD_XRES 132 #define LCD_XRES 132
#define LCD_YRES 132 #define LCD_YRES 132

View file

@ -2,16 +2,14 @@
# at your option, any later version. See the LICENSE.txt file for the text of # at your option, any later version. See the LICENSE.txt file for the text of
# the license. # the license.
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Makefile for armsrc, see ../common/Makefile.common for common settings # Makefile for armsrc, see ../common_arm/Makefile.common for common settings
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
APP_INCLUDES = apps.h
# This Makefile might have been called directly, not via the root Makefile, so: # This Makefile might have been called directly, not via the root Makefile, so:
ifeq ($(PLTNAME),) ifeq ($(PLTNAME),)
-include ../Makefile.platform -include ../Makefile.platform
-include ../.Makefile.options.cache -include ../.Makefile.options.cache
include ../common/Makefile.hal include ../common_arm/Makefile.hal
# detect if there were changes in the platform definitions, requiring a clean # detect if there were changes in the platform definitions, requiring a clean
ifeq ($(PLATFORM_CHANGED), true) ifeq ($(PLATFORM_CHANGED), true)
$(error platform definitions have been changed, please "make clean" at the root of the project) $(error platform definitions have been changed, please "make clean" at the root of the project)
@ -28,20 +26,24 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c
SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO15693 = iso15693.c iso15693tools.c
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c
#UNUSED: mifaresniff.c desfire_crypto.c
SRC_ISO14443b = iso14443b.c SRC_ISO14443b = iso14443b.c
SRC_FELICA = felica.c SRC_FELICA = felica.c
SRC_CRAPTO1 = crypto1.c des.c desfire_key.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c SRC_CRAPTO1 = crypto1.c des.c desfire_key.c mifaredesfire.c aes.c platform_util.c
SRC_CRC = crc.c crc16.c crc32.c SRC_CRC = crc.c crc16.c crc32.c
SRC_ICLASS = iclass.c optimized_cipher.c SRC_ICLASS = iclass.c optimized_cipher.c
SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c
SRC_SPIFFS = spiffs.c spiffs_cache.c spiffs_check.c spiffs_gc.c spiffs_nucleus.c spiffs_hydrogen.c SRC_NFCBARCODE = thinfilm.c
# SRC_BEE = bee.c # SRC_BEE = bee.c
# RDV40 related hardware support # RDV40 related hardware support
ifneq (,$(findstring WITH_FLASH,$(APP_CFLAGS))) ifneq (,$(findstring WITH_FLASH,$(APP_CFLAGS)))
SRC_FLASH = flashmem.c SRC_FLASH = flashmem.c
SRC_SPIFFS = spiffs.c spiffs_cache.c spiffs_check.c spiffs_gc.c spiffs_nucleus.c spiffs_hydrogen.c
else else
SRC_FLASH = SRC_FLASH =
SRC_SPIFFS =
endif endif
ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS))) ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS)))
@ -80,7 +82,7 @@ SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
APP_CFLAGS += $(ZLIB_CFLAGS) APP_CFLAGS += $(ZLIB_CFLAGS)
# zlib includes: # zlib includes:
APP_CFLAGS += -I../zlib APP_CFLAGS += -I../common/zlib
# stdint.h provided locally until GCC 4.5 becomes C99 compliant, # stdint.h provided locally until GCC 4.5 becomes C99 compliant,
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
@ -88,9 +90,9 @@ APP_CFLAGS += -I. -fno-stack-protector -fno-pie
# Compile these in thumb mode (small size) # Compile these in thumb mode (small size)
THUMBSRC = start.c \ THUMBSRC = start.c \
protocols.c \
$(SRC_LCD) \ $(SRC_LCD) \
$(SRC_ISO15693) \ $(SRC_ISO15693) \
$(SRC_NFCBARCODE) \
$(SRC_LF) \ $(SRC_LF) \
$(SRC_ZLIB) \ $(SRC_ZLIB) \
$(SRC_LEGIC) \ $(SRC_LEGIC) \
@ -101,6 +103,7 @@ THUMBSRC = start.c \
$(SRC_SPIFFS) \ $(SRC_SPIFFS) \
appmain.c \ appmain.c \
printf.c \ printf.c \
dbprint.c \
commonutil.c \ commonutil.c \
util.c \ util.c \
string.c \ string.c \
@ -127,12 +130,12 @@ VERSIONSRC = version.c \
fpga_version_info.c fpga_version_info.c
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
include ../common/Makefile.common include ../common_arm/Makefile.common
COMMON_FLAGS = -Os COMMON_FLAGS = -Os
OBJS = $(OBJDIR)/fullimage.s19 OBJS = $(OBJDIR)/fullimage.s19
FPGA_COMPRESSOR = ../client/fpga_compress FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress
all: $(OBJS) all: $(OBJS)
@ -143,7 +146,7 @@ version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o
$(info [-] GEN $@) $(info [-] GEN $@)
$(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@ $(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR)
$(info [-] GEN $@) $(info [-] GEN $@)
$(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@ $(Q)$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@
@ -151,7 +154,7 @@ $(OBJDIR)/fpga_all.o: $(OBJDIR)/fpga_all.bit.z
$(info [-] GEN $@) $(info [-] GEN $@)
$(Q)$(OBJCOPY) -O elf32-littlearm -I binary -B arm --prefix-sections=fpga_all_bit $^ $@ $(Q)$(OBJCOPY) -O elf32-littlearm -I binary -B arm --prefix-sections=fpga_all_bit $^ $@
$(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR)
$(info [-] GEN $@) $(info [-] GEN $@)
ifeq ($(Q),@) ifeq ($(Q),@)
@$(FPGA_COMPRESSOR) $(filter %.bit,$^) $@ >/dev/null @$(FPGA_COMPRESSOR) $(filter %.bit,$^) $@ >/dev/null
@ -160,8 +163,8 @@ else
endif endif
$(FPGA_COMPRESSOR): $(FPGA_COMPRESSOR):
$(info [*] MAKE $@) $(error [!] MISSING $@ => To build it, go the root of the repo and do "make $(notdir $@)")
$(Q)$(MAKE) --no-print-directory -C ../client $(notdir $(FPGA_COMPRESSOR)) $(error [!] MISSING $@)
$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
$(info [=] LD $@) $(info [=] LD $@)
@ -179,7 +182,7 @@ $(OBJDIR)/fullimage.data.bin: $(OBJDIR)/fullimage.stage1.elf
$(info [-] GEN $@) $(info [-] GEN $@)
$(Q)$(OBJCOPY) -O binary -I elf32-littlearm --only-section .data $^ $@ $(Q)$(OBJCOPY) -O binary -I elf32-littlearm --only-section .data $^ $@
$(OBJDIR)/fullimage.data.bin.z: $(OBJDIR)/fullimage.data.bin $(FPGA_COMPRESSOR) $(OBJDIR)/fullimage.data.bin.z: $(OBJDIR)/fullimage.data.bin | $(FPGA_COMPRESSOR)
$(info [-] GEN $@) $(info [-] GEN $@)
ifeq ($(Q),@) ifeq ($(Q),@)
@$(FPGA_COMPRESSOR) $(filter %.bin,$^) $@ >/dev/null @$(FPGA_COMPRESSOR) $(filter %.bin,$^) $@ >/dev/null
@ -200,6 +203,7 @@ tarbin: $(OBJS)
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf) $(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)
clean: clean:
$(Q)$(DELETE) $(DEPENDENCY_FILES)
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19 $(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
@ -215,3 +219,4 @@ help:
@echo Possible targets: @echo Possible targets:
@echo + all - Build the full image $(OBJDIR)/fullimage.s19 @echo + all - Build the full image $(OBJDIR)/fullimage.s19
@echo + clean - Clean $(OBJDIR) @echo + clean - Clean $(OBJDIR)

View file

@ -27,7 +27,7 @@ ifneq (,$(findstring WITH_STANDALONE_HF_MATTYRUN,$(APP_CFLAGS)))
endif endif
# WITH_STANDALONE_HF_COLIN # WITH_STANDALONE_HF_COLIN
ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS))) ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS)))
SRC_STANDALONE = vtsend.c hf_colin.c SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c
endif endif
# WITH_STANDALONE_HF_BOG # WITH_STANDALONE_HF_BOG
ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS)))

View file

@ -19,7 +19,18 @@ you can simply run 'script run read_pwd_mem' or just 'mem dump p l 256'
from the client to view the stored quadlets. from the client to view the stored quadlets.
*/ */
#include "hf_bog.h" #include "standalone.h" // standalone definitions
#include "proxmark3_arm.h"
#include "iso14443a.h"
#include "protocols.h"
#include "util.h"
#include "spiffs.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "dbprint.h"
#include "ticks.h"
#include "BigBuf.h"
#include "string.h"
#define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8) #define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8)
#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8) #define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8)
@ -62,10 +73,10 @@ void RAMFUNC SniffAndStore(uint8_t param) {
bool ReaderIsActive = false; bool ReaderIsActive = false;
// Set up the demodulator for tag -> reader responses. // Set up the demodulator for tag -> reader responses.
DemodInit(receivedResp, receivedRespPar); Demod14aInit(receivedResp, receivedRespPar);
// Set up the demodulator for the reader -> tag commands // Set up the demodulator for the reader -> tag commands
UartInit(receivedCmd, receivedCmdPar); Uart14aInit(receivedCmd, receivedCmdPar);
// Setup and start DMA. // Setup and start DMA.
if (!FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE)) { if (!FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE)) {
@ -74,8 +85,8 @@ void RAMFUNC SniffAndStore(uint8_t param) {
return; return;
} }
tUart *uart = GetUart(); tUart14a *uart = GetUart14a();
tDemod *demod = GetDemod(); tDemod14a *demod = GetDemod14a();
// We won't start recording the frames that we acquire until we trigger; // We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a // a good trigger condition to get started is probably when we see a
@ -153,13 +164,13 @@ void RAMFUNC SniffAndStore(uint8_t param) {
break; break;
} }
/* ready to receive another command. */ /* ready to receive another command. */
UartReset(); Uart14aReset();
/* reset the demod code, which might have been */ /* reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */ /* false-triggered by the commands from the reader. */
DemodReset(); Demod14aReset();
LED_B_OFF(); LED_B_OFF();
} }
ReaderIsActive = (uart->state != STATE_UNSYNCD); ReaderIsActive = (uart->state != STATE_14A_UNSYNCD);
} }
// no need to try decoding tag data if the reader is sending - and we cannot afford the time // no need to try decoding tag data if the reader is sending - and we cannot afford the time
@ -176,13 +187,13 @@ void RAMFUNC SniffAndStore(uint8_t param) {
triggered = true; triggered = true;
// ready to receive another response. // ready to receive another response.
DemodReset(); Demod14aReset();
// reset the Miller decoder including its (now outdated) input buffer // reset the Miller decoder including its (now outdated) input buffer
UartReset(); Uart14aReset();
// UartInit(receivedCmd, receivedCmdPar); // UartInit(receivedCmd, receivedCmdPar);
LED_C_OFF(); LED_C_OFF();
} }
TagIsActive = (demod->state != DEMOD_UNSYNCD); TagIsActive = (demod->state != DEMOD_14A_UNSYNCD);
} }
} }

View file

@ -1,27 +0,0 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// StandAlone Mod
//-----------------------------------------------------------------------------
#ifndef __HF_BOG_H
#define __HF_BOG_H
#include "proxmark3.h"
#include "mifareutil.h"
#include "iso14443a.h"
#include "protocols.h"
#include "util.h"
#include "standalone.h" // standalone definitions
#include <stdbool.h> // for bool
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "printf.h"
#include "parity.h"
#include "spiffs.h"
#endif /* __HF_BOG_H */

View file

@ -8,12 +8,81 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// main code for HF Mifare aka ColinRun by Colin Brigato // main code for HF Mifare aka ColinRun by Colin Brigato
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "standalone.h" // standalone definitions
#include <stdbool.h> // for bool
#include <stdio.h>
#include <inttypes.h>
#include "hf_colin.h" #include "hf_colin.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "dbprint.h"
#include "ticks.h"
#include "commonutil.h"
#include "crc16.h"
#include "BigBuf.h"
#include "frozen.h"
#include "proxmark3_arm.h"
#include "mifaresim.h" // mifare1ksim
#include "mifareutil.h"
#include "iso14443a.h"
#include "util.h"
#include "vtsend.h"
#include "spiffs.h"
#include "string.h"
#define MF1KSZ 1024 #define MF1KSZ 1024
#define MF1KSZSIZE 64 #define MF1KSZSIZE 64
#define AUTHENTICATION_TIMEOUT 848 #define AUTHENTICATION_TIMEOUT 848
#define HFCOLIN_LASTTAG_SYMLINK "hf_colin/lasttag.bin" #define HFCOLIN_LASTTAG_SYMLINK "hf_colin/lasttag.bin"
#define HFCOLIN_SCHEMAS_JSON "hf_colin/schemas.json"
/* Example jsonconfig file schemas.json : (array !)
[{
"name": "UrmetCaptive",
"trigger": "0x8829da9daf76",
"keysA": [
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76"
],
"keysB": [
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76",
"0x8829da9daf76"
]
},{
"name": "Noralsy",
...
]
*/
uint8_t cjuid[10]; uint8_t cjuid[10];
uint32_t cjcuid; uint32_t cjcuid;
@ -27,6 +96,56 @@ int curlline;
// Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare // Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare
static const uint8_t is_hex[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0,
0, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static inline uint64_t hex2i(const char *s) {
uint64_t val = 0;
if (s == NULL || s[0] == 0)
return 0;
if (s[1] == 'x')
s += 2;
else if (*s == 'x')
s++;
while (is_hex[(uint8_t)*s])
val = (val << 4) | (is_hex[(uint8_t) * (s++)] - 1);
return val;
}
/*char *noralsy2test =
"{\"name\":\"noralsy2\",\"trigger\":\"0x414C41524F4E\",\"keysA\":[\"0x414C41524F4E\",\"0x414C41524F4E\","
"\"0x414C41524F4E\","
"\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\","
"\"0x414C41524F4E\",\"0x414C41524F4E\","
"\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\",\"0x414C41524F4E\","
"\"0x414C41524F4E\"],\"keysB\":["
"\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\","
"\"0x424C41524F4E\",\"0x424C41524F4E\","
"\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\",\"0x424C41524F4E\","
"\"0x424C41524F4E\",\"0x424C41524F4E\","
"\"0x424C41524F4E\",\"0x424C41524F4E\"]}";*/
/*char *urmetcaptive2test =
"{\"name\":\"urmetcaptive2\",\"trigger\":\"0x8829da9daf76\",\"keysA\":[\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\"],\"keysB\":["
"\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\","
"\"0x8829da9daf76\",\"0x8829da9daf76\"]}";*/
typedef struct MFC1KSchema { typedef struct MFC1KSchema {
uint8_t name[32]; uint8_t name[32];
uint64_t trigger; uint64_t trigger;
@ -36,50 +155,49 @@ typedef struct MFC1KSchema {
#define MAX_SCHEMAS 4 #define MAX_SCHEMAS 4
static void scan_keys(const char *str, int len, uint64_t *user_data) {
struct json_token t;
int i;
char ks[32];
for (i = 0; json_scanf_array_elem(str, len, "", i, &t) > 0; i++) {
sprintf(ks, "%.*s", t.len, t.ptr);
user_data[i] = hex2i(ks);
}
}
MFC1KSchema Schemas[MAX_SCHEMAS]; MFC1KSchema Schemas[MAX_SCHEMAS];
MFC1KSchema Noralsy = { /*MFC1KSchema Noralsy = {
.name = "Noralsy", .name = "Noralsy",
.trigger = 0x414c41524f4e, .trigger = 0x414c41524f4e,
.keysA = { .keysA = {0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e,
0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e,
0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e},
0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e .keysB = {0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e,
}, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e,
.keysB = { 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e}};
0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e,
0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e,
0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e
}
};
MFC1KSchema InfiHexact = {.name = "Infineon/Hexact", MFC1KSchema InfiHexact = {.name = "Infineon/Hexact",
.trigger = 0x484558414354, .trigger = 0x484558414354,
.keysA = {0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, .keysA = {0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354,
0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354,
0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354,
0x484558414354 0x484558414354},
},
.keysB = {0xa22ae129c013, 0x49fae4e3849f, 0x38fcf33072e0, 0x8ad5517b4b18, 0x509359f131b1, .keysB = {0xa22ae129c013, 0x49fae4e3849f, 0x38fcf33072e0, 0x8ad5517b4b18, 0x509359f131b1,
0x6c78928e1317, 0xaa0720018738, 0xa6cac2886412, 0x62d0c424ed8e, 0xe64a986a5d94, 0x6c78928e1317, 0xaa0720018738, 0xa6cac2886412, 0x62d0c424ed8e, 0xe64a986a5d94,
0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f 0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f}};
} */
};
MFC1KSchema UrmetCaptive = { /*MFC1KSchema UrmetCaptive = {
.name = "Urmet Captive", .name = "Urmet Captive",
.trigger = 0x8829da9daf76, .trigger = 0x8829da9daf76,
.keysA = { .keysA = {0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76},
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76 .keysB = {0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
}, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
.keysB = { 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}};
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, */
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76
}
};
int total_schemas = 0; int total_schemas = 0;
@ -125,6 +243,41 @@ foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s |
} }
*/ */
char *ReadSchemasFromSPIFFS(char *filename) {
SpinOff(0);
int changed = rdv40_spiffs_lazy_mount();
uint32_t size = size_in_spiffs((char *)filename);
uint8_t *mem = BigBuf_malloc(size);
rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)mem, size, RDV40_SPIFFS_SAFETY_SAFE);
if (changed) {
rdv40_spiffs_lazy_unmount();
}
SpinOff(0);
return (char *)mem;
}
void add_schemas_from_json_in_spiffs(char *filename) {
char *jsonfile = ReadSchemasFromSPIFFS((char *)filename);
int i, len = strlen(jsonfile);
struct json_token t;
for (i = 0; json_scanf_array_elem(jsonfile, len, "", i, &t) > 0; i++) {
char *tmpname;
char *tmptrigger;
MFC1KSchema tmpscheme;
json_scanf(t.ptr, t.len, "{ name:%Q, trigger:%Q, keysA:%M, keysB:%M}", &tmpname, &tmptrigger, scan_keys,
&tmpscheme.keysA, scan_keys, &tmpscheme.keysB);
memcpy(tmpscheme.name, tmpname, 32);
tmpscheme.trigger = hex2i(tmptrigger);
add_schema(Schemas, tmpscheme, &total_schemas);
DbprintfEx(FLAG_NEWLINE, "Schema loaded : %s", tmpname);
cjSetCursLeft();
}
}
void ReadLastTagFromFlash() { void ReadLastTagFromFlash() {
SpinOff(0); SpinOff(0);
LED_A_ON(); LED_A_ON();
@ -168,8 +321,8 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
sprintf(dest, "hf_colin/mf_%02x%02x%02x%02x.bin", buid[0], buid[1], buid[2], buid[3]); sprintf(dest, "hf_colin/mf_%02x%02x%02x%02x.bin", buid[0], buid[1], buid[2], buid[3]);
// TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and // TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and
// unoptimized mount operations we should manage at out level the mount status before and after the whole standalone // unoptimized mount operations we should manage at out level the mount status before and after the whole
// mode // standalone mode
rdv40_spiffs_write((char *)dest, (uint8_t *)data, len, RDV40_SPIFFS_SAFETY_SAFE); rdv40_spiffs_write((char *)dest, (uint8_t *)data, len, RDV40_SPIFFS_SAFETY_SAFE);
// lastag will only contain filename/path to last written tag file so we don't loose time or space. // lastag will only contain filename/path to last written tag file so we don't loose time or space.
rdv40_spiffs_make_symlink((char *)dest, (char *)HFCOLIN_LASTTAG_SYMLINK, RDV40_SPIFFS_SAFETY_SAFE); rdv40_spiffs_make_symlink((char *)dest, (char *)HFCOLIN_LASTTAG_SYMLINK, RDV40_SPIFFS_SAFETY_SAFE);
@ -185,10 +338,10 @@ void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIG
void RunMod() { void RunMod() {
StandAloneMode(); StandAloneMode();
add_schema(Schemas, Noralsy, &total_schemas); // add_schema(Schemas, Noralsy, &total_schemas);
add_schema(Schemas, InfiHexact, &total_schemas); // add_schema(Schemas, InfiHexact, &total_schemas);
add_schema(Schemas, UrmetCaptive, &total_schemas); // add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON);
// add_schema(Schemas, UrmetCaptive, &total_schemas);
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
currline = 20; currline = 20;
@ -242,9 +395,7 @@ void RunMod() {
// French VIGIK system @2017 // French VIGIK system @2017
//---------------------------- //----------------------------
#define STKEYS 37 const uint64_t mfKeys[] = {
const uint64_t mfKeys[STKEYS] = {
0xffffffffffff, // TRANSPORTS 0xffffffffffff, // TRANSPORTS
0x000000000000, // Blankkey 0x000000000000, // Blankkey
0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT... 0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT...
@ -285,8 +436,8 @@ void RunMod() {
}; };
// Can remember something like that in case of Bigbuf // Can remember something like that in case of Bigbuf
keyBlock = BigBuf_malloc(STKEYS * 6); keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); int mfKeysCnt = ARRAYLEN(mfKeys);
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
@ -325,6 +476,8 @@ void RunMod() {
currfline = 24; currfline = 24;
cjSetCursLeft(); cjSetCursLeft();
add_schemas_from_json_in_spiffs((char *)HFCOLIN_SCHEMAS_JSON);
failtag: failtag:
vtsend_cursor_position_save(NULL); vtsend_cursor_position_save(NULL);
@ -419,8 +572,8 @@ failtag:
if (key == -1) { if (key == -1) {
err = 1; err = 1;
allKeysFound = false; allKeysFound = false;
// used in portable imlementation on microcontroller: it reports back the fail and open the standalone // used in portable imlementation on microcontroller: it reports back the fail and open the
// lock reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); // standalone lock reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
break; break;
} else if (key == -2) { } else if (key == -2) {
err = 1; // Can't select card. err = 1; // Can't select card.
@ -587,7 +740,7 @@ readysim:
// if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) { // if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
flags |= FLAG_UID_IN_EMUL; flags |= FLAG_UID_IN_EMUL;
//} //}
Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid); Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid, 0, 0);
LED_C_OFF(); LED_C_OFF();
SpinOff(50); SpinOff(50);
vtsend_cursor_position_restore(NULL); vtsend_cursor_position_restore(NULL);

View file

@ -16,22 +16,6 @@
#ifndef __HF_COLIN_H #ifndef __HF_COLIN_H
#define __HF_COLIN_H #define __HF_COLIN_H
#include "proxmark3.h"
#include "mifaresim.h" // mifare1ksim
#include "mifareutil.h"
#include "iso14443a.h"
#include "protocols.h"
#include "util.h"
#include "pmflash.h"
#include "standalone.h" // standalone definitions
#include <stdbool.h> // for bool
#include <stdio.h>
#include <string.h>
#include "vtsend.h"
#include "apps.h"
#include "printf.h"
#include "spiffs.h"
#define _XRED_ "\x1b[31m" #define _XRED_ "\x1b[31m"
#define _XGREEN_ "\x1b[32m" #define _XGREEN_ "\x1b[32m"
#define _XYELLOW_ "\x1b[33m" #define _XYELLOW_ "\x1b[33m"

View file

@ -33,7 +33,21 @@ on a blank card.
## Spanish full description of the project [here](http://bit.ly/2c9nZXR). ## Spanish full description of the project [here](http://bit.ly/2c9nZXR).
*/ */
#include "hf_mattyrun.h" #include "standalone.h" // standalone definitions
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#include "string.h"
#include "commonutil.h"
#include "iso14443a.h"
#include "mifarecmd.h"
#include "crc16.h"
#include "BigBuf.h"
#include "mifaresim.h" // mifare1ksim
#include "mifareutil.h"
uint8_t uid[10]; uint8_t uid[10];
uint32_t cuid; uint32_t cuid;
@ -262,7 +276,7 @@ void RunMod() {
keys in keyBlock's memory space . keys in keyBlock's memory space .
*/ */
keyBlock = BigBuf_malloc(stKeyBlock * 6); keyBlock = BigBuf_malloc(stKeyBlock * 6);
int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); int mfKeysCnt = ARRAYLEN(mfKeys);
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) { for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
@ -400,7 +414,7 @@ void RunMod() {
simflags = FLAG_4B_UID_IN_DATA; simflags = FLAG_4B_UID_IN_DATA;
break; break;
} }
Mifare1ksim(simflags | FLAG_MF_1K, 0, uid); Mifare1ksim(simflags | FLAG_MF_1K, 0, uid, 0, 0);
LED_B_OFF(); LED_B_OFF();
/* /*

View file

@ -1,23 +0,0 @@
//-----------------------------------------------------------------------------
// Matías A. Ré Medina 2016
// Christian Herrmann, 2018
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// StandAlone Mod
//-----------------------------------------------------------------------------
#ifndef __HF_MATTYRUN_H
#define __HF_MATTYRUN_H
#include "standalone.h" // standalone definitions
#include "apps.h" // debugstatements, lfops?
#include "pm3_cmd.h" // mifare1ksim flags
#include "mifaresim.h" // mifare1ksim
#include "mifareutil.h"
#define OPTS 2
#endif /* __HF_MATTYRUN_H */

View file

@ -9,8 +9,21 @@
// main code for HF standalone mode Mifare /sniff/emulation by Craig Young // main code for HF standalone mode Mifare /sniff/emulation by Craig Young
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "hf_young.h" #include "standalone.h" // standalone definitions
#include "common.h" #include <inttypes.h>
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#include "string.h"
#include "commonutil.h"
#include "mifarecmd.h"
#include "iso14443a.h"
#include "protocols.h"
#define OPTS 2
typedef struct { typedef struct {
uint8_t uid[10]; uint8_t uid[10];
@ -138,18 +151,18 @@ void RunMod() {
SpinDelay(500); SpinDelay(500);
// Begin clone function here: // Begin clone function here:
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards: /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
SendCommandOLD(CMD_MIFARE_CSETBLOCK, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16); SendCommandOLD(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16);
Block read is similar: Block read is similar:
SendCommandOLD(CMD_MIFARE_CGETBLOCK, params, blockNo, 0,...}; SendCommandOLD(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...};
We need to imitate that call with blockNo 0 to set a uid. We need to imitate that call with blockNo 0 to set a uid.
The get and set commands are handled in this file: The get and set commands are handled in this file:
// Work with "magic Chinese" card // Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK: case CMD_HF_MIFARE_CSETBL:
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes); MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break; break;
case CMD_MIFARE_CGETBLOCK: case CMD_HF_MIFARE_CGETBL:
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes); MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break; break;

View file

@ -24,8 +24,19 @@
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// main code for LF aka HID corporate brutefore by Federico Dotta & Maurizio Agazzini // main code for LF aka HID corporate brutefore by Federico Dotta & Maurizio Agazzini
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
#include "standalone.h" // standalone definitions
#include "lf_hidbrute.h" #include "lf_hidbrute.h"
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#include "lfops.h"
#define OPTS 3
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)"); DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)");
} }

View file

@ -14,10 +14,7 @@
#ifndef __LF_HIDBRUTE_H #ifndef __LF_HIDBRUTE_H
#define __LF_HIDBRUTE_H #define __LF_HIDBRUTE_H
#include "standalone.h" // standalone definitions #include <stdint.h>
#include "apps.h" // debugstatements, lfops?
#define OPTS 3
void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc); void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc);

View file

@ -7,7 +7,12 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// main code for skeleton aka IceRun by Iceman // main code for skeleton aka IceRun by Iceman
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "lf_icerun.h" #include "standalone.h" // standalone definitions
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF skeleton mode - aka IceRun (iceman)"); DbpString(" LF skeleton mode - aka IceRun (iceman)");

View file

@ -9,7 +9,16 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// main code for LF aka Proxbrute by Brad antoniewicz // main code for LF aka Proxbrute by Brad antoniewicz
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "lf_proxbrute.h" #include "standalone.h" // standalone definitions
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#include "lfops.h"
#define OPTS 2
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)");

View file

@ -8,7 +8,16 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// main code for LF aka SamyRun by Samy Kamkar // main code for LF aka SamyRun by Samy Kamkar
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "lf_samyrun.h" #include "standalone.h" // standalone definitions
#include "proxmark3_arm.h"
#include "appmain.h"
#include "fpgaloader.h"
#include "lfops.h"
#include "util.h"
#include "dbprint.h"
#include "ticks.h"
#define OPTS 2
void ModInfo(void) { void ModInfo(void) {
DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)"); DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)");

View file

@ -1,5 +1,6 @@
#include "standalone.h" // standalone definitions #include "standalone.h" // standalone definitions
#include "apps.h" // debug statements
#include "dbprint.h"
void ModInfo(void) { void ModInfo(void) {
DbpString(" No standalone mode present"); DbpString(" No standalone mode present");

View file

@ -11,9 +11,6 @@
#ifndef __STANDALONE_H #ifndef __STANDALONE_H
#define __STANDALONE_H #define __STANDALONE_H
#include <stdbool.h> // for bool
#include <inttypes.h> // PRIu64
void RunMod(); void RunMod();
void ModInfo(); void ModInfo();

File diff suppressed because it is too large Load diff

45
armsrc/appmain.h Normal file
View file

@ -0,0 +1,45 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __APPMAIN_H
#define __APPMAIN_H
#include "common.h"
extern const uint8_t OddByteParity[256];
extern int rsamples; // = 0;
extern uint8_t trigger;
extern bool allow_send_wtx;
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
#define MAX_ADC_HF_VOLTAGE 36300
// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV
#define MAX_ADC_HF_VOLTAGE_RDV40 140800
// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV
#define MAX_ADC_LF_VOLTAGE 140800
extern int ToSendMax;
extern uint8_t ToSend[];
void send_wtx(uint16_t wtx);
void ReadMem(int addr);
void __attribute__((noreturn)) AppMain(void);
uint16_t AvgAdc(int ch);
void print_result(char *name, uint8_t *buf, size_t len);
//void PrintToSendBuffer(void);
void ToSendStuffBit(int b);
void ToSendReset(void);
void ListenReaderField(uint8_t limit);
void StandAloneMode(void);
void printStandAloneModes(void);
#endif

View file

@ -1,253 +0,0 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __APPS_H
#define __APPS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdarg.h>
#include "common.h"
#include "usb_cdc.h"
#include "crc32.h"
#include "lfdemod.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "hitag2.h"
#include "hitagS.h"
#include "mifare.h"
#include "pcf7931.h"
#include "desfire.h"
#include "iso14443b.h"
#include "Standalone/standalone.h"
#include "flashmem.h"
extern const uint8_t OddByteParity[256];
extern int rsamples; // = 0;
extern uint8_t trigger;
// This may be used (sparingly) to declare a function to be copied to
// and executed from RAM
#define RAMFUNC __attribute((long_call, section(".ramfunc")))
/// appmain.h
void ReadMem(int addr);
void __attribute__((noreturn)) AppMain(void);
//void DbpIntegers(int a, int b, int c);
void DbpString(char *str);
void DbpStringEx(uint32_t flags, char *str);
void Dbprintf(const char *fmt, ...);
void DbprintfEx(uint32_t flags, const char *fmt, ...);
void Dbhexdump(int len, uint8_t *d, bool bAsci);
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
#define MAX_ADC_HF_VOLTAGE 36300
// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV
#define MAX_ADC_HF_VOLTAGE_RDV40 140800
// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV
#define MAX_ADC_LF_VOLTAGE 140800
uint16_t AvgAdc(int ch);
void print_result(char *name, uint8_t *buf, size_t len);
//void PrintToSendBuffer(void);
void ToSendStuffBit(int b);
void ToSendReset(void);
void ListenReaderField(uint8_t limit);
extern int ToSendMax;
extern uint8_t ToSend[];
void StandAloneMode(void);
void printStandAloneModes(void);
/// lfops.h
extern uint8_t decimation;
extern uint8_t bits_per_sample ;
extern bool averaging;
void AcquireRawAdcSamples125k(int divisor);
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
void ReadTItag(void);
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
void AcquireTiType(void);
void AcquireRawBitsTI(void);
void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycles);
void SimulateTagLowFrequency(int period, int gap, bool ledcontrol);
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles);
void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol);
void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol);
void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26
void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol);
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5);
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
void T55xxResetRead(uint8_t flags);
//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
void T55xxWriteBlock(uint8_t *data);
// void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode);
void T55xxWakeUp(uint32_t Pwd, uint8_t flags);
void T55xx_ChkPwds(uint8_t flags);
void TurnReadLFOn(uint32_t delay);
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd);
void Cotag(uint32_t arg0);
void setT55xxConfig(uint8_t arg0, t55xx_config *c);
t55xx_config *getT55xxConfig(void);
void printT55xxConfig(void);
void loadT55xxConfig(void);
/// iso14443b.h
void SimulateIso14443bTag(uint32_t pupi);
void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
void ReadSTMemoryIso14443b(uint8_t numofblocks);
void RAMFUNC SniffIso14443b(void);
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
void SendRawCommand14443B_Ex(PacketCommandNG *c);
void ClearFpgaShiftingRegisters(void);
// iso14443a.h
void RAMFUNC SniffIso14443a(uint8_t param);
void ReaderIso14443a(PacketCommandNG *c);
// Also used in iclass.c
//bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
void iso14a_set_trigger(bool enable);
// also used in emv
//bool prepare_allocated_tag_modulation(tag_response_info_t *response_info);
//int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len);
// epa.h
void EPA_PACE_Collect_Nonce(PacketCommandNG *c);
void EPA_PACE_Replay(PacketCommandNG *c);
// mifarecmd.h
void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain);
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes);
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
void MifareAcquireNonces(uint32_t arg0, uint32_t flags);
void MifareChkKeys(uint8_t *datain);
void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareEMemClr(void);
void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain);
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
int MifareECardLoad(uint32_t arg0, uint32_t arg1);
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card?
void MifareSetMod(uint8_t *datain);
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
void OnSuccessMagic();
void OnErrorMagic(uint8_t reason);
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
//void RAMFUNC SniffMifare(uint8_t param);
//desfire
void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain);
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
// mifaredesfire.h
bool InitDesfireCard();
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareDesfireGetInformation();
void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain);
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout);
void OnSuccess();
void OnError(uint8_t reason);
// desfire_crypto.h
void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings);
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings);
void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
size_t key_block_size(const desfirekey_t key);
size_t padded_data_length(const size_t nbytes, const size_t block_size);
size_t maced_data_length(const desfirekey_t key, const size_t nbytes);
size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings);
void cmac_generate_subkeys(desfirekey_t key);
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
// iso15693.h
void RecordRawAdcSamplesIso15693(void);
void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox
void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox
void Iso15693InitReader(void);
// iclass.h
void RAMFUNC SniffIClass(void);
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void ReaderIClass(uint8_t arg0);
void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac);
void iClass_Authentication(uint8_t *mac);
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain);
void iClass_WriteBlock(uint8_t blockno, uint8_t *data);
void iClass_ReadBlk(uint8_t blockno);
bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len);
void iClass_Dump(uint8_t blockno, uint8_t numblks);
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
void iClass_ReadCheck(uint8_t blockno, uint8_t keytype);
// cmd.h
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
int receive_ng(PacketCommandNG *rx);
// util.h
void HfSniff(int, int);
//felica.c
void felica_sendraw(PacketCommandNG *c);
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip);
void felica_sim_lite(uint64_t uid);
void felica_dump_lite_s();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -5,10 +5,7 @@
#ifndef __BUZZER_H #ifndef __BUZZER_H
#define __BUZZER_H #define __BUZZER_H
#include <stdarg.h> #include "common.h"
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#define n_2_7khz 185 #define n_2_7khz 185
#define note_1 956 #define note_1 956
@ -27,24 +24,3 @@ void Ring_ALL(uint16_t count);
void Ring_Little_Star(uint16_t count); void Ring_Little_Star(uint16_t count);
#endif #endif

View file

@ -30,7 +30,10 @@
* @brief * @brief
*/ */
#include "cmd.h" #include "cmd.h"
#include "usb_cdc.h"
#include "usart.h"
#include "crc16.h" #include "crc16.h"
#include "string.h"
// Flags to tell where to add CRC on sent replies // Flags to tell where to add CRC on sent replies
bool reply_with_crc_on_usb = false; bool reply_with_crc_on_usb = false;

View file

@ -35,14 +35,6 @@
#include "common.h" #include "common.h"
#include "pm3_cmd.h" #include "pm3_cmd.h"
#include "usb_cdc.h"
#include "usart.h"
#include "proxmark3.h"
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
int receive_ng(PacketCommandNG *rx);
// Flags to tell where to add CRC on sent replies // Flags to tell where to add CRC on sent replies
extern bool reply_with_crc_on_usb; extern bool reply_with_crc_on_usb;
@ -51,33 +43,10 @@ extern bool reply_with_crc_on_fpc;
extern bool reply_via_fpc; extern bool reply_via_fpc;
extern bool reply_via_usb; extern bool reply_via_usb;
extern void Dbprintf(const char *fmt, ...); int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
#define Dbprintf_usb(...) {\ int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
bool tmpfpc = reply_via_fpc;\ int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
bool tmpusb = reply_via_usb;\ int receive_ng(PacketCommandNG *rx);
reply_via_fpc = false;\
reply_via_usb = true;\
Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;}
#define Dbprintf_fpc(...) {\
bool tmpfpc = reply_via_fpc;\
bool tmpusb = reply_via_usb;\
reply_via_fpc = true;\
reply_via_usb = false;\
Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;}
#define Dbprintf_all(...) {\
bool tmpfpc = reply_via_fpc;\
bool tmpusb = reply_via_usb;\
reply_via_fpc = true;\
reply_via_usb = true;\
Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;}
#endif // _PROXMARK_CMD_H_ #endif // _PROXMARK_CMD_H_

130
armsrc/dbprint.c Normal file
View file

@ -0,0 +1,130 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Mar 2006
// Edits by Gerhard de Koning Gans, Sep 2007 (##)
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// The main application code. This is the first thing called after start.c
// executes.
//-----------------------------------------------------------------------------
#include "dbprint.h"
#include "string.h"
#include "cmd.h"
#include "printf.h"
#define DEBUG 1
//=============================================================================
// Debug print functions, to go out over USB, to the usual PC-side client.
//=============================================================================
void DbpStringEx(uint32_t flags, char *str) {
#if DEBUG
struct {
uint16_t flag;
uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)];
} PACKED data;
data.flag = flags;
uint16_t len = MIN(strlen(str), sizeof(data.buf));
memcpy(data.buf, str, len);
reply_ng(CMD_DEBUG_PRINT_STRING, PM3_SUCCESS, (uint8_t *)&data, sizeof(data.flag) + len);
#endif
}
void DbpString(char *str) {
#if DEBUG
DbpStringEx(FLAG_LOG, str);
#endif
}
void DbprintfEx(uint32_t flags, const char *fmt, ...) {
#if DEBUG
// should probably limit size here; oh well, let's just use a big buffer
char output_string[128] = {0x00};
va_list ap;
va_start(ap, fmt);
kvsprintf(fmt, output_string, 10, ap);
va_end(ap);
DbpStringEx(flags, output_string);
#endif
}
void Dbprintf(const char *fmt, ...) {
#if DEBUG
// should probably limit size here; oh well, let's just use a big buffer
char output_string[128] = {0x00};
va_list ap;
va_start(ap, fmt);
kvsprintf(fmt, output_string, 10, ap);
va_end(ap);
DbpString(output_string);
#endif
}
// prints HEX & ASCII
void Dbhexdump(int len, uint8_t *d, bool bAsci) {
#if DEBUG
char ascii[9];
while (len > 0) {
int l = (len > 8) ? 8 : len;
memcpy(ascii, d, l);
ascii[l] = 0;
// filter safe ascii
for (int i = 0; i < l; i++) {
if (ascii[i] < 32 || ascii[i] > 126) {
ascii[i] = '.';
}
}
if (bAsci)
Dbprintf("%-8s %*D", ascii, l, d, " ");
else
Dbprintf("%*D", l, d, " ");
len -= 8;
d += 8;
}
#endif
}
void print_result(char *name, uint8_t *buf, size_t len) {
uint8_t *p = buf;
uint16_t tmp = len & 0xFFF0;
for (; p - buf < tmp; p += 16) {
Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
name,
p - buf,
len,
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
);
}
if (len % 16 != 0) {
char s[46] = {0};
char *sp = s;
for (; p - buf < len; p++) {
sprintf(sp, "%02x ", p[0]);
sp += 3;
}
Dbprintf("[%s: %02d/%02d] %s", name, p - buf, len, s);
}
}
/* useful when debugging new protocol implementations like FeliCa
void PrintToSendBuffer(void) {
DbpString("Printing ToSendBuffer:");
Dbhexdump(ToSendMax, ToSend, 0);
}
*/

53
armsrc/dbprint.h Normal file
View file

@ -0,0 +1,53 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __DBPRINT_H
#define __DBPRINT_H
#include "common.h"
#include "ansi.h"
#define Dbprintf_usb(...) {\
bool tmpfpc = reply_via_fpc;\
bool tmpusb = reply_via_usb;\
reply_via_fpc = false;\
reply_via_usb = true;\
Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;}
#define Dbprintf_fpc(...) {\
bool tmpfpc = reply_via_fpc;\
bool tmpusb = reply_via_usb;\
reply_via_fpc = true;\
reply_via_usb = false;\
Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;}
#define Dbprintf_all(...) {\
bool tmpfpc = reply_via_fpc;\
bool tmpusb = reply_via_usb;\
reply_via_fpc = true;\
reply_via_usb = true;\
Dbprintf(__VA_ARGS__);\
reply_via_fpc = tmpfpc;\
reply_via_usb = tmpusb;}
void DbpString(char *str);
void DbpStringEx(uint32_t flags, char *str);
void Dbprintf(const char *fmt, ...);
void DbprintfEx(uint32_t flags, const char *fmt, ...);
void Dbhexdump(int len, uint8_t *d, bool bAsci);
void print_result(char *name, uint8_t *buf, size_t len);
//void PrintToSendBuffer(void);
#endif

View file

@ -27,6 +27,7 @@
*/ */
#include "des.h" #include "des.h"
#include "string.h"
const uint8_t sbox[256] = { const uint8_t sbox[256] = {
/* S-box 1 */ /* S-box 1 */

View file

@ -27,8 +27,7 @@
#ifndef __DES_H_ #ifndef __DES_H_
#define __DES_H_ #define __DES_H_
#include <stdint.h> #include "common.h"
#include <string.h>
/* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA. /* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA.
* Also we only implement the three key mode */ * Also we only implement the three key mode */

View file

@ -1,9 +1,7 @@
#ifndef __DESFIRE_H #ifndef __DESFIRE_H
#define __DESFIRE_H #define __DESFIRE_H
#include <string.h> #include "common.h"
#include <stdarg.h>
#include "mbedtls/aes.h"
#include "mifare.h" #include "mifare.h"
#define MAX_CRYPTO_BLOCK_SIZE 16 #define MAX_CRYPTO_BLOCK_SIZE 16

View file

@ -1,18 +0,0 @@
#ifndef __DESFIRE_CRYPTO_H
#define __DESFIRE_CRYPTO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include "crc32.h"
#include "printf.h"
#include "desfire.h"
#include "iso14443a.h"
#ifdef __cplusplus
}
#endif
#endif

View file

@ -25,8 +25,16 @@
* Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication * Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication
* May 2005 * May 2005
*/ */
#include <string.h>
#include "desfire_crypto.h" #include "desfire_crypto.h"
#include "crc32.h"
#include "printf.h"
#include "desfire.h"
#include "iso14443a.h"
#include "mbedtls/aes.h"
static void xor(const uint8_t *ivect, uint8_t *data, const size_t len); static void xor(const uint8_t *ivect, uint8_t *data, const size_t len);
static size_t key_macing_length(desfirekey_t key); static size_t key_macing_length(desfirekey_t key);

View file

@ -0,0 +1,18 @@
#ifndef __DESFIRE_CRYPTO_H
#define __DESFIRE_CRYPTO_H
#include "common.h"
#include "desfire.h"
void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings);
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings);
void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
size_t key_block_size(const desfirekey_t key);
size_t padded_data_length(const size_t nbytes, const size_t block_size);
size_t maced_data_length(const desfirekey_t key, const size_t nbytes);
size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings);
void cmac_generate_subkeys(desfirekey_t key);
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
#endif

View file

@ -18,6 +18,7 @@
*/ */
#include "desfire_key.h" #include "desfire_key.h"
#include "string.h"
static inline void update_key_schedules(desfirekey_t key); static inline void update_key_schedules(desfirekey_t key);

View file

@ -1,11 +1,8 @@
#ifndef __DESFIRE_KEY_INCLUDED #ifndef __DESFIRE_KEY_INCLUDED
#define __DESFIRE_KEY_INCLUDED #define __DESFIRE_KEY_INCLUDED
#include <stdlib.h> #include "common.h"
#include <stdint.h>
#include "iso14443a.h"
#include "desfire.h" #include "desfire.h"
//#include "mifare.h" // iso14a_card_select_t struct
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key); void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key); void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key); void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key);
@ -17,4 +14,5 @@ void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version,
uint8_t Desfire_key_get_version(desfirekey_t key); uint8_t Desfire_key_get_version(desfirekey_t key);
void Desfire_key_set_version(desfirekey_t key, uint8_t version); void Desfire_key_set_version(desfirekey_t key, uint8_t version);
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key); void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
#endif #endif

View file

@ -12,8 +12,7 @@
#ifndef __EMVCARD_H #ifndef __EMVCARD_H
#define __EMVCARD_H #define __EMVCARD_H
#include <stdint.h> #include "common.h"
#include <stddef.h>
//structure to hold received/set tag values //structure to hold received/set tag values
//variable data inputs have length specifiers //variable data inputs have length specifiers

View file

@ -12,6 +12,16 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "epa.h" #include "epa.h"
#include "cmd.h"
#include "fpgaloader.h"
#include "iso14443a.h"
#include "iso14443b.h"
#include "string.h"
#include "util.h"
#include "dbprint.h"
#include "commonutil.h"
#include "ticks.h"
// Protocol and Parameter Selection Request for ISO 14443 type A cards // Protocol and Parameter Selection Request for ISO 14443 type A cards
// use regular (1x) speed in both directions // use regular (1x) speed in both directions
// CRC is already included // CRC is already included
@ -470,14 +480,14 @@ void EPA_PACE_Replay(PacketCommandNG *c) {
uint8_t response_apdu[300] = {0}; uint8_t response_apdu[300] = {0};
// now replay the data and measure the timings // now replay the data and measure the timings
for (int i = 0; i < sizeof(apdu_lengths_replay); i++) { for (int i = 0; i < ARRAYLEN(apdu_lengths_replay); i++) {
StartCountUS(); StartCountUS();
func_return = EPA_APDU(apdus_replay[i].data, func_return = EPA_APDU(apdus_replay[i].data,
apdu_lengths_replay[i], apdu_lengths_replay[i],
response_apdu); response_apdu);
timings[i] = GetCountUS(); timings[i] = GetCountUS();
// every step but the last one should succeed // every step but the last one should succeed
if (i < sizeof(apdu_lengths_replay) - 1 if (i < ARRAYLEN(apdu_lengths_replay) - 1
&& (func_return < 6 && (func_return < 6
|| response_apdu[func_return - 4] != 0x90 || response_apdu[func_return - 4] != 0x90
|| response_apdu[func_return - 3] != 0x00)) { || response_apdu[func_return - 3] != 0x00)) {

View file

@ -11,9 +11,8 @@
#ifndef __EPA_H #ifndef __EPA_H
#define __EPA_H #define __EPA_H
#include "cmd.h" #include "common.h"
#include "iso14443a.h" #include "pm3_cmd.h"
#include "iso14443b.h"
// this struct is used by EPA_Parse_CardAccess and contains info about the // this struct is used by EPA_Parse_CardAccess and contains info about the
// PACE protocol supported by the chip // PACE protocol supported by the chip
@ -23,8 +22,6 @@ typedef struct {
uint8_t parameter_id; uint8_t parameter_id;
} pace_version_info_t; } pace_version_info_t;
// note: EPA_PACE_Collect_Nonce and EPA_PACE_Replay are declared in apps.h
// general functions // general functions
void EPA_Finish(); void EPA_Finish();
size_t EPA_Parse_CardAccess(uint8_t *data, size_t EPA_Parse_CardAccess(uint8_t *data,
@ -37,4 +34,7 @@ int EPA_Setup();
int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password); int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password);
int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce); int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce);
void EPA_PACE_Collect_Nonce(PacketCommandNG *c);
void EPA_PACE_Replay(PacketCommandNG *c);
#endif /* __EPA_H */ #endif /* __EPA_H */

View file

@ -1,13 +1,18 @@
#include "proxmark3.h" #include "felica.h"
#include "apps.h" #include "proxmark3_arm.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "util.h" #include "util.h"
#include "usb_cdc.h" // for usb_poll_validate_length
#include "protocols.h" #include "protocols.h"
#include "crc16.h" // crc16 ccitt #include "crc16.h" // crc16 ccitt
#include "fpgaloader.h"
#include "string.h"
#include "commonutil.h"
#include "dbprint.h"
#include "ticks.h"
#include "mifare.h"
// FeliCa timings // FeliCa timings
// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56Mhz) cycles // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles
#ifndef FELICA_REQUEST_GUARD_TIME #ifndef FELICA_REQUEST_GUARD_TIME
# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) # define FELICA_REQUEST_GUARD_TIME (6800/16 + 1)
#endif #endif
@ -746,7 +751,7 @@ void felica_dump_lite_s() {
// for (c=0; c < 8; c++) // for (c=0; c < 8; c++)
// ndef[c] = FelicaFrame.framebytes[c+4]; // ndef[c] = FelicaFrame.framebytes[c+4];
for (blknum = 0; blknum < sizeof(liteblks);) { for (blknum = 0; blknum < ARRAYLEN(liteblks);) {
// block to read. // block to read.
BuildFliteRdblk(ndef, 1, &liteblks[blknum]); BuildFliteRdblk(ndef, 1, &liteblks[blknum]);

View file

@ -1,21 +1,22 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Samy Kamkar, 2011, 2012 // Jonathan Westhues, Aug 2005
// Brad antoniewicz 2011 // Gerhard de Koning Gans, April 2008, May 2011
// Christian Herrmann, 2017
// //
// This code is licensed to you under the terms of the GNU GPL, version 2 or, // 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 // at your option, any later version. See the LICENSE.txt file for the text of
// the license. // the license.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// StandAlone Mod // Definitions internal to the app source.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __FELICA_H
#define __FELICA_H
#ifndef __LF_PROXBRUTE_H #include "common.h"
#define __LF_PROXBRUTE_H #include "cmd.h"
#include "standalone.h" // standalone definitions void felica_sendraw(PacketCommandNG *c);
#include "apps.h" // debugstatements, lfops? void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip);
void felica_sim_lite(uint64_t uid);
void felica_dump_lite_s();
#define OPTS 2 #endif
#endif /* __LF_PROXBRUTE_H */

View file

@ -1,6 +1,11 @@
#include "flashmem.h" #include "flashmem.h"
#include "pmflash.h" #include "pmflash.h"
#include "proxmark3_arm.h"
#include "ticks.h"
#include "dbprint.h"
#include "string.h"
/* here: use NCPS2 @ PA10: */ /* here: use NCPS2 @ PA10: */
#define SPI_CSR_NUM 2 #define SPI_CSR_NUM 2
#define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16) #define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16)
@ -16,7 +21,7 @@ uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
void FlashmemSetSpiBaudrate(uint32_t baudrate) { void FlashmemSetSpiBaudrate(uint32_t baudrate) {
FLASHMEM_SPIBAUDRATE = baudrate; FLASHMEM_SPIBAUDRATE = baudrate;
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE / 1000000); Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000);
} }
// initialize // initialize
@ -563,25 +568,28 @@ void Flashmem_print_info(void) {
uint8_t keysum[2]; uint8_t keysum[2];
uint16_t num; uint16_t num;
Flash_CheckBusy(BUSY_TIMEOUT);
uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET, keysum, 2); uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET, keysum, 2);
if (isok == 2) { if (isok == 2) {
num = ((keysum[1] << 8) | keysum[0]); num = ((keysum[1] << 8) | keysum[0]);
if (num != 0xFFFF && num != 0x0) if (num != 0xFFFF && num != 0x0)
Dbprintf(" Mifare................"_YELLOW_("%d")"keys", num); Dbprintf(" Mifare.................."_YELLOW_("%d")"keys", num);
} }
Flash_CheckBusy(BUSY_TIMEOUT);
isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET, keysum, 2); isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET, keysum, 2);
if (isok == 2) { if (isok == 2) {
num = ((keysum[1] << 8) | keysum[0]); num = ((keysum[1] << 8) | keysum[0]);
if (num != 0xFFFF && num != 0x0) if (num != 0xFFFF && num != 0x0)
Dbprintf(" T55x7................."_YELLOW_("%d")"keys", num); Dbprintf(" T55x7..................."_YELLOW_("%d")"keys", num);
} }
Flash_CheckBusy(BUSY_TIMEOUT);
isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET, keysum, 2); isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET, keysum, 2);
if (isok == 2) { if (isok == 2) {
num = ((keysum[1] << 8) | keysum[0]); num = ((keysum[1] << 8) | keysum[0]);
if (num != 0xFFFF && num != 0x0) if (num != 0xFFFF && num != 0x0)
Dbprintf(" iClass................"_YELLOW_("%d")"keys", num); Dbprintf(" iClass.................."_YELLOW_("%d")"keys", num);
} }
FlashStop(); FlashStop();

View file

@ -28,9 +28,7 @@
#ifndef __FLASHMEM_H #ifndef __FLASHMEM_H
#define __FLASHMEM_H #define __FLASHMEM_H
#include "proxmark3.h" #include "common.h"
#include "apps.h"
#include "ticks.h"
// Used Command // Used Command
#define ID 0x90 #define ID 0x90
@ -102,7 +100,6 @@
#define MAX_BLOCKS 4 #define MAX_BLOCKS 4
#define MAX_SECTORS 16 #define MAX_SECTORS 16
#define MCK 48000000
//#define FLASH_BAUD 24000000 //#define FLASH_BAUD 24000000
#define FLASH_MINFAST 24000000 //33000000 #define FLASH_MINFAST 24000000 //33000000
#define FLASH_BAUD MCK/2 #define FLASH_BAUD MCK/2
@ -112,7 +109,6 @@
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST) #define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void Dbprintf(const char *fmt, ...);
void FlashmemSetSpiBaudrate(uint32_t baudrate); void FlashmemSetSpiBaudrate(uint32_t baudrate);
bool FlashInit(); bool FlashInit();

View file

@ -11,6 +11,15 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "fpgaloader.h" #include "fpgaloader.h"
#include "proxmark3_arm.h"
#include "appmain.h"
#include "BigBuf.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "zlib.h"
#include "fpga.h"
#include "string.h"
// remember which version of the bitstream we have already downloaded to the FPGA // remember which version of the bitstream we have already downloaded to the FPGA
static int downloaded_bitstream = 0; static int downloaded_bitstream = 0;
@ -81,7 +90,7 @@ void SetupSpi(int mode) {
AT91C_BASE_SPI->SPI_CSR[0] = AT91C_BASE_SPI->SPI_CSR[0] =
(1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) (1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
(1 << 16) | // Delay Before SPCK (1 MCK period) (1 << 16) | // Delay Before SPCK (1 MCK period)
(6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud (6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud
AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits) AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits)
(0 << 3) | // Chip Select inactive after transfer (0 << 3) | // Chip Select inactive after transfer
AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
@ -101,7 +110,7 @@ void SetupSpi(int mode) {
AT91C_BASE_SPI->SPI_CSR[2] = AT91C_BASE_SPI->SPI_CSR[2] =
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
( 1 << 16) | // Delay Before SPCK (1 MCK period) ( 1 << 16) | // Delay Before SPCK (1 MCK period)
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits) AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
( 0 << 3) | // Chip Select inactive after transfer ( 0 << 3) | // Chip Select inactive after transfer
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
@ -153,8 +162,7 @@ void FpgaSetupSsc(void) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Set up DMA to receive samples from the FPGA. We will use the PDC, with // Set up DMA to receive samples from the FPGA. We will use the PDC, with
// a single buffer as a circular buffer (so that we just chain back to // a single buffer as a circular buffer (so that we just chain back to
// ourselves, not to another buffer). The stuff to manipulate those buffers // ourselves, not to another buffer).
// is in apps.h, because it should be inlined, for speed.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool FpgaSetupSscDma(uint8_t *buf, int len) { bool FpgaSetupSscDma(uint8_t *buf, int len) {
if (buf == NULL) return false; if (buf == NULL) return false;
@ -395,6 +403,8 @@ void FpgaDownloadAndGo(int bitstream_version) {
if (downloaded_bitstream == bitstream_version) if (downloaded_bitstream == bitstream_version)
return; return;
// Send waiting time extension request as this will take a while
send_wtx(1500);
z_stream compressed_fpga_stream; z_stream compressed_fpga_stream;
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00}; uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};

View file

@ -12,32 +12,10 @@
#ifndef __FPGALOADER_H #ifndef __FPGALOADER_H
#define __FPGALOADER_H #define __FPGALOADER_H
#include <stdint.h> #include "common.h"
#include <stdbool.h>
#include "apps.h"
#include "fpga.h"
#include "common.h" // standard definitions
#include "proxmark3.h" // common area
#include "string.h"
#include "BigBuf.h" // bigbuf mem
#include "zlib.h" // uncompress
void FpgaSendCommand(uint16_t cmd, uint16_t v);
void FpgaWriteConfWord(uint8_t v);
void FpgaDownloadAndGo(int bitstream_version);
// void FpgaGatherVersion(int bitstream_version, char *dst, int len);
void FpgaSetupSsc(void);
void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, int len);
void Fpga_print_status(void);
int FpgaGetCurrent(void);
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; #define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; #define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
void SetAdcMuxFor(uint32_t whichGpio);
// extern and generel turn off the antenna method
void switch_off(void);
// definitions for multiple FPGA config files support // definitions for multiple FPGA config files support
#define FPGA_BITSTREAM_LF 1 #define FPGA_BITSTREAM_LF 1
@ -97,4 +75,18 @@ void switch_off(void);
#define FPGA_HF_ISO18092_FLAG_424K (2<<0) // 0010 should enable 414k mode (untested). No autodetect #define FPGA_HF_ISO18092_FLAG_424K (2<<0) // 0010 should enable 414k mode (untested). No autodetect
#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag #define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag
void FpgaSendCommand(uint16_t cmd, uint16_t v);
void FpgaWriteConfWord(uint8_t v);
void FpgaDownloadAndGo(int bitstream_version);
// void FpgaGatherVersion(int bitstream_version, char *dst, int len);
void FpgaSetupSsc(void);
void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, int len);
void Fpga_print_status(void);
int FpgaGetCurrent(void);
void SetAdcMuxFor(uint32_t whichGpio);
// extern and generel turn off the antenna method
void switch_off(void);
#endif #endif

1470
armsrc/frozen.c Normal file

File diff suppressed because it is too large Load diff

313
armsrc/frozen.h Normal file
View file

@ -0,0 +1,313 @@
/*
* Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
* Copyright (c) 2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_FROZEN_FROZEN_H_
#define CS_FROZEN_FROZEN_H_
#include <stdarg.h>
#include <stdio.h>
/* JSON token type */
enum json_token_type {
JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */
JSON_TYPE_STRING,
JSON_TYPE_NUMBER,
JSON_TYPE_TRUE,
JSON_TYPE_FALSE,
JSON_TYPE_NULL,
JSON_TYPE_OBJECT_START,
JSON_TYPE_OBJECT_END,
JSON_TYPE_ARRAY_START,
JSON_TYPE_ARRAY_END,
JSON_TYPES_CNT
};
/*
* Structure containing token type and value. Used in `json_walk()` and
* `json_scanf()` with the format specifier `%T`.
*/
struct json_token {
const char *ptr; /* Points to the beginning of the value */
int len; /* Value length */
enum json_token_type type; /* Type of the token, possible values are above */
};
#define JSON_INVALID_TOKEN \
{ 0, 0, JSON_TYPE_INVALID }
/* Error codes */
#define JSON_STRING_INVALID -1
#define JSON_STRING_INCOMPLETE -2
/*
* Callback-based SAX-like API.
*
* Property name and length is given only if it's available: i.e. if current
* event is an object's property. In other cases, `name` is `NULL`. For
* example, name is never given:
* - For the first value in the JSON string;
* - For events JSON_TYPE_OBJECT_END and JSON_TYPE_ARRAY_END
*
* E.g. for the input `{ "foo": 123, "bar": [ 1, 2, { "baz": true } ] }`,
* the sequence of callback invocations will be as follows:
*
* - type: JSON_TYPE_OBJECT_START, name: NULL, path: "", value: NULL
* - type: JSON_TYPE_NUMBER, name: "foo", path: ".foo", value: "123"
* - type: JSON_TYPE_ARRAY_START, name: "bar", path: ".bar", value: NULL
* - type: JSON_TYPE_NUMBER, name: "0", path: ".bar[0]", value: "1"
* - type: JSON_TYPE_NUMBER, name: "1", path: ".bar[1]", value: "2"
* - type: JSON_TYPE_OBJECT_START, name: "2", path: ".bar[2]", value: NULL
* - type: JSON_TYPE_TRUE, name: "baz", path: ".bar[2].baz", value: "true"
* - type: JSON_TYPE_OBJECT_END, name: NULL, path: ".bar[2]", value: "{ \"baz\":
*true }"
* - type: JSON_TYPE_ARRAY_END, name: NULL, path: ".bar", value: "[ 1, 2, {
*\"baz\": true } ]"
* - type: JSON_TYPE_OBJECT_END, name: NULL, path: "", value: "{ \"foo\": 123,
*\"bar\": [ 1, 2, { \"baz\": true } ] }"
*/
typedef void (*json_walk_callback_t)(void *callback_data, const char *name,
size_t name_len, const char *path,
const struct json_token *token);
/*
* Parse `json_string`, invoking `callback` in a way similar to SAX parsers;
* see `json_walk_callback_t`.
* Return number of processed bytes, or a negative error code.
*/
int json_walk(const char *json_string, int json_string_length,
json_walk_callback_t callback, void *callback_data);
/*
* JSON generation API.
* struct json_out abstracts output, allowing alternative printing plugins.
*/
struct json_out {
int (*printer)(struct json_out *, const char *str, size_t len);
union {
struct {
char *buf;
size_t size;
size_t len;
} buf;
void *data;
FILE *fp;
} u;
};
extern int json_printer_buf(struct json_out *, const char *, size_t);
extern int json_printer_file(struct json_out *, const char *, size_t);
#define JSON_OUT_BUF(buf, len) \
{ \
json_printer_buf, { \
{ buf, len, 0 } \
} \
}
#define JSON_OUT_FILE(fp) \
{ \
json_printer_file, { \
{ (char *) fp, 0, 0 } \
} \
}
typedef int (*json_printf_callback_t)(struct json_out *, va_list *ap);
/*
* Generate formatted output into a given sting buffer.
* This is a superset of printf() function, with extra format specifiers:
* - `%B` print json boolean, `true` or `false`. Accepts an `int`.
* - `%Q` print quoted escaped string or `null`. Accepts a `const char *`.
* - `%.*Q` same as `%Q`, but with length. Accepts `int`, `const char *`
* - `%V` print quoted base64-encoded string. Accepts a `const char *`, `int`.
* - `%H` print quoted hex-encoded string. Accepts a `int`, `const char *`.
* - `%M` invokes a json_printf_callback_t function. That callback function
* can consume more parameters.
*
* Return number of bytes printed. If the return value is bigger than the
* supplied buffer, that is an indicator of overflow. In the overflow case,
* overflown bytes are not printed.
*/
int json_printf(struct json_out *, const char *fmt, ...);
int json_vprintf(struct json_out *, const char *fmt, va_list ap);
/*
* Same as json_printf, but prints to a file.
* File is created if does not exist. File is truncated if already exists.
*/
int json_fprintf(const char *file_name, const char *fmt, ...);
int json_vfprintf(const char *file_name, const char *fmt, va_list ap);
/*
* Print JSON into an allocated 0-terminated string.
* Return allocated string, or NULL on error.
* Example:
*
* ```c
* char *str = json_asprintf("{a:%H}", 3, "abc");
* printf("%s\n", str); // Prints "616263"
* free(str);
* ```
*/
char *json_asprintf(const char *fmt, ...);
char *json_vasprintf(const char *fmt, va_list ap);
/*
* Helper %M callback that prints contiguous C arrays.
* Consumes void *array_ptr, size_t array_size, size_t elem_size, char *fmt
* Return number of bytes printed.
*/
int json_printf_array(struct json_out *, va_list *ap);
/*
* Scan JSON string `str`, performing scanf-like conversions according to `fmt`.
* This is a `scanf()` - like function, with following differences:
*
* 1. Object keys in the format string may be not quoted, e.g. "{key: %d}"
* 2. Order of keys in an object is irrelevant.
* 3. Several extra format specifiers are supported:
* - %B: consumes `int *` (or `char *`, if `sizeof(bool) == sizeof(char)`),
* expects boolean `true` or `false`.
* - %Q: consumes `char **`, expects quoted, JSON-encoded string. Scanned
* string is malloc-ed, caller must free() the string.
* - %V: consumes `char **`, `int *`. Expects base64-encoded string.
* Result string is base64-decoded, malloced and NUL-terminated.
* The length of result string is stored in `int *` placeholder.
* Caller must free() the result.
* - %H: consumes `int *`, `char **`.
* Expects a hex-encoded string, e.g. "fa014f".
* Result string is hex-decoded, malloced and NUL-terminated.
* The length of the result string is stored in `int *` placeholder.
* Caller must free() the result.
* - %M: consumes custom scanning function pointer and
* `void *user_data` parameter - see json_scanner_t definition.
* - %T: consumes `struct json_token *`, fills it out with matched token.
*
* Return number of elements successfully scanned & converted.
* Negative number means scan error.
*/
int json_scanf(const char *str, int str_len, const char *fmt, ...);
int json_vscanf(const char *str, int str_len, const char *fmt, va_list ap);
/* json_scanf's %M handler */
typedef void (*json_scanner_t)(const char *str, int len, void *user_data);
/*
* Helper function to scan array item with given path and index.
* Fills `token` with the matched JSON token.
* Return -1 if no array element found, otherwise non-negative token length.
*/
int json_scanf_array_elem(const char *s, int len, const char *path, int index,
struct json_token *token);
/*
* Unescape JSON-encoded string src,slen into dst, dlen.
* src and dst may overlap.
* If destination buffer is too small (or zero-length), result string is not
* written but the length is counted nevertheless (similar to snprintf).
* Return the length of unescaped string in bytes.
*/
int json_unescape(const char *src, int slen, char *dst, int dlen);
/*
* Escape a string `str`, `str_len` into the printer `out`.
* Return the number of bytes printed.
*/
int json_escape(struct json_out *out, const char *str, size_t str_len);
/*
* Read the whole file in memory.
* Return malloc-ed file content, or NULL on error. The caller must free().
*/
char *json_fread(const char *file_name);
/*
* Update given JSON string `s,len` by changing the value at given `json_path`.
* The result is saved to `out`. If `json_fmt` == NULL, that deletes the key.
* If path is not present, missing keys are added. Array path without an
* index pushes a value to the end of an array.
* Return 1 if the string was changed, 0 otherwise.
*
* Example: s is a JSON string { "a": 1, "b": [ 2 ] }
* json_setf(s, len, out, ".a", "7"); // { "a": 7, "b": [ 2 ] }
* json_setf(s, len, out, ".b", "7"); // { "a": 1, "b": 7 }
* json_setf(s, len, out, ".b[]", "7"); // { "a": 1, "b": [ 2,7 ] }
* json_setf(s, len, out, ".b", NULL); // { "a": 1 }
*/
int json_setf(const char *s, int len, struct json_out *out,
const char *json_path, const char *json_fmt, ...);
int json_vsetf(const char *s, int len, struct json_out *out,
const char *json_path, const char *json_fmt, va_list ap);
/*
* Pretty-print JSON string `s,len` into `out`.
* Return number of processed bytes in `s`.
*/
int json_prettify(const char *s, int len, struct json_out *out);
/*
* Prettify JSON file `file_name`.
* Return number of processed bytes, or negative number of error.
* On error, file content is not modified.
*/
int json_prettify_file(const char *file_name);
/*
* Iterate over an object at given JSON `path`.
* On each iteration, fill the `key` and `val` tokens. It is OK to pass NULL
* for `key`, or `val`, in which case they won't be populated.
* Return an opaque value suitable for the next iteration, or NULL when done.
*
* Example:
*
* ```c
* void *h = NULL;
* struct json_token key, val;
* while ((h = json_next_key(s, len, h, ".foo", &key, &val)) != NULL) {
* printf("[%.*s] -> [%.*s]\n", key.len, key.ptr, val.len, val.ptr);
* }
* ```
*/
void *json_next_key(const char *s, int len, void *handle, const char *path,
struct json_token *key, struct json_token *val);
/*
* Iterate over an array at given JSON `path`.
* Similar to `json_next_key`, but fills array index `idx` instead of `key`.
*/
void *json_next_elem(const char *s, int len, void *handle, const char *path,
int *idx, struct json_token *val);
#ifndef JSON_MAX_PATH_LEN
#define JSON_MAX_PATH_LEN 256
#endif
#ifndef JSON_MINIMAL
#define JSON_MINIMAL 1
#endif
#ifndef JSON_ENABLE_BASE64
#define JSON_ENABLE_BASE64 !JSON_MINIMAL
#endif
#ifndef JSON_ENABLE_HEX
#define JSON_ENABLE_HEX !JSON_MINIMAL
#endif
#endif /* CS_FROZEN_FROZEN_H_ */

View file

@ -1,8 +1,9 @@
#include "proxmark3.h" #include "proxmark3_arm.h"
#include "apps.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h" #include "util.h"
#include "usb_cdc.h" // for usb_poll_validate_length
static void RAMFUNC optimizedSniff(void); static void RAMFUNC optimizedSniff(void);

View file

@ -1,22 +1,16 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Samy Kamkar 2012 // Jonathan Westhues, Aug 2005
// Christian Herrmann, 2017 // Gerhard de Koning Gans, April 2008, May 2011
// //
// This code is licensed to you under the terms of the GNU GPL, version 2 or, // 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 // at your option, any later version. See the LICENSE.txt file for the text of
// the license. // the license.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// StandAlone Mod // Definitions internal to the app source.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __HFSNOOP_H
#define __HFSNOOP_H
#ifndef __LF_SAMYRUN_H void HfSniff(int, int);
#define __LF_SAMYRUN_H
//#include <stdbool.h> // for bool #endif
#include "standalone.h" // standalone definitions
#include "apps.h" // debugstatements, lfops?
#define OPTS 2
#endif /* __LF_SAMYRUN_H */

View file

@ -20,15 +20,20 @@
#include "hitag2.h" #include "hitag2.h"
#include "hitag2_crypto.h" #include "hitag2_crypto.h"
#include "hitag.h"
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h" #include "string.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
// Successful crypto auth
static bool bCrypto; static bool bCrypto;
// Is in auth stage
static bool bAuthenticating; static bool bAuthenticating;
// Successful password auth
static bool bPwd; static bool bPwd;
static bool bSuccessful; static bool bSuccessful;
@ -272,8 +277,8 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
break; break;
} }
// LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false); // LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false);
// LogTrace(tx, nbytes(txlen), 0, 0, NULL, true); // LogTrace(tx, nbytes(txlen), 0, 0, NULL, true);
if (tag.crypto_active) { if (tag.crypto_active) {
hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8); hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8);
@ -377,7 +382,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
if (bPwd && write) { if (bPwd && !bAuthenticating && write) {
if (!hitag2_write_page(rx, rxlen, tx, txlen)) { if (!hitag2_write_page(rx, rxlen, tx, txlen)) {
return false; return false;
} }
@ -398,22 +403,29 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
// Received UID, tag password // Received UID, tag password
case 32: { case 32: {
// stage 1, got UID
if (!bPwd) { if (!bPwd) {
*txlen = 32;
memcpy(tx, password, 4);
bPwd = true; bPwd = true;
memcpy(tag.sectors[blocknr], rx, 4); bAuthenticating = true;
blocknr++; memcpy(tx, password, 4);
*txlen = 32;
} else { } else {
// stage 2, got config byte+password TAG, discard as will read later
if (blocknr == 1) { if (bAuthenticating) {
//store password in block1, the TAG answers with Block3, but we need the password in memory bAuthenticating = false;
memcpy(tag.sectors[blocknr], tx, 4); if (write) {
} else { if (!hitag2_write_page(rx, rxlen, tx, txlen)) {
return false;
}
break;
}
}
// stage 2+, got data block
else {
memcpy(tag.sectors[blocknr], rx, 4); memcpy(tag.sectors[blocknr], rx, 4);
blocknr++;
} }
blocknr++;
if (blocknr > 7) { if (blocknr > 7) {
DbpString("Read succesful!"); DbpString("Read succesful!");
bSuccessful = true; bSuccessful = true;
@ -488,19 +500,22 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
} }
// Received UID, crypto tag answer // Received UID, crypto tag answer
case 32: { case 32: {
// stage 1, got UID
if (!bCrypto) { if (!bCrypto) {
uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40; uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40;
uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24; uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24;
Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t)((REV64(ui64key)) >> 32), (uint32_t)((REV64(ui64key)) & 0xffffffff), REV32(ui32uid)); Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t)((REV64(ui64key)) >> 32), (uint32_t)((REV64(ui64key)) & 0xffffffff), REV32(ui32uid));
cipher_state = _hitag2_init(REV64(ui64key), REV32(ui32uid), 0); cipher_state = _hitag2_init(REV64(ui64key), REV32(ui32uid), 0);
// PRN
memset(tx, 0x00, 4); memset(tx, 0x00, 4);
// Secret data
memset(tx + 4, 0xff, 4); memset(tx + 4, 0xff, 4);
hitag2_cipher_transcrypt(&cipher_state, tx + 4, 4, 0); hitag2_cipher_transcrypt(&cipher_state, tx + 4, 4, 0);
*txlen = 64; *txlen = 64;
bCrypto = true; bCrypto = true;
bAuthenticating = true; bAuthenticating = true;
} else { } else {
// Check if we received answer tag (at) // stage 2, got config byte+password TAG, discard as will read later
if (bAuthenticating) { if (bAuthenticating) {
bAuthenticating = false; bAuthenticating = false;
if (write) { if (write) {
@ -509,7 +524,9 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
} }
break; break;
} }
} else { }
// stage 2+, got data block
else {
// Store the received block // Store the received block
memcpy(tag.sectors[blocknr], rx, 4); memcpy(tag.sectors[blocknr], rx, 4);
blocknr++; blocknr++;
@ -692,7 +709,7 @@ void SniffHitag(void) {
StopTicks(); StopTicks();
// int frame_count; // int frame_count;
int response; int response;
int overflow; int overflow;
bool rising_edge; bool rising_edge;
@ -750,7 +767,7 @@ void SniffHitag(void) {
// Reset the received frame, frame count and timing info // Reset the received frame, frame count and timing info
memset(rx, 0x00, sizeof(rx)); memset(rx, 0x00, sizeof(rx));
// frame_count = 0; // frame_count = 0;
response = 0; response = 0;
overflow = 0; overflow = 0;
reader_frame = false; reader_frame = false;
@ -857,7 +874,7 @@ void SniffHitag(void) {
// Check if frame was captured // Check if frame was captured
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame); LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame);
// Check if we recognize a valid authentication attempt // Check if we recognize a valid authentication attempt
@ -907,7 +924,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
StopTicks(); StopTicks();
// int frame_count = 0; // int frame_count = 0;
int response = 0, overflow = 0; int response = 0, overflow = 0;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
size_t rxlen = 0; size_t rxlen = 0;
@ -950,7 +967,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
// Set up simulator mode, frequency divisor which will drive the FPGA // Set up simulator mode, frequency divisor which will drive the FPGA
// and analog mux selection. // and analog mux selection.
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Configure output pin that is connected to the FPGA (for modulating) // Configure output pin that is connected to the FPGA (for modulating)
@ -1025,7 +1042,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
// Check if frame was captured // Check if frame was captured
if (rxlen > 4) { if (rxlen > 4) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, response, NULL, true); LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
// Disable timer 1 with external trigger to avoid triggers during our own modulation // Disable timer 1 with external trigger to avoid triggers during our own modulation
@ -1081,7 +1098,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
StopTicks(); StopTicks();
// int frame_count = 0; // int frame_count = 0;
int response = 0; int response = 0;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
size_t rxlen = 0; size_t rxlen = 0;
@ -1104,6 +1121,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
memcpy(password, htd->pwd.password, 4); memcpy(password, htd->pwd.password, 4);
blocknr = 0; blocknr = 0;
bPwd = false; bPwd = false;
bAuthenticating = false;
break; break;
} }
case RHT2F_AUTHENTICATE: { case RHT2F_AUTHENTICATE: {
@ -1155,7 +1173,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// Set fpga in edge detect with reader field, we can modulate as reader now // Set fpga in edge detect with reader field, we can modulate as reader now
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Configure output and enable pin that is connected to the FPGA (for modulating) // Configure output and enable pin that is connected to the FPGA (for modulating)
@ -1216,7 +1234,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// Check if frame was captured and store it // Check if frame was captured and store it
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, response, NULL, false); LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
} }
@ -1272,7 +1290,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// Add transmitted frame to total count // Add transmitted frame to total count
if (txlen > 0) { if (txlen > 0) {
// frame_count++; // frame_count++;
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
} }
@ -1366,7 +1384,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
StopTicks(); StopTicks();
// int frame_count = 0; // int frame_count = 0;
int response = 0; int response = 0;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
size_t rxlen = 0; size_t rxlen = 0;
@ -1405,6 +1423,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
Dbhexdump(4, password, false); Dbhexdump(4, password, false);
blocknr = page; blocknr = page;
bPwd = false; bPwd = false;
bAuthenticating = false;
writestate = WRITE_STATE_START; writestate = WRITE_STATE_START;
} }
break; break;
@ -1425,7 +1444,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
// Set fpga in edge detect with reader field, we can modulate as reader now // Set fpga in edge detect with reader field, we can modulate as reader now
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Disable modulation at default, which means enable the field // Disable modulation at default, which means enable the field
@ -1486,7 +1505,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
// Check if frame was captured and store it // Check if frame was captured and store it
if (rxlen > 0) { if (rxlen > 0) {
// frame_count++; // frame_count++;
LogTrace(rx, nbytes(rxlen), response, response, NULL, false); LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
} }
@ -1527,7 +1546,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
// Add transmitted frame to total count // Add transmitted frame to total count
if (txlen > 0) { if (txlen > 0) {
// frame_count++; // frame_count++;
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true); LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
} }

View file

@ -11,8 +11,7 @@
#ifndef _HITAG2_H_ #ifndef _HITAG2_H_
#define _HITAG2_H_ #define _HITAG2_H_
#include <stdint.h> #include "common.h"
#include <stdbool.h>
#include "hitag.h" #include "hitag.h"
void SniffHitag(void); void SniffHitag(void);

View file

@ -11,6 +11,9 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "hitag2_crypto.h" #include "hitag2_crypto.h"
#include "util.h"
#include "string.h"
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */ /* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
// Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007. // Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
// For educational purposes only. // For educational purposes only.

View file

@ -1,12 +1,7 @@
#ifndef __HITAG2_CRYPTO_H #ifndef __HITAG2_CRYPTO_H
#define __HITAG2_CRYPTO_H #define __HITAG2_CRYPTO_H
#ifdef __cplusplus #include "common.h"
extern "C" {
#endif
#include "string.h"
#include "util.h"
struct hitag2_tag { struct hitag2_tag {
uint32_t uid; uint32_t uid;
@ -29,8 +24,5 @@ uint32_t _hitag2_byte(uint64_t *x);
void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv); void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv);
int hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is); int hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is);
int hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) ; int hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) ;
#ifdef __cplusplus
}
#endif
#endif #endif

View file

@ -13,6 +13,17 @@
#include "hitagS.h" #include "hitagS.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "string.h"
#include "commonutil.h"
#include "hitag2_crypto.h"
#define CRC_PRESET 0xFF #define CRC_PRESET 0xFF
#define CRC_POLYNOM 0x1D #define CRC_POLYNOM 0x1D
@ -983,7 +994,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) {
// and analog mux selection. // and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Configure output pin that is connected to the FPGA (for modulating) // Configure output pin that is connected to the FPGA (for modulating)
@ -1182,7 +1193,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
// Set fpga in edge detect with reader field, we can modulate as reader now // Set fpga in edge detect with reader field, we can modulate as reader now
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Configure output and enable pin that is connected to the FPGA (for modulating) // Configure output and enable pin that is connected to the FPGA (for modulating)
@ -1517,7 +1528,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
// Set fpga in edge detect with reader field, we can modulate as reader now // Set fpga in edge detect with reader field, we can modulate as reader now
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Disable modulation at default, which means enable the field // Disable modulation at default, which means enable the field
@ -1778,7 +1789,7 @@ void check_challenges(bool file_given, uint8_t *data) {
// Set fpga in edge detect with reader field, we can modulate as reader now // Set fpga in edge detect with reader field, we can modulate as reader now
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD); SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Disable modulation at default, which means enable the field // Disable modulation at default, which means enable the field

View file

@ -12,16 +12,9 @@
#ifndef _HITAGS_H_ #ifndef _HITAGS_H_
#define _HITAGS_H_ #define _HITAGS_H_
#include <stdint.h> #include "common.h"
#include <stdbool.h>
#include <stdlib.h>
#include "hitag2_crypto.h"
#include "hitag.h" #include "hitag.h"
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
#include "BigBuf.h"
void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data); void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data);
void ReadHitagS(hitag_function htf, hitag_data *htd); void ReadHitagS(hitag_function htf, hitag_data *htd);

View file

@ -10,6 +10,14 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "i2c.h" #include "i2c.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "string.h"
#define GPIO_RST AT91C_PIO_PA1 #define GPIO_RST AT91C_PIO_PA1
#define GPIO_SCL AT91C_PIO_PA5 #define GPIO_SCL AT91C_PIO_PA5
#define GPIO_SDA AT91C_PIO_PA7 #define GPIO_SDA AT91C_PIO_PA7
@ -26,7 +34,7 @@
volatile unsigned long c; volatile unsigned long c;
// Direct use the loop to delay. 6 instructions loop, Masterclock 48Mhz, // Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz,
// delay=1 is about 200kbps // delay=1 is about 200kbps
// timer. // timer.
// I2CSpinDelayClk(4) = 12.31us // I2CSpinDelayClk(4) = 12.31us
@ -41,7 +49,7 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
#define ISO7618_MAX_FRAME 255 #define ISO7618_MAX_FRAME 255
// try i2c bus recovery at 100kHz = 5uS high, 5uS low // try i2c bus recovery at 100kHz = 5us high, 5us low
void I2C_recovery(void) { void I2C_recovery(void) {
DbpString("Performing i2c bus recovery"); DbpString("Performing i2c bus recovery");

View file

@ -1,10 +1,7 @@
#ifndef __I2C_H #ifndef __I2C_H
#define __I2C_H #define __I2C_H
#include <stddef.h> #include "common.h"
#include "proxmark3.h"
#include "apps.h"
#include "BigBuf.h"
#include "mifare.h" #include "mifare.h"
#define I2C_DEVICE_ADDRESS_BOOT 0xB0 #define I2C_DEVICE_ADDRESS_BOOT 0xB0
@ -18,7 +15,6 @@
#define I2C_DEVICE_CMD_GETVERSION 0x06 #define I2C_DEVICE_CMD_GETVERSION 0x06
#define I2C_DEVICE_CMD_SEND_T0 0x07 #define I2C_DEVICE_CMD_SEND_T0 0x07
void I2C_recovery(void); void I2C_recovery(void);
void I2C_init(void); void I2C_init(void);
void I2C_Reset(void); void I2C_Reset(void);
@ -48,4 +44,5 @@ void SmartCardSetBaud(uint64_t arg0);
void SmartCardSetClock(uint64_t arg0); void SmartCardSetClock(uint64_t arg0);
void I2C_print_status(void); void I2C_print_status(void);
int I2C_get_version(uint8_t *maj, uint8_t *min); int I2C_get_version(uint8_t *maj, uint8_t *min);
#endif #endif

View file

@ -36,15 +36,24 @@
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "apps.h" #include "iclass.h"
#include "proxmark3_arm.h"
#include "cmd.h" #include "cmd.h"
// Needed for CRC in emulation mode; // Needed for CRC in emulation mode;
// same construction as in ISO 14443; // same construction as in ISO 14443;
// different initial value (CRC_ICLASS) // different initial value (CRC_ICLASS)
#include "crc16.h" #include "crc16.h"
#include "protocols.h"
#include "optimized_cipher.h" #include "optimized_cipher.h"
#include "usb_cdc.h" // for usb_poll_validate_length
#include "appmain.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "string.h"
#include "util.h"
#include "dbprint.h"
#include "protocols.h"
#include "ticks.h"
static int timeout = 4096; static int timeout = 4096;
static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay); static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay);
@ -92,21 +101,21 @@ typedef struct {
int bitBuffer; int bitBuffer;
int dropPosition; int dropPosition;
uint8_t *output; uint8_t *output;
} tUart; } tUartIc;
*/ */
typedef struct { typedef struct {
enum { enum {
DEMOD_UNSYNCD, DEMOD_IC_UNSYNCD,
DEMOD_START_OF_COMMUNICATION, DEMOD_IC_START_OF_COMMUNICATION,
DEMOD_START_OF_COMMUNICATION2, DEMOD_IC_START_OF_COMMUNICATION2,
DEMOD_START_OF_COMMUNICATION3, DEMOD_IC_START_OF_COMMUNICATION3,
DEMOD_SOF_COMPLETE, DEMOD_IC_SOF_COMPLETE,
DEMOD_MANCHESTER_D, DEMOD_IC_MANCHESTER_D,
DEMOD_MANCHESTER_E, DEMOD_IC_MANCHESTER_E,
DEMOD_END_OF_COMMUNICATION, DEMOD_IC_END_OF_COMMUNICATION,
DEMOD_END_OF_COMMUNICATION2, DEMOD_IC_END_OF_COMMUNICATION2,
DEMOD_MANCHESTER_F, DEMOD_IC_MANCHESTER_F,
DEMOD_ERROR_WAIT DEMOD_IC_ERROR_WAIT
} state; } state;
int bitCount; int bitCount;
int posCount; int posCount;
@ -125,7 +134,7 @@ typedef struct {
SUB_BOTH SUB_BOTH
} sub; } sub;
uint8_t *output; uint8_t *output;
} tDemod; } tDemodIc;
/* /*
* Abrasive's uart implementation * Abrasive's uart implementation
@ -138,8 +147,13 @@ typedef struct {
bool frame_done; bool frame_done;
uint8_t *buf; uint8_t *buf;
int len; int len;
} tUart; } tUartIc;
static tUart Uart; static tUartIc Uart;
static void OnError(uint8_t reason) {
reply_old(CMD_ACK, 0, reason, 0, 0, 0);
switch_off();
}
static void uart_reset(void) { static void uart_reset(void) {
Uart.frame_done = false; Uart.frame_done = false;
@ -499,8 +513,8 @@ static RAMFUNC int OutOfNDecoding(int bit) {
//============================================================================= //=============================================================================
// Manchester // Manchester
//============================================================================= //=============================================================================
static tDemod Demod; static tDemodIc Demod;
static void DemodReset() { static void DemodIcReset() {
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.posCount = 0; Demod.posCount = 0;
Demod.syncBit = 0; Demod.syncBit = 0;
@ -512,11 +526,11 @@ static void DemodReset() {
Demod.samples = 0; Demod.samples = 0;
Demod.len = 0; Demod.len = 0;
Demod.sub = SUB_NONE; Demod.sub = SUB_NONE;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
} }
static void DemodInit(uint8_t *data) { static void DemodIcInit(uint8_t *data) {
Demod.output = data; Demod.output = data;
DemodReset(); DemodIcReset();
} }
// UART debug // UART debug
@ -592,7 +606,7 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) {
return false; return false;
} }
if (Demod.state == DEMOD_UNSYNCD) { if (Demod.state == DEMOD_IC_UNSYNCD) {
Demod.output[Demod.len] = 0xfa; Demod.output[Demod.len] = 0xfa;
Demod.syncBit = 0; Demod.syncBit = 0;
//Demod.samples = 0; //Demod.samples = 0;
@ -620,7 +634,7 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) {
if (Demod.syncBit) { if (Demod.syncBit) {
Demod.len = 0; Demod.len = 0;
Demod.state = DEMOD_START_OF_COMMUNICATION; Demod.state = DEMOD_IC_START_OF_COMMUNICATION;
Demod.sub = SUB_FIRST_HALF; Demod.sub = SUB_FIRST_HALF;
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.shiftReg = 0; Demod.shiftReg = 0;
@ -644,12 +658,12 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) {
} }
// SOF must be long burst... otherwise stay unsynced!!! // SOF must be long burst... otherwise stay unsynced!!!
if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit))
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
} else { } else {
// SOF must be long burst... otherwise stay unsynced!!! // SOF must be long burst... otherwise stay unsynced!!!
if (!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) { if (!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) {
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
error = 0x88; error = 0x88;
uart_debug(error, bit); uart_debug(error, bit);
return false; return false;
@ -682,74 +696,74 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) {
} }
if (Demod.sub == SUB_NONE) { if (Demod.sub == SUB_NONE) {
if (Demod.state == DEMOD_SOF_COMPLETE) { if (Demod.state == DEMOD_IC_SOF_COMPLETE) {
Demod.output[Demod.len] = 0x0f; Demod.output[Demod.len] = 0x0f;
Demod.len++; Demod.len++;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
return true; return true;
} else { } else {
Demod.state = DEMOD_ERROR_WAIT; Demod.state = DEMOD_IC_ERROR_WAIT;
error = 0x33; error = 0x33;
} }
} }
switch (Demod.state) { switch (Demod.state) {
case DEMOD_START_OF_COMMUNICATION: case DEMOD_IC_START_OF_COMMUNICATION:
if (Demod.sub == SUB_BOTH) { if (Demod.sub == SUB_BOTH) {
Demod.state = DEMOD_START_OF_COMMUNICATION2; Demod.state = DEMOD_IC_START_OF_COMMUNICATION2;
Demod.posCount = 1; Demod.posCount = 1;
Demod.sub = SUB_NONE; Demod.sub = SUB_NONE;
} else { } else {
Demod.output[Demod.len] = 0xab; Demod.output[Demod.len] = 0xab;
Demod.state = DEMOD_ERROR_WAIT; Demod.state = DEMOD_IC_ERROR_WAIT;
error = 0xd2; error = 0xd2;
} }
break; break;
case DEMOD_START_OF_COMMUNICATION2: case DEMOD_IC_START_OF_COMMUNICATION2:
if (Demod.sub == SUB_SECOND_HALF) { if (Demod.sub == SUB_SECOND_HALF) {
Demod.state = DEMOD_START_OF_COMMUNICATION3; Demod.state = DEMOD_IC_START_OF_COMMUNICATION3;
} else { } else {
Demod.output[Demod.len] = 0xab; Demod.output[Demod.len] = 0xab;
Demod.state = DEMOD_ERROR_WAIT; Demod.state = DEMOD_IC_ERROR_WAIT;
error = 0xd3; error = 0xd3;
} }
break; break;
case DEMOD_START_OF_COMMUNICATION3: case DEMOD_IC_START_OF_COMMUNICATION3:
if (Demod.sub == SUB_SECOND_HALF) { if (Demod.sub == SUB_SECOND_HALF) {
Demod.state = DEMOD_SOF_COMPLETE; Demod.state = DEMOD_IC_SOF_COMPLETE;
} else { } else {
Demod.output[Demod.len] = 0xab; Demod.output[Demod.len] = 0xab;
Demod.state = DEMOD_ERROR_WAIT; Demod.state = DEMOD_IC_ERROR_WAIT;
error = 0xd4; error = 0xd4;
} }
break; break;
case DEMOD_SOF_COMPLETE: case DEMOD_IC_SOF_COMPLETE:
case DEMOD_MANCHESTER_D: case DEMOD_IC_MANCHESTER_D:
case DEMOD_MANCHESTER_E: case DEMOD_IC_MANCHESTER_E:
// OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443)
// 00001111 = 1 (0 in 14443) // 00001111 = 1 (0 in 14443)
if (Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF if (Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF
Demod.bitCount++; Demod.bitCount++;
Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100; Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100;
Demod.state = DEMOD_MANCHESTER_D; Demod.state = DEMOD_IC_MANCHESTER_D;
} else if (Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF } else if (Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF
Demod.bitCount++; Demod.bitCount++;
Demod.shiftReg >>= 1; Demod.shiftReg >>= 1;
Demod.state = DEMOD_MANCHESTER_E; Demod.state = DEMOD_IC_MANCHESTER_E;
} else if (Demod.sub == SUB_BOTH) { } else if (Demod.sub == SUB_BOTH) {
Demod.state = DEMOD_MANCHESTER_F; Demod.state = DEMOD_IC_MANCHESTER_F;
} else { } else {
Demod.state = DEMOD_ERROR_WAIT; Demod.state = DEMOD_IC_ERROR_WAIT;
error = 0x55; error = 0x55;
} }
break; break;
case DEMOD_MANCHESTER_F: case DEMOD_IC_MANCHESTER_F:
// Tag response does not need to be a complete byte! // Tag response does not need to be a complete byte!
if (Demod.len > 0 || Demod.bitCount > 0) { if (Demod.len > 0 || Demod.bitCount > 0) {
if (Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF if (Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF
@ -758,22 +772,22 @@ static RAMFUNC int ManchesterDecoding_iclass(uint32_t v) {
Demod.len++; Demod.len++;
} }
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
return true; return true;
} else { } else {
Demod.output[Demod.len] = 0xad; Demod.output[Demod.len] = 0xad;
Demod.state = DEMOD_ERROR_WAIT; Demod.state = DEMOD_IC_ERROR_WAIT;
error = 0x03; error = 0x03;
} }
break; break;
case DEMOD_ERROR_WAIT: case DEMOD_IC_ERROR_WAIT:
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
break; break;
default: default:
Demod.output[Demod.len] = 0xdd; Demod.output[Demod.len] = 0xdd;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_IC_UNSYNCD;
break; break;
} }
@ -818,10 +832,10 @@ static void iclass_setup_sniff(void) {
set_tracing(true); set_tracing(true);
// Initialize Demod and Uart structs // Initialize Demod and Uart structs
DemodInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); DemodIcInit(BigBuf_malloc(ICLASS_BUFFER_SIZE));
uart_init(BigBuf_malloc(ICLASS_BUFFER_SIZE)); uart_init(BigBuf_malloc(ICLASS_BUFFER_SIZE));
//UartInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); //UartIcInit(BigBuf_malloc(ICLASS_BUFFER_SIZE));
if (DBGLEVEL > 1) { if (DBGLEVEL > 1) {
// Print debug information about the buffer sizes // Print debug information about the buffer sizes
@ -884,9 +898,17 @@ void RAMFUNC SniffIClass(void) {
// contains LOW nibble = tag data // contains LOW nibble = tag data
// so two bytes are needed in order to get 1byte of either reader or tag data. (ie 2 sample bytes) // so two bytes are needed in order to get 1byte of either reader or tag data. (ie 2 sample bytes)
// since reader data is manchester encoded, we need 2bytes of data in order to get one demoded byte. (ie: 4 sample bytes) // since reader data is manchester encoded, we need 2bytes of data in order to get one demoded byte. (ie: 4 sample bytes)
while (!BUTTON_PRESS()) { uint16_t checked = 0;
for (;;) {
WDT_HIT(); WDT_HIT();
if (checked == 1000) {
if (BUTTON_PRESS() || data_available()) break;
checked = 0;
} else {
checked++;
}
previous_data <<= 8; previous_data <<= 8;
previous_data |= *data; previous_data |= *data;
@ -919,7 +941,7 @@ void RAMFUNC SniffIClass(void) {
if (Uart.frame_done) { if (Uart.frame_done) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
LogTrace(Uart.buf, Uart.len, time_start, time_stop, NULL, true); LogTrace(Uart.buf, Uart.len, time_start, time_stop, NULL, true);
DemodReset(); DemodIcReset();
uart_reset(); uart_reset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
@ -951,12 +973,12 @@ void RAMFUNC SniffIClass(void) {
if (ManchesterDecoding_iclass(foo)) { if (ManchesterDecoding_iclass(foo)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
DemodReset(); DemodIcReset();
uart_reset(); uart_reset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
} }
TagIsActive = (Demod.state != DEMOD_UNSYNCD); TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD);
} }
tag_byte = 0; tag_byte = 0;
foo = 0; foo = 0;
@ -996,9 +1018,18 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
(void)b; (void)b;
while (!BUTTON_PRESS()) { uint16_t checked = 0;
for (;;) {
WDT_HIT(); WDT_HIT();
if (checked == 1000) {
if (BUTTON_PRESS() || data_available()) return false;
checked = 0;
} else {
checked++;
}
// keep tx buffer in a defined state anyway. // keep tx buffer in a defined state anyway.
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
AT91C_BASE_SSC->SSC_THR = 0x00; AT91C_BASE_SSC->SSC_THR = 0x00;
@ -1195,11 +1226,11 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) { if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) {
// Button pressed // Button pressed
reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
goto out; goto out;
} }
} }
reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
} else if (simType == 3) { } else if (simType == 3) {
//This is 'full sim' mode, where we use the emulator storage for data. //This is 'full sim' mode, where we use the emulator storage for data.
@ -1226,20 +1257,20 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
// keyroll 1 // keyroll 1
if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) { if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE)) {
reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
// Button pressed // Button pressed
goto out; goto out;
} }
// keyroll 2 // keyroll 2
if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * EPURSE_MAC_SIZE)) { if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * EPURSE_MAC_SIZE)) {
reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
// Button pressed // Button pressed
goto out; goto out;
} }
} }
// double the amount of collected data. // double the amount of collected data.
reply_old(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); reply_old(CMD_ACK, CMD_HF_ICLASS_SIMULATE, i * 2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
} else { } else {
// We may want a mode here where we hardcode the csns to use (from proxclone). // We may want a mode here where we hardcode the csns to use (from proxclone).
@ -1307,7 +1338,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
// Reader 81 anticoll. CSN // Reader 81 anticoll. CSN
// Tag CSN // Tag CSN
uint8_t *modulated_response; uint8_t *modulated_response = NULL;
int modulated_response_size = 0; int modulated_response_size = 0;
uint8_t *trace_data = NULL; uint8_t *trace_data = NULL;
int trace_data_size = 0; int trace_data_size = 0;
@ -1382,11 +1413,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
//This is used for responding to READ-block commands or other data which is dynamically generated //This is used for responding to READ-block commands or other data which is dynamically generated
//First the 'trace'-data, not encoded for FPGA //First the 'trace'-data, not encoded for FPGA
uint8_t *data_generic_trace = BigBuf_malloc(8 + 2);//8 bytes data + 2byte CRC is max tag answer uint8_t *data_generic_trace = BigBuf_malloc((8 * 4) + 2);//8 bytes data + 2byte CRC is max tag answer
//Then storage for the modulated data //Then storage for the modulated data
//Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes) //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes)
uint8_t *data_response = BigBuf_malloc((8 + 2) * 2 + 2); uint8_t *data_response = BigBuf_malloc(((8 * 4) + 2) * 2 + 2);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
SpinDelay(100); SpinDelay(100);
@ -1436,6 +1467,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
trace_data_size = sizeof(anticoll_data); trace_data_size = sizeof(anticoll_data);
goto send; goto send;
} }
if (len == 4) { if (len == 4) {
// block0,1,2,5 is always readable. // block0,1,2,5 is always readable.
switch (receivedCmd[1]) { switch (receivedCmd[1]) {
@ -1444,13 +1476,13 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
modulated_response_size = resp_csn_len; modulated_response_size = resp_csn_len;
trace_data = csn_data; trace_data = csn_data;
trace_data_size = sizeof(csn_data); trace_data_size = sizeof(csn_data);
break; goto send;
case 1: // configuration (0c 01) case 1: // configuration (0c 01)
modulated_response = resp_conf; modulated_response = resp_conf;
modulated_response_size = resp_conf_len; modulated_response_size = resp_conf_len;
trace_data = conf_data; trace_data = conf_data;
trace_data_size = sizeof(conf_data); trace_data_size = sizeof(conf_data);
break; goto send;
case 2: // e-purse (0c 02) case 2: // e-purse (0c 02)
modulated_response = resp_cc; modulated_response = resp_cc;
modulated_response_size = resp_cc_len; modulated_response_size = resp_cc_len;
@ -1460,19 +1492,30 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
if (reader_mac_buf != NULL) { if (reader_mac_buf != NULL) {
memcpy(reader_mac_buf, card_challenge_data, 8); memcpy(reader_mac_buf, card_challenge_data, 8);
} }
break; goto send;
case 5:// Application Issuer Area (0c 05) case 5:// Application Issuer Area (0c 05)
modulated_response = resp_aia; modulated_response = resp_aia;
modulated_response_size = resp_aia_len; modulated_response_size = resp_aia_len;
trace_data = aia_data; trace_data = aia_data;
trace_data_size = sizeof(aia_data); trace_data_size = sizeof(aia_data);
goto send;
default : {
if (simulationMode == MODE_FULLSIM) { // 0x0C
//Read block
//Take the data...
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
AddCrc(data_generic_trace, 8);
trace_data = data_generic_trace;
trace_data_size = 10;
CodeIClassTagAnswer(trace_data, trace_data_size);
memcpy(modulated_response, ToSend, ToSendMax);
modulated_response_size = ToSendMax;
goto send;
}
break; break;
default: }
break; }//swith
} }// if 4
goto send;
}
} else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81
// Reader selects anticollission CSN. // Reader selects anticollission CSN.
// Tag sends the corresponding real CSN // Tag sends the corresponding real CSN
@ -1542,17 +1585,15 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
trace_data = NULL; trace_data = NULL;
trace_data_size = 0; trace_data_size = 0;
goto send; goto send;
} else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4) { // 0x0C } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06
//Read block //Read block
uint16_t blk = receivedCmd[1];
//Take the data... //Take the data...
memcpy(data_generic_trace, emulator + (blk << 3), 8); memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4);
AddCrc(data_generic_trace, 8); AddCrc(data_generic_trace, 8 * 4);
trace_data = data_generic_trace; trace_data = data_generic_trace;
trace_data_size = 10; trace_data_size = 34;
CodeIClassTagAnswer(trace_data, trace_data_size); CodeIClassTagAnswer(trace_data, trace_data_size);
memcpy(data_response, ToSend, ToSendMax); memcpy(modulated_response, ToSend, ToSendMax);
modulated_response = data_response;
modulated_response_size = ToSendMax; modulated_response_size = ToSendMax;
goto send; goto send;
} else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) {
@ -1632,8 +1673,15 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
AT91C_BASE_SSC->SSC_THR = 0x00; AT91C_BASE_SSC->SSC_THR = 0x00;
while (!BUTTON_PRESS()) { uint16_t checked = 0;
for (;;) {
if (checked == 1000) {
if (BUTTON_PRESS() || data_available()) return 0;
checked = 0;
} else {
checked++;
}
// Prevent rx holding register from overflowing // Prevent rx holding register from overflowing
if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) { if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {
b = AT91C_BASE_SSC->SSC_RHR; b = AT91C_BASE_SSC->SSC_RHR;
@ -1787,7 +1835,7 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
bool skip = false; bool skip = false;
// Setup UART/DEMOD to receive // Setup UART/DEMOD to receive
DemodInit(receivedResponse); DemodIcInit(receivedResponse);
if (elapsed) *elapsed = 0; if (elapsed) *elapsed = 0;
@ -1800,9 +1848,18 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
(void)b; (void)b;
while (!BUTTON_PRESS()) { uint16_t checked = 0;
for (;;) {
WDT_HIT(); WDT_HIT();
if (checked == 1000) {
if (BUTTON_PRESS() || data_available()) return false;
checked = 0;
} else {
checked++;
}
// keep tx buffer in a defined state anyway. // keep tx buffer in a defined state anyway.
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00; AT91C_BASE_SSC->SSC_THR = 0x00;
@ -1993,6 +2050,7 @@ void ReaderIClass(uint8_t arg0) {
setupIclassReader(); setupIclassReader();
uint16_t checked = 0;
bool userCancelled = BUTTON_PRESS() || data_available(); bool userCancelled = BUTTON_PRESS() || data_available();
while (!userCancelled) { while (!userCancelled) {
@ -2092,7 +2150,13 @@ void ReaderIClass(uint8_t arg0) {
} }
} }
LED_B_OFF(); LED_B_OFF();
userCancelled = BUTTON_PRESS() || data_available();
if (checked == 1000) {
userCancelled = BUTTON_PRESS() || data_available();
checked = 0;
} else {
checked++;
}
} }
if (userCancelled) { if (userCancelled) {
@ -2222,7 +2286,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac) {
switch_off(); switch_off();
} }
// not used. ?!? ( CMD_ICLASS_READCHECK) // not used. ?!? ( CMD_HF_ICLASS_READCHECK)
// turn off afterwards // turn off afterwards
void iClass_ReadCheck(uint8_t blockno, uint8_t keytype) { void iClass_ReadCheck(uint8_t blockno, uint8_t keytype) {
uint8_t readcheck[] = { keytype, blockno }; uint8_t readcheck[] = { keytype, blockno };
@ -2286,11 +2350,17 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
setupIclassReader(); setupIclassReader();
uint16_t checked = 0;
int read_status = 0; int read_status = 0;
uint8_t startup_limit = 10; uint8_t startup_limit = 10;
while (read_status != 2) { while (read_status != 2) {
if (BUTTON_PRESS() && !data_available()) goto out; if (checked == 1000) {
if (BUTTON_PRESS() || !data_available()) goto out;
checked = 0;
} else {
checked++;
}
read_status = handshakeIclassTag_ext(card_data, use_credit_key); read_status = handshakeIclassTag_ext(card_data, use_credit_key);
if (startup_limit-- == 0) { if (startup_limit-- == 0) {
@ -2305,7 +2375,12 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
for (i = 0; i < keyCount; i++) { for (i = 0; i < keyCount; i++) {
// Allow button press / usb cmd to interrupt device // Allow button press / usb cmd to interrupt device
if (BUTTON_PRESS() && !data_available()) break; if (checked == 1000) {
if (BUTTON_PRESS() || !data_available()) goto out;
checked = 0;
} else {
checked++;
}
WDT_HIT(); WDT_HIT();
LED_B_ON(); LED_B_ON();

29
armsrc/iclass.h Normal file
View file

@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __ICLASS_H
#define __ICLASS_H
#include "common.h"
void RAMFUNC SniffIClass(void);
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void ReaderIClass(uint8_t arg0);
void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac);
void iClass_Authentication(uint8_t *mac);
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain);
void iClass_WriteBlock(uint8_t blockno, uint8_t *data);
void iClass_ReadBlk(uint8_t blockno);
bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len);
void iClass_Dump(uint8_t blockno, uint8_t numblks);
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
void iClass_ReadCheck(uint8_t blockno, uint8_t keytype);
#endif

View file

@ -11,10 +11,25 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "iso14443a.h" #include "iso14443a.h"
#include "string.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "appmain.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "parity.h"
#include "mifareutil.h"
#include "commonutil.h"
#include "crc16.h"
#include "protocols.h"
#define MAX_ISO14A_TIMEOUT 524288 #define MAX_ISO14A_TIMEOUT 524288
static uint32_t iso14a_timeout; static uint32_t iso14a_timeout;
// if iso14443a not active - transmit/receive dont try to execute // if iso14443a not active - transmit/receive dont try to execute
static bool iso14443a_active = false; static bool hf_field_active = false;
uint8_t colpos = 0; uint8_t colpos = 0;
int rsamples = 0; int rsamples = 0;
@ -25,7 +40,7 @@ static uint8_t iso14_pcb_blocknum = 0;
// //
// ISO14443 timing: // ISO14443 timing:
// //
// minimum time between the start bits of consecutive transfers from reader to tag: 7000 carrier (13.56Mhz) cycles // minimum time between the start bits of consecutive transfers from reader to tag: 7000 carrier (13.56MHz) cycles
#define REQUEST_GUARD_TIME (7000/16 + 1) #define REQUEST_GUARD_TIME (7000/16 + 1)
// minimum time between last modulation of tag and next start bit from reader to tag: 1172 carrier cycles // minimum time between last modulation of tag and next start bit from reader to tag: 1172 carrier cycles
#define FRAME_DELAY_TIME_PICC_TO_PCD (1172/16 + 1) #define FRAME_DELAY_TIME_PICC_TO_PCD (1172/16 + 1)
@ -161,7 +176,7 @@ void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par) {
// Note 1: the bitstream may start at any time. We therefore need to sync. // Note 1: the bitstream may start at any time. We therefore need to sync.
// Note 2: the interpretation of Sequence Y and Z depends on the preceding sequence. // Note 2: the interpretation of Sequence Y and Z depends on the preceding sequence.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static tUart Uart; static tUart14a Uart;
// Lookup-Table to decide if 4 raw bits are a modulation. // Lookup-Table to decide if 4 raw bits are a modulation.
// We accept the following: // We accept the following:
@ -176,12 +191,12 @@ const bool Mod_Miller_LUT[] = {
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
tUart *GetUart() { tUart14a *GetUart14a() {
return &Uart; return &Uart;
} }
void UartReset(void) { void Uart14aReset(void) {
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14A_UNSYNCD;
Uart.bitCount = 0; Uart.bitCount = 0;
Uart.len = 0; // number of decoded data bytes Uart.len = 0; // number of decoded data bytes
Uart.parityLen = 0; // number of decoded parity bytes Uart.parityLen = 0; // number of decoded parity bytes
@ -194,17 +209,17 @@ void UartReset(void) {
Uart.syncBit = 9999; Uart.syncBit = 9999;
} }
void UartInit(uint8_t *data, uint8_t *par) { void Uart14aInit(uint8_t *data, uint8_t *par) {
Uart.output = data; Uart.output = data;
Uart.parity = par; Uart.parity = par;
UartReset(); Uart14aReset();
} }
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
Uart.fourBits = (Uart.fourBits << 8) | bit; Uart.fourBits = (Uart.fourBits << 8) | bit;
if (Uart.state == STATE_UNSYNCD) { // not yet synced if (Uart.state == STATE_14A_UNSYNCD) { // not yet synced
Uart.syncBit = 9999; // not set Uart.syncBit = 9999; // not set
// 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication") // 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication")
@ -230,20 +245,20 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
Uart.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); Uart.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8);
Uart.startTime -= Uart.syncBit; Uart.startTime -= Uart.syncBit;
Uart.endTime = Uart.startTime; Uart.endTime = Uart.startTime;
Uart.state = STATE_START_OF_COMMUNICATION; Uart.state = STATE_14A_START_OF_COMMUNICATION;
} }
} else { } else {
if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) { if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {
if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error
UartReset(); Uart14aReset();
} else { // Modulation in first half = Sequence Z = logic "0" } else { // Modulation in first half = Sequence Z = logic "0"
if (Uart.state == STATE_MILLER_X) { // error - must not follow after X if (Uart.state == STATE_14A_MILLER_X) { // error - must not follow after X
UartReset(); Uart14aReset();
} else { } else {
Uart.bitCount++; Uart.bitCount++;
Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg
Uart.state = STATE_MILLER_Z; Uart.state = STATE_14A_MILLER_Z;
Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 6; Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 6;
if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity)
Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); Uart.output[Uart.len++] = (Uart.shiftReg & 0xff);
@ -262,7 +277,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1" if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1"
Uart.bitCount++; Uart.bitCount++;
Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg
Uart.state = STATE_MILLER_X; Uart.state = STATE_14A_MILLER_X;
Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 2; Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 2;
if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity)
Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); Uart.output[Uart.len++] = (Uart.shiftReg & 0xff);
@ -276,8 +291,8 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
} }
} }
} else { // no modulation in both halves - Sequence Y } else { // no modulation in both halves - Sequence Y
if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication if (Uart.state == STATE_14A_MILLER_Z || Uart.state == STATE_14A_MILLER_Y) { // Y after logic "0" - End of Communication
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14A_UNSYNCD;
Uart.bitCount--; // last "0" was part of EOC sequence Uart.bitCount--; // last "0" was part of EOC sequence
Uart.shiftReg <<= 1; // drop it Uart.shiftReg <<= 1; // drop it
if (Uart.bitCount > 0) { // if we decoded some bits if (Uart.bitCount > 0) { // if we decoded some bits
@ -294,15 +309,15 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
if (Uart.len) { if (Uart.len) {
return true; // we are finished with decoding the raw data sequence return true; // we are finished with decoding the raw data sequence
} else { } else {
UartReset(); // Nothing received - start over Uart14aReset(); // Nothing received - start over
} }
} }
if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC if (Uart.state == STATE_14A_START_OF_COMMUNICATION) { // error - must not follow directly after SOC
UartReset(); Uart14aReset();
} else { // a logic "0" } else { // a logic "0"
Uart.bitCount++; Uart.bitCount++;
Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg
Uart.state = STATE_MILLER_Y; Uart.state = STATE_14A_MILLER_Y;
if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity)
Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); Uart.output[Uart.len++] = (Uart.shiftReg & 0xff);
Uart.parityBits <<= 1; // make room for the parity bit Uart.parityBits <<= 1; // make room for the parity bit
@ -336,7 +351,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
// 8 ticks modulated: A collision. Save the collision position and treat as Sequence D // 8 ticks modulated: A collision. Save the collision position and treat as Sequence D
// Note 1: the bitstream may start at any time. We therefore need to sync. // Note 1: the bitstream may start at any time. We therefore need to sync.
// Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only) // Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only)
tDemod Demod; tDemod14a Demod;
// Lookup-Table to decide if 4 raw bits are a modulation. // Lookup-Table to decide if 4 raw bits are a modulation.
// We accept three or four "1" in any position // We accept three or four "1" in any position
@ -348,11 +363,11 @@ const bool Mod_Manchester_LUT[] = {
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4]) #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
#define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])
tDemod *GetDemod() { tDemod14a *GetDemod14a() {
return &Demod; return &Demod;
} }
void DemodReset(void) { void Demod14aReset(void) {
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_14A_UNSYNCD;
Demod.len = 0; // number of decoded data bytes Demod.len = 0; // number of decoded data bytes
Demod.parityLen = 0; Demod.parityLen = 0;
Demod.shiftReg = 0; // shiftreg to hold decoded data bits Demod.shiftReg = 0; // shiftreg to hold decoded data bits
@ -367,17 +382,17 @@ void DemodReset(void) {
Demod.samples = 0; Demod.samples = 0;
} }
void DemodInit(uint8_t *data, uint8_t *par) { void Demod14aInit(uint8_t *data, uint8_t *par) {
Demod.output = data; Demod.output = data;
Demod.parity = par; Demod.parity = par;
DemodReset(); Demod14aReset();
} }
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) {
Demod.twoBits = (Demod.twoBits << 8) | bit; Demod.twoBits = (Demod.twoBits << 8) | bit;
if (Demod.state == DEMOD_UNSYNCD) { if (Demod.state == DEMOD_14A_UNSYNCD) {
if (Demod.highCnt < 2) { // wait for a stable unmodulated signal if (Demod.highCnt < 2) { // wait for a stable unmodulated signal
if (Demod.twoBits == 0x0000) { if (Demod.twoBits == 0x0000) {
@ -399,7 +414,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
Demod.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); Demod.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8);
Demod.startTime -= Demod.syncBit; Demod.startTime -= Demod.syncBit;
Demod.bitCount = offset; // number of decoded data bits Demod.bitCount = offset; // number of decoded data bits
Demod.state = DEMOD_MANCHESTER_DATA; Demod.state = DEMOD_14A_MANCHESTER_DATA;
} }
} }
} else { } else {
@ -455,7 +470,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
if (Demod.len) { if (Demod.len) {
return true; // we are finished with decoding the raw data sequence return true; // we are finished with decoding the raw data sequence
} else { // nothing received. Start over } else { // nothing received. Start over
DemodReset(); Demod14aReset();
} }
} }
} }
@ -463,6 +478,82 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
return false; // not finished yet, need more data return false; // not finished yet, need more data
} }
// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits.
RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) {
Demod.twoBits = (Demod.twoBits << 8) | bit;
if (Demod.state == DEMOD_14A_UNSYNCD) {
if (Demod.highCnt < 2) { // wait for a stable unmodulated signal
if (Demod.twoBits == 0x0000) {
Demod.highCnt++;
} else {
Demod.highCnt = 0;
}
} else {
Demod.syncBit = 0xFFFF; // not set
if ((Demod.twoBits & 0x7700) == 0x7000) Demod.syncBit = 7;
else if ((Demod.twoBits & 0x3B80) == 0x3800) Demod.syncBit = 6;
else if ((Demod.twoBits & 0x1DC0) == 0x1C00) Demod.syncBit = 5;
else if ((Demod.twoBits & 0x0EE0) == 0x0E00) Demod.syncBit = 4;
else if ((Demod.twoBits & 0x0770) == 0x0700) Demod.syncBit = 3;
else if ((Demod.twoBits & 0x03B8) == 0x0380) Demod.syncBit = 2;
else if ((Demod.twoBits & 0x01DC) == 0x01C0) Demod.syncBit = 1;
else if ((Demod.twoBits & 0x00EE) == 0x00E0) Demod.syncBit = 0;
if (Demod.syncBit != 0xFFFF) {
Demod.startTime = (GetCountSspClk() & 0xfffffff8);
Demod.startTime -= Demod.syncBit;
Demod.bitCount = 1; // number of decoded data bits
Demod.shiftReg = 1;
Demod.state = DEMOD_14A_MANCHESTER_DATA;
}
}
} else {
if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half
if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision
if (!Demod.collisionPos) {
Demod.collisionPos = (Demod.len << 3) + Demod.bitCount;
}
} // modulation in first half only - Sequence D = 1
Demod.bitCount++;
Demod.shiftReg = (Demod.shiftReg << 1) | 0x1; // in both cases, add a 1 to the shiftreg
if (Demod.bitCount == 8) { // if we decoded a full byte
Demod.output[Demod.len++] = (Demod.shiftReg & 0xff);
Demod.bitCount = 0;
Demod.shiftReg = 0;
}
Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1) - 4;
} else { // no modulation in first half
if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0
Demod.bitCount++;
Demod.shiftReg = (Demod.shiftReg << 1); // add a 0 to the shiftreg
if (Demod.bitCount >= 8) { // if we decoded a full byte
Demod.output[Demod.len++] = (Demod.shiftReg & 0xff);
Demod.bitCount = 0;
Demod.shiftReg = 0;
}
Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1);
} else { // no modulation in both halves - End of communication
if (Demod.bitCount > 0) { // there are some remaining data bits
Demod.shiftReg <<= (8 - Demod.bitCount); // left align the decoded bits
Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output
return true;
}
if (Demod.len) {
return true; // we are finished with decoding the raw data sequence
} else { // nothing received. Start over
Demod14aReset();
}
}
}
}
return false; // not finished yet, need more data
}
//============================================================================= //=============================================================================
// Finally, a `sniffer' for ISO 14443 Type A // Finally, a `sniffer' for ISO 14443 Type A
// Both sides of communication! // Both sides of communication!
@ -506,10 +597,10 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
bool ReaderIsActive = false; bool ReaderIsActive = false;
// Set up the demodulator for tag -> reader responses. // Set up the demodulator for tag -> reader responses.
DemodInit(receivedResp, receivedRespPar); Demod14aInit(receivedResp, receivedRespPar);
// Set up the demodulator for the reader -> tag commands // Set up the demodulator for the reader -> tag commands
UartInit(receivedCmd, receivedCmdPar); Uart14aInit(receivedCmd, receivedCmdPar);
DbpString("Starting to sniff"); DbpString("Starting to sniff");
@ -583,13 +674,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
true)) break; true)) break;
} }
/* ready to receive another command. */ /* ready to receive another command. */
UartReset(); Uart14aReset();
/* reset the demod code, which might have been */ /* reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */ /* false-triggered by the commands from the reader. */
DemodReset(); Demod14aReset();
LED_B_OFF(); LED_B_OFF();
} }
ReaderIsActive = (Uart.state != STATE_UNSYNCD); ReaderIsActive = (Uart.state != STATE_14A_UNSYNCD);
} }
// no need to try decoding tag data if the reader is sending - and we cannot afford the time // no need to try decoding tag data if the reader is sending - and we cannot afford the time
@ -608,13 +699,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
if ((!triggered) && (param & 0x01)) triggered = true; if ((!triggered) && (param & 0x01)) triggered = true;
// ready to receive another response. // ready to receive another response.
DemodReset(); Demod14aReset();
// reset the Miller decoder including its (now outdated) input buffer // reset the Miller decoder including its (now outdated) input buffer
UartReset(); Uart14aReset();
//UartInit(receivedCmd, receivedCmdPar); //Uart14aInit(receivedCmd, receivedCmdPar);
LED_C_OFF(); LED_C_OFF();
} }
TagIsActive = (Demod.state != DEMOD_UNSYNCD); TagIsActive = (Demod.state != DEMOD_14A_UNSYNCD);
} }
} }
@ -754,7 +845,7 @@ static bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
// Now run a `software UART` on the stream of incoming samples. // Now run a `software UART` on the stream of incoming samples.
UartInit(received, par); Uart14aInit(received, par);
// clear RXRDY: // clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -1073,7 +1164,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) { if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_SIMULATE_MIFARE_CARD, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
return; return;
} }
@ -1193,7 +1284,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
ar_nr_nonces[index].state = SECOND; ar_nr_nonces[index].state = SECOND;
// send to client (one struct nonces_t) // send to client (one struct nonces_t)
reply_ng(CMD_SIMULATE_MIFARE_CARD, PM3_SUCCESS, (uint8_t *)&ar_nr_nonces[index], sizeof(nonces_t)); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_SUCCESS, (uint8_t *)&ar_nr_nonces[index], sizeof(nonces_t));
ar_nr_nonces[index].state = EMPTY; ar_nr_nonces[index].state = EMPTY;
ar_nr_nonces[index].sector = 0; ar_nr_nonces[index].sector = 0;
@ -1517,7 +1608,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
Dbprintf("-[ Num of moebius tries [%d]", moebius_count); Dbprintf("-[ Num of moebius tries [%d]", moebius_count);
} }
reply_ng(CMD_SIMULATE_MIFARE_CARD, retval, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
} }
// prepare a delayed transfer. This simply shifts ToSend[] by a number // prepare a delayed transfer. This simply shifts ToSend[] by a number
@ -1553,7 +1644,7 @@ void PrepareDelayedTransfer(uint16_t delay) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) {
if (!iso14443a_active) if (!hf_field_active)
return; return;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
@ -1719,7 +1810,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) {
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
// Now run a 'software UART' on the stream of incoming samples. // Now run a 'software UART' on the stream of incoming samples.
UartInit(received, par); Uart14aInit(received, par);
// Clear RXRDY: // Clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -1931,14 +2022,14 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Kovio - Thinfilm barcode. TAG-TALK-FIRST -
// Wait a certain time for tag response // Wait a certain time for tag response
// If a response is captured return TRUE // If a response is captured return TRUE
// If it takes too long return FALSE // If it takes too long return FALSE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len) {
uint32_t c = 0;
if (!iso14443a_active) if (!hf_field_active)
return false; return false;
// Set FPGA mode to "reader listen mode", no modulation (listen // Set FPGA mode to "reader listen mode", no modulation (listen
@ -1948,7 +2039,56 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
// Now get the answer from the card // Now get the answer from the card
DemodInit(receivedResponse, receivedResponsePar); Demod14aInit(receivedResponse, NULL);
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
(void)b;
uint32_t receive_timer = GetTickCount();
for (;;) {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
if (ManchesterDecoding_Thinfilm(b)) {
*received_len = Demod.len;
// log
LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false);
return true;
}
}
// timeout already in ms + 10ms guard time
if (GetTickCount() - receive_timer > 1160)
break;
}
*received_len = Demod.len;
// log
LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false);
return false;
}
//-----------------------------------------------------------------------------
// Wait a certain time for tag response
// If a response is captured return TRUE
// If it takes too long return FALSE
//-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) {
uint32_t c = 0;
if (!hf_field_active)
return false;
// Set FPGA mode to "reader listen mode", no modulation (listen
// only, since we are receiving, not transmitting).
// Signal field is on with the appropriate LED
LED_D_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
// Now get the answer from the card
Demod14aInit(receivedResponse, receivedResponsePar);
// clear RXRDY: // clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -1964,7 +2104,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
if (ManchesterDecoding(b, offset, 0)) { if (ManchesterDecoding(b, offset, 0)) {
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FRAME_DELAY_TIME_PICC_TO_PCD); NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FRAME_DELAY_TIME_PICC_TO_PCD);
return true; return true;
} else if (c++ > timeout && Demod.state == DEMOD_UNSYNCD) { } else if (c++ > timeout && Demod.state == DEMOD_14A_UNSYNCD) {
return false; return false;
} }
} }
@ -2018,6 +2158,7 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par) {
return Demod.len; return Demod.len;
} }
// This function misstreats the ISO 14443a anticollision procedure. // This function misstreats the ISO 14443a anticollision procedure.
// by fooling the reader there is a collision and forceing the reader to // by fooling the reader there is a collision and forceing the reader to
// increase the uid bytes. The might be an overflow, DoS will occure. // increase the uid bytes. The might be an overflow, DoS will occure.
@ -2363,8 +2504,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
LED_D_OFF(); LED_D_OFF();
// Signal field is on with the appropriate LED // Signal field is on with the appropriate LED
if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN)
fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN)
LED_D_ON(); LED_D_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode);
@ -2374,18 +2514,19 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
StartCountSspClk(); StartCountSspClk();
// Prepare the demodulation functions // Prepare the demodulation functions
DemodReset(); Demod14aReset();
UartReset(); Uart14aReset();
NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER;
iso14a_set_timeout(1060); // 106 * 10ms default iso14a_set_timeout(1060); // 106 * 10ms default
iso14443a_active = true; hf_field_active = true;
} }
void iso14443a_off() {
void hf_field_off(void) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
iso14443a_active = false; hf_field_active = false;
} }
/* Peter Fillmore 2015 /* Peter Fillmore 2015
@ -2590,7 +2731,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
return; return;
OUT: OUT:
iso14443a_off(); hf_field_off();
set_tracing(false); set_tracing(false);
} }
@ -2885,7 +3026,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf)); reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf));
iso14443a_off(); hf_field_off();
set_tracing(false); set_tracing(false);
} }
@ -2893,7 +3034,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
* Mifare Classic NACK-bug detection * Mifare Classic NACK-bug detection
* Thanks to @doegox for the feedback and new approaches. * Thanks to @doegox for the feedback and new approaches.
*/ */
void DetectNACKbug() { void DetectNACKbug(void) {
uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@ -3120,10 +3261,10 @@ void DetectNACKbug() {
data[0] = isOK; data[0] = isOK;
data[1] = num_nacks; data[1] = num_nacks;
num_to_bytes(i, 2, data + 2); num_to_bytes(i, 2, data + 2);
reply_ng(CMD_MIFARE_NACK_DETECT, status, data, 4); reply_ng(CMD_HF_MIFARE_NACK_DETECT, status, data, 4);
//reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0); //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0);
BigBuf_free(); BigBuf_free();
iso14443a_off(); hf_field_off();
set_tracing(false); set_tracing(false);
} }

View file

@ -13,21 +13,9 @@
#ifndef __ISO14443A_H #ifndef __ISO14443A_H
#define __ISO14443A_H #define __ISO14443A_H
#ifdef __cplusplus #include "common.h"
extern "C" { #include "mifare.h" // struct
#endif
#include "pm3_cmd.h" #include "pm3_cmd.h"
#include "cmd.h"
#include "apps.h"
#include "util.h"
#include "string.h"
#include "crc16.h"
#include "mifaresniff.h"
#include "crapto1/crapto1.h"
#include "mifareutil.h"
#include "parity.h"
#include "mifare.h" // structs
// When the PM acts as tag and is receiving it takes // When the PM acts as tag and is receiving it takes
// 2 ticks delay in the RF part (for the first falling edge), // 2 ticks delay in the RF part (for the first falling edge),
@ -42,11 +30,11 @@ extern "C" {
typedef struct { typedef struct {
enum { enum {
DEMOD_UNSYNCD, DEMOD_14A_UNSYNCD,
// DEMOD_HALF_SYNCD, // DEMOD_14A_HALF_SYNCD,
// DEMOD_MOD_FIRST_HALF, // DEMOD_14A_MOD_FIRST_HALF,
// DEMOD_NOMOD_FIRST_HALF, // DEMOD_14A_NOMOD_FIRST_HALF,
DEMOD_MANCHESTER_DATA DEMOD_14A_MANCHESTER_DATA
} state; } state;
uint16_t twoBits; uint16_t twoBits;
uint16_t highCnt; uint16_t highCnt;
@ -61,7 +49,7 @@ typedef struct {
uint32_t startTime, endTime; uint32_t startTime, endTime;
uint8_t *output; uint8_t *output;
uint8_t *parity; uint8_t *parity;
} tDemod; } tDemod14a;
/* /*
typedef enum { typedef enum {
MOD_NOMOD = 0, MOD_NOMOD = 0,
@ -73,11 +61,11 @@ typedef enum {
typedef struct { typedef struct {
enum { enum {
STATE_UNSYNCD, STATE_14A_UNSYNCD,
STATE_START_OF_COMMUNICATION, STATE_14A_START_OF_COMMUNICATION,
STATE_MILLER_X, STATE_14A_MILLER_X,
STATE_MILLER_Y, STATE_14A_MILLER_Y,
STATE_MILLER_Z, STATE_14A_MILLER_Z,
// DROP_NONE, // DROP_NONE,
// DROP_FIRST_HALF, // DROP_FIRST_HALF,
} state; } state;
@ -93,7 +81,7 @@ typedef struct {
uint32_t startTime, endTime; uint32_t startTime, endTime;
uint8_t *output; uint8_t *output;
uint8_t *parity; uint8_t *parity;
} tUart; } tUart14a;
#ifndef AddCrc14A #ifndef AddCrc14A
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
@ -109,12 +97,12 @@ typedef struct {
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
tDemod *GetDemod(void); tDemod14a *GetDemod14a(void);
void DemodReset(void); void Demod14aReset(void);
void DemodInit(uint8_t *data, uint8_t *par); void Demod14aInit(uint8_t *data, uint8_t *par);
tUart *GetUart(void); tUart14a *GetUart14a(void);
void UartReset(void); void Uart14aReset(void);
void UartInit(uint8_t *data, uint8_t *par); void Uart14aInit(uint8_t *data, uint8_t *par);
RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time); 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); RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time);
@ -132,6 +120,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats); int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades); int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
void iso14a_set_trigger(bool enable); void iso14a_set_trigger(bool enable);
void hf_field_off(void);
int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen); int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen);
int EmSend4bit(uint8_t resp); int EmSend4bit(uint8_t resp);
@ -148,10 +137,8 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
void DetectNACKbug(); void DetectNACKbug(void);
#ifdef __cplusplus bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len);
}
#endif
#endif /* __ISO14443A_H */ #endif /* __ISO14443A_H */

View file

@ -10,6 +10,20 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "iso14443b.h" #include "iso14443b.h"
#include "proxmark3_arm.h"
#include "common.h" // access to global variable: DBGLEVEL
#include "util.h"
#include "string.h"
#include "crc16.h"
#include "protocols.h"
#include "appmain.h"
#include "BigBuf.h"
#include "cmd.h"
#include "fpgaloader.h"
#include "commonutil.h"
#include "dbprint.h"
#include "ticks.h"
#ifndef FWT_TIMEOUT_14B #ifndef FWT_TIMEOUT_14B
// defaults to 2000ms // defaults to 2000ms
# define FWT_TIMEOUT_14B 35312 # define FWT_TIMEOUT_14B 35312
@ -52,7 +66,7 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
//============================================================================= //=============================================================================
// An ISO 14443 Type B tag. We listen for commands from the reader, using // An ISO 14443 Type B tag. We listen for commands from the reader, using
// a UART kind of thing that's implemented in software. When we get a // a kind of thing that's implemented in software. When we get a
// frame (i.e., a group of bytes between SOF and EOF), we check the CRC. // frame (i.e., a group of bytes between SOF and EOF), we check the CRC.
// If it's good, then we can do something appropriate with it, and send // If it's good, then we can do something appropriate with it, and send
// a response. // a response.
@ -60,14 +74,14 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// The software UART that receives commands from the reader, and its state variables. // The software that receives commands from the reader, and its state variables.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static struct { static struct {
enum { enum {
STATE_UNSYNCD, STATE_14B_UNSYNCD,
STATE_GOT_FALLING_EDGE_OF_SOF, STATE_14B_GOT_FALLING_EDGE_OF_SOF,
STATE_AWAITING_START_BIT, STATE_14B_AWAITING_START_BIT,
STATE_RECEIVING_DATA STATE_14B_RECEIVING_DATA
} state; } state;
uint16_t shiftReg; uint16_t shiftReg;
int bitCnt; int bitCnt;
@ -77,8 +91,8 @@ static struct {
uint8_t *output; uint8_t *output;
} Uart; } Uart;
static void UartReset() { static void Uart14bReset() {
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
Uart.shiftReg = 0; Uart.shiftReg = 0;
Uart.bitCnt = 0; Uart.bitCnt = 0;
Uart.byteCnt = 0; Uart.byteCnt = 0;
@ -86,9 +100,9 @@ static void UartReset() {
Uart.posCnt = 0; Uart.posCnt = 0;
} }
static void UartInit(uint8_t *data) { static void Uart14bInit(uint8_t *data) {
Uart.output = data; Uart.output = data;
UartReset(); Uart14bReset();
// memset(Uart.output, 0x00, MAX_FRAME_SIZE); // memset(Uart.output, 0x00, MAX_FRAME_SIZE);
} }
@ -120,7 +134,7 @@ static struct {
} Demod; } Demod;
// Clear out the state of the "UART" that receives from the tag. // Clear out the state of the "UART" that receives from the tag.
static void DemodReset() { static void Demod14bReset() {
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.posCount = 0; Demod.posCount = 0;
@ -133,9 +147,9 @@ static void DemodReset() {
Demod.endTime = 0; Demod.endTime = 0;
} }
static void DemodInit(uint8_t *data) { static void Demod14bInit(uint8_t *data) {
Demod.output = data; Demod.output = data;
DemodReset(); Demod14bReset();
// memset(Demod.output, 0x00, MAX_FRAME_SIZE); // memset(Demod.output, 0x00, MAX_FRAME_SIZE);
} }
@ -315,16 +329,16 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) {
*/ */
static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
switch (Uart.state) { switch (Uart.state) {
case STATE_UNSYNCD: case STATE_14B_UNSYNCD:
if (!bit) { if (!bit) {
// we went low, so this could be the beginning of an SOF // we went low, so this could be the beginning of an SOF
Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; Uart.state = STATE_14B_GOT_FALLING_EDGE_OF_SOF;
Uart.posCnt = 0; Uart.posCnt = 0;
Uart.bitCnt = 0; Uart.bitCnt = 0;
} }
break; break;
case STATE_GOT_FALLING_EDGE_OF_SOF: case STATE_14B_GOT_FALLING_EDGE_OF_SOF:
Uart.posCnt++; Uart.posCnt++;
if (Uart.posCnt == 2) { // sample every 4 1/fs in the middle of a bit if (Uart.posCnt == 2) { // sample every 4 1/fs in the middle of a bit
if (bit) { if (bit) {
@ -333,11 +347,11 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
// zeros that it's a valid SOF // zeros that it's a valid SOF
Uart.posCnt = 0; Uart.posCnt = 0;
Uart.byteCnt = 0; Uart.byteCnt = 0;
Uart.state = STATE_AWAITING_START_BIT; Uart.state = STATE_14B_AWAITING_START_BIT;
LED_A_ON(); // Indicate we got a valid SOF LED_A_ON(); // Indicate we got a valid SOF
} else { } else {
// didn't stay down long enough before going high, error // didn't stay down long enough before going high, error
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
} }
} else { } else {
// do nothing, keep waiting // do nothing, keep waiting
@ -348,27 +362,27 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
if (Uart.bitCnt > 12) { if (Uart.bitCnt > 12) {
// Give up if we see too many zeros without a one, too. // Give up if we see too many zeros without a one, too.
LED_A_OFF(); LED_A_OFF();
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
} }
break; break;
case STATE_AWAITING_START_BIT: case STATE_14B_AWAITING_START_BIT:
Uart.posCnt++; Uart.posCnt++;
if (bit) { if (bit) {
if (Uart.posCnt > 50 / 2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs if (Uart.posCnt > 50 / 2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs
// stayed high for too long between characters, error // stayed high for too long between characters, error
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
} }
} else { } else {
// falling edge, this starts the data byte // falling edge, this starts the data byte
Uart.posCnt = 0; Uart.posCnt = 0;
Uart.bitCnt = 0; Uart.bitCnt = 0;
Uart.shiftReg = 0; Uart.shiftReg = 0;
Uart.state = STATE_RECEIVING_DATA; Uart.state = STATE_14B_RECEIVING_DATA;
} }
break; break;
case STATE_RECEIVING_DATA: case STATE_14B_RECEIVING_DATA:
Uart.posCnt++; Uart.posCnt++;
if (Uart.posCnt == 2) { if (Uart.posCnt == 2) {
// time to sample a bit // time to sample a bit
@ -391,30 +405,30 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
if (Uart.byteCnt >= Uart.byteCntMax) { if (Uart.byteCnt >= Uart.byteCntMax) {
// Buffer overflowed, give up // Buffer overflowed, give up
LED_A_OFF(); LED_A_OFF();
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
} else { } else {
// so get the next byte now // so get the next byte now
Uart.posCnt = 0; Uart.posCnt = 0;
Uart.state = STATE_AWAITING_START_BIT; Uart.state = STATE_14B_AWAITING_START_BIT;
} }
} else if (Uart.shiftReg == 0x000) { } else if (Uart.shiftReg == 0x000) {
// this is an EOF byte // this is an EOF byte
LED_A_OFF(); // Finished receiving LED_A_OFF(); // Finished receiving
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
if (Uart.byteCnt != 0) if (Uart.byteCnt != 0)
return true; return true;
} else { } else {
// this is an error // this is an error
LED_A_OFF(); LED_A_OFF();
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
} }
} }
break; break;
default: default:
LED_A_OFF(); LED_A_OFF();
Uart.state = STATE_UNSYNCD; Uart.state = STATE_14B_UNSYNCD;
break; break;
} }
return false; return false;
@ -454,7 +468,7 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
} }
*/ */
// Now run a `software UART' on the stream of incoming samples. // Now run a `software UART' on the stream of incoming samples.
UartInit(received); Uart14bInit(received);
uint8_t mask; uint8_t mask;
while (!BUTTON_PRESS()) { while (!BUTTON_PRESS()) {
@ -949,7 +963,7 @@ static void GetTagSamplesFor14443bDemod() {
BigBuf_free(); BigBuf_free();
// Set up the demodulator for tag -> reader responses. // Set up the demodulator for tag -> reader responses.
DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
// The DMA buffer, used to stream samples from the FPGA // The DMA buffer, used to stream samples from the FPGA
int8_t *dmaBuf = (int8_t *) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); int8_t *dmaBuf = (int8_t *) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
@ -1306,8 +1320,8 @@ void iso14443b_setup() {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Initialize Demod and Uart structs // Initialize Demod and Uart structs
DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
// connect Demodulated Signal to ADC: // connect Demodulated Signal to ADC:
SetAdcMuxFor(GPIO_MUXSEL_HIPKD); SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
@ -1411,8 +1425,8 @@ static void iso1444b_setup_sniff(void) {
set_tracing(true); set_tracing(true);
// Initialize Demod and Uart structs // Initialize Demod and Uart structs
DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); Demod14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); Uart14bInit(BigBuf_malloc(MAX_FRAME_SIZE));
if (DBGLEVEL > 1) { if (DBGLEVEL > 1) {
// Print debug information about the buffer sizes // Print debug information about the buffer sizes
@ -1502,8 +1516,8 @@ void RAMFUNC SniffIso14443b(void) {
if (Handle14443bReaderUartBit(ci & 0x01)) { if (Handle14443bReaderUartBit(ci & 0x01)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true);
UartReset(); Uart14bReset();
DemodReset(); Demod14bReset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
} }
@ -1511,12 +1525,12 @@ void RAMFUNC SniffIso14443b(void) {
if (Handle14443bReaderUartBit(cq & 0x01)) { if (Handle14443bReaderUartBit(cq & 0x01)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true);
UartReset(); Uart14bReset();
DemodReset(); Demod14bReset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
} }
ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF); ReaderIsActive = (Uart.state > STATE_14B_GOT_FALLING_EDGE_OF_SOF);
} }
// no need to try decoding tag data if the reader is sending - and we cannot afford the time // no need to try decoding tag data if the reader is sending - and we cannot afford the time
@ -1527,8 +1541,8 @@ void RAMFUNC SniffIso14443b(void) {
if (Handle14443bTagSamplesDemod(ci, cq)) { if (Handle14443bTagSamplesDemod(ci, cq)) {
time_stop = GetCountSspClk() - time_0; time_stop = GetCountSspClk() - time_0;
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
UartReset(); Uart14bReset();
DemodReset(); Demod14bReset();
} else { } else {
time_start = GetCountSspClk() - time_0; time_start = GetCountSspClk() - time_0;
} }

View file

@ -13,18 +13,10 @@
#ifndef __ISO14443B_H #ifndef __ISO14443B_H
#define __ISO14443B_H #define __ISO14443B_H
#ifdef __cplusplus #include "common.h"
extern "C" {
#endif
#include "proxmark3.h"
#include "common.h" // access to global variable: DBGLEVEL
#include "apps.h"
#include "util.h"
#include "string.h"
#include "crc16.h"
#include "mifare.h" #include "mifare.h"
#include "protocols.h" #include "pm3_cmd.h"
#ifndef AddCrc14A #ifndef AddCrc14A
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) # define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
@ -34,12 +26,18 @@ extern "C" {
# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1)
#endif #endif
void SendRawCommand14443B_Ex(PacketCommandNG *c);
void iso14443b_setup(); void iso14443b_setup();
uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response); uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response);
uint8_t iso14443b_select_card(iso14b_card_select_t *card); uint8_t iso14443b_select_card(iso14b_card_select_t *card);
uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card); uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card);
void SimulateIso14443bTag(uint32_t pupi);
void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
void ReadSTMemoryIso14443b(uint8_t numofblocks);
void RAMFUNC SniffIso14443b(void);
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
void SendRawCommand14443B_Ex(PacketCommandNG *c);
// testfunctions // testfunctions
void WaitForFpgaDelayQueueIsEmpty(uint16_t delay); void WaitForFpgaDelayQueueIsEmpty(uint16_t delay);
void ClearFpgaShiftingRegisters(void); void ClearFpgaShiftingRegisters(void);
@ -53,8 +51,4 @@ void ClearFpgaShiftingRegisters(void);
#define SIM_ACKNOWLEDGE 5 #define SIM_ACKNOWLEDGE 5
#define SIM_WORK 6 #define SIM_WORK 6
#ifdef __cplusplus
}
#endif
#endif /* __ISO14443B_H */ #endif /* __ISO14443B_H */

View file

@ -32,8 +32,8 @@
// //
// VICC (tag) -> VCD (reader) // VICC (tag) -> VCD (reader)
// Modulation: // Modulation:
// ASK / one subcarrier (423,75 khz) // ASK / one subcarrier (423,75 kHz)
// FSK / two subcarriers (423,75 khz && 484,28 khz) // FSK / two subcarriers (423,75 kHz && 484,28 kHz)
// Data Rates / Modes: // Data Rates / Modes:
// low ASK: 6,62 kbit/s // low ASK: 6,62 kbit/s
// low FSK: 6.67 kbit/s // low FSK: 6.67 kbit/s
@ -58,12 +58,20 @@
// *) remove or refactor code under "depricated" // *) remove or refactor code under "depricated"
// *) document all the functions // *) document all the functions
#include "proxmark3.h" #include "iso15693.h"
#include "proxmark3_arm.h"
#include "util.h" #include "util.h"
#include "apps.h"
#include "string.h" #include "string.h"
#include "iso15693tools.h" #include "iso15693tools.h"
#include "cmd.h" #include "cmd.h"
#include "appmain.h"
#include "dbprint.h"
#include "fpgaloader.h"
#include "commonutil.h"
#include "ticks.h"
#include "BigBuf.h"
#include "crc16.h"
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// ISO 15693 Part 2 - Air Interface // ISO 15693 Part 2 - Air Interface

26
armsrc/iso15693.h Normal file
View file

@ -0,0 +1,26 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __ISO15693_H
#define __ISO15693_H
#include "common.h"
#include "pm3_cmd.h" // struct
void RecordRawAdcSamplesIso15693(void);
void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox
void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox
void Iso15693InitReader(void);
#endif

View file

@ -7,7 +7,7 @@
Linker script for the ARM binary Linker script for the ARM binary
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
*/ */
INCLUDE ../common/ldscript.common INCLUDE ../common_arm/ldscript.common
PHDRS PHDRS
{ {

View file

@ -11,11 +11,20 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "legicrf.h" #include "legicrf.h"
#include "ticks.h" /* timers */
#include "crc.h" /* legic crc-4 */ #include "crc.h" /* legic crc-4 */
#include "legic_prng.h" /* legic PRNG impl */ #include "legic_prng.h" /* legic PRNG impl */
#include "legic.h" /* legic_card_select_t struct */ #include "legic.h" /* legic_card_select_t struct */
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "string.h"
#include "protocols.h"
static uint8_t *legic_mem; /* card memory, used for read, write */ static uint8_t *legic_mem; /* card memory, used for read, write */
static legic_card_select_t card;/* metadata of currently selected card */ static legic_card_select_t card;/* metadata of currently selected card */
static crc_t legic_crc; static crc_t legic_crc;

View file

@ -12,7 +12,7 @@
#ifndef __LEGICRF_H #ifndef __LEGICRF_H
#define __LEGICRF_H #define __LEGICRF_H
#include "proxmark3.h" #include "common.h"
void LegicRfInfo(void); void LegicRfInfo(void);
void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv);

View file

@ -11,11 +11,17 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "legicrf.h" #include "legicrf.h"
#include "ticks.h" /* timers */
#include "crc.h" /* legic crc-4 */ #include "crc.h" /* legic crc-4 */
#include "legic_prng.h" /* legic PRNG impl */ #include "legic_prng.h" /* legic PRNG impl */
#include "legic.h" /* legic_card_select_t struct */ #include "legic.h" /* legic_card_select_t struct */
#include "proxmark3_arm.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
static uint8_t *legic_mem; /* card memory, used for sim */ static uint8_t *legic_mem; /* card memory, used for sim */
static legic_card_select_t card;/* metadata of currently selected card */ static legic_card_select_t card;/* metadata of currently selected card */
static crc_t legic_crc; static crc_t legic_crc;

View file

@ -12,7 +12,7 @@
#ifndef __LEGICRFSIM_H #ifndef __LEGICRFSIM_H
#define __LEGICRFSIM_H #define __LEGICRFSIM_H
#include "proxmark3.h" #include "common.h"
void LegicRfSimulate(uint8_t tagtype); void LegicRfSimulate(uint8_t tagtype);

View file

@ -8,54 +8,71 @@
// Also routines for raw mode reading/simulating of LF waveform // Also routines for raw mode reading/simulating of LF waveform
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "proxmark3.h" #include "lfops.h"
#include "apps.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h" #include "util.h"
#include "hitag2.h" #include "commonutil.h"
#include "crc16.h" #include "crc16.h"
#include "string.h" #include "string.h"
#include "printf.h"
#include "lfdemod.h" #include "lfdemod.h"
#include "lfsampling.h" #include "lfsampling.h"
#include "protocols.h" #include "protocols.h"
#include "usb_cdc.h" // for usb_poll_validate_length
#include "common.h"
#include "pmflash.h" #include "pmflash.h"
#include "flashmem.h" // persistence on mem #include "flashmem.h" // persistence on flash
/*
Notes about EM4xxx timings.
The timing values differs between cards, we got EM410x, EM43x5, EM445x etc.
We are trying to unify and enable the Proxmark to easily detect and select correct timings automatic.
The measures from datasheets doesn't always match correct the hardware features of RDV4 antenans and we still wanted to let other devices with other custom antennas
still benefit from this repo. This is why its configurable and we use to set these dynamic settings in device external flash memory.
//#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
//#define WRITE_GAP 8*8 // 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
//#define WRITE_0 15*8 // 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
//#define WRITE_1 47*8 // 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
//#define READ_GAP 15*8
// VALUES TAKEN FROM EM4x function: SendForward // VALUES TAKEN FROM EM4x function: SendForward
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) // START_GAP = 440; (55*8) cycles at 125kHz (8us = 1cycle)
// WRITE_GAP = 128; (16*8) // WRITE_GAP = 128; (16*8)
// WRITE_1 = 256 32*8; (32*8) // WRITE_1 = 256 32*8; (32*8)
// These timings work for 4469/4269/4305 (with the 55*8 above) // These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 // WRITE_0 = 23*8 , 9*8
// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) Not about ARM TIMERS
// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz Short note about timers on Proxmark device ARM. They are a bit differently implemented and gives decent correctness.
// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
// T0 = TIMER_CLOCK1 / 125000 = 192 SAM7S has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
// 1 Cycle = 8 microseconds(us) == 1 field clock TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
New timer implemenation in ticks.c, which is used in LFOPS.c
1us = 1.5ticks
1fc = 8us = 12ticks
Terms you find in different datasheets and how they match.
1 Cycle = 8 microseconds(us) == 1 field clock (fc)
Note about HITAG timing
Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
T0 = TIMER_CLOCK1 / 125000 = 192
// new timer:
// = 1us = 1.5ticks
// 1fc = 8us = 12ticks
/*
========================================================================================================== ==========================================================================================================
T55x7 Timing T55x7 Timing
========================================================================================================== ==========================================================================================================
// t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ;
ATA5577 Downlink Protocol Timings. ATA5577 Downlink Protocol Timings.
Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz)
Note: These timings are from the datasheet and doesn't map the best to the features of the RVD4 LF antenna.
RDV4 LF antenna has high voltage and the drop of power when turning off the rf field takes about 1-2 TC longer.
----------------------------------------------------------------------- -----------------------------------------------------------------------
Fixed-bit-length Protocol | Normal Downlink | Fast Downlink | Fixed-bit-length Protocol | Normal Downlink | Fast Downlink |
------------------------------+-----------------------------------+-----------------------------------+------ ------------------------------+-----------------------------------+-----------------------------------+------
@ -110,21 +127,23 @@
| |10 data | d10 | dref + 25 | dref + 32 | dref + 40 | dref + 13 | dref + 16 | dref + 20 | Tc | | |10 data | d10 | dref + 25 | dref + 32 | dref + 40 | dref + 13 | dref + 16 | dref + 20 | Tc |
| |11 data | d11 | dref + 41 | dref + 48 | dref + 56 | dref + 21 | dref + 24 | dref + 28 | Tc | | |11 data | d11 | dref + 41 | dref + 48 | dref + 56 | dref + 21 | dref + 24 | dref + 28 | Tc |
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
*/
// Initial values if not in flash Initial values if not in flash
/*
// Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. SG = Start gap
// StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap WG = Write gap
t55xx_config T55xx_Timing = {{ RG = Read gap
Explainations for array T55xx_Timing below
SG WG Bit 0/00 Bit 1/01 Bit 10 Bit 11 RG
--------------------------------------------------------------------
{ 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed { 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed
{ 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref.
{ 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0
{ 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4
}
};
*/ */
// StartGap WriteGap Bit 0/00 Bit 1/01 ReadGap Bit 10 Bit 11 t55xx_configurations_t T55xx_Timing = {
t55xx_config T55xx_Timing = {{ {
{ 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed { 29 * 8, 17 * 8, 15 * 8, 47 * 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, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref.
{ 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0
@ -134,61 +153,136 @@ t55xx_config T55xx_Timing = {{
// Some defines for readability // Some defines for readability
#define T55xx_DLMode_Fixed 0 // Default Mode #define T55XX_DLMODE_FIXED 0 // Default Mode
#define T55xx_DLMode_LLR 1 // Long Leading Reference #define T55XX_DLMODE_LLR 1 // Long Leading Reference
#define T55xx_DLMode_Leading0 2 // Leading Zero #define T55XX_DLMODE_LEADING_ZERO 2 // Leading Zero
#define T55xx_DLMode_1of4 3 // 1 of 4 #define T55XX_DLMODE_1OF4 3 // 1 of 4
#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference #define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference
void printT55xxConfig(void) { // ATA55xx shared presets & routines
int DLMode; static uint32_t GetT55xxClockBit(uint32_t clock) {
switch (clock) {
DbpString(_BLUE_("LF T55XX config")); case 128:
for (DLMode = 0; DLMode < 4; DLMode++) { return T55x7_BITRATE_RF_128;
switch (DLMode) { case 100:
case T55xx_DLMode_Fixed : return T55x7_BITRATE_RF_100;
Dbprintf("r 0 fixed bit length (default)"); case 64:
break; return T55x7_BITRATE_RF_64;
case T55xx_DLMode_LLR : case 50:
Dbprintf("r 1 long leading reference"); return T55x7_BITRATE_RF_50;
break; case 40:
case T55xx_DLMode_Leading0 : return T55x7_BITRATE_RF_40;
Dbprintf("r 2 leading zero"); case 32:
break; return T55x7_BITRATE_RF_32;
case T55xx_DLMode_1of4 : case 16:
Dbprintf("r 3 1 of 4 coding reference"); return T55x7_BITRATE_RF_16;
break; case 8:
} return T55x7_BITRATE_RF_8;
Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[DLMode].start_gap / 8, T55xx_Timing.m[DLMode].start_gap); default :
Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); return 0;
Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0);
Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1);
Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap);
if (DLMode == T55xx_DLMode_1of4) {
Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2);
Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3);
}
} }
} }
void setT55xxConfig(uint8_t arg0, t55xx_config *c) { void printT55xxConfig(void) {
uint8_t DLMode;
// uint8_t ClearT55Settings = c->m[0].start_gap & 0xffff; // all values will be ffff if clear requested
#define PRN_NA sprintf(s + strlen(s), _RED_("N/A") "| ");
for (DLMode = 0; DLMode < 4; DLMode++) { DbpString(_BLUE_("LF T55XX config"));
if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap;// * 8; Dbprintf(" [r] [a] [b] [c] [d] [e] [f] [g]");
if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap;// * 8; Dbprintf(" mode |start|write|write|write| read|write|write");
if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ;// * 8; Dbprintf(" | gap | gap | 0 | 1 | gap | 2 | 3");
if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ;// * 8; Dbprintf("---------------------------+-----+-----+-----+-----+-----+-----+------");
if (DLMode == T55xx_DLMode_1of4) {
if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2;// * 8; for (uint8_t i = 0; i < 4; i++) {
if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3;// * 8 ;
} else { char s[160];
T55xx_Timing.m[DLMode].write_2 = 0x00; memset(s, 0, sizeof(s));
T55xx_Timing.m[DLMode].write_3 = 0x00;
switch (i) {
case T55XX_DLMODE_FIXED :
sprintf(s, _YELLOW_("fixed bit length") _GREEN_("(default)") "|");
break;
case T55XX_DLMODE_LLR :
sprintf(s, _YELLOW_(" long leading reference") "|");
break;
case T55XX_DLMODE_LEADING_ZERO :
sprintf(s, _YELLOW_(" leading zero") "|");
break;
case T55XX_DLMODE_1OF4 :
sprintf(s, _YELLOW_(" 1 of 4 coding reference") "|");
break;
default:
break;
} }
if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap;//* 8;
if (T55xx_Timing.m[i].start_gap != 0xFFFF)
sprintf(s + strlen(s), " %3d | ", T55xx_Timing.m[i].start_gap / 8);
else
PRN_NA;
if (T55xx_Timing.m[i].write_gap != 0xFFFF)
sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_gap / 8);
else
PRN_NA;
if (T55xx_Timing.m[i].write_0 != 0xFFFF)
sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_0 / 8);
else
PRN_NA;
if (T55xx_Timing.m[i].write_1 != 0xFFFF)
sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_1 / 8);
else
PRN_NA;
if (T55xx_Timing.m[i].read_gap != 0xFFFF)
sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].read_gap / 8);
else
PRN_NA;
if (T55xx_Timing.m[i].write_2 != 0xFFFF && i == T55XX_DLMODE_1OF4)
sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_2 / 8);
else
PRN_NA
if (T55xx_Timing.m[i].write_3 != 0xFFFF && i == T55XX_DLMODE_1OF4)
sprintf(s + strlen(s), "%3d | ", T55xx_Timing.m[i].write_3 / 8);
else
PRN_NA;
s[strlen(s)] = 0;
DbpString(s);
}
DbpString("");
}
void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c) {
for (uint8_t i = 0; i < 4; i++) {
if (c->m[i].start_gap != 0)
T55xx_Timing.m[i].start_gap = c->m[i].start_gap;
if (c->m[i].write_gap != 0)
T55xx_Timing.m[i].write_gap = c->m[i].write_gap;
if (c->m[i].write_0 != 0)
T55xx_Timing.m[i].write_0 = c->m[i].write_0;
if (c->m[i].write_1 != 0)
T55xx_Timing.m[i].write_1 = c->m[i].write_1;
if (i == T55XX_DLMODE_1OF4) {
if (c->m[i].write_2 != 0)
T55xx_Timing.m[i].write_2 = c->m[i].write_2;
if (c->m[i].write_3 != 0)
T55xx_Timing.m[i].write_3 = c->m[i].write_3;
} else {
T55xx_Timing.m[i].write_2 = 0x00;
T55xx_Timing.m[i].write_3 = 0x00;
}
if (c->m[i].read_gap != 0)
T55xx_Timing.m[i].read_gap = c->m[i].read_gap;
} }
printT55xxConfig(); printT55xxConfig();
@ -203,7 +297,6 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
return; return;
} }
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
@ -215,21 +308,23 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN);
// delete old configuration
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xD); Flash_Erase4k(3, 0xD);
// write new
res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) {
DbpString("T55XX Config save success"); DbpString("T55XX Config save " _GREEN_("success"));
} }
BigBuf_free(); BigBuf_free();
#endif #endif
} }
t55xx_config *getT55xxConfig(void) { t55xx_configurations_t *getT55xxConfig(void) {
return &T55xx_Timing;//_FixedBit; return &T55xx_Timing;//_FixedBit;
} }
@ -308,7 +403,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
} }
// hack2 needed--- it appears to take about 8-16us to turn the antenna back on // hack2 needed--- it appears to take about 8-16us to turn the antenna back on
// leading to ~ 1 to 2 125khz samples extra in every off period // leading to ~ 1 to 2 125kHz samples extra in every off period
// so we should test for last 0 before next 1 and reduce period_0 by this extra amount... // so we should test for last 0 before next 1 and reduce period_0 by this extra amount...
// but is this time different for every antenna or other hw builds??? more testing needed // but is this time different for every antenna or other hw builds??? more testing needed
@ -366,7 +461,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
// Turn off antenna // Turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// tell client we are done // tell client we are done
reply_ng(CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_MOD_THEN_ACQ_RAW_ADC, PM3_SUCCESS, NULL, 0);
} }
/* blank r/w tag data stream /* blank r/w tag data stream
@ -381,9 +476,9 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
void ReadTItag(void) { void ReadTItag(void) {
StartTicks(); StartTicks();
// some hardcoded initial params // some hardcoded initial params
// when we read a TI tag we sample the zerocross line at 2Mhz // when we read a TI tag we sample the zerocross line at 2MHz
// TI tags modulate a 1 as 16 cycles of 123.2Khz // TI tags modulate a 1 as 16 cycles of 123.2kHz
// TI tags modulate a 0 as 16 cycles of 134.2Khz // TI tags modulate a 0 as 16 cycles of 134.2kHz
#define FSAMPLE 2000000 #define FSAMPLE 2000000
#define FREQLO 123200 #define FREQLO 123200
#define FREQHI 134200 #define FREQHI 134200
@ -399,9 +494,9 @@ void ReadTItag(void) {
// when to tell if we're close enough to one freq or another // when to tell if we're close enough to one freq or another
uint32_t threshold = (sampleslo - sampleshi + 1) >> 1; uint32_t threshold = (sampleslo - sampleshi + 1) >> 1;
// TI tags charge at 134.2Khz // TI tags charge at 134.2kHz
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
// Place FPGA in passthrough mode, in this mode the CROSS_LO line // Place FPGA in passthrough mode, in this mode the CROSS_LO line
// connects to SSP_DIN and the SSP_DOUT logic level controls // connects to SSP_DIN and the SSP_DOUT logic level controls
@ -627,8 +722,8 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) {
} }
Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc); Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc);
// TI tags charge at 134.2Khz // TI tags charge at 134.2kHz
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
// Place FPGA in passthrough mode, in this mode the CROSS_LO line // Place FPGA in passthrough mode, in this mode the CROSS_LO line
// connects to SSP_DIN and the SSP_DOUT logic level controls // connects to SSP_DIN and the SSP_DOUT logic level controls
// whether we're modulating the antenna (high) // whether we're modulating the antenna (high)
@ -701,9 +796,9 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl
sample_config *sc = getSamplingConfig(); sample_config *sc = getSamplingConfig();
if ((sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255)) if ((sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255))
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
else if (sc->divisor == 0) else if (sc->divisor == 0)
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
else else
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
@ -946,7 +1041,7 @@ void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles) {
void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) { void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol) {
CmdHIDsimTAGEx(hi, lo, ledcontrol, -1); CmdHIDsimTAGEx(hi, lo, ledcontrol, -1);
reply_ng(CMD_HID_SIM_TAG, PM3_EOPABORTED, NULL, 0); reply_ng(CMD_LF_HID_SIMULATE, PM3_EOPABORTED, NULL, 0);
} }
// prepare a waveform pattern in the buffer based on the ID given then // prepare a waveform pattern in the buffer based on the ID given then
@ -984,7 +1079,7 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk,
if (ledcontrol) LED_A_ON(); if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol); SimulateTagLowFrequency(n, 0, ledcontrol);
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
reply_ng(CMD_FSK_SIM_TAG, PM3_EOPABORTED, NULL, 0); reply_ng(CMD_LF_FSK_SIMULATE, PM3_EOPABORTED, NULL, 0);
} }
// compose ask waveform for one bit(ASK) // compose ask waveform for one bit(ASK)
@ -1073,7 +1168,7 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c
if (ledcontrol) LED_A_ON(); if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol); SimulateTagLowFrequency(n, 0, ledcontrol);
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
reply_ng(CMD_ASK_SIM_TAG, PM3_EOPABORTED, NULL, 0); reply_ng(CMD_LF_ASK_SIMULATE, PM3_EOPABORTED, NULL, 0);
} }
//carrier can be 2,4 or 8 //carrier can be 2,4 or 8
@ -1120,7 +1215,7 @@ void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, u
if (ledcontrol) LED_A_ON(); if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol); SimulateTagLowFrequency(n, 0, ledcontrol);
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
reply_ng(CMD_PSK_SIM_TAG, PM3_EOPABORTED, NULL, 0); reply_ng(CMD_LF_PSK_SIMULATE, PM3_EOPABORTED, NULL, 0);
} }
// loop to get raw HID waveform then FSK demodulate the TAG ID from it // loop to get raw HID waveform then FSK demodulate the TAG ID from it
@ -1129,7 +1224,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
size_t size; size_t size;
uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t hi2 = 0, hi = 0, lo = 0;
int dummyIdx = 0; int dummyIdx = 0;
// Configure to go in 125Khz listen mode // Configure to go in 125kHz listen mode
LFSetupFPGAForADC(95, true); LFSetupFPGAForADC(95, true);
//clear read buffer //clear read buffer
@ -1380,7 +1475,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
BigBuf_Clear_keep_EM(); BigBuf_Clear_keep_EM();
// Configure to go in 125Khz listen mode // Configure to go in 125kHz listen mode
LFSetupFPGAForADC(95, true); LFSetupFPGAForADC(95, true);
while (!BUTTON_PRESS() && !data_available()) { while (!BUTTON_PRESS() && !data_available()) {
@ -1478,37 +1573,35 @@ void TurnReadLF_off(uint32_t delay) {
} }
// Macro for code readability // Macro for code readability
#define BitStream_Byte(X) ((X) >> 3) #define BITSTREAM_BYTE(x) ((x) >> 3) // iceman note: isn't this NIBBLE???
#define BitStream_Bit(X) ((X) & 7) #define BITSTREAM_BIT(x) ((x) & 7)
#define t55_llr_ref (136 * 8)
#define t55_send_PwdMode (arg & 0x01) #define T55_LLR_REF (136 * 8)
#define t55_send_Page ((arg & 0x02) >> 1)
#define t55_send_TestMode ((arg & 0x04) >> 2)
#define t55_send_RegReadMode ((arg & 0x20) >> 5)
#define t55_send_ReadCmd ((arg & 0x40) >> 6)
#define t55_send_Reset ((arg & 0x80) >> 7)
// Write one bit to chip // Write one bit to chip
void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
// Dbprintf ("%d",bit);
// If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0
switch (bit) { switch (bit) {
case 0 : case 0 :
// send bit 0/00
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0);
break; // Send bit 0/00 break;
case 1 : case 1 :
// send bit 1/01
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1);
break; // Send bit 1/01 break;
case 2 : case 2 :
// send bits 10 (1 of 4)
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2);
break; // Send bits 10 (1 of 4) break;
case 3 : case 3 :
// send bits 11 (1 of 4)
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3);
break; // Send bits 11 (1 of 4) break;
case 4 : case 4 :
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + t55_llr_ref); // send Long Leading Reference
break; // Send Long Leading Reference TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + T55_LLR_REF);
break;
} }
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1522,94 +1615,110 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
// num_bits - how many bits (low x bits of data) Max 32 bits at a time // num_bits - how many bits (low x bits of data) Max 32 bits at a time
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
// returns "Next" bit offset / bits stored (for next store) // returns "Next" bit offset / bits stored (for next store)
uint8_t T55xx_SetBits(uint8_t *BitStream, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) {
int8_t offset; int8_t offset;
int8_t NextOffset = start_offset; int8_t next_offset = start_offset;
// Check if data will fit. // Check if data will fit.
if ((start_offset + num_bits) <= (max_len * 8)) { if ((start_offset + num_bits) <= (max_len * 8)) {
// Loop through the data and store // Loop through the data and store
for (offset = (num_bits - 1); offset >= 0; offset--) { for (offset = (num_bits - 1); offset >= 0; offset--) {
if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1 if ((data >> offset) & 1)
else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0 bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1
else
bs[BITSTREAM_BYTE(next_offset)] &= (0xff ^ (1 << BITSTREAM_BIT(next_offset))); // Set 0
NextOffset++; next_offset++;
} }
} else { } else {
// Note: This should never happen unless some code changes cause it. // Note: This should never happen unless some code changes cause it.
// So short message for coders when testing. // So short message for coders when testing.
Dbprintf("T55 too many bits"); Dbprintf(_RED_("T55 too many bits"));
} }
return NextOffset; return next_offset;
} }
// Send one downlink command to the card // Send one downlink command to the card
// void T55xx_SendCMD (uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) {
void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) {
/* /*
arg bits arg bits
xxxx xxxxxxx1 0x001 PwdMode xxxx xxxxxxx1 0x001 password mode (Y/N)
xxxx xxxxxx1x 0x002 Page xxxx xxxxxx1x 0x002 page (0|1)
xxxx xxxxx1xx 0x004 testMode xxxx xxxxx1xx 0x004 test mode (Y/N)
xxxx xxx11xxx 0x018 downlink mode xxxx xxx11xxx 0x018 selected downlink mode (0|1|2|3|)
xxxx xx1xxxxx 0x020 !reg_readmode xxxx xx1xxxxx 0x020 !reg_readmode (ICEMAN ?? Why use negative in the bool ??)
xxxx x1xxxxxx 0x040 called for a read, so no data packet xxxx x1xxxxxx 0x040 called for a read, so no data packet (Y/N)
xxxx 1xxxxxxx 0x080 reset xxxx 1xxxxxxx 0x080 reset (Y/N)
xxx1 xxxxxxxx 0x100 brute force xxx1 xxxxxxxx 0x100 brute force (Y/N)
111x xxxxxxxx 0xE00 Block 111x xxxxxxxx 0xE00 block to write (0-7)
*/ */
bool t55_send_pwdmode = (arg & 0x1);
bool t55_send_page = ((arg >> 1) & 0x1);
bool t55_send_testmode = ((arg >> 2) & 0x1);
bool t55_send_regreadmode = ((arg >> 5) & 0x1);
bool t55_send_readcmd = ((arg >> 6) & 0x1);
bool t55_send_reset = ((arg >> 7) & 0x1);
bool t55_brute_mem = ((arg >> 8) & 0x1);
uint8_t downlink_mode = (arg >> 3) & 0x03; uint8_t downlink_mode = (arg >> 3) & 0x03;
uint8_t i = 0; uint8_t block_no = (arg >> 9) & 0x07;
uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
uint8_t BitStreamLen = 0;
uint8_t SendBits;
uint8_t start_wait = 4;
bool brute_mem = (arg & 0x100);
uint8_t Block = (arg >> 9) & 0x07;
if (brute_mem) start_wait = 0; // no startup delay when in bruteforce command
uint8_t start_wait = (t55_brute_mem) ? 0 : 4;
// Build Bit Stream to send. // Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
memset(BitStream, 0x00, sizeof(BitStream)); uint8_t bs[10];
memset(bs, 0x00, sizeof(bs));
BitStreamLen = 0; // Ensure 0 bit index to start. uint8_t len = 0;
// Add Leading 0 and 1 of 4 reference bit // build bit stream to send.
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4))
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream));
// Add extra reference 0 for 1 of 4 // add Leading 0
if (downlink_mode == T55xx_DLMode_1of4) if (downlink_mode == T55XX_DLMODE_LEADING_ZERO)
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
// Add Opcode // add 1 of 4 reference bit
if (t55_send_Reset) { if (downlink_mode == T55XX_DLMODE_1OF4) {
// Reset : r*) 00 len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); // add extra zero
len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
}
// add Opcode
if (t55_send_reset) {
// reset : r*) 00
len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs));
} else { } else {
if (t55_send_TestMode) Dbprintf("TestMODE");
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 0 : 1, 1, sizeof(BitStream)); if (t55_send_testmode)
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 1 : t55_send_Page, 1, sizeof(BitStream)); Dbprintf(_YELLOW_("Using Test Mode"));
//if (PwdMode) {
if (t55_send_PwdMode) { len = T55xx_SetBits(bs, len, t55_send_testmode ? 0 : 1, 1, sizeof(bs));
len = T55xx_SetBits(bs, len, t55_send_testmode ? 1 : t55_send_page, 1, sizeof(bs));
if (t55_send_pwdmode) {
// Leading 0 and 1 of 4 00 fixed bits if passsword used // Leading 0 and 1 of 4 00 fixed bits if passsword used
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) { if ((downlink_mode == T55XX_DLMODE_LEADING_ZERO) || (downlink_mode == T55XX_DLMODE_1OF4)) {
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs));
} }
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Pwd, 32, sizeof(BitStream)); len = T55xx_SetBits(bs, len, pwd, 32, sizeof(bs));
} }
// Add Lock bit 0 // Add Lock bit 0
if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); if (t55_send_regreadmode == false)
len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
// Add Data if a write command // Add Data if a write command
if (!t55_send_ReadCmd) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Data, 32, sizeof(BitStream)); if (t55_send_readcmd == false)
len = T55xx_SetBits(bs, len, data, 32, sizeof(bs));
// Add Address // Add Address
if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Block, 3, sizeof(BitStream)); if (t55_send_regreadmode == false)
len = T55xx_SetBits(bs, len, block_no, 3, sizeof(bs));
} }
// Send Bits to T55xx // Send Bits to T55xx
@ -1621,22 +1730,23 @@ void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) {
// Trigger T55x7 in mode. // Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); WaitUS(T55xx_Timing.m[downlink_mode].start_gap);
// If long leading 0 send long reference pulse // If long leading 0 send long reference pulse
if (downlink_mode == T55xx_DLMode_LLR) if (downlink_mode == T55XX_DLMODE_LLR)
T55xxWriteBit(T55xx_LongLeadingReference, downlink_mode);//Timing); // Send Long Leading Start Reference T55xxWriteBit(T55XX_LONGLEADINGREFERENCE, downlink_mode);//Timing); // Send Long Leading Start Reference
if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time uint8_t sendbits;
for (i = 0; i < BitStreamLen - 1; i += 2) { if ((downlink_mode == T55XX_DLMODE_1OF4) && (len > 0)) { // 1 of 4 need to send 2 bits at a time
SendBits = (BitStream[BitStream_Byte(i)] >> (BitStream_Bit(i)) & 1) << 1; // Bit i for (uint8_t i = 0; i < len - 1; i += 2) {
SendBits += (BitStream[BitStream_Byte(i + 1)] >> (BitStream_Bit(i + 1)) & 1); // Bit i+1; sendbits = (bs[BITSTREAM_BYTE(i)] >> (BITSTREAM_BIT(i)) & 1) << 1; // Bit i
T55xxWriteBit(SendBits & 3, downlink_mode);//Timing); sendbits += (bs[BITSTREAM_BYTE(i + 1)] >> (BITSTREAM_BIT(i + 1)) & 1); // Bit i+1;
T55xxWriteBit(sendbits & 3, downlink_mode);
} }
} else { } else {
for (i = 0; i < BitStreamLen; i++) { for (uint8_t i = 0; i < len; i++) {
SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i)); sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i));
T55xxWriteBit(SendBits & 1, downlink_mode);//Timing); T55xxWriteBit(sendbits & 1, downlink_mode);
} }
} }
} }
@ -1722,7 +1832,7 @@ void T55xxWriteBlock(uint8_t *data) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// cmd_send(CMD_ACK,0,0,0,0,0); // cmd_send(CMD_ACK,0,0,0,0,0);
reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_T55XX_WRITEBL, PM3_SUCCESS, NULL, 0);
LED_A_OFF(); LED_A_OFF();
} }
@ -1731,7 +1841,7 @@ void T55xxWriteBlock(uint8_t *data) {
void T55xxWriteBlock(uint8_t *data) { void T55xxWriteBlock(uint8_t *data) {
t55xx_write_block_t *c = (t55xx_write_block_t *)data; t55xx_write_block_t *c = (t55xx_write_block_t *)data;
T55xxWriteBlockExt(c->data, c->blockno, c->pwd, c->flags); T55xxWriteBlockExt(c->data, c->blockno, c->pwd, c->flags);
// reply_ng(CMD_T55XX_WRITE_BLOCK, PM3_SUCCESS, NULL, 0); // reply_ng(CMD_LF_T55XX_WRITEBL, PM3_SUCCESS, NULL, 0);
} }
*/ */
/* /*
@ -1783,7 +1893,7 @@ bool brute_mem = (flags & 0x0100) >> 8;
// Turn the field off // Turn the field off
if (!brute_mem) { if (!brute_mem) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_T55XX_READ_BLOCK, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_T55XX_READBL, PM3_SUCCESS, NULL, 0);
LED_A_OFF(); LED_A_OFF();
} }
} }
@ -1843,7 +1953,7 @@ void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block,
// Turn the field off // Turn the field off
if (!brute_mem) { if (!brute_mem) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_T55XX_READ_BLOCK, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_T55XX_READBL, PM3_SUCCESS, NULL, 0);
LED_A_OFF(); LED_A_OFF();
} }
@ -1941,12 +2051,12 @@ OUT:
LEDsoff(); LEDsoff();
} }
void T55xxWakeUp(uint32_t Pwd, uint8_t flags) { void T55xxWakeUp(uint32_t pwd, uint8_t flags) {
flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block
LED_B_ON(); LED_B_ON();
T55xx_SendCMD(0, Pwd, flags); T55xx_SendCMD(0, pwd, flags);
//-- Turn and leave field on to let the begin repeating transmission //-- Turn and leave field on to let the begin repeating transmission
TurnReadLFOn(20 * 1000); TurnReadLFOn(20 * 1000);
@ -2173,7 +2283,7 @@ uint8_t *fwd_write_ptr; //forwardlink bit pointer
//==================================================================== //====================================================================
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// VALUES TAKEN FROM EM4x function: SendForward // VALUES TAKEN FROM EM4x function: SendForward
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) // START_GAP = 440; (55*8) cycles at 125kHz (8us = 1cycle)
// WRITE_GAP = 128; (16*8) // WRITE_GAP = 128; (16*8)
// WRITE_1 = 256 32*8; (32*8) // WRITE_1 = 256 32*8; (32*8)
@ -2331,7 +2441,7 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
DoPartialAcquisition(20, true, 6000, 1000); DoPartialAcquisition(20, true, 6000, 1000);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_EM4X_READ_WORD, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_EM4X_READWORD, PM3_SUCCESS, NULL, 0);
LED_A_OFF(); LED_A_OFF();
} }
@ -2364,7 +2474,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
DoPartialAcquisition(20, true, 6000, 1000); DoPartialAcquisition(20, true, 6000, 1000);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_EM4X_WRITE_WORD, PM3_SUCCESS, NULL, 0); reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_SUCCESS, NULL, 0);
LED_A_OFF(); LED_A_OFF();
} }

69
armsrc/lfops.h Normal file
View file

@ -0,0 +1,69 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __LFOPS_H
#define __LFOPS_H
#include "common.h"
#include "pm3_cmd.h" // struct
extern uint8_t decimation;
extern uint8_t bits_per_sample ;
extern bool averaging;
void AcquireRawAdcSamples125k(int divisor);
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
void ReadTItag(void);
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
void AcquireTiType(void);
void AcquireRawBitsTI(void);
void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycles);
void SimulateTagLowFrequency(int period, int gap, bool ledcontrol);
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, bool ledcontrol, int numcycles);
void CmdHIDsimTAG(uint32_t hi, uint32_t lo, bool ledcontrol);
void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk, uint16_t bitslen, uint8_t *bits, bool ledcontrol);
void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
void CmdPSKsimTag(uint8_t carrier, uint8_t invert, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol);
void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26
void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol);
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5);
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
void T55xxResetRead(uint8_t flags);
//id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
void T55xxWriteBlock(uint8_t *data);
// void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode);
void T55xxWakeUp(uint32_t pwd, uint8_t flags);
void T55xx_ChkPwds(uint8_t flags);
void TurnReadLFOn(uint32_t delay);
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd);
void Cotag(uint32_t arg0);
void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c);
t55xx_configurations_t *getT55xxConfig(void);
void printT55xxConfig(void);
void loadT55xxConfig(void);
#endif

View file

@ -8,12 +8,20 @@
#include "lfsampling.h" #include "lfsampling.h"
#include "proxmark3_arm.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "lfdemod.h"
/* /*
Default LF config is set to: Default LF config is set to:
decimation = 1 (we keep 1 out of 1 samples) decimation = 1 (we keep 1 out of 1 samples)
bits_per_sample = 8 bits_per_sample = 8
averaging = YES averaging = YES
divisor = 95 (125khz) divisor = 95 (125kHz)
trigger_threshold = 0 trigger_threshold = 0
*/ */
sample_config config = { 1, 8, 1, 95, 0 } ; sample_config config = { 1, 8, 1, 95, 0 } ;
@ -83,9 +91,9 @@ void pushBit(BitstreamOut *stream, uint8_t bit) {
void LFSetupFPGAForADC(int divisor, bool lf_field) { void LFSetupFPGAForADC(int divisor, bool lf_field) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if ((divisor == 1) || (divisor < 0) || (divisor > 255)) if ((divisor == 1) || (divisor < 0) || (divisor > 255))
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
else if (divisor == 0) else if (divisor == 0)
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
else else
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);

View file

@ -1,12 +1,8 @@
#ifndef __LFSAMPLING_H #ifndef __LFSAMPLING_H
#define __LFSAMPLING_H #define __LFSAMPLING_H
#include "proxmark3.h" #include "common.h"
#include "apps.h" #include "pm3_cmd.h"
#include "util.h"
#include "string.h"
#include "usb_cdc.h" // for usb_poll_validate_length
#include "ticks.h" // for StartTicks
typedef struct BitstreamOut BitstreamOut; typedef struct BitstreamOut BitstreamOut;
@ -82,5 +78,4 @@ sample_config *getSamplingConfig();
void printConfig(); void printConfig();
#endif // __LFSAMPLING_H #endif // __LFSAMPLING_H

View file

@ -15,9 +15,23 @@
#include "mifarecmd.h" #include "mifarecmd.h"
#include <inttypes.h>
#include "pmflash.h" #include "pmflash.h"
#include "proxmark3_arm.h"
#include "string.h"
#include "mifareutil.h"
#include "protocols.h"
#include "parity.h"
#include "BigBuf.h"
#include "cmd.h"
#include "flashmem.h"
#include "fpgaloader.h"
#include "iso14443a.h"
#include "mifaredesfire.h"
#include "util.h"
#include "commonutil.h"
#include "crc16.h"
#include "dbprint.h"
#include "ticks.h"
#ifndef HARDNESTED_AUTHENTICATION_TIMEOUT #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT
# define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) # define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
@ -94,7 +108,7 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) {
if (DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); if (DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
LED_B_ON(); LED_B_ON();
reply_ng(CMD_MIFARE_READBL, status, dataoutbuf, 16); reply_ng(CMD_HF_MIFARE_READBL, status, dataoutbuf, 16);
LED_B_OFF(); LED_B_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1495,7 +1509,7 @@ OUT:
uint16_t bar = 0; uint16_t bar = 0;
uint8_t j = 0; uint8_t j = 0;
for (uint8_t m = 64; m < sizeof(found); m++) { for (uint8_t m = 64; m < ARRAYLEN(found); m++) {
bar |= ((uint16_t)(found[m] & 1) << j++); bar |= ((uint16_t)(found[m] & 1) << j++);
} }
@ -1601,7 +1615,7 @@ void MifareChkKeys(uint8_t *datain) {
LED_B_ON(); LED_B_ON();
reply_ng(CMD_MIFARE_CHKKEYS, PM3_SUCCESS, (uint8_t *)&keyresult, sizeof(keyresult)); reply_ng(CMD_HF_MIFARE_CHKKEYS, PM3_SUCCESS, (uint8_t *)&keyresult, sizeof(keyresult));
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
@ -1637,7 +1651,7 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) {
// //
size_t size = blockcnt * 16; size_t size = blockcnt * 16;
if (size > PM3_CMD_DATA_SIZE) { if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0); reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return; return;
} }
@ -1646,7 +1660,7 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) {
emlGetMem(buf, blockno, blockcnt); // data, block num, blocks count (max 4) emlGetMem(buf, blockno, blockcnt); // data, block num, blocks count (max 4)
LED_B_ON(); LED_B_ON();
reply_ng(CMD_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size); reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size);
LED_B_OFF(); LED_B_OFF();
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
} }
@ -1990,7 +2004,7 @@ TEST2:
OUT: OUT:
data[0] = isGen; data[0] = isGen;
reply_ng(CMD_MIFARE_CIDENT, PM3_SUCCESS, data, sizeof(data)); reply_ng(CMD_HF_MIFARE_CIDENT, PM3_SUCCESS, data, sizeof(data));
// turns off // turns off
OnSuccessMagic(); OnSuccessMagic();
BigBuf_free(); BigBuf_free();
@ -2059,7 +2073,7 @@ void MifareSetMod(uint8_t *datain) {
crypto1_destroy(pcs); crypto1_destroy(pcs);
LED_B_ON(); LED_B_ON();
reply_ng(CMD_MIFARE_SETMOD, isOK, NULL, 0); reply_ng(CMD_HF_MIFARE_SETMOD, isOK, NULL, 0);
LED_B_OFF(); LED_B_OFF();

View file

@ -1,27 +1,52 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Merlok - June 2011 // Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans - May 2008 // Gerhard de Koning Gans, April 2008, May 2011
// Hagen Fritsch - June 2010
// //
// This code is licensed to you under the terms of the GNU GPL, version 2 or, // 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 // at your option, any later version. See the LICENSE.txt file for the text of
// the license. // the license.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Routines to support ISO 14443 type A. // Definitions internal to the app source.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __MIFARECMD_H #ifndef __MIFARECMD_H
#define __MIFARECMD_H #define __MIFARECMD_H
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
#include "iso14443a.h"
#include "crapto1/crapto1.h"
#include "mifareutil.h"
#include "common.h" #include "common.h"
#include "crc.h"
#include "protocols.h" void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain);
#include "parity.h"
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes);
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
void MifareAcquireNonces(uint32_t arg0, uint32_t flags);
void MifareChkKeys(uint8_t *datain);
void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareEMemClr(void);
void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain);
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
int MifareECardLoad(uint32_t arg0, uint32_t arg1);
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card?
void MifareSetMod(uint8_t *datain);
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
void OnSuccessMagic();
void OnErrorMagic(uint8_t reason);
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
//void RAMFUNC SniffMifare(uint8_t param);
void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain);
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
#endif #endif

View file

@ -1,5 +1,20 @@
#include "mifaredesfire.h" #include "mifaredesfire.h"
#include "common.h"
#include "proxmark3_arm.h"
#include "string.h"
#include "BigBuf.h"
#include "desfire_key.h"
#include "mifareutil.h"
#include "des.h"
#include "cmd.h"
#include "dbprint.h"
#include "fpgaloader.h"
#include "iso14443a.h"
#include "crc16.h"
#include "mbedtls/aes.h"
#include "commonutil.h"
#define MAX_APPLICATION_COUNT 28 #define MAX_APPLICATION_COUNT 28
#define MAX_FILE_COUNT 16 #define MAX_FILE_COUNT 16
#define MAX_DESFIRE_FRAME_SIZE 60 #define MAX_DESFIRE_FRAME_SIZE 60

View file

@ -1,13 +1,26 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, Aug 2005
// Gerhard de Koning Gans, April 2008, May 2011
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Definitions internal to the app source.
//-----------------------------------------------------------------------------
#ifndef __MIFAREDESFIRE_H #ifndef __MIFAREDESFIRE_H
#define __MIFAREDESFIRE_H #define __MIFAREDESFIRE_H
#include "common.h" #include "common.h"
#include "proxmark3.h"
#include "apps.h" bool InitDesfireCard();
#include "string.h" void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain);
#include "BigBuf.h" void MifareDesfireGetInformation();
#include "iso14443a.h" void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
#include "desfire_key.h" void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain);
#include "mifareutil.h" int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
#include "des.h" size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout);
void OnSuccess();
void OnError(uint8_t reason);
#endif #endif

View file

@ -20,19 +20,24 @@
// /!\ Printing Debug message is disrupting emulation, // /!\ Printing Debug message is disrupting emulation,
// Only use with caution during debugging // Only use with caution during debugging
#include "mifaresim.h"
#include <inttypes.h>
#include "iso14443a.h" #include "iso14443a.h"
#include "mifaresim.h"
#include "crapto1/crapto1.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "string.h" #include "string.h"
#include "mifareutil.h" #include "mifareutil.h"
#include "fpgaloader.h" #include "fpgaloader.h"
#include "proxmark3.h" #include "proxmark3_arm.h"
#include "usb_cdc.h"
#include "cmd.h" #include "cmd.h"
#include "protocols.h" #include "protocols.h"
#include "apps.h" #include "appmain.h"
#include "util.h"
#include "commonutil.h"
#include "crc16.h"
#include "dbprint.h"
#include "ticks.h"
static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) { static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
uint8_t sector_trailer[16]; uint8_t sector_trailer[16];
@ -163,7 +168,7 @@ static bool IsAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
} }
} }
static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) { static bool MifareSimInit(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf // SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
// ATQA // ATQA
@ -250,21 +255,21 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
if ((flags & FLAG_MF_MINI) == FLAG_MF_MINI) { if ((flags & FLAG_MF_MINI) == FLAG_MF_MINI) {
memcpy(rATQA, rATQA_Mini, sizeof(rATQA)); memcpy(rATQA, rATQA_Mini, sizeof(rATQA));
rSAK[0] = rSAK_Mini; rSAK[0] = rSAK_Mini;
Dbprintf("Mifare Mini"); if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare Mini ATQA/SAK");
} else if ((flags & FLAG_MF_1K) == FLAG_MF_1K) { } else if ((flags & FLAG_MF_1K) == FLAG_MF_1K) {
memcpy(rATQA, rATQA_1k, sizeof(rATQA)); memcpy(rATQA, rATQA_1k, sizeof(rATQA));
rSAK[0] = rSAK_1k; rSAK[0] = rSAK_1k;
Dbprintf("Mifare 1K"); if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK");
} else if ((flags & FLAG_MF_2K) == FLAG_MF_2K) { } else if ((flags & FLAG_MF_2K) == FLAG_MF_2K) {
memcpy(rATQA, rATQA_2k, sizeof(rATQA)); memcpy(rATQA, rATQA_2k, sizeof(rATQA));
rSAK[0] = rSAK_2k; rSAK[0] = rSAK_2k;
*rats = rRATS; *rats = rRATS;
*rats_len = sizeof(rRATS); *rats_len = sizeof(rRATS);
Dbprintf("Mifare 2K with RATS support"); if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare 2K ATQA/SAK with RATS support");
} else if ((flags & FLAG_MF_4K) == FLAG_MF_4K) { } else if ((flags & FLAG_MF_4K) == FLAG_MF_4K) {
memcpy(rATQA, rATQA_4k, sizeof(rATQA)); memcpy(rATQA, rATQA_4k, sizeof(rATQA));
rSAK[0] = rSAK_4k; rSAK[0] = rSAK_4k;
Dbprintf("Mifare 4K"); if (DBGLEVEL > DBG_NONE) Dbprintf("Enforcing Mifare 4K ATQA/SAK");
} }
// Prepare UID arrays // Prepare UID arrays
@ -279,7 +284,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
*cuid = bytes_to_num(rUIDBCC1, 4); *cuid = bytes_to_num(rUIDBCC1, 4);
// BCC // BCC
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
if (DBGLEVEL >= DBG_NONE) { if (DBGLEVEL > DBG_NONE) {
Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]); Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
} }
@ -300,7 +305,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
// BCC // BCC
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
if (DBGLEVEL >= DBG_NONE) { if (DBGLEVEL > DBG_NONE) {
Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x", Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]); rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]);
} }
@ -326,7 +331,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3]; rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3];
if (DBGLEVEL >= DBG_NONE) { if (DBGLEVEL > DBG_NONE) {
Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3],
@ -340,6 +345,17 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
Dbprintf("[-] ERROR: UID size not defined"); Dbprintf("[-] ERROR: UID size not defined");
return false; return false;
} }
if (flags & FLAG_FORCED_ATQA) {
rATQA[0] = atqa >> 8;
rATQA[1] = atqa & 0xff;
}
if (flags & FLAG_FORCED_SAK) {
rSAK[0] = sak;
}
if (DBGLEVEL > DBG_NONE) {
Dbprintf("ATQA : %02X %02X", rATQA[1], rATQA[0]);
Dbprintf("SAK : %02X", rSAK[0]);
}
// clone UIDs for byte-frame anti-collision multiple tag selection procedure // clone UIDs for byte-frame anti-collision multiple tag selection procedure
memcpy(rUIDBCC1b4, &rUIDBCC1[1], 4); memcpy(rUIDBCC1b4, &rUIDBCC1[1], 4);
@ -432,7 +448,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ... *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted) * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
*/ */
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) { void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak) {
tag_response_info_t *responses; tag_response_info_t *responses;
uint8_t cardSTATE = MFEMUL_NOFIELD; uint8_t cardSTATE = MFEMUL_NOFIELD;
uint8_t uid_len = 0; // 4,7, 10 uint8_t uid_len = 0; // 4,7, 10
@ -495,12 +511,12 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
uint8_t rAUTH_NT_keystream[4]; uint8_t rAUTH_NT_keystream[4];
uint32_t nonce = 0; uint32_t nonce = 0;
tUart *uart = GetUart(); tUart14a *uart = GetUart14a();
// free eventually allocated BigBuf memory but keep Emulator Memory // free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
if (MifareSimInit(flags, datain, &responses, &cuid, &uid_len, &rats, &rats_len) == false) { if (MifareSimInit(flags, datain, atqa, sak, &responses, &cuid, &uid_len, &rats, &rats_len) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
return; return;
} }
@ -1221,7 +1237,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
if ((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE) { // Interactive mode flag, means we need to send ACK if ((flags & FLAG_INTERACTIVE) == FLAG_INTERACTIVE) { // Interactive mode flag, means we need to send ACK
//Send the collected ar_nr in the response //Send the collected ar_nr in the response
reply_old(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp)); reply_old(CMD_ACK, CMD_HF_MIFARE_SIMULATE, button_pushed, 0, &ar_nr_resp, sizeof(ar_nr_resp));
} }
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

View file

@ -13,14 +13,12 @@
#ifndef __MIFARESIM_H #ifndef __MIFARESIM_H
#define __MIFARESIM_H #define __MIFARESIM_H
#include <stdint.h> #include "common.h"
#ifndef CheckCrc14A #ifndef CheckCrc14A
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) # define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
#endif #endif
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain);
#define AC_DATA_READ 0 #define AC_DATA_READ 0
#define AC_DATA_WRITE 1 #define AC_DATA_WRITE 1
#define AC_DATA_INC 2 #define AC_DATA_INC 2
@ -36,4 +34,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain);
#define AUTHKEYB 1 #define AUTHKEYB 1
#define AUTHKEYNONE 0xff #define AUTHKEYNONE 0xff
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak);
#endif #endif

View file

@ -68,10 +68,10 @@ void RAMFUNC SniffMifare(uint8_t param) {
// Set up the demodulator for tag -> reader responses. // Set up the demodulator for tag -> reader responses.
DemodInit(receivedResp, receivedRespPar); Demod14aInit(receivedResp, receivedRespPar);
// Set up the demodulator for the reader -> tag commands // Set up the demodulator for the reader -> tag commands
UartInit(receivedCmd, receivedCmdPar); Uart14aInit(receivedCmd, receivedCmdPar);
// Setup and start DMA. // Setup and start DMA.
// set transfer address and number of bytes. Start transfer. // set transfer address and number of bytes. Start transfer.
@ -80,8 +80,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
return; return;
} }
tUart *uart = GetUart(); tUart14a *uart = GetUart14a();
tDemod *demod = GetDemod(); tDemod14a *demod = GetDemod14a();
MfSniffInit(); MfSniffInit();
@ -149,10 +149,10 @@ void RAMFUNC SniffMifare(uint8_t param) {
uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4); uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4);
if (MillerDecoding(readerbyte, (sniffCounter - 1) * 4)) { if (MillerDecoding(readerbyte, (sniffCounter - 1) * 4)) {
LogTrace(receivedCmd, uart->len, 0, 0, NULL, true); LogTrace(receivedCmd, uart->len, 0, 0, NULL, true);
DemodReset(); Demod14aReset();
UartReset(); Uart14aReset();
} }
ReaderIsActive = (uart->state != STATE_UNSYNCD); ReaderIsActive = (uart->state != STATE_14A_UNSYNCD);
} }
// no need to try decoding tag data if the reader is sending // no need to try decoding tag data if the reader is sending
@ -160,10 +160,10 @@ void RAMFUNC SniffMifare(uint8_t param) {
uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F); uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F);
if (ManchesterDecoding(tagbyte, 0, (sniffCounter - 1) * 4)) { if (ManchesterDecoding(tagbyte, 0, (sniffCounter - 1) * 4)) {
LogTrace(receivedResp, demod->len, 0, 0, NULL, false); LogTrace(receivedResp, demod->len, 0, 0, NULL, false);
DemodReset(); Demod14aReset();
UartReset(); Uart14aReset();
} }
TagIsActive = (demod->state != DEMOD_UNSYNCD); TagIsActive = (demod->state != DEMOD_14A_UNSYNCD);
} }
} }
previous_data = *data; previous_data = *data;

View file

@ -11,13 +11,6 @@
#ifndef __MIFARESNIFF_H #ifndef __MIFARESNIFF_H
#define __MIFARESNIFF_H #define __MIFARESNIFF_H
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
#include "iso14443a.h"
#include "crapto1/crapto1.h"
#include "mifareutil.h"
#include "common.h" #include "common.h"
#define SNF_INIT 0 #define SNF_INIT 0

View file

@ -9,6 +9,17 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "mifareutil.h" #include "mifareutil.h"
#include "string.h"
#include "BigBuf.h"
#include "iso14443a.h"
#include "ticks.h"
#include "dbprint.h"
#include "parity.h"
#include "commonutil.h"
#include "crc16.h"
#include "protocols.h"
#include "des.h"
int DBGLEVEL = DBG_ERROR; int DBGLEVEL = DBG_ERROR;
// crypto1 helpers // crypto1 helpers

View file

@ -12,14 +12,8 @@
#ifndef __MIFAREUTIL_H #ifndef __MIFAREUTIL_H
#define __MIFAREUTIL_H #define __MIFAREUTIL_H
#include "proxmark3.h" #include "common.h"
#include "apps.h"
#include "parity.h"
#include "util.h"
#include "string.h"
#include "iso14443a.h"
#include "crapto1/crapto1.h" #include "crapto1/crapto1.h"
#include "des.h"
// mifare authentication // mifare authentication
#define CRYPT_NONE 0 #define CRYPT_NONE 0

894
armsrc/nprintf.c Normal file
View file

@ -0,0 +1,894 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
// embedded systems with a very limited resources. These routines are thread
// safe and reentrant!
// Use this instead of the bloated standard/newlib printf cause these use
// malloc for printf (and may not be thread safe).
//
///////////////////////////////////////////////////////////////////////////////
#include "nprintf.h"
// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
// printf_config.h header file
// default: undefined
#ifdef PRINTF_INCLUDE_CONFIG_H
#include "printf_config.h"
#endif
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
// numeric number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_NTOA_BUFFER_SIZE
#define PRINTF_NTOA_BUFFER_SIZE 32U
#endif
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
// float number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_FTOA_BUFFER_SIZE
#define PRINTF_FTOA_BUFFER_SIZE 32U
#endif
// support for the floating point type (%f)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_SUPPORT_FLOAT
#endif
// support for exponential floating point notation (%e/%g)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_SUPPORT_EXPONENTIAL
#endif
// define the default floating point precision
// default: 6 digits
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
#endif
// define the largest float suitable to print with %f
// default: 1e9
#ifndef PRINTF_MAX_FLOAT
#define PRINTF_MAX_FLOAT 1e9
#endif
// support for the long long types (%llu or %p)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_SUPPORT_LONG_LONG
#endif
// support for the ptrdiff_t type (%t)
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_SUPPORT_PTRDIFF_T
#endif
///////////////////////////////////////////////////////////////////////////////
// internal flag definitions
#define FLAGS_ZEROPAD (1U << 0U)
#define FLAGS_LEFT (1U << 1U)
#define FLAGS_PLUS (1U << 2U)
#define FLAGS_SPACE (1U << 3U)
#define FLAGS_HASH (1U << 4U)
#define FLAGS_UPPERCASE (1U << 5U)
#define FLAGS_CHAR (1U << 6U)
#define FLAGS_SHORT (1U << 7U)
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
// import float.h for DBL_MAX
#if defined(PRINTF_SUPPORT_FLOAT)
#include <float.h>
#endif
// output function type
typedef void (*out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type
typedef struct {
void (*fct)(char character, void *arg);
void *arg;
} out_fct_wrap_type;
// internal buffer output
static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) {
if (idx < maxlen) {
((char *)buffer)[idx] = character;
}
}
// internal null output
static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) {
(void)character;
(void)buffer;
(void)idx;
(void)maxlen;
}
// internal _putchar wrapper
static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) {
(void)buffer;
(void)idx;
(void)maxlen;
if (character) {
_putchar(character);
}
}
// internal output function wrapper
static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) {
(void)idx;
(void)maxlen;
if (character) {
// buffer is the output fct pointer
((out_fct_wrap_type *)buffer)->fct(character, ((out_fct_wrap_type *)buffer)->arg);
}
}
// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char *str, size_t maxsize) {
const char *s;
for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str);
}
// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch) {
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char **str) {
unsigned int i = 0U;
while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}
// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width, unsigned int flags) {
const size_t start_idx = idx;
// pad spaces up to given width
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
for (size_t i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen);
}
}
// reverse string
while (len) {
out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
// internal itoa format
static size_t _ntoa_format(out_fct_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) {
// pad leading zeros
if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash
if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--;
if (len && (base == 16U)) {
len--;
}
}
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x';
} else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X';
} else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b';
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
} else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
} else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) {
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) {
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
#endif // PRINTF_SUPPORT_LONG_LONG
#if defined(PRINTF_SUPPORT_FLOAT)
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
#endif
// internal ftoa for fixed decimal floating point
static size_t _ftoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) {
char buf[PRINTF_FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0.0;
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
// test for special values
if (value != value)
return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
if (value < -DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
if (value > DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
#else
return 0U;
#endif
}
// test for negative
bool negative = false;
if (value < 0) {
negative = true;
value = 0 - value;
}
// set default precision, if not set explicitly
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
buf[len++] = '0';
prec--;
}
int whole = (int)value;
double tmp = (value - whole) * pow10[prec];
unsigned long frac = (unsigned long)tmp;
diff = tmp - frac;
if (diff > 0.5) {
++frac;
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
if (frac >= pow10[prec]) {
frac = 0;
++whole;
}
} else if (diff < 0.5) {
} else if ((frac == 0U) || (frac & 1U)) {
// if halfway, round up if odd OR if last digit is 0
++frac;
}
if (prec == 0U) {
diff = value - (double)whole;
if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
// exactly 0.5 and ODD, then round up
// 1.5 -> 2, but 2.5 -> 2
++whole;
}
} else {
unsigned int count = prec;
// now do fractional part, as an unsigned number
while (len < PRINTF_FTOA_BUFFER_SIZE) {
--count;
buf[len++] = (char)(48U + (frac % 10U));
if (!(frac /= 10U)) {
break;
}
}
// add extra 0s
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
buf[len++] = '0';
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
// add decimal
buf[len++] = '.';
}
}
// do whole part, number is reversed
while (len < PRINTF_FTOA_BUFFER_SIZE) {
buf[len++] = (char)(48 + (whole % 10));
if (!(whole /= 10)) {
break;
}
}
// pad leading zeros
if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
} else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
} else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
static size_t _etoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) {
// check for NaN and special values
if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
}
// determine the sign
const bool negative = value < 0;
if (negative) {
value = -value;
}
// default precision
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// determine the decimal exponent
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
union {
uint64_t U;
double F;
} conv;
conv.F = value;
int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
// now we want to compute 10^expval but we want to be sure it won't overflow
exp2 = (int)(expval * 3.321928094887362 + 0.5);
const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
const double z2 = z * z;
conv.U = (uint64_t)(exp2 + 1023) << 52U;
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
// correct for rounding errors
if (value < conv.F) {
expval--;
conv.F /= 10;
}
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
// in "%g" mode, "prec" is the number of *significant figures* not decimals
if (flags & FLAGS_ADAPT_EXP) {
// do we want to fall-back to "%f" mode?
if ((value >= 1e-4) && (value < 1e6)) {
if ((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
} else {
prec = 0;
}
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0U;
expval = 0;
} else {
// we use one sigfig for the whole part
if ((prec > 0) && (flags & FLAGS_PRECISION)) {
--prec;
}
}
}
// will everything fit?
unsigned int fwidth = width;
if (width > minwidth) {
// we didn't fall-back so subtract the characters required for the exponent
fwidth -= minwidth;
} else {
// not enough characters, so go back to default sizing
fwidth = 0U;
}
if ((flags & FLAGS_LEFT) && minwidth) {
// if we're padding on the right, DON'T pad the floating part
fwidth = 0U;
}
// rescale the float value
if (expval) {
value /= conv.F;
}
// output the floating part
const size_t start_idx = idx;
idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
// output the exponent part
if (minwidth) {
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
// internal vsnprintf
static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const char *format, va_list va) {
unsigned int flags, width, precision, n;
size_t idx = 0U;
if (!buffer) {
// use null output function
out = _out_null;
}
while (*format) {
// format specifier? %[flags][width][.precision][length]
if (*format != '%') {
// no
out(*format, buffer, idx++, maxlen);
format++;
continue;
} else {
// yes, evaluate it
format++;
}
// evaluate flags
flags = 0U;
do {
switch (*format) {
case '0':
flags |= FLAGS_ZEROPAD;
format++;
n = 1U;
break;
case '-':
flags |= FLAGS_LEFT;
format++;
n = 1U;
break;
case '+':
flags |= FLAGS_PLUS;
format++;
n = 1U;
break;
case ' ':
flags |= FLAGS_SPACE;
format++;
n = 1U;
break;
case '#':
flags |= FLAGS_HASH;
format++;
n = 1U;
break;
default :
n = 0U;
break;
}
} while (n);
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = _atoi(&format);
} else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int) - w;
} else {
width = (unsigned int)w;
}
format++;
}
// evaluate precision field
precision = 0U;
if (*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = _atoi(&format);
} else if (*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
format++;
}
}
// evaluate length field
switch (*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if (*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
}
break;
case 'h' :
flags |= FLAGS_SHORT;
format++;
if (*format == 'h') {
flags |= FLAGS_CHAR;
format++;
}
break;
#if defined(PRINTF_SUPPORT_PTRDIFF_T)
case 't' :
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
#endif
case 'j' :
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
case 'z' :
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
default :
break;
}
// evaluate specifier
switch (*format) {
case 'd' :
case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if (*format == 'x' || *format == 'X') {
base = 16U;
} else if (*format == 'o') {
base = 8U;
} else if (*format == 'b') {
base = 2U;
} else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if (*format == 'X') {
flags |= FLAGS_UPPERCASE;
}
// no plus or space flag for u, x, X, o, b
if ((*format != 'i') && (*format != 'd')) {
flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
}
// ignore '0' flag when precision is given
if (flags & FLAGS_PRECISION) {
flags &= ~FLAGS_ZEROPAD;
}
// convert the integer
if ((*format == 'i') || (*format == 'd')) {
// signed
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
const long long value = va_arg(va, long long);
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
#endif
} else if (flags & FLAGS_LONG) {
const long value = va_arg(va, long);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
} else {
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
} else {
// unsigned
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
#endif
} else if (flags & FLAGS_LONG) {
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
} else {
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
}
}
format++;
break;
}
#if defined(PRINTF_SUPPORT_FLOAT)
case 'f' :
case 'F' :
if (*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e':
case 'E':
case 'g':
case 'G':
if ((*format == 'g') || (*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
case 'c' : {
unsigned int l = 1U;
// pre padding
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// char output
out((char)va_arg(va, int), buffer, idx++, maxlen);
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 's' : {
const char *p = va_arg(va, char *);
unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1);
// pre padding
if (flags & FLAGS_PRECISION) {
l = (l < precision ? l : precision);
}
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// string output
while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
out(*(p++), buffer, idx++, maxlen);
}
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 'p' : {
width = sizeof(void *) * 2U;
flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
#if defined(PRINTF_SUPPORT_LONG_LONG)
const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
if (is_ll) {
idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void *), false, 16U, precision, width, flags);
} else {
#endif
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void *)), false, 16U, precision, width, flags);
#if defined(PRINTF_SUPPORT_LONG_LONG)
}
#endif
format++;
break;
}
case '%' :
out('%', buffer, idx++, maxlen);
format++;
break;
default :
out(*format, buffer, idx++, maxlen);
format++;
break;
}
}
// termination
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
// return written chars without terminating \0
return (int)idx;
}
///////////////////////////////////////////////////////////////////////////////
int printf_(const char *format, ...) {
va_list va;
va_start(va, format);
char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t) -1, format, va);
va_end(va);
return ret;
}
int sprintf_(char *buffer, const char *format, ...) {
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, (size_t) -1, format, va);
va_end(va);
return ret;
}
int snprintf_(char *buffer, size_t count, const char *format, ...) {
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
va_end(va);
return ret;
}
int vprintf_(const char *format, va_list va) {
char buffer[1];
return _vsnprintf(_out_char, buffer, (size_t) -1, format, va);
}
int vsnprintf_(char *buffer, size_t count, const char *format, va_list va) {
return _vsnprintf(_out_buffer, buffer, count, format, va);
}
int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) {
va_list va;
va_start(va, format);
const out_fct_wrap_type out_fct_wrap = { out, arg };
const int ret = _vsnprintf(_out_fct, (char *)(uintptr_t)&out_fct_wrap, (size_t) -1, format, va);
va_end(va);
return ret;
}

107
armsrc/nprintf.h Normal file
View file

@ -0,0 +1,107 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
// embedded systems with a very limited resources.
// Use this instead of bloated standard/newlib printf.
// These routines are thread safe and reentrant.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _PRINTF_H_
#define _PRINTF_H_
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
/**
* Output a character to a custom device like UART, used by the printf() function
* This function is declared here only. You have to write your custom implementation somewhere
* \param character Character to output
*/
void _putchar(char character);
/**
* Tiny printf implementation
* You have to implement _putchar if you use printf()
* To avoid conflicts with the regular printf() API it is overridden by macro defines
* and internal underscore-appended functions like printf_() are used
* \param format A string that specifies the format of the output
* \return The number of characters that are written into the array, not counting the terminating null character
*/
#define printf printf_
int printf_(const char *format, ...);
/**
* Tiny sprintf implementation
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!
* \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
* \param format A string that specifies the format of the output
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define sprintf sprintf_
int sprintf_(char *buffer, const char *format, ...);
/**
* Tiny snprintf/vsnprintf implementation
* \param buffer A pointer to the buffer where to store the formatted string
* \param count The maximum number of characters to store in the buffer, including a terminating null character
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that COULD have been written into the buffer, not counting the terminating
* null character. A value equal or larger than count indicates truncation. Only when the returned value
* is non-negative and less than count, the string has been completely written.
*/
#define snprintf snprintf_
#define vsnprintf vsnprintf_
int snprintf_(char *buffer, size_t count, const char *format, ...);
int vsnprintf_(char *buffer, size_t count, const char *format, va_list va);
/**
* Tiny vprintf implementation
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define vprintf vprintf_
int vprintf_(const char *format, va_list va);
/**
* printf with output function
* You may use this as dynamic alternative to printf() with its fixed _putchar() output
* \param out An output function which takes one character and an argument pointer
* \param arg An argument pointer for user data passed to output function
* \param format A string that specifies the format of the output
* \return The number of characters that are sent to the output function, not counting the terminating null character
*/
int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...);
#endif // _PRINTF_H_

View file

@ -1,9 +1,7 @@
#ifndef OPTIMIZED_CIPHER_H #ifndef OPTIMIZED_CIPHER_H
#define OPTIMIZED_CIPHER_H #define OPTIMIZED_CIPHER_H
#include <stdint.h> #include "common.h"
#include <stddef.h>
#include <stdbool.h>
/** /**
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2 * Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2

View file

@ -1,5 +1,15 @@
#include "pcf7931.h" #include "pcf7931.h"
#include "proxmark3_arm.h"
#include "cmd.h"
#include "BigBuf.h"
#include "fpgaloader.h"
#include "ticks.h"
#include "dbprint.h"
#include "util.h"
#include "lfsampling.h"
#include "string.h"
#define T0_PCF 8 //period for the pcf7931 in us #define T0_PCF 8 //period for the pcf7931 in us
#define ALLOC 16 #define ALLOC 16
@ -404,7 +414,7 @@ void SendCmdPCF7931(uint32_t *tab) {
Dbprintf("Sending data frame..."); Dbprintf("Sending data frame...");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
LED_A_ON(); LED_A_ON();

View file

@ -1,11 +1,7 @@
#ifndef __PCF7931_H #ifndef __PCF7931_H
#define __PCF7931_H #define __PCF7931_H
#include "proxmark3.h" #include "common.h"
#include "apps.h"
#include "lfsampling.h"
#include "pcf7931.h"
#include "string.h"
size_t DemodPCF7931(uint8_t **outBlocks); size_t DemodPCF7931(uint8_t **outBlocks);
bool IsBlock0PCF7931(uint8_t *block); bool IsBlock0PCF7931(uint8_t *block);

View file

@ -35,6 +35,8 @@
*/ */
#include "printf.h" #include "printf.h"
#include "string.h"
typedef unsigned char u_char; typedef unsigned char u_char;
typedef unsigned int u_int; typedef unsigned int u_int;
typedef unsigned long long u_quad_t; typedef unsigned long long u_quad_t;

View file

@ -11,9 +11,8 @@
#ifndef __PRINTF_H #ifndef __PRINTF_H
#define __PRINTF_H #define __PRINTF_H
#include <stdarg.h> #include "common.h"
#include <stddef.h> #include <stdarg.h> // va_list
#include "string.h"
int kvsprintf(const char *fmt, void *arg, int radix, va_list ap) __attribute__((format(printf, 1, 0))); int kvsprintf(const char *fmt, void *arg, int radix, va_list ap) __attribute__((format(printf, 1, 0)));
int vsprintf(char *dest, const char *fmt, va_list ap) __attribute__((format(printf, 2, 0))); int vsprintf(char *dest, const char *fmt, va_list ap) __attribute__((format(printf, 2, 0)));

View file

@ -1,9 +1,7 @@
#ifndef RADIXSORT_H__ #ifndef RADIXSORT_H__
#define RADIXSORT_H__ #define RADIXSORT_H__
#include <string.h> #include "common.h"
#include <stdint.h>
#include <stdlib.h>
typedef union { typedef union {
struct { struct {
@ -20,4 +18,5 @@ typedef union {
} rscounts_t; } rscounts_t;
uint64_t *radixSort(uint64_t *array, uint32_t size); uint64_t *radixSort(uint64_t *array, uint32_t size);
#endif // RADIXSORT_H__ #endif // RADIXSORT_H__

View file

@ -43,6 +43,12 @@
RDV40_SPIFFS_SAFE_FOOTER RDV40_SPIFFS_SAFE_FOOTER
#include "spiffs.h" #include "spiffs.h"
#include "flashmem.h"
#include "dbprint.h"
#include "printf.h"
#include "common.h"
#include "string.h"
#include "BigBuf.h"
///// FLASH LEVEL R/W/E operations for feeding SPIFFS Driver///////////////// ///// FLASH LEVEL R/W/E operations for feeding SPIFFS Driver/////////////////
static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) { static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) {

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