mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 06:13:51 -07:00
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
commit
1b9841cc6e
96 changed files with 4668 additions and 2039 deletions
4
.github/workflows/windows.yml
vendored
4
.github/workflows/windows.yml
vendored
|
@ -98,9 +98,9 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: WSL setup
|
- name: WSL setup
|
||||||
uses: Vampire/setup-wsl@v1
|
uses: Vampire/setup-wsl@v2
|
||||||
with:
|
with:
|
||||||
distribution: Ubuntu-20.04
|
distribution: Ubuntu-22.04
|
||||||
update: "true"
|
update: "true"
|
||||||
additional-packages: git
|
additional-packages: git
|
||||||
ca-certificates
|
ca-certificates
|
||||||
|
|
38
CHANGELOG.md
38
CHANGELOG.md
|
@ -3,6 +3,40 @@ 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]
|
||||||
|
- Fixed the client build on Android (@wh201906)
|
||||||
|
- Added TCP connection support on Windows (@wh201906)
|
||||||
|
- Added `data num` - easy convert between dec/hex/bin (@iceman1001)
|
||||||
|
- Fixed `hf mfdes info` - now handles incorrect tag answers better (@didiera)
|
||||||
|
- Fixed `hf mfdes` generic help text is now correct (@didiera)
|
||||||
|
- Fixed `pm3` script to correctly identify WSL enabled distros (@henrygab)
|
||||||
|
- Changed device enumeration with "unique USB serial numbers when built with `FLASH` -- **_UPDATES BOOTROM ALSO_**" (@henrygab)
|
||||||
|
- Changed the readline package to v8.2 in the CMAKE files for the client (@iceman1001)
|
||||||
|
- Fixed `pm3` script for passing arguments (@doegox)
|
||||||
|
- Fixed python paths to include current directory (@jmichelp)
|
||||||
|
- Fixed infinite loops in spindelayus (@lnv42)
|
||||||
|
- Add ICECLASS standalone read/sim mode (@natesales)
|
||||||
|
- Changed `hf iclass encode` - added verbose flag (@natesales)
|
||||||
|
- Changed `hf waveshare` - now identify 1.54 nfc epaper correct (@ah01)
|
||||||
|
- Fixed `Makefile` regression that broke `make install` (@henrygab)
|
||||||
|
- Fixed `lf em 4x70 brute` - now works as expected (@adite)
|
||||||
|
- Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906)
|
||||||
|
- Added `lf em 4x70 brute` command (@adite)
|
||||||
|
- Added documentation for usage of Proxmark3 under WSL2 (@henrygab)
|
||||||
|
- Fixed device permissions via updated `udev` rules (@henrygab)
|
||||||
|
- Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906)
|
||||||
|
- Changed `hf iclass decrypt` - mark credentials as decrypted in the dump (@natesales)
|
||||||
|
- Changed `hf iclass view` - show credentials on a decrypted dump (@natesales)
|
||||||
|
- Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn)
|
||||||
|
- Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato)
|
||||||
|
-
|
||||||
|
|
||||||
|
## [Nitride.4.16191][2023-01-29]
|
||||||
|
- Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox)
|
||||||
|
- Fixed some coverity fixes (@iceman1001)
|
||||||
|
- Fixed `make accessrights` on Fedora (@mooey5775)
|
||||||
|
- Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn)
|
||||||
|
- Added `hf 15` sub-commands for controlling EAS, AFI, privacy mode, and the setting of passwords on SLIX tags (@mjacksn)
|
||||||
|
- Added new magic gen4 cards command in docs (@McEloff)
|
||||||
- Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001)
|
- Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001)
|
||||||
- Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001)
|
- Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001)
|
||||||
- Changed `hf emrtd dump` - looking for lower case .bin extensions (@iceman1001)
|
- Changed `hf emrtd dump` - looking for lower case .bin extensions (@iceman1001)
|
||||||
|
@ -40,7 +74,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001)
|
- Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001)
|
||||||
- Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001)
|
- Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001)
|
||||||
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
||||||
- Fixed `make accessrights` on Fedora (@mooey5775)
|
|
||||||
|
|
||||||
## [Radium.4.15864][2022-10-29]
|
## [Radium.4.15864][2022-10-29]
|
||||||
- Changed `lf indala sim` - now accepts fc / cn (@iceman1001)
|
- Changed `lf indala sim` - now accepts fc / cn (@iceman1001)
|
||||||
|
@ -145,7 +178,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Added new standalone mode `lf_em4100rsww` (@zabszk)
|
- Added new standalone mode `lf_em4100rsww` (@zabszk)
|
||||||
- Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz)
|
- Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz)
|
||||||
- Added `script run hf_mf_hid_sim.lua` (@micsen)
|
- Added `script run hf_mf_hid_sim.lua` (@micsen)
|
||||||
|
- Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve)
|
||||||
|
|
||||||
## [Frostbit.4.14831][2022-01-11]
|
## [Frostbit.4.14831][2022-01-11]
|
||||||
- Changed Wiegand format lookup - now case-insensitive (@iceman1001)
|
- Changed Wiegand format lookup - now case-insensitive (@iceman1001)
|
||||||
|
@ -1363,6 +1396,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Mifare simulation, `hf mf sim` (was broken a long time) (@pwpiwi)
|
- Mifare simulation, `hf mf sim` (was broken a long time) (@pwpiwi)
|
||||||
- Major improvements in LF area and data operations. (@marshmellow42, @iceman1001)
|
- Major improvements in LF area and data operations. (@marshmellow42, @iceman1001)
|
||||||
- Issues regarding LF simulation (@pwpiwi)
|
- Issues regarding LF simulation (@pwpiwi)
|
||||||
|
- Issue interpreting NXP "get sys info" command return value for icode tags. (@mjacksn)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers do not seem to enforce update. (@holiman).
|
- iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers do not seem to enforce update. (@holiman).
|
||||||
|
|
24
Makefile
24
Makefile
|
@ -65,7 +65,13 @@ ifneq (,$(INSTALLSIMFW))
|
||||||
endif
|
endif
|
||||||
ifeq ($(platform),Linux)
|
ifeq ($(platform),Linux)
|
||||||
$(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(UDEV_PREFIX)
|
$(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(UDEV_PREFIX)
|
||||||
$(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
# If user is running ArchLinux, use group 'uucp'
|
||||||
|
# Else, use group 'dialout'
|
||||||
|
ifneq ($(wildcard /etc/arch-release),)
|
||||||
|
$(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
|
else
|
||||||
|
$(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
uninstall: common/uninstall
|
uninstall: common/uninstall
|
||||||
|
@ -75,21 +81,28 @@ common/uninstall:
|
||||||
ifneq (,$(INSTALLSCRIPTS))
|
ifneq (,$(INSTALLSCRIPTS))
|
||||||
$(Q)$(INSTALLSUDO) $(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script)))
|
$(Q)$(INSTALLSUDO) $(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(INSTALLSHARES))
|
ifneq (,$(INSTALLSHARES))
|
||||||
$(Q)$(INSTALLSUDO) $(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share)))
|
$(Q)$(INSTALLSUDO) $(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(INSTALLDOCS))
|
ifneq (,$(INSTALLDOCS))
|
||||||
$(Q)$(INSTALLSUDO) $(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc)))
|
$(Q)$(INSTALLSUDO) $(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc)))
|
||||||
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
|
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(INSTALLTOOLS))
|
ifneq (,$(INSTALLTOOLS))
|
||||||
$(Q)$(INSTALLSUDO) $(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool)))
|
$(Q)$(INSTALLSUDO) $(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
|
||||||
|
|
||||||
ifneq (,$(INSTALLSIMFW))
|
ifneq (,$(INSTALLSIMFW))
|
||||||
$(Q)$(INSTALLSUDO) $(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
|
$(Q)$(INSTALLSUDO) $(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
$(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
|
||||||
|
|
||||||
ifeq ($(platform),Linux)
|
ifeq ($(platform),Linux)
|
||||||
$(Q)$(INSTALLSUDO) $(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
$(Q)$(INSTALLSUDO) $(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
endif
|
endif
|
||||||
|
@ -256,8 +269,15 @@ endif
|
||||||
# configure system to ignore PM3 device as a modem (ModemManager blacklist, effective *only* if ModemManager is not using _strict_ policy)
|
# configure system to ignore PM3 device as a modem (ModemManager blacklist, effective *only* if ModemManager is not using _strict_ policy)
|
||||||
# Read doc/md/ModemManager-Must-Be-Discarded.md for more info
|
# Read doc/md/ModemManager-Must-Be-Discarded.md for more info
|
||||||
udev:
|
udev:
|
||||||
$(SUDO) cp -rf driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
ifneq ($(wildcard /etc/arch-release),)
|
||||||
|
# If user is running ArchLinux, use group 'uucp'
|
||||||
|
$(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
|
else
|
||||||
|
# Else, use group 'dialout'
|
||||||
|
$(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
|
||||||
|
endif
|
||||||
$(SUDO) udevadm control --reload-rules
|
$(SUDO) udevadm control --reload-rules
|
||||||
|
$(SUDO) udevadm trigger --action=change
|
||||||
|
|
||||||
# configure system to add user to the dialout group and if bluetooth group exists, add user to it
|
# configure system to add user to the dialout group and if bluetooth group exists, add user to it
|
||||||
# you need to logout, relogin to get this access right correct.
|
# you need to logout, relogin to get this access right correct.
|
||||||
|
|
|
@ -5,8 +5,23 @@ PLATFORM=PM3RDV4
|
||||||
#PLATFORM=PM3GENERIC
|
#PLATFORM=PM3GENERIC
|
||||||
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
|
# If you want more than one PLATFORM_EXTRAS option, separate them by spaces:
|
||||||
#PLATFORM_EXTRAS=BTADDON
|
#PLATFORM_EXTRAS=BTADDON
|
||||||
|
#PLATFORM_EXTRAS=FLASH
|
||||||
|
#PLATFORM_EXTRAS=BTADDON FLASH
|
||||||
#STANDALONE=LF_SAMYRUN
|
#STANDALONE=LF_SAMYRUN
|
||||||
|
|
||||||
|
# Uncomment the lines below in order to make a 256KB image
|
||||||
|
# and comment out the lines above
|
||||||
|
|
||||||
|
#PLATFORM=PM3GENERIC
|
||||||
|
#PLATFORM_SIZE=256
|
||||||
|
#STANDALONE=
|
||||||
|
#SKIP_HITAG=1
|
||||||
|
#SKIP_FELICA=1
|
||||||
|
#SKIP_HFPLOT=1
|
||||||
|
#SKIP_NFCBARCODE=1
|
||||||
|
#SKIP_ZX8211=1
|
||||||
|
#SKIP_LF=1
|
||||||
|
|
||||||
# To accelerate repetitive compilations:
|
# To accelerate repetitive compilations:
|
||||||
# Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache
|
# Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache
|
||||||
# And uncomment the following line
|
# And uncomment the following line
|
||||||
|
|
|
@ -50,12 +50,12 @@ define KNOWN_STANDALONE_DEFINITIONS
|
||||||
| LF_ICEHID | LF HID collector to flashmem |
|
| LF_ICEHID | LF HID collector to flashmem |
|
||||||
| (RDV4 only) | |
|
| (RDV4 only) | |
|
||||||
+----------------------------------------------------------+
|
+----------------------------------------------------------+
|
||||||
| LF_NEXID | LF Nexwatch collector to flashmem |
|
|
||||||
| (RDV4 only) | |
|
|
||||||
+----------------------------------------------------------+
|
|
||||||
| LF_NEDAP_SIM | LF Nedap ID simple simulator |
|
| LF_NEDAP_SIM | LF Nedap ID simple simulator |
|
||||||
| | |
|
| | |
|
||||||
+----------------------------------------------------------+
|
+----------------------------------------------------------+
|
||||||
|
| LF_NEXID | LF Nexwatch collector to flashmem |
|
||||||
|
| (RDV4 only) | |
|
||||||
|
+----------------------------------------------------------+
|
||||||
| LF_PROXBRUTE | HID ProxII bruteforce |
|
| LF_PROXBRUTE | HID ProxII bruteforce |
|
||||||
| | - Brad Antoniewicz |
|
| | - Brad Antoniewicz |
|
||||||
+----------------------------------------------------------+
|
+----------------------------------------------------------+
|
||||||
|
@ -125,8 +125,10 @@ define KNOWN_STANDALONE_DEFINITIONS
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM
|
STANDALONE_MODES := LF_SKELETON
|
||||||
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI
|
STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE
|
||||||
|
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG
|
||||||
|
STANDALONE_MODES += DANKARMULTI
|
||||||
STANDALONE_MODES_REQ_BT := HF_REBLAY
|
STANDALONE_MODES_REQ_BT := HF_REBLAY
|
||||||
STANDALONE_MODES_REQ_SMARTCARD :=
|
STANDALONE_MODES_REQ_SMARTCARD :=
|
||||||
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM
|
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM
|
||||||
|
|
|
@ -21,6 +21,42 @@ SRC_STANDALONE = placeholder.c
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_SKELETON,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_LF_SKELETON,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_skeleton.c
|
SRC_STANDALONE = lf_skeleton.c
|
||||||
endif
|
endif
|
||||||
|
# WITH_STANDALONE_LF_EM4100EMUL
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_em4100emul.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_EM4100RSWB
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWB,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_em4100rswb.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_EM4100RSWW
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWW,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_em4100rsww.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_EM4100RWC
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_em4100rwc.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_HIDBRUTE
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_hidbrute.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_HIDFCBRUTE
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_HIDFCBRUTE,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_hidfcbrute.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_ICEHID
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_icehid.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_NEDAP_SIM
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_NEDAP_SIM,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_nedap_sim.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_LF_NEXID
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_LF_NEXID,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = lf_nexid.c
|
||||||
|
endif
|
||||||
# WITH_STANDALONE_LF_SAMYRUN
|
# WITH_STANDALONE_LF_SAMYRUN
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_SAMYRUN,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_LF_SAMYRUN,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_samyrun.c
|
SRC_STANDALONE = lf_samyrun.c
|
||||||
|
@ -33,29 +69,9 @@ endif
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_PROX2BRUTE,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_LF_PROX2BRUTE,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_prox2brute.c
|
SRC_STANDALONE = lf_prox2brute.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_LF_HIDBRUTE
|
# WITH_STANDALONE_LF_THAREXDE
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_LF_THAREXDE,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_hidbrute.c
|
SRC_STANDALONE = lf_tharexde.c
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_LF_HIDFCBRUTE
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_HIDFCBRUTE,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = lf_hidfcbrute.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_HF_YOUNG
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = hf_young.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_HF_MATTYRUN
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_MATTYRUN,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = hf_mattyrun.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_HF_COLIN
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_HF_BOG
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = hf_bog.c
|
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_HF_14ASNIFF
|
# WITH_STANDALONE_HF_14ASNIFF
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS)))
|
||||||
|
@ -73,33 +89,21 @@ endif
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_AVEFUL,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_AVEFUL,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_aveful.c
|
SRC_STANDALONE = hf_aveful.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_HF_TCPRST
|
# WITH_STANDALONE_HF_BOG
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_TCPRST,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_tcprst.c
|
SRC_STANDALONE = hf_bog.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_LF_ICEHID
|
# WITH_STANDALONE_HF_COLIN
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_icehid.c
|
SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_LF_NEXID
|
# WITH_STANDALONE_HF_CRAFTBYTE
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_NEXID,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_CRAFTBYTE,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_nexid.c
|
SRC_STANDALONE = hf_craftbyte.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_LF_EM4100EMUL
|
# WITH_STANDALONE_HF_ICECLASS
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_ICECLASS,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_em4100emul.c
|
SRC_STANDALONE = hf_iceclass.c
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_LF_EM4100RSWB
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWB,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = lf_em4100rswb.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_LF_EM4100RSWW
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWW,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = lf_em4100rsww.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_LF_EM4100RWC
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = lf_em4100rwc.c
|
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_HF_LEGIC
|
# WITH_STANDALONE_HF_LEGIC
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_LEGIC,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_LEGIC,$(APP_CFLAGS)))
|
||||||
|
@ -109,37 +113,33 @@ endif
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_LEGICSIM,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_LEGICSIM,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_legicsim.c
|
SRC_STANDALONE = hf_legicsim.c
|
||||||
endif
|
endif
|
||||||
|
# WITH_STANDALONE_HF_MATTYRUN
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_HF_MATTYRUN,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = hf_mattyrun.c
|
||||||
|
endif
|
||||||
|
# WITH_STANDALONE_HF_MFCSIM
|
||||||
|
ifneq (,$(findstring WITH_STANDALONE_HF_MFCSIM,$(APP_CFLAGS)))
|
||||||
|
SRC_STANDALONE = hf_mfcsim.c
|
||||||
|
endif
|
||||||
# WITH_STANDALONE_HF_MSDSAL
|
# WITH_STANDALONE_HF_MSDSAL
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_MSDSAL,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_MSDSAL,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_msdsal.c
|
SRC_STANDALONE = hf_msdsal.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_HF_ICECLASS
|
# WITH_STANDALONE_HF_REBLAY
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_ICECLASS,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_REBLAY,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_iceclass.c
|
SRC_STANDALONE = hf_reblay.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_LF_THAREXDE
|
# WITH_STANDALONE_HF_TCPRST
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_THAREXDE,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_TCPRST,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = lf_tharexde.c
|
SRC_STANDALONE = hf_tcprst.c
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_HF_CRAFTBYTE
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_CRAFTBYTE,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = hf_craftbyte.c
|
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_HF_TMUDFORD
|
# WITH_STANDALONE_HF_TMUDFORD
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_TMUDFORD,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_TMUDFORD,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_tmudford.c
|
SRC_STANDALONE = hf_tmudford.c
|
||||||
endif
|
endif
|
||||||
# WITH_STANDALONE_HF_REBLAY
|
# WITH_STANDALONE_HF_YOUNG
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_REBLAY,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_reblay.c
|
SRC_STANDALONE = hf_young.c
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_HF_MFCSIM
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_HF_MFCSIM,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = hf_mfcsim.c
|
|
||||||
endif
|
|
||||||
# WITH_STANDALONE_LF_NEDAP_SIM
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_LF_NEDAP_SIM,$(APP_CFLAGS)))
|
|
||||||
SRC_STANDALONE = lf_nedap_sim.c
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS)))
|
||||||
|
|
|
@ -44,8 +44,9 @@
|
||||||
#define ICE_STATE_READER 3
|
#define ICE_STATE_READER 3
|
||||||
#define ICE_STATE_CONFIGCARD 4
|
#define ICE_STATE_CONFIGCARD 4
|
||||||
#define ICE_STATE_DUMP_SIM 5
|
#define ICE_STATE_DUMP_SIM 5
|
||||||
|
#define ICE_STATE_READ_SIM 6
|
||||||
|
|
||||||
#define HF_ICLASS_NUM_MODES 6
|
#define HF_ICLASS_NUM_MODES 7
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// Select which standalone function to be active.
|
// Select which standalone function to be active.
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
//#define ICE_USE ICE_STATE_READER
|
//#define ICE_USE ICE_STATE_READER
|
||||||
//#define ICE_USE ICE_STATE_CONFIGCARD
|
//#define ICE_USE ICE_STATE_CONFIGCARD
|
||||||
//#define ICE_USE ICE_STATE_DUMP_SIM
|
//#define ICE_USE ICE_STATE_DUMP_SIM
|
||||||
|
//#define ICE_USE ICE_STATE_READ_SIM
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
@ -720,6 +722,16 @@ void RunMod(void) {
|
||||||
mode = ICE_STATE_NONE;
|
mode = ICE_STATE_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ICE_STATE_READ_SIM: {
|
||||||
|
DbpString("-=[ enter " _CYAN_("`read & sim`") " mode, read cards, then sim after button press ]=-");
|
||||||
|
DbpString("Entering reader dump mode");
|
||||||
|
reader_dump_mode();
|
||||||
|
SpinDelay(1200); // debounce button press
|
||||||
|
DbpString("Entering fullsim mode");
|
||||||
|
fullsim_mode();
|
||||||
|
DbpString("Exiting fullsim mode");
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) Brad Antoniewicz 2011
|
// Copyright (C) Yann Gascuel 2023
|
||||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -92,11 +92,11 @@ void RunMod(void) {
|
||||||
|
|
||||||
// switch leds to be able to know (aproximatly) which card number worked (64 tries loop)
|
// switch leds to be able to know (aproximatly) which card number worked (64 tries loop)
|
||||||
LED_A_INV(); // switch led A every try
|
LED_A_INV(); // switch led A every try
|
||||||
if ((cardnum-CARDNUM_START) % 8 == 7) // switch led B every 8 tries
|
if ((cardnum - CARDNUM_START) % 8 == 7) // switch led B every 8 tries
|
||||||
LED_B_INV();
|
LED_B_INV();
|
||||||
if ((cardnum-CARDNUM_START) % 16 == 15) // switch led C every 16 tries
|
if ((cardnum - CARDNUM_START) % 16 == 15) // switch led C every 16 tries
|
||||||
LED_C_INV();
|
LED_C_INV();
|
||||||
if ((cardnum-CARDNUM_START) % 32 == 31) // switch led D every 32 tries
|
if ((cardnum - CARDNUM_START) % 32 == 31) // switch led D every 32 tries
|
||||||
LED_D_INV();
|
LED_D_INV();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,8 @@ STANDALONE_MODES_REQ_FLASH :=
|
||||||
STANDALONE_MODES_REQ_BT :=
|
STANDALONE_MODES_REQ_BT :=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Please respect alphabetic order!
|
||||||
|
|
||||||
## Update MAKEFILE.INC
|
## Update MAKEFILE.INC
|
||||||
^[Top](#top)
|
^[Top](#top)
|
||||||
|
|
||||||
|
@ -117,6 +119,8 @@ ifneq (,$(findstring WITH_STANDALONE_LF_FOO,$(APP_CFLAGS)))
|
||||||
endif
|
endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Please respect alphabetic order!
|
||||||
|
|
||||||
## Adding identification string of your mode
|
## Adding identification string of your mode
|
||||||
^[Top](#top)
|
^[Top](#top)
|
||||||
|
|
||||||
|
@ -174,9 +178,11 @@ Once you're ready to share your mode, please
|
||||||
|
|
||||||
* add a line in CHANGELOG.md
|
* add a line in CHANGELOG.md
|
||||||
* add your mode in the modes table in `doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md`
|
* add your mode in the modes table in `doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md`
|
||||||
* add your mode in `tools/build_all_firmwares.sh`
|
* add your mode in `tools/build_all_firmwares.sh` such that it reflects `armsrc/Standalone/Makefile.hal` list of firmwares to build.
|
||||||
|
|
||||||
and submit your PR.
|
Please respect alphabetic order of standalone modes everywhere!
|
||||||
|
|
||||||
|
Then submit your PR.
|
||||||
|
|
||||||
Once approved, add also your mode in https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode
|
Once approved, add also your mode in https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode
|
||||||
|
|
||||||
|
|
|
@ -453,6 +453,12 @@ static void SendCapabilities(void) {
|
||||||
capabilities.baudrate = g_usart_baudrate;
|
capabilities.baudrate = g_usart_baudrate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RDV4
|
||||||
|
capabilities.is_rdv4 = true;
|
||||||
|
#else
|
||||||
|
capabilities.is_rdv4 = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
capabilities.compiled_with_flash = true;
|
capabilities.compiled_with_flash = true;
|
||||||
capabilities.hw_available_flash = FlashInit();
|
capabilities.hw_available_flash = FlashInit();
|
||||||
|
@ -1221,6 +1227,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
em4x70_write_key((em4x70_data_t *)packet->data.asBytes, true);
|
em4x70_write_key((em4x70_data_t *)packet->data.asBytes, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CMD_LF_EM4X70_BRUTE: {
|
||||||
|
em4x70_brute((em4x70_data_t *)packet->data.asBytes, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ZX8211
|
#ifdef WITH_ZX8211
|
||||||
|
@ -1287,20 +1297,76 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
SetTag15693Uid(payload->uid);
|
SetTag15693Uid(payload->uid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY: {
|
case CMD_HF_ISO15693_SLIX_DISABLE_EAS: {
|
||||||
struct p {
|
struct p {
|
||||||
uint8_t pwd[4];
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
struct p *payload = (struct p *) packet->data.asBytes;
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
DisablePrivacySlixLIso15693(payload->pwd);
|
DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI: {
|
case CMD_HF_ISO15693_SLIX_ENABLE_EAS: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
EnableEAS_AFISlixIso15693(payload->pwd, payload->usepwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_WRITE_PWD: {
|
||||||
|
struct p {
|
||||||
|
uint8_t old_pwd[4];
|
||||||
|
uint8_t new_pwd[4];
|
||||||
|
uint8_t pwd_id;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: {
|
||||||
struct p {
|
struct p {
|
||||||
uint8_t pwd[4];
|
uint8_t pwd[4];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
struct p *payload = (struct p *) packet->data.asBytes;
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
DisableEAS_AFISlixLIso15693(payload->pwd);
|
DisablePrivacySlixIso15693(payload->pwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
EnablePrivacySlixIso15693(payload->pwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
PassProtectAFISlixIso15693(payload->pwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_WRITE_AFI: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool use_pwd;
|
||||||
|
uint8_t uid[8];
|
||||||
|
bool use_uid;
|
||||||
|
uint8_t afi;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
WriteAFIIso15693(payload->pwd, payload->use_pwd, payload->uid, payload->use_uid, payload->afi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
|
PassProtextEASSlixIso15693(payload->pwd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2405,8 +2471,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (page < 3)
|
if (page < 3) {
|
||||||
isok = Flash_WipeMemoryPage(page);
|
isok = Flash_WipeMemoryPage(page);
|
||||||
|
// let spiffs check and update its info post flash erase
|
||||||
|
rdv40_spiffs_check();
|
||||||
|
}
|
||||||
|
|
||||||
reply_mix(CMD_ACK, isok, 0, 0, 0, 0);
|
reply_mix(CMD_ACK, isok, 0, 0, 0, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
@ -2611,6 +2680,17 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
I2C_init(false);
|
I2C_init(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_FLASH
|
||||||
|
if (FlashInit()) {
|
||||||
|
uint64_t flash_uniqueID = 0;
|
||||||
|
if (!Flash_CheckBusy(BUSY_TIMEOUT)) { // OK because firmware was built for devices with flash
|
||||||
|
Flash_UniqueID((uint8_t *)(&flash_uniqueID));
|
||||||
|
}
|
||||||
|
FlashStop();
|
||||||
|
usb_update_serial(flash_uniqueID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_FPC_USART
|
#ifdef WITH_FPC_USART
|
||||||
usart_init(USART_BAUD_RATE, USART_PARITY);
|
usart_init(USART_BAUD_RATE, USART_PARITY);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -131,7 +131,7 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, const uint8_t *data,
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len) {
|
int reply_ng(uint16_t cmd, int16_t status, const uint8_t *data, size_t len) {
|
||||||
return reply_ng_internal(cmd, status, data, len, true);
|
return reply_ng_internal(cmd, status, data, len, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern bool g_reply_via_fpc;
|
||||||
extern bool g_reply_via_usb;
|
extern bool g_reply_via_usb;
|
||||||
|
|
||||||
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||||
int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
|
int reply_ng(uint16_t cmd, int16_t status, const 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 reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||||
int receive_ng(PacketCommandNG *rx);
|
int receive_ng(PacketCommandNG *rx);
|
||||||
|
|
||||||
|
|
|
@ -755,7 +755,7 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect,
|
||||||
memcpy(ovect, data, block_size);
|
memcpy(ovect, data, block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE];
|
uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||||
|
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case T_DES:
|
case T_DES:
|
||||||
|
|
106
armsrc/em4x70.c
106
armsrc/em4x70.c
|
@ -21,6 +21,7 @@
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
#include "lfadc.h"
|
#include "lfadc.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "optimized_cipherutils.h"
|
||||||
#include "em4x70.h"
|
#include "em4x70.h"
|
||||||
#include "appmain.h" // tear
|
#include "appmain.h" // tear
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ static int em4x70_receive(uint8_t *bits, size_t length);
|
||||||
static bool find_listen_window(bool command);
|
static bool find_listen_window(bool command);
|
||||||
|
|
||||||
static void init_tag(void) {
|
static void init_tag(void) {
|
||||||
memset(tag.data, 0x00, ARRAYLEN(tag.data));
|
memset(tag.data, 0x00, sizeof(tag.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x70_setup_read(void) {
|
static void em4x70_setup_read(void) {
|
||||||
|
@ -298,14 +299,14 @@ static bool check_ack(void) {
|
||||||
// returns true if signal structue corresponds to ACK, anything else is
|
// returns true if signal structue corresponds to ACK, anything else is
|
||||||
// counted as NAK (-> false)
|
// counted as NAK (-> false)
|
||||||
// ACK 64 + 64
|
// ACK 64 + 64
|
||||||
// NACK 64 + 48
|
// NAK 64 + 48
|
||||||
if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) &&
|
if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) &&
|
||||||
check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) {
|
||||||
// ACK
|
// ACK
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Othewise it was a NACK or Listen Window
|
// Otherwise it was a NAK or Listen Window
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +340,7 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon
|
||||||
uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0};
|
||||||
int num = em4x70_receive(grnd, 20);
|
int num = em4x70_receive(grnd, 20);
|
||||||
if (num < 20) {
|
if (num < 20) {
|
||||||
Dbprintf("Auth failed");
|
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Auth failed");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
bits2bytes(grnd, 24, response);
|
bits2bytes(grnd, 24, response);
|
||||||
|
@ -349,6 +350,80 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_byte(uint8_t *target, int value) {
|
||||||
|
int c = value > 0xFF;
|
||||||
|
*target = reflect8(value);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t *frnd, uint16_t start_key, uint8_t *response) {
|
||||||
|
|
||||||
|
uint8_t auth_resp[3] = {0};
|
||||||
|
uint8_t rev_rnd[7];
|
||||||
|
uint8_t temp_rnd[7];
|
||||||
|
|
||||||
|
reverse_arraycopy((uint8_t *)rnd, rev_rnd, sizeof(rev_rnd));
|
||||||
|
memcpy(temp_rnd, rnd, sizeof(temp_rnd));
|
||||||
|
|
||||||
|
for (int k = start_key; k <= 0xFFFF; ++k) {
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
WDT_HIT();
|
||||||
|
|
||||||
|
uint16_t rev_k = reflect16(k);
|
||||||
|
switch (address) {
|
||||||
|
case 9:
|
||||||
|
c = set_byte(&temp_rnd[0], rev_rnd[0] + (rev_k & 0xFF));
|
||||||
|
c = set_byte(&temp_rnd[1], rev_rnd[1] + c + ((rev_k >> 8) & 0xFF));
|
||||||
|
c = set_byte(&temp_rnd[2], rev_rnd[2] + c);
|
||||||
|
c = set_byte(&temp_rnd[3], rev_rnd[3] + c);
|
||||||
|
c = set_byte(&temp_rnd[4], rev_rnd[4] + c);
|
||||||
|
c = set_byte(&temp_rnd[5], rev_rnd[5] + c);
|
||||||
|
set_byte(&temp_rnd[6], rev_rnd[6] + c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
c = set_byte(&temp_rnd[2], rev_rnd[2] + (rev_k & 0xFF));
|
||||||
|
c = set_byte(&temp_rnd[3], rev_rnd[3] + c + ((rev_k >> 8) & 0xFF));
|
||||||
|
c = set_byte(&temp_rnd[4], rev_rnd[4] + c);
|
||||||
|
c = set_byte(&temp_rnd[5], rev_rnd[5] + c);
|
||||||
|
set_byte(&temp_rnd[6], rev_rnd[6] + c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
c = set_byte(&temp_rnd[4], rev_rnd[4] + (rev_k & 0xFF));
|
||||||
|
c = set_byte(&temp_rnd[5], rev_rnd[5] + c + ((rev_k >> 8) & 0xFF));
|
||||||
|
set_byte(&temp_rnd[6], rev_rnd[6] + c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Dbprintf("Bad block number given: %d", address);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report progress every 256 attempts
|
||||||
|
if ((k % 0x100) == 0) {
|
||||||
|
Dbprintf("Trying: %04X", k);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Due to performance reason, we only try it once. Therefore you need a very stable RFID communcation.
|
||||||
|
if (authenticate(temp_rnd, frnd, auth_resp) == PM3_SUCCESS) {
|
||||||
|
if (g_dbglevel >= DBG_INFO)
|
||||||
|
Dbprintf("Authentication success with rnd: %02X%02X%02X%02X%02X%02X%02X", temp_rnd[0], temp_rnd[1], temp_rnd[2], temp_rnd[3], temp_rnd[4], temp_rnd[5], temp_rnd[6]);
|
||||||
|
response[0] = (k >> 8) & 0xFF;
|
||||||
|
response[1] = k & 0xFF;
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BUTTON_PRESS() || data_available()) {
|
||||||
|
Dbprintf("EM4x70 Bruteforce Interrupted");
|
||||||
|
return PM3_EOPABORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
static int send_pin(const uint32_t pin) {
|
static int send_pin(const uint32_t pin) {
|
||||||
|
|
||||||
// sends pin code for unlocking
|
// sends pin code for unlocking
|
||||||
|
@ -576,7 +651,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundheader) {
|
if (!foundheader) {
|
||||||
Dbprintf("Failed to find read header");
|
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Failed to find read header");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,6 +813,27 @@ void em4x70_auth(em4x70_data_t *etd, bool ledcontrol) {
|
||||||
reply_ng(CMD_LF_EM4X70_AUTH, status, response, sizeof(response));
|
reply_ng(CMD_LF_EM4X70_AUTH, status, response, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void em4x70_brute(em4x70_data_t *etd, bool ledcontrol) {
|
||||||
|
uint8_t status = 0;
|
||||||
|
uint8_t response[2] = {0};
|
||||||
|
|
||||||
|
command_parity = etd->parity;
|
||||||
|
|
||||||
|
init_tag();
|
||||||
|
em4x70_setup_read();
|
||||||
|
|
||||||
|
// Find the Tag
|
||||||
|
if (get_signalproperties() && find_em4x70_tag()) {
|
||||||
|
|
||||||
|
// Bruteforce partial key
|
||||||
|
status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response) == PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
StopTicks();
|
||||||
|
lf_finalize(ledcontrol);
|
||||||
|
reply_ng(CMD_LF_EM4X70_BRUTE, status, response, sizeof(response));
|
||||||
|
}
|
||||||
|
|
||||||
void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol) {
|
void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol) {
|
||||||
|
|
||||||
uint8_t status = 0;
|
uint8_t status = 0;
|
||||||
|
|
|
@ -32,6 +32,7 @@ typedef enum {
|
||||||
|
|
||||||
void em4x70_info(em4x70_data_t *etd, bool ledcontrol);
|
void em4x70_info(em4x70_data_t *etd, bool ledcontrol);
|
||||||
void em4x70_write(em4x70_data_t *etd, bool ledcontrol);
|
void em4x70_write(em4x70_data_t *etd, bool ledcontrol);
|
||||||
|
void em4x70_brute(em4x70_data_t *etd, bool ledcontrol);
|
||||||
void em4x70_unlock(em4x70_data_t *etd, bool ledcontrol);
|
void em4x70_unlock(em4x70_data_t *etd, bool ledcontrol);
|
||||||
void em4x70_auth(em4x70_data_t *etd, bool ledcontrol);
|
void em4x70_auth(em4x70_data_t *etd, bool ledcontrol);
|
||||||
void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol);
|
void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol);
|
||||||
|
|
|
@ -1229,6 +1229,17 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
|
||||||
|
|
||||||
AddCrc14A(rPPS, sizeof(rPPS) - 2);
|
AddCrc14A(rPPS, sizeof(rPPS) - 2);
|
||||||
|
|
||||||
|
if (tagType == 7) {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
uint8_t gen_pwd[4];
|
||||||
|
uint16_t start = (*pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH;
|
||||||
|
emlGetMemBt(pwd, start, sizeof(pwd));
|
||||||
|
Uint4byteToMemBe(gen_pwd, ul_ev1_pwdgenB(data));
|
||||||
|
if (memcmp(pwd, gen_pwd, sizeof(pwd)) == 0) {
|
||||||
|
rPACK[0] = 0x80;
|
||||||
|
rPACK[1] = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
AddCrc14A(rPACK, sizeof(rPACK) - 2);
|
AddCrc14A(rPACK, sizeof(rPACK) - 2);
|
||||||
|
|
||||||
static tag_response_info_t responses_init[] = {
|
static tag_response_info_t responses_init[] = {
|
||||||
|
|
|
@ -177,6 +177,36 @@ static void CodeIso15693AsReaderEOF(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) {
|
||||||
|
|
||||||
|
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
|
uint8_t cmd[5] = {0};
|
||||||
|
BuildIdentifyRequest(cmd);
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
SendDataTag(cmd, sizeof(cmd), false, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, eof_time, &recvlen);
|
||||||
|
|
||||||
|
if (recvlen != 12) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uid[0] = answer[2];
|
||||||
|
uid[1] = answer[3];
|
||||||
|
uid[2] = answer[4];
|
||||||
|
uid[3] = answer[5];
|
||||||
|
uid[4] = answer[6];
|
||||||
|
uid[5] = answer[7];
|
||||||
|
uid[6] = answer[8];
|
||||||
|
uid[7] = answer[9];
|
||||||
|
|
||||||
|
BigBuf_free();
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// encode data using "1 out of 256" scheme
|
// encode data using "1 out of 256" scheme
|
||||||
// data rate is 1,66 kbit/s (fc/8192)
|
// data rate is 1,66 kbit/s (fc/8192)
|
||||||
// is designed for more robust communication over longer distances
|
// is designed for more robust communication over longer distances
|
||||||
|
@ -2431,6 +2461,8 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
||||||
case ISO15693_WRITE_AFI:
|
case ISO15693_WRITE_AFI:
|
||||||
case ISO15693_LOCK_AFI:
|
case ISO15693_LOCK_AFI:
|
||||||
case ISO15693_WRITE_DSFID:
|
case ISO15693_WRITE_DSFID:
|
||||||
|
case ISO15693_WRITE_PASSWORD:
|
||||||
|
case ISO15693_PASSWORD_PROTECT_EAS:
|
||||||
case ISO15693_LOCK_DSFID:
|
case ISO15693_LOCK_DSFID:
|
||||||
timeout = ISO15693_READER_TIMEOUT_WRITE;
|
timeout = ISO15693_READER_TIMEOUT_WRITE;
|
||||||
request_answer = data[0] & ISO15_REQ_OPTION;
|
request_answer = data[0] & ISO15_REQ_OPTION;
|
||||||
|
@ -2640,7 +2672,7 @@ void SetTag15693Uid(const uint8_t *uid) {
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) {
|
static void init_password_15693_Slix(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) {
|
||||||
memcpy(buffer, pwd, 4);
|
memcpy(buffer, pwd, 4);
|
||||||
if (rnd) {
|
if (rnd) {
|
||||||
buffer[0] ^= rnd[0];
|
buffer[0] ^= rnd[0];
|
||||||
|
@ -2650,14 +2682,14 @@ static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) {
|
static bool get_rnd_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) {
|
||||||
// 0x04, == NXP from manufacture id list.
|
// 0x04, == NXP from manufacture id list.
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 };
|
||||||
AddCrc15(c, 3);
|
AddCrc15(c, 3);
|
||||||
|
|
||||||
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
uint16_t recvlen = 0;
|
uint16_t recvlen = 0;
|
||||||
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
int res = SendDataTag(c, sizeof(c), true, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
if (res != PM3_SUCCESS && recvlen != 5) {
|
if (res != PM3_SUCCESS && recvlen != 5) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2668,15 +2700,16 @@ static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) {
|
static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) {
|
||||||
|
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x04, == NXP from manufacture id list.
|
// 0x04, == NXP from manufacture id list.
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
init_password_15693_slixl(&c[4], password, rnd);
|
init_password_15693_Slix(&c[4], password, rnd);
|
||||||
AddCrc15(c, 8);
|
AddCrc15(c, 8);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2689,16 +2722,226 @@ static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, ui
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password, uint8_t *uid) {
|
||||||
static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
|
||||||
|
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
init_password_15693_Slix(&c[12], password, rnd);
|
||||||
|
|
||||||
|
memcpy(&c[3], uid, 8);
|
||||||
|
AddCrc15(c, 16);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password) {
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
init_password_15693_Slix(&c[3], password, rnd);
|
||||||
|
AddCrc15(c, 7);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd) {
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usepwd) {
|
||||||
|
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if (res_setpass != PM3_SUCCESS) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA3, 0x04, 0x00, 0x00};
|
||||||
|
AddCrc15(c, 3);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd) {
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usepwd) {
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if (res_setpass != PM3_SUCCESS) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA2, 0x04, 0x00, 0x00};
|
||||||
|
//init_password_15693_Slix(&c[3], password, rnd);
|
||||||
|
AddCrc15(c, 3);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, uint8_t *password, uint8_t *uid) {
|
||||||
|
|
||||||
|
uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
memcpy(&new_pwd_cmd[3], uid, 8);
|
||||||
|
memcpy(&new_pwd_cmd[12], password, 4);
|
||||||
|
|
||||||
|
AddCrc15(new_pwd_cmd, 16);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res_wrp = SendDataTag(new_pwd_cmd, sizeof(new_pwd_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res_wrp != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, uint8_t *password) {
|
||||||
|
|
||||||
|
uint8_t flags;
|
||||||
|
|
||||||
|
if (set_option_flag)
|
||||||
|
flags = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION;
|
||||||
|
else
|
||||||
|
flags = ISO15_REQ_DATARATE_HIGH;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if (res_setpass != PM3_SUCCESS) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t new_pass_protect_cmd[] = { flags, ISO15693_PASSWORD_PROTECT_EAS, 0x04, 0x00, 0x00};
|
||||||
|
AddCrc15(new_pass_protect_cmd, 3);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res = SendDataTag(new_pass_protect_cmd, sizeof(new_pass_protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t write_afi_15693(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi) {
|
||||||
|
|
||||||
|
if (!use_uid) {
|
||||||
|
int res_getuid = get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
if (res_getuid != PM3_SUCCESS) {
|
||||||
|
return res_getuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usepwd) {
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if (res_setpass != PM3_SUCCESS) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cmd[] = { ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_AFI, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
memcpy(&cmd[2], uid, 8);
|
||||||
|
cmd[10] = afi;
|
||||||
|
AddCrc15(cmd, 11);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res = SendDataTag(cmd, sizeof(cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS || recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static uint32_t enable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_ENABLE_PRIVACY, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_ENABLE_PRIVACY, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
memcpy(&c[3], uid, 8);
|
memcpy(&c[3], uid, 8);
|
||||||
init_password_15693_slixl(&c[11], password, rnd);
|
init_password_15693_Slix(&c[11], password, rnd);
|
||||||
AddCrc15(c, 15);
|
AddCrc15(c, 15);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2711,16 +2954,16 @@ static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_ti
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
memcpy(&c[3], uid, 8);
|
memcpy(&c[3], uid, 8);
|
||||||
c[11] = pass_id;
|
c[11] = pass_id;
|
||||||
init_password_15693_slixl(&c[12], password, NULL);
|
init_password_15693_Slix(&c[12], password, NULL);
|
||||||
AddCrc15(c, 16);
|
AddCrc15(c, 16);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2734,16 +2977,16 @@ static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_ti
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) {
|
static uint32_t destroy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) {
|
||||||
|
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_DESTROY, ISO15693_ENABLE_PRIVACY, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_DESTROY, ISO15693_ENABLE_PRIVACY, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
memcpy(&c[3], uid, 8);
|
memcpy(&c[3], uid, 8);
|
||||||
init_password_15693_slixl(&c[11], password, rnd);
|
init_password_15693_Slix(&c[11], password, rnd);
|
||||||
AddCrc15(c, 15);
|
AddCrc15(c, 15);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2758,8 +3001,32 @@ static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uin
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Sets a PRIVACY password to all ZEROS
|
void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id) {
|
||||||
void DisablePrivacySlixLIso15693(uint8_t *password) {
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = PM3_EFAILED;
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, &eof_time, uid);
|
||||||
|
|
||||||
|
res = set_pass_15693_Slix(start_time, &eof_time, pwd_id, old_password, uid);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = write_password_15693_Slix(start_time, &eof_time, pwd_id, new_password, uid);
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0);
|
||||||
|
|
||||||
|
switch_off();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisablePrivacySlixIso15693(uint8_t *password) {
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
Iso15693InitReader();
|
Iso15693InitReader();
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
@ -2769,13 +3036,12 @@ void DisablePrivacySlixLIso15693(uint8_t *password) {
|
||||||
// 0x04 Privacy
|
// 0x04 Privacy
|
||||||
// 0x08 Destroy SLIX-L
|
// 0x08 Destroy SLIX-L
|
||||||
// 0x10 EAS/AFI
|
// 0x10 EAS/AFI
|
||||||
int res = set_pass_15693_slixl(start_time, &eof_time, 0x04, password);
|
int res = disable_privacy_15693_Slix(start_time, &eof_time, 0x04, password);
|
||||||
reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, res, NULL, 0);
|
reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, res, NULL, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets a EAS/AFI password to all ZEROS
|
void EnablePrivacySlixIso15693(uint8_t *password) {
|
||||||
void DisableEAS_AFISlixLIso15693(uint8_t *password) {
|
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
Iso15693InitReader();
|
Iso15693InitReader();
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
@ -2785,8 +3051,71 @@ void DisableEAS_AFISlixLIso15693(uint8_t *password) {
|
||||||
// 0x04 Privacy
|
// 0x04 Privacy
|
||||||
// 0x08 Destroy SLIX-L
|
// 0x08 Destroy SLIX-L
|
||||||
// 0x10 EAS/AFI
|
// 0x10 EAS/AFI
|
||||||
int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password);
|
int res = set_privacy_15693_Slix(start_time, &eof_time, password);
|
||||||
reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI, res, NULL, 0);
|
reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, res, NULL, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
|
||||||
|
// Password identifier Password byte
|
||||||
|
// 0x04 Privacy
|
||||||
|
// 0x08 Destroy SLIX-L
|
||||||
|
// 0x10 EAS/AFI
|
||||||
|
int res = disable_eas_15693_Slix(start_time, &eof_time, password, usepwd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_EAS, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
|
||||||
|
// Password identifier Password byte
|
||||||
|
// 0x04 Privacy
|
||||||
|
// 0x08 Destroy SLIX-L
|
||||||
|
// 0x10 EAS/AFI
|
||||||
|
int res = enable_eas_15693_Slix(start_time, &eof_time, password, usepwd);
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_EAS, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PassProtextEASSlixIso15693(uint8_t *password) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, false, password);
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
void PassProtectAFISlixIso15693(uint8_t *password) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, true, password);
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteAFIIso15693(uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = write_afi_15693(start_time, &eof_time, password, use_pwd, uid, use_uid, afi);
|
||||||
|
//int res = PM3_SUCCESS;
|
||||||
|
reply_ng(CMD_HF_ISO15693_WRITE_AFI, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
|
@ -62,6 +62,12 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui
|
||||||
|
|
||||||
void SetTag15693Uid(const uint8_t *uid);
|
void SetTag15693Uid(const uint8_t *uid);
|
||||||
|
|
||||||
void DisablePrivacySlixLIso15693(uint8_t *password);
|
void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id);
|
||||||
void DisableEAS_AFISlixLIso15693(uint8_t *password);
|
void DisablePrivacySlixIso15693(uint8_t *password);
|
||||||
|
void EnablePrivacySlixIso15693(uint8_t *password);
|
||||||
|
void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd);
|
||||||
|
void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd);
|
||||||
|
void PassProtextEASSlixIso15693(uint8_t *password);
|
||||||
|
void PassProtectAFISlixIso15693(uint8_t *password);
|
||||||
|
void WriteAFIIso15693(uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -296,7 +296,9 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) {
|
||||||
uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold,
|
uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold,
|
||||||
bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip, bool ledcontrol) {
|
bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip, bool ledcontrol) {
|
||||||
|
|
||||||
initSampleBuffer(&sample_size);
|
initSampleBuffer(&sample_size); // sample size in bytes
|
||||||
|
sample_size <<= 3; // sample size in bits
|
||||||
|
sample_size /= bits_per_sample; // sample count
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
if (g_dbglevel >= DBG_DEBUG) {
|
||||||
printSamples();
|
printSamples();
|
||||||
|
@ -368,8 +370,11 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
||||||
|
if (bits_per_sample == 8) {
|
||||||
|
// these functions only consider bps==8
|
||||||
removeSignalOffset(data.buffer, samples.total_saved);
|
removeSignalOffset(data.buffer, samples.total_saved);
|
||||||
computeSignalProperties(data.buffer, samples.total_saved);
|
computeSignalProperties(data.buffer, samples.total_saved);
|
||||||
|
}
|
||||||
return data.numbits;
|
return data.numbits;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -139,6 +139,7 @@ void MifareDesfireGetInformation(void) {
|
||||||
uint8_t details[14];
|
uint8_t details[14];
|
||||||
} PACKED payload;
|
} PACKED payload;
|
||||||
|
|
||||||
|
memset(&payload, 0x00, sizeof(payload));
|
||||||
/*
|
/*
|
||||||
1 = PCB 1
|
1 = PCB 1
|
||||||
2 = cid 2
|
2 = cid 2
|
||||||
|
@ -181,6 +182,12 @@ void MifareDesfireGetInformation(void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len < sizeof(payload.versionHW)+1) {
|
||||||
|
Dbprintf("Tag answer to MFDES_GET_VERSION was too short: data in Hardware Information is probably invalid.");
|
||||||
|
print_result("Answer", resp, len);
|
||||||
|
memset(resp+len, 0xFF, sizeof(payload.versionHW)+1 - len); // clear remaining bytes
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW));
|
memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW));
|
||||||
|
|
||||||
// ADDITION_FRAME 1
|
// ADDITION_FRAME 1
|
||||||
|
@ -193,6 +200,13 @@ void MifareDesfireGetInformation(void) {
|
||||||
switch_off();
|
switch_off();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len < sizeof(payload.versionSW)+1) {
|
||||||
|
Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 1 was too short: data in Software Information is probably invalid.");
|
||||||
|
print_result("Answer", resp, len);
|
||||||
|
memset(resp+len, 0xFF, sizeof(payload.versionSW)+1 - len); // clear remaining bytes
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW));
|
memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW));
|
||||||
|
|
||||||
// ADDITION_FRAME 2
|
// ADDITION_FRAME 2
|
||||||
|
@ -205,6 +219,12 @@ void MifareDesfireGetInformation(void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len < sizeof(payload.details)+1) {
|
||||||
|
Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 2 was too short: data in Batch number and Production date is probably invalid");
|
||||||
|
print_result("Answer", resp, len);
|
||||||
|
memset(resp+len, 0xFF, sizeof(payload.details)+1 - len); // clear remaining bytes
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(payload.details, resp + 1, sizeof(payload.details));
|
memcpy(payload.details, resp + 1, sizeof(payload.details));
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
|
|
@ -34,11 +34,17 @@ VERSIONSRC = version_pm3.c
|
||||||
# THUMBSRC :=
|
# THUMBSRC :=
|
||||||
|
|
||||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
||||||
APP_CFLAGS = -I. -ffunction-sections -fdata-sections
|
APP_CFLAGS = -I. -ffunction-sections -fdata-sections -DAS_BOOTROM
|
||||||
|
|
||||||
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc, no-common makes sure uninitialized vars don't end up in COMMON area
|
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc, no-common makes sure uninitialized vars don't end up in COMMON area
|
||||||
APP_CFLAGS += -fno-stack-protector -fno-pie -fno-common
|
APP_CFLAGS += -fno-stack-protector -fno-pie -fno-common
|
||||||
|
|
||||||
|
ifneq (,$(findstring WITH_FLASH,$(PLATFORM_DEFS)))
|
||||||
|
APP_CFLAGS += -DWITH_FLASH
|
||||||
|
APP_CFLAGS += -I../common_arm
|
||||||
|
THUMBSRC += flashmem.c ticks.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
|
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
|
||||||
include ../common_arm/Makefile.common
|
include ../common_arm/Makefile.common
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#include "clocks.h"
|
#include "clocks.h"
|
||||||
#include "usb_cdc.h"
|
#include "usb_cdc.h"
|
||||||
|
|
||||||
|
#ifdef WITH_FLASH
|
||||||
|
#include "flashmem.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "proxmark3_arm.h"
|
#include "proxmark3_arm.h"
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
|
@ -214,8 +218,18 @@ static void flash_mode(void) {
|
||||||
bootrom_unlocked = false;
|
bootrom_unlocked = false;
|
||||||
uint8_t rx[sizeof(PacketCommandOLD)];
|
uint8_t rx[sizeof(PacketCommandOLD)];
|
||||||
g_common_area.command = COMMON_AREA_COMMAND_NONE;
|
g_common_area.command = COMMON_AREA_COMMAND_NONE;
|
||||||
if (!g_common_area.flags.button_pressed && BUTTON_PRESS())
|
if (!g_common_area.flags.button_pressed && BUTTON_PRESS()) {
|
||||||
g_common_area.flags.button_pressed = 1;
|
g_common_area.flags.button_pressed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_FLASH
|
||||||
|
if (FlashInit()) { // checks for existence of flash also ... OK because bootrom was built for devices with flash
|
||||||
|
uint64_t flash_uniqueID = 0;
|
||||||
|
Flash_UniqueID((uint8_t *)&flash_uniqueID);
|
||||||
|
FlashStop();
|
||||||
|
usb_update_serial(flash_uniqueID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
usb_enable();
|
usb_enable();
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ SECTIONS
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
*(.data)
|
*(.data)
|
||||||
*(.data.*)
|
*(.data.*)
|
||||||
|
*(.ramfunc)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >ram AT>bootphase2 :phase2
|
} >ram AT>bootphase2 :phase2
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ if (NOT SKIPREADLINE EQUAL 1)
|
||||||
ExternalProject_Add_StepTargets(ncurses configure build install)
|
ExternalProject_Add_StepTargets(ncurses configure build install)
|
||||||
|
|
||||||
ExternalProject_Add(readline
|
ExternalProject_Add(readline
|
||||||
URL ftp://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz
|
URL ftp://ftp.gnu.org/gnu/readline/readline-8.2.tar.gz
|
||||||
PREFIX deps/readline
|
PREFIX deps/readline
|
||||||
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
|
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
|
||||||
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
|
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
|
||||||
|
@ -163,11 +163,12 @@ endif (NOT SKIPJANSSONSYSTEM EQUAL 1)
|
||||||
|
|
||||||
if(EMBED_BZIP2)
|
if(EMBED_BZIP2)
|
||||||
set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
|
set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2)
|
||||||
|
# Specify SOURCE_DIR will cause some errors
|
||||||
ExternalProject_Add(bzip2
|
ExternalProject_Add(bzip2
|
||||||
GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2
|
GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2
|
||||||
GIT_TAG platform-tools-30.0.2
|
GIT_TAG platform-tools-30.0.2
|
||||||
PREFIX deps/bzip2
|
PREFIX deps/bzip2
|
||||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2
|
# SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2
|
||||||
CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x
|
CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x
|
||||||
BUILD_IN_SOURCE ON
|
BUILD_IN_SOURCE ON
|
||||||
BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a
|
BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a
|
||||||
|
@ -584,6 +585,9 @@ if (MINGW)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}")
|
set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}")
|
||||||
set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
|
# link Winsock2
|
||||||
|
set(ADDITIONAL_LNK ws2_32 ${ADDITIONAL_LNK})
|
||||||
endif (MINGW)
|
endif (MINGW)
|
||||||
|
|
||||||
target_include_directories(proxmark3 PRIVATE
|
target_include_directories(proxmark3 PRIVATE
|
||||||
|
|
|
@ -93,7 +93,6 @@ LUALIBLD =
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
LUAPLATFORM = mingw
|
LUAPLATFORM = mingw
|
||||||
LDLIBS += -lws2_32
|
|
||||||
else
|
else
|
||||||
ifeq ($(platform),Darwin)
|
ifeq ($(platform),Darwin)
|
||||||
LUAPLATFORM = macosx
|
LUAPLATFORM = macosx
|
||||||
|
@ -103,6 +102,11 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
## Winsock2
|
||||||
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
|
LDLIBS += -lws2_32
|
||||||
|
endif
|
||||||
|
|
||||||
## Reveng
|
## Reveng
|
||||||
REVENGLIBPATH = ./deps/reveng
|
REVENGLIBPATH = ./deps/reveng
|
||||||
REVENGLIBINC = -I$(REVENGLIBPATH)
|
REVENGLIBINC = -I$(REVENGLIBPATH)
|
||||||
|
|
|
@ -17,7 +17,7 @@ target_compile_definitions(pm3rrg_rdv4_hardnested_nosimd PRIVATE NOSIMD_BUILD)
|
||||||
## Mingw platforms: AMD64
|
## Mingw platforms: AMD64
|
||||||
set(X86_CPUS x86 x86_64 i686 AMD64)
|
set(X86_CPUS x86 x86_64 i686 AMD64)
|
||||||
set(ARM64_CPUS arm64 aarch64)
|
set(ARM64_CPUS arm64 aarch64)
|
||||||
set(ARM32_CPUS armel armhf)
|
set(ARM32_CPUS armel armhf armv7-a)
|
||||||
|
|
||||||
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
|
||||||
|
|
|
@ -3,36 +3,46 @@
|
||||||
# -- iceman fork version --
|
# -- iceman fork version --
|
||||||
# -- contribute to this list, sharing is caring --
|
# -- contribute to this list, sharing is caring --
|
||||||
#
|
#
|
||||||
# Defaultkey(firstkeyusedbyprogramifnouserdefinedkey)
|
# Default key
|
||||||
FFFFFFFFFFFF
|
FFFFFFFFFFFF
|
||||||
# Blankkey
|
#
|
||||||
|
# Blank key
|
||||||
000000000000
|
000000000000
|
||||||
|
#
|
||||||
# NFC Forum MADkey
|
# NFC Forum MADkey
|
||||||
A0A1A2A3A4A5
|
A0A1A2A3A4A5
|
||||||
|
#
|
||||||
# MAD access key A (reversed)
|
# MAD access key A (reversed)
|
||||||
A5A4A3A2A1A0
|
A5A4A3A2A1A0
|
||||||
|
#
|
||||||
# MAD access key B
|
# MAD access key B
|
||||||
89ECA97F8C2A
|
89ECA97F8C2A
|
||||||
#
|
#
|
||||||
|
#
|
||||||
B0B1B2B3B4B5
|
B0B1B2B3B4B5
|
||||||
C0C1C2C3C4C5
|
C0C1C2C3C4C5
|
||||||
D0D1D2D3D4D5
|
D0D1D2D3D4D5
|
||||||
AABBCCDDEEFF
|
AABBCCDDEEFF
|
||||||
4D3A99C351DD
|
4D3A99C351DD
|
||||||
1A982C7E459A
|
1A982C7E459A
|
||||||
|
#
|
||||||
# key A Wien
|
# key A Wien
|
||||||
D3F7D3F7D3F7
|
D3F7D3F7D3F7
|
||||||
|
#
|
||||||
# key B Wien
|
# key B Wien
|
||||||
5A1B85FCE20A
|
5A1B85FCE20A
|
||||||
#
|
#
|
||||||
|
#
|
||||||
714C5C886E97
|
714C5C886E97
|
||||||
587EE5F9350F
|
587EE5F9350F
|
||||||
A0478CC39091
|
A0478CC39091
|
||||||
533CB6C723F6
|
533CB6C723F6
|
||||||
8FD0A4F256E9
|
8FD0A4F256E9
|
||||||
|
#
|
||||||
# iCopy-X
|
# iCopy-X
|
||||||
E00000000000
|
E00000000000
|
||||||
#
|
#
|
||||||
|
#
|
||||||
E7D6064C5860
|
E7D6064C5860
|
||||||
B27CCAB30DBD
|
B27CCAB30DBD
|
||||||
#
|
#
|
||||||
|
@ -41,6 +51,9 @@ D2ECE8B9395E
|
||||||
# NSCP default key
|
# NSCP default key
|
||||||
1494E81663D7
|
1494E81663D7
|
||||||
#
|
#
|
||||||
|
# NFC tools
|
||||||
|
7c9fb8474242
|
||||||
|
#
|
||||||
# Kiev keys
|
# Kiev keys
|
||||||
569369C5A0E5
|
569369C5A0E5
|
||||||
632193BE1C3C
|
632193BE1C3C
|
||||||
|
@ -54,31 +67,41 @@ F14EE7CAE863
|
||||||
# RKF
|
# RKF
|
||||||
# Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA
|
# Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA
|
||||||
FC00018778F7
|
FC00018778F7
|
||||||
|
#
|
||||||
# Västtrafiken KeyA
|
# Västtrafiken KeyA
|
||||||
0297927C0F77
|
0297927C0F77
|
||||||
54726176656C
|
54726176656C
|
||||||
|
#
|
||||||
# Västtrafiken KeyB
|
# Västtrafiken KeyB
|
||||||
00000FFE2488
|
00000FFE2488
|
||||||
776974687573
|
776974687573
|
||||||
EE0042F88840
|
EE0042F88840
|
||||||
|
#
|
||||||
# RKF SLKeyA
|
# RKF SLKeyA
|
||||||
26940B21FF5D
|
26940B21FF5D
|
||||||
A64598A77478
|
A64598A77478
|
||||||
|
#
|
||||||
# RKF SLKeyB
|
# RKF SLKeyB
|
||||||
5C598C9C58B5
|
5C598C9C58B5
|
||||||
E4D2770A89BE
|
E4D2770A89BE
|
||||||
# RKF RejskortDanmark KeyA
|
#
|
||||||
|
# RKF Rejskort Danmark KeyA
|
||||||
722BFCC5375F
|
722BFCC5375F
|
||||||
# RKF RejskortDanmark KeyB
|
#
|
||||||
|
# RKF Rejskort Danmark KeyB
|
||||||
F1D83F964314
|
F1D83F964314
|
||||||
# RKF JOJOPRIVAKeyA
|
#
|
||||||
|
# RKF JOJOPRIVA KeyA
|
||||||
505249564141
|
505249564141
|
||||||
# RKF JOJOPRIVAKeyB
|
#
|
||||||
|
# RKF JOJOPRIVA KeyB
|
||||||
505249564142
|
505249564142
|
||||||
# RKF JOJOGROUPKeyA
|
#
|
||||||
|
# RKF JOJOGROUP KeyA
|
||||||
47524F555041
|
47524F555041
|
||||||
434F4D4D4F41
|
434F4D4D4F41
|
||||||
# RKF JOJOGROUPKeyB
|
#
|
||||||
|
# RKF JOJOGROUP KeyB
|
||||||
47524F555042
|
47524F555042
|
||||||
434F4D4D4F42
|
434F4D4D4F42
|
||||||
#
|
#
|
||||||
|
@ -108,11 +131,14 @@ F1D83F964314
|
||||||
200000000000
|
200000000000
|
||||||
222222222222
|
222222222222
|
||||||
27DD91F1FCF1
|
27DD91F1FCF1
|
||||||
# DirectoryandeventlogKeyB
|
#
|
||||||
|
# Directory and eventlog KeyB
|
||||||
2BA9621E0A36
|
2BA9621E0A36
|
||||||
# DirectoryandeventlogKeyA
|
#
|
||||||
|
# Directory and eventlog KeyA
|
||||||
4AF9D7ADEBE4
|
4AF9D7ADEBE4
|
||||||
#
|
#
|
||||||
|
#
|
||||||
333333333333
|
333333333333
|
||||||
33F974B42769
|
33F974B42769
|
||||||
34D1DF9934C5
|
34D1DF9934C5
|
||||||
|
@ -131,9 +157,11 @@ A00000000000
|
||||||
A053A292A4AF
|
A053A292A4AF
|
||||||
A94133013401
|
A94133013401
|
||||||
AAAAAAAAAAAA
|
AAAAAAAAAAAA
|
||||||
# Keyfromladyada.net
|
#
|
||||||
|
# Key from ladyada.net
|
||||||
ABCDEF123456
|
ABCDEF123456
|
||||||
#
|
#
|
||||||
|
#
|
||||||
B00000000000
|
B00000000000
|
||||||
B127C6F41436
|
B127C6F41436
|
||||||
BBBBBBBBBBBB
|
BBBBBBBBBBBB
|
||||||
|
@ -147,7 +175,9 @@ EEEEEEEEEEEE
|
||||||
# data from forum
|
# data from forum
|
||||||
FFFFFF545846
|
FFFFFF545846
|
||||||
#
|
#
|
||||||
|
#
|
||||||
F1A97341A9FC
|
F1A97341A9FC
|
||||||
|
#
|
||||||
# hotel system
|
# hotel system
|
||||||
44AB09010845
|
44AB09010845
|
||||||
85FED980EA5A
|
85FED980EA5A
|
||||||
|
@ -157,7 +187,9 @@ F1A97341A9FC
|
||||||
# ARD (fr) key B
|
# ARD (fr) key B
|
||||||
4A2B29111213
|
4A2B29111213
|
||||||
#
|
#
|
||||||
|
#
|
||||||
4143414F5250
|
4143414F5250
|
||||||
|
#
|
||||||
# Tehran Railway
|
# Tehran Railway
|
||||||
A9B43414F585
|
A9B43414F585
|
||||||
1FB235AC1388
|
1FB235AC1388
|
||||||
|
@ -169,13 +201,17 @@ F4A9EF2AFC6D
|
||||||
#
|
#
|
||||||
# S0 B
|
# S0 B
|
||||||
89EAC97F8C2A
|
89EAC97F8C2A
|
||||||
|
#
|
||||||
# S4 A
|
# S4 A
|
||||||
43C7600DEE6B
|
43C7600DEE6B
|
||||||
|
#
|
||||||
# S6 A
|
# S6 A
|
||||||
0120BF672A64
|
0120BF672A64
|
||||||
|
#
|
||||||
# S6 B
|
# S6 B
|
||||||
FB0B20DF1F34
|
FB0B20DF1F34
|
||||||
#
|
#
|
||||||
|
#
|
||||||
A9F953DEF0A3
|
A9F953DEF0A3
|
||||||
#
|
#
|
||||||
# Data from forum
|
# Data from forum
|
||||||
|
@ -233,14 +269,17 @@ AAFB06045877
|
||||||
# gym
|
# gym
|
||||||
# Fysiken A
|
# Fysiken A
|
||||||
3E65E4FB65B3
|
3E65E4FB65B3
|
||||||
|
#
|
||||||
# Fysiken B
|
# Fysiken B
|
||||||
25094DF6F148
|
25094DF6F148
|
||||||
|
#
|
||||||
# CleverFit
|
# CleverFit
|
||||||
A05DBD98E0FC
|
A05DBD98E0FC
|
||||||
#
|
#
|
||||||
# Hotel KeyCard
|
# Hotel KeyCard
|
||||||
D3B595E9DD63
|
D3B595E9DD63
|
||||||
AFBECD121004
|
AFBECD121004
|
||||||
|
#
|
||||||
# SimonsVoss
|
# SimonsVoss
|
||||||
6471A5EF2D1A
|
6471A5EF2D1A
|
||||||
#
|
#
|
||||||
|
@ -396,9 +435,11 @@ C52876869800
|
||||||
# Data from mall
|
# Data from mall
|
||||||
# playland balikesir
|
# playland balikesir
|
||||||
ABBA1234FCB0
|
ABBA1234FCB0
|
||||||
|
#
|
||||||
# A trio bowling bahcelievler
|
# A trio bowling bahcelievler
|
||||||
314F495254FF
|
314F495254FF
|
||||||
4152414B4E41
|
4152414B4E41
|
||||||
|
#
|
||||||
# karinca park nigde
|
# karinca park nigde
|
||||||
4E474434FFFF
|
4E474434FFFF
|
||||||
#
|
#
|
||||||
|
@ -477,18 +518,21 @@ D9A37831DCE5
|
||||||
C5CFE06D9EA3
|
C5CFE06D9EA3
|
||||||
C0DECE673829
|
C0DECE673829
|
||||||
#
|
#
|
||||||
|
#
|
||||||
A56C2DF9A26D
|
A56C2DF9A26D
|
||||||
#
|
#
|
||||||
# Data from https://pastebin.com/vbwast74
|
# Data from https://pastebin.com/vbwast74
|
||||||
#
|
|
||||||
68D3F7307C89
|
68D3F7307C89
|
||||||
|
#
|
||||||
# Smart Rider. Western Australian Public Transport Cards
|
# Smart Rider. Western Australian Public Transport Cards
|
||||||
568C9083F71C
|
568C9083F71C
|
||||||
#
|
#
|
||||||
# Bangkok metro key
|
# Bangkok metro key
|
||||||
97F5DA640B18
|
97F5DA640B18
|
||||||
|
#
|
||||||
# Metro Valencia key
|
# Metro Valencia key
|
||||||
A8844B0BCA06
|
A8844B0BCA06
|
||||||
|
#
|
||||||
# HTC Eindhoven key
|
# HTC Eindhoven key
|
||||||
857464D3AAD1
|
857464D3AAD1
|
||||||
#
|
#
|
||||||
|
@ -501,6 +545,7 @@ A8844B0BCA06
|
||||||
# French VIGIK
|
# French VIGIK
|
||||||
# VIGIK1 A
|
# VIGIK1 A
|
||||||
314B49474956
|
314B49474956
|
||||||
|
#
|
||||||
# VIGIK1 B
|
# VIGIK1 B
|
||||||
564C505F4D41
|
564C505F4D41
|
||||||
BA5B895DA162
|
BA5B895DA162
|
||||||
|
@ -508,16 +553,20 @@ BA5B895DA162
|
||||||
# Vigik mystery Keys Mifare 1k EV1 (S50)
|
# Vigik mystery Keys Mifare 1k EV1 (S50)
|
||||||
# 16 A
|
# 16 A
|
||||||
5C8FF9990DA2
|
5C8FF9990DA2
|
||||||
|
#
|
||||||
# 17 A
|
# 17 A
|
||||||
75CCB59C9BED
|
75CCB59C9BED
|
||||||
|
#
|
||||||
# 16 B
|
# 16 B
|
||||||
D01AFEEB890A
|
D01AFEEB890A
|
||||||
|
#
|
||||||
# 17 B
|
# 17 B
|
||||||
4B791BEA7BCC
|
4B791BEA7BCC
|
||||||
#
|
#
|
||||||
# BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
|
# BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
|
||||||
021209197591
|
021209197591
|
||||||
#
|
#
|
||||||
|
#
|
||||||
2EF720F2AF76
|
2EF720F2AF76
|
||||||
414C41524F4E
|
414C41524F4E
|
||||||
424C41524F4E
|
424C41524F4E
|
||||||
|
@ -676,6 +725,7 @@ F7A39753D018
|
||||||
410B9B40B872
|
410B9B40B872
|
||||||
2CB1A90071C8
|
2CB1A90071C8
|
||||||
#
|
#
|
||||||
|
#
|
||||||
8697389ACA26
|
8697389ACA26
|
||||||
1AB23CD45EF6
|
1AB23CD45EF6
|
||||||
013889343891
|
013889343891
|
||||||
|
@ -691,6 +741,7 @@ EC0A9B1A9E06
|
||||||
0F230695923F
|
0F230695923F
|
||||||
0000014B5C31
|
0000014B5C31
|
||||||
#
|
#
|
||||||
|
#
|
||||||
BEDB604CC9D1
|
BEDB604CC9D1
|
||||||
B8A1F613CF3D
|
B8A1F613CF3D
|
||||||
B578F38A5C61
|
B578F38A5C61
|
||||||
|
@ -699,12 +750,15 @@ B66AC040203A
|
||||||
2E641D99AD5B
|
2E641D99AD5B
|
||||||
AD4FB33388BF
|
AD4FB33388BF
|
||||||
69FB7B7CD8EE
|
69FB7B7CD8EE
|
||||||
|
#
|
||||||
# Hotel
|
# Hotel
|
||||||
2A6D9205E7CA
|
2A6D9205E7CA
|
||||||
13B91C226E56
|
13B91C226E56
|
||||||
|
#
|
||||||
# KABA Hotel Locks
|
# KABA Hotel Locks
|
||||||
2A2C13CC242A
|
2A2C13CC242A
|
||||||
#
|
#
|
||||||
|
#
|
||||||
27FBC86A00D0
|
27FBC86A00D0
|
||||||
01FA3FC68349
|
01FA3FC68349
|
||||||
#
|
#
|
||||||
|
@ -761,8 +815,10 @@ D58023BA2BDC
|
||||||
2ED3B15E7C0F
|
2ED3B15E7C0F
|
||||||
F66224EE1E89
|
F66224EE1E89
|
||||||
#
|
#
|
||||||
|
#
|
||||||
60012E9BA3FA
|
60012E9BA3FA
|
||||||
#
|
#
|
||||||
|
#
|
||||||
DE1FCBEC764B
|
DE1FCBEC764B
|
||||||
81BFBE8CACBA
|
81BFBE8CACBA
|
||||||
BFF123126C9B
|
BFF123126C9B
|
||||||
|
@ -775,11 +831,13 @@ D80511FC2AB4
|
||||||
BB467463ACD6
|
BB467463ACD6
|
||||||
E67C8010502D
|
E67C8010502D
|
||||||
FF58BA1B4478
|
FF58BA1B4478
|
||||||
|
#
|
||||||
# Data from https://pastebin.com/Kz8xp4ev
|
# Data from https://pastebin.com/Kz8xp4ev
|
||||||
FBF225DC5D58
|
FBF225DC5D58
|
||||||
#
|
#
|
||||||
# Data https://pastebin.com/BEm6bdAE
|
# Data https://pastebin.com/BEm6bdAE
|
||||||
# vingcard.txt
|
# vingcard.txt
|
||||||
|
# Note: most likely diversified
|
||||||
4708111C8604
|
4708111C8604
|
||||||
3D50D902EA48
|
3D50D902EA48
|
||||||
96A301BCE267
|
96A301BCE267
|
||||||
|
@ -801,10 +859,12 @@ D58660D1ACDE
|
||||||
50A11381502C
|
50A11381502C
|
||||||
C01FC822C6E5
|
C01FC822C6E5
|
||||||
0854BF31111E
|
0854BF31111E
|
||||||
# More keys:
|
#
|
||||||
|
# More keys
|
||||||
8A19D40CF2B5
|
8A19D40CF2B5
|
||||||
AE8587108640
|
AE8587108640
|
||||||
# SafLock standalone door locks.
|
#
|
||||||
|
# SafLock standalone door locks
|
||||||
135B88A94B8B
|
135B88A94B8B
|
||||||
#
|
#
|
||||||
# Russian Troika card
|
# Russian Troika card
|
||||||
|
@ -863,7 +923,7 @@ F8493407799D
|
||||||
6B8BD9860763
|
6B8BD9860763
|
||||||
D3A297DC2698
|
D3A297DC2698
|
||||||
#
|
#
|
||||||
# Keys from MifareClassicTool project
|
# Keys from Mifare Classic Tool project
|
||||||
044CE1872BC3
|
044CE1872BC3
|
||||||
045CECA15535
|
045CECA15535
|
||||||
0BE5FAC8B06A
|
0BE5FAC8B06A
|
||||||
|
@ -918,7 +978,6 @@ FD8705E721B0
|
||||||
00ADA2CD516D
|
00ADA2CD516D
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
##
|
|
||||||
237A4D0D9119
|
237A4D0D9119
|
||||||
0ED7846C2BC9
|
0ED7846C2BC9
|
||||||
FFFFD06F83E3
|
FFFFD06F83E3
|
||||||
|
@ -965,12 +1024,13 @@ A2B2C9D187FB
|
||||||
# Hotel Adina
|
# Hotel Adina
|
||||||
9EBC3EB37130
|
9EBC3EB37130
|
||||||
#
|
#
|
||||||
# most likely diversed individual keys.
|
# most likely diversifed individual keys.
|
||||||
# data from https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c
|
# data from https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c
|
||||||
491CDC863104
|
491CDC863104
|
||||||
A2F63A485632
|
A2F63A485632
|
||||||
98631ED2B229
|
98631ED2B229
|
||||||
19F1FFE02563
|
19F1FFE02563
|
||||||
|
#
|
||||||
# Argentina
|
# Argentina
|
||||||
563A22C01FC8
|
563A22C01FC8
|
||||||
43CA22C13091
|
43CA22C13091
|
||||||
|
@ -983,7 +1043,6 @@ AFBECD120454
|
||||||
842146108088
|
842146108088
|
||||||
#
|
#
|
||||||
# TAPCARD PUBLIC TRANSPORT LA
|
# TAPCARD PUBLIC TRANSPORT LA
|
||||||
#
|
|
||||||
EA1B88DF0A76
|
EA1B88DF0A76
|
||||||
D1991E71E2C5
|
D1991E71E2C5
|
||||||
05F89678CFCF
|
05F89678CFCF
|
||||||
|
@ -1018,7 +1077,6 @@ E3AD9E9BA5D4
|
||||||
6C9EC046C1A4
|
6C9EC046C1A4
|
||||||
#
|
#
|
||||||
# ROC HIGHSCHOOL ACCESSCARD
|
# ROC HIGHSCHOOL ACCESSCARD
|
||||||
#
|
|
||||||
B021669B44BB
|
B021669B44BB
|
||||||
B18CDCDE52B7
|
B18CDCDE52B7
|
||||||
A22647F422AE
|
A22647F422AE
|
||||||
|
@ -1050,8 +1108,7 @@ BE7C4F6C7A9A
|
||||||
5EC7938F140A
|
5EC7938F140A
|
||||||
82D58AA49CCB
|
82D58AA49CCB
|
||||||
#
|
#
|
||||||
# MELONCARD
|
# MELON CARD
|
||||||
#
|
|
||||||
323334353637
|
323334353637
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -1071,7 +1128,6 @@ A7FB4824ACBF
|
||||||
10F3BEBC01DF
|
10F3BEBC01DF
|
||||||
#
|
#
|
||||||
# Transportes Insular La Palma
|
# Transportes Insular La Palma
|
||||||
#
|
|
||||||
0172066B2F03
|
0172066B2F03
|
||||||
0000085F0000
|
0000085F0000
|
||||||
1A80B93F7107
|
1A80B93F7107
|
||||||
|
@ -1106,7 +1162,6 @@ B1A862985913
|
||||||
F3F0172066B2
|
F3F0172066B2
|
||||||
#
|
#
|
||||||
# Tehran ezpay
|
# Tehran ezpay
|
||||||
#
|
|
||||||
38A88AEC1C43
|
38A88AEC1C43
|
||||||
CBD2568BC7C6
|
CBD2568BC7C6
|
||||||
7BCB4774EC8F
|
7BCB4774EC8F
|
||||||
|
@ -1124,7 +1179,6 @@ D3B1C7EA5C53
|
||||||
BB3D7B11D224
|
BB3D7B11D224
|
||||||
#
|
#
|
||||||
# Chaco
|
# Chaco
|
||||||
#
|
|
||||||
B210CFA436D2
|
B210CFA436D2
|
||||||
B8B1CFA646A8
|
B8B1CFA646A8
|
||||||
A9F95891F0A4
|
A9F95891F0A4
|
||||||
|
@ -1147,11 +1201,11 @@ A0004A000036
|
||||||
4243414F5250
|
4243414F5250
|
||||||
DFE73BE48AC6
|
DFE73BE48AC6
|
||||||
#
|
#
|
||||||
|
#
|
||||||
B069D0D03D17
|
B069D0D03D17
|
||||||
000131B93F28
|
000131B93F28
|
||||||
#
|
#
|
||||||
# From the DFW Area, TX, USA
|
# From the DFW Area, TX, USA
|
||||||
#
|
|
||||||
A506370E7C0F
|
A506370E7C0F
|
||||||
26396F2042E7
|
26396F2042E7
|
||||||
70758FDD31E0
|
70758FDD31E0
|
||||||
|
@ -1169,7 +1223,6 @@ B47058139187
|
||||||
67CC03B7D577
|
67CC03B7D577
|
||||||
#
|
#
|
||||||
# From the HTL Mödling, NÖ, AT
|
# From the HTL Mödling, NÖ, AT
|
||||||
#
|
|
||||||
A5524645CD91
|
A5524645CD91
|
||||||
D964406E67B4
|
D964406E67B4
|
||||||
99858A49C119
|
99858A49C119
|
||||||
|
@ -1179,7 +1232,6 @@ C27D999912EA
|
||||||
4C60F4B15BA8
|
4C60F4B15BA8
|
||||||
#
|
#
|
||||||
# CAFE + CO, AT
|
# CAFE + CO, AT
|
||||||
#
|
|
||||||
35D850D10A24
|
35D850D10A24
|
||||||
4B511F4D28DD
|
4B511F4D28DD
|
||||||
E45230E7A9E8
|
E45230E7A9E8
|
||||||
|
@ -1187,27 +1239,25 @@ E45230E7A9E8
|
||||||
FB6C88B7E279
|
FB6C88B7E279
|
||||||
#
|
#
|
||||||
# Metro Card, AT
|
# Metro Card, AT
|
||||||
#
|
|
||||||
223C3427108A
|
223C3427108A
|
||||||
#
|
#
|
||||||
# Unknown, AT
|
# Unknown, AT
|
||||||
#
|
|
||||||
23D4CDFF8DA3
|
23D4CDFF8DA3
|
||||||
E6849FCC324B
|
E6849FCC324B
|
||||||
12FD3A94DF0E
|
12FD3A94DF0E
|
||||||
#
|
#
|
||||||
# Unknown, AT
|
# Unknown, AT
|
||||||
#
|
|
||||||
0B83797A9C64
|
0B83797A9C64
|
||||||
39AD2963D3D1
|
39AD2963D3D1
|
||||||
|
#
|
||||||
# Hotel Berlin Classic room A KEY
|
# Hotel Berlin Classic room A KEY
|
||||||
34B16CD59FF8
|
34B16CD59FF8
|
||||||
|
#
|
||||||
# Hotel Berlin Classic room B KEY
|
# Hotel Berlin Classic room B KEY
|
||||||
BB2C0007D022
|
BB2C0007D022
|
||||||
#
|
#
|
||||||
# Coinmatic laundry Smart card
|
# Coinmatic laundry Smart card
|
||||||
# data from: https://pastebin.com/XZQiLtUf
|
# data from: https://pastebin.com/XZQiLtUf
|
||||||
#
|
|
||||||
0734BFB93DAB
|
0734BFB93DAB
|
||||||
85A438F72A8A
|
85A438F72A8A
|
||||||
#
|
#
|
||||||
|
@ -1215,6 +1265,7 @@ BB2C0007D022
|
||||||
58AC17BF3629
|
58AC17BF3629
|
||||||
B62307B62307
|
B62307B62307
|
||||||
#
|
#
|
||||||
|
#
|
||||||
A2A3CCA2A3CC
|
A2A3CCA2A3CC
|
||||||
#
|
#
|
||||||
# Granada, ES Transport Card
|
# Granada, ES Transport Card
|
||||||
|
@ -1260,6 +1311,7 @@ B8937130B6BA
|
||||||
D7744A1A0C44
|
D7744A1A0C44
|
||||||
82908B57EF4F
|
82908B57EF4F
|
||||||
FE04ECFE5577
|
FE04ECFE5577
|
||||||
|
#
|
||||||
# comfort inn hotel
|
# comfort inn hotel
|
||||||
4D57414C5648
|
4D57414C5648
|
||||||
4D48414C5648
|
4D48414C5648
|
||||||
|
@ -1306,13 +1358,11 @@ A82045A10949
|
||||||
#
|
#
|
||||||
# funnivarium
|
# funnivarium
|
||||||
# forum ankara
|
# forum ankara
|
||||||
#
|
|
||||||
2602FFFFFFFF
|
2602FFFFFFFF
|
||||||
#
|
#
|
||||||
# macera adasi
|
# macera adasi
|
||||||
# ankara kentpark
|
# ankara kentpark
|
||||||
# INACTIVE
|
# INACTIVE
|
||||||
#
|
|
||||||
0A4600FF00FF
|
0A4600FF00FF
|
||||||
DFF293979FA7
|
DFF293979FA7
|
||||||
4D6F62692E45
|
4D6F62692E45
|
||||||
|
@ -1321,21 +1371,17 @@ DFF293979FA7
|
||||||
# petrol ofisi
|
# petrol ofisi
|
||||||
# positive card
|
# positive card
|
||||||
# ode-gec
|
# ode-gec
|
||||||
#
|
|
||||||
0406080A0C0E
|
0406080A0C0E
|
||||||
#
|
#
|
||||||
# konya elkart
|
# konya elkart
|
||||||
#
|
|
||||||
988ACDECDFB0
|
988ACDECDFB0
|
||||||
120D00FFFFFF
|
120D00FFFFFF
|
||||||
#
|
#
|
||||||
# bowlingo
|
# bowlingo
|
||||||
# serdivan avym
|
# serdivan avym
|
||||||
#
|
|
||||||
4AE23A562A80
|
4AE23A562A80
|
||||||
#
|
#
|
||||||
# kart54
|
# kart 54
|
||||||
#
|
|
||||||
2AFFD6F88B97
|
2AFFD6F88B97
|
||||||
A9F3F289B70C
|
A9F3F289B70C
|
||||||
DB6819558A25
|
DB6819558A25
|
||||||
|
@ -1346,20 +1392,16 @@ B16B2E573235
|
||||||
#
|
#
|
||||||
# crazy park
|
# crazy park
|
||||||
# kizilay avm
|
# kizilay avm
|
||||||
#
|
|
||||||
00DD300F4F10
|
00DD300F4F10
|
||||||
#
|
#
|
||||||
# kartsistem B
|
# kartsistem B
|
||||||
#
|
|
||||||
FEE2A3FBC5B6
|
FEE2A3FBC5B6
|
||||||
#
|
#
|
||||||
# toru ent
|
# toru ent
|
||||||
# taurus avm
|
# taurus avm
|
||||||
#
|
|
||||||
005078565703
|
005078565703
|
||||||
#
|
#
|
||||||
# Ving?
|
# Ving?
|
||||||
#
|
|
||||||
0602721E8F06
|
0602721E8F06
|
||||||
FC0B50AF8700
|
FC0B50AF8700
|
||||||
F7BA51A9434E
|
F7BA51A9434E
|
||||||
|
@ -1407,7 +1449,6 @@ D0DDDF2933EC
|
||||||
#
|
#
|
||||||
# bursakart
|
# bursakart
|
||||||
# bursa transport card
|
# bursa transport card
|
||||||
#
|
|
||||||
755D49191A78
|
755D49191A78
|
||||||
DAC7E0CBA8FD
|
DAC7E0CBA8FD
|
||||||
68D3263A8CD6
|
68D3263A8CD6
|
||||||
|
@ -1418,30 +1459,29 @@ B2FE3B2875A6
|
||||||
#
|
#
|
||||||
# playland
|
# playland
|
||||||
# maltepe park
|
# maltepe park
|
||||||
#
|
|
||||||
ABCC1276FCB0
|
ABCC1276FCB0
|
||||||
AABAFFCC7612
|
AABAFFCC7612
|
||||||
#
|
#
|
||||||
# lunasan
|
# lunasan
|
||||||
# kocaeli fair
|
# kocaeli fair
|
||||||
#
|
|
||||||
26107E7006A0
|
26107E7006A0
|
||||||
#
|
#
|
||||||
# gamefactory
|
# gamefactory
|
||||||
# ozdilek
|
# ozdilek
|
||||||
#
|
|
||||||
17D071403C20
|
17D071403C20
|
||||||
#
|
#
|
||||||
|
#
|
||||||
534F4C415249
|
534F4C415249
|
||||||
534F4C303232
|
534F4C303232
|
||||||
#
|
#
|
||||||
# Nespresso, smart card
|
# Nespresso, smart card
|
||||||
# key-gen algo, these keys are for one card
|
# key-gen algo, these keys are for one card (keys diversified)
|
||||||
FF9A84635BD2
|
FF9A84635BD2
|
||||||
6F30126EE7E4
|
6F30126EE7E4
|
||||||
6039ABB101BB
|
6039ABB101BB
|
||||||
F1A1239A4487
|
F1A1239A4487
|
||||||
#
|
#
|
||||||
|
#
|
||||||
B882FD4A9F78
|
B882FD4A9F78
|
||||||
CD7FFFF81C4A
|
CD7FFFF81C4A
|
||||||
AA0857C641A3
|
AA0857C641A3
|
||||||
|
@ -1524,9 +1564,10 @@ ABFEDC124578
|
||||||
5E594208EF02
|
5E594208EF02
|
||||||
AF9E38D36582
|
AF9E38D36582
|
||||||
#
|
#
|
||||||
#Norwegian building site identication card. (HMS KORT)
|
# Norwegian building site identication card. (HMS KORT)
|
||||||
# Key a
|
# Key a
|
||||||
10DF4D1859C8
|
10DF4D1859C8
|
||||||
|
#
|
||||||
# Key B
|
# Key B
|
||||||
B5244E79B0C8
|
B5244E79B0C8
|
||||||
#
|
#
|
||||||
|
@ -1594,7 +1635,6 @@ F53E9F4114A9
|
||||||
AD38C17DE7D2
|
AD38C17DE7D2
|
||||||
#
|
#
|
||||||
# SUBE cards keys (new)
|
# SUBE cards keys (new)
|
||||||
#
|
|
||||||
2DEB57A3EA8F
|
2DEB57A3EA8F
|
||||||
32C1BB023F87
|
32C1BB023F87
|
||||||
70E3AD3F2D29
|
70E3AD3F2D29
|
||||||
|
@ -1623,7 +1663,6 @@ F5C1B3F62FDA
|
||||||
7E6545076619
|
7E6545076619
|
||||||
#
|
#
|
||||||
# SUBE cards keys (old)
|
# SUBE cards keys (old)
|
||||||
#
|
|
||||||
4C5A766DFE3A
|
4C5A766DFE3A
|
||||||
32C6768847F5
|
32C6768847F5
|
||||||
F68930789631
|
F68930789631
|
||||||
|
@ -1651,7 +1690,9 @@ BFE25035B0C8
|
||||||
D5C172325DD3
|
D5C172325DD3
|
||||||
992B152E834A
|
992B152E834A
|
||||||
CE75D7EADEAF
|
CE75D7EADEAF
|
||||||
# Russian Podorozhnik card (Saint-Petersburg transport, may be combined with Troika)
|
#
|
||||||
|
# Russian Podorozhnik card (Saint-Petersburg transport)
|
||||||
|
# may be combined with Troika
|
||||||
038B5F9B5A2A
|
038B5F9B5A2A
|
||||||
04DC35277635
|
04DC35277635
|
||||||
0C420A20E056
|
0C420A20E056
|
||||||
|
@ -1681,11 +1722,12 @@ D27058C6E2C7
|
||||||
E19504C39461
|
E19504C39461
|
||||||
FA1FBB3F0F1F
|
FA1FBB3F0F1F
|
||||||
FF16014FEFC7
|
FF16014FEFC7
|
||||||
##################################
|
|
||||||
# Keys from Flipper Zero Community
|
|
||||||
#
|
#
|
||||||
|
# Keys from Flipper Zero Community
|
||||||
# Last update: Aug 13, 2022
|
# Last update: Aug 13, 2022
|
||||||
#
|
#
|
||||||
|
# unknown if keys are diversified or static default
|
||||||
|
#
|
||||||
# Strelka Extension
|
# Strelka Extension
|
||||||
5C83859F2224
|
5C83859F2224
|
||||||
66B504430416
|
66B504430416
|
||||||
|
@ -1771,7 +1813,7 @@ CB9D507CE56D
|
||||||
# Armenian Underground Ticket
|
# Armenian Underground Ticket
|
||||||
A0A1A2A8A4A5
|
A0A1A2A8A4A5
|
||||||
#
|
#
|
||||||
# BadgeMaker Leaked from https://github.com/UberGuidoZ
|
# Badge Maker Leaked from https://github.com/UberGuidoZ
|
||||||
1A1B1C1D1E1F
|
1A1B1C1D1E1F
|
||||||
1665FE2AE945
|
1665FE2AE945
|
||||||
158B51947A8E
|
158B51947A8E
|
||||||
|
@ -1813,7 +1855,7 @@ D10008074A6F
|
||||||
6F6674776172
|
6F6674776172
|
||||||
6520446F7665
|
6520446F7665
|
||||||
#
|
#
|
||||||
# Apartment keyfobs (USA) from Corvette830
|
# Apartment keyfobs (USA) (Corvette830)
|
||||||
E60F8387F0B9
|
E60F8387F0B9
|
||||||
FFD46FF6C5EE
|
FFD46FF6C5EE
|
||||||
4F9661ED2E70
|
4F9661ED2E70
|
||||||
|
@ -1822,8 +1864,8 @@ FFD46FF6C5EE
|
||||||
16CA203B811B
|
16CA203B811B
|
||||||
11AC8C8F3AF2
|
11AC8C8F3AF2
|
||||||
#
|
#
|
||||||
# The Westin Jakarta Indonesia from D4DB0D
|
# The Westin Jakarta Indonesia (D4DB0D)
|
||||||
# Peppers Hotel Unknown location from D4DB0D
|
# Peppers Hotel Unknown location (D4D0D)
|
||||||
6E0DD4136B0A
|
6E0DD4136B0A
|
||||||
141940E9B71B
|
141940E9B71B
|
||||||
3B1D3AAC866E
|
3B1D3AAC866E
|
||||||
|
@ -1836,12 +1878,12 @@ F09BB8DD142D
|
||||||
B4B3FFEDBE0A
|
B4B3FFEDBE0A
|
||||||
540E0D2D1D08
|
540E0D2D1D08
|
||||||
#
|
#
|
||||||
# Schlage 9691T Keyfob from seasnaill
|
# Schlage 9691T Keyfob (seasnaill)
|
||||||
7579B671051A
|
7579B671051A
|
||||||
4F4553746B41
|
4F4553746B41
|
||||||
#
|
#
|
||||||
# Vigik ScanBadge App (fr.badgevigik.scanbadge)
|
# Vigik ScanBadge App (fr.badgevigik.scanbadge)
|
||||||
# Website https://badge-vigik.fr/ - By Alex`
|
# Website https://badge-vigik.fr/ (Alex)
|
||||||
0000A2B3C86F
|
0000A2B3C86F
|
||||||
021200C20307
|
021200C20307
|
||||||
021209197507
|
021209197507
|
||||||
|
@ -1868,6 +1910,7 @@ B4B3FFEDBE0A
|
||||||
9EB7C8A6D4E3
|
9EB7C8A6D4E3
|
||||||
A22AE12C9013
|
A22AE12C9013
|
||||||
AFC984A3576E
|
AFC984A3576E
|
||||||
|
#
|
||||||
# Vigik verified by quantum-x
|
# Vigik verified by quantum-x
|
||||||
# https://github.com/RfidResearchGroup/proxmark3/pull/1742#issuecomment-1206113976
|
# https://github.com/RfidResearchGroup/proxmark3/pull/1742#issuecomment-1206113976
|
||||||
A00027000099
|
A00027000099
|
||||||
|
@ -1892,8 +1935,8 @@ A00003000057
|
||||||
# iGuard Simple (and reverse) keys
|
# iGuard Simple (and reverse) keys
|
||||||
AAAAAAFFFFFF
|
AAAAAAFFFFFF
|
||||||
FFFFFFAAAAAA
|
FFFFFFAAAAAA
|
||||||
# Added by VideoMan.
|
#
|
||||||
# Random Hotel A Key Sec 0 Blk 3 - KABA Lock
|
# Random Hotel A Key Sec 0 Blk 3 - KABA Lock (VideoMan)
|
||||||
3111A3A303EB
|
3111A3A303EB
|
||||||
# Transport system Uruguay - STM
|
# Transport system Uruguay - STM
|
||||||
# Shared key - sec 0 blk 3
|
# Shared key - sec 0 blk 3
|
||||||
|
@ -1910,9 +1953,9 @@ D144BD193063
|
||||||
8627C10A7014
|
8627C10A7014
|
||||||
453857395635
|
453857395635
|
||||||
#
|
#
|
||||||
##########################################
|
# Data from "the more, the marriott" mifare project (colonel borkmundus)
|
||||||
# added by colonelborkmundus
|
#
|
||||||
# "the more, the marriott" mifare project
|
# Isn't theirs Saflok ?
|
||||||
#
|
#
|
||||||
# 20230125-01, Elite Member Marriott Rewards
|
# 20230125-01, Elite Member Marriott Rewards
|
||||||
43012BD9EB87
|
43012BD9EB87
|
||||||
|
@ -1979,3 +2022,12 @@ C49DAE1C6049
|
||||||
6E029927600D
|
6E029927600D
|
||||||
3E173F64C01C
|
3E173F64C01C
|
||||||
C670A9AD6066
|
C670A9AD6066
|
||||||
|
#
|
||||||
|
# 1k - the industrialist
|
||||||
|
2158E314C3DF
|
||||||
|
#
|
||||||
|
# 1k - waldorf astoria
|
||||||
|
011C6CF459E8
|
||||||
|
#
|
||||||
|
# Food GEM
|
||||||
|
6686FADE5566
|
|
@ -122,7 +122,7 @@ if (NOT SKIPREADLINE EQUAL 1)
|
||||||
ExternalProject_Add_StepTargets(ncurses configure build install)
|
ExternalProject_Add_StepTargets(ncurses configure build install)
|
||||||
|
|
||||||
ExternalProject_Add(readline
|
ExternalProject_Add(readline
|
||||||
URL ftp://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz
|
URL ftp://ftp.gnu.org/gnu/readline/readline-8.2.tar.gz
|
||||||
PREFIX deps/readline
|
PREFIX deps/readline
|
||||||
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
|
DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline
|
||||||
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
|
CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static
|
||||||
|
@ -294,6 +294,7 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/cmdhfseos.c
|
${PM3_ROOT}/client/src/cmdhfseos.c
|
||||||
${PM3_ROOT}/client/src/cmdhfst.c
|
${PM3_ROOT}/client/src/cmdhfst.c
|
||||||
${PM3_ROOT}/client/src/cmdhfst25ta.c
|
${PM3_ROOT}/client/src/cmdhfst25ta.c
|
||||||
|
${PM3_ROOT}/client/src/cmdhftesla.c
|
||||||
${PM3_ROOT}/client/src/cmdhftexkom.c
|
${PM3_ROOT}/client/src/cmdhftexkom.c
|
||||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||||
|
|
|
@ -13,7 +13,7 @@ local err_lock = 'use -k or change cfg0 block'
|
||||||
local _print = 0
|
local _print = 0
|
||||||
copyright = ''
|
copyright = ''
|
||||||
author = 'Nathan Glaser'
|
author = 'Nathan Glaser'
|
||||||
version = 'v1.0.4'
|
version = 'v1.0.5'
|
||||||
date = 'Created - Jan 2022'
|
date = 'Created - Jan 2022'
|
||||||
desc = 'This script enables easy programming of an Ultimate Mifare Magic card'
|
desc = 'This script enables easy programming of an Ultimate Mifare Magic card'
|
||||||
example = [[
|
example = [[
|
||||||
|
@ -483,8 +483,19 @@ local function write_signature(data)
|
||||||
end
|
end
|
||||||
local info = connect()
|
local info = connect()
|
||||||
if not info then return false, "Can't select card" end
|
if not info then return false, "Can't select card" end
|
||||||
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
|
if ulprotocol == '00' then
|
||||||
print('Writing new signature',data)
|
print('Writing new MFC signature',data)
|
||||||
|
send('CF'.._key..'6B48')
|
||||||
|
lib14a.disconnect()
|
||||||
|
connect() -- not 100% sure why it's needed, but without this blocks aren't actually written
|
||||||
|
local sig1 = data:sub(1, 32)
|
||||||
|
local sig2 = data:sub(33, 64)
|
||||||
|
|
||||||
|
send('CF'.._key..'CD45'..sig1)
|
||||||
|
send('CF'.._key..'CD46'..sig2)
|
||||||
|
send('CF'.._key..'CD475C8FF9990DA270F0F8694B791BEA7BCC')
|
||||||
|
else
|
||||||
|
print('Writing new MFUL signature',data)
|
||||||
local b,c
|
local b,c
|
||||||
local cmd = 'A2F%d%s'
|
local cmd = 'A2F%d%s'
|
||||||
local j = 2
|
local j = 2
|
||||||
|
@ -495,6 +506,7 @@ local function write_signature(data)
|
||||||
if resp ~= '0A' then lib14a.disconnect(); return nil, oops('Failed to write signature') end
|
if resp ~= '0A' then lib14a.disconnect(); return nil, oops('Failed to write signature') end
|
||||||
j = j + 1
|
j = j + 1
|
||||||
end
|
end
|
||||||
|
end
|
||||||
lib14a.disconnect()
|
lib14a.disconnect()
|
||||||
return true, 'Ok'
|
return true, 'Ok'
|
||||||
end
|
end
|
||||||
|
|
|
@ -139,14 +139,10 @@ local function main(args)
|
||||||
-- force lock bytes, otherwise the Amiibo won't be recognized
|
-- force lock bytes, otherwise the Amiibo won't be recognized
|
||||||
blocks[16] = blocks[16]:sub(1, 4)..'0FE0'
|
blocks[16] = blocks[16]:sub(1, 4)..'0FE0'
|
||||||
|
|
||||||
-- add PWD and PACK if necessary
|
-- add PWD and PACK
|
||||||
local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8)
|
local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8)
|
||||||
if blocks[147] == nil or blocks[147] == '00000000' then
|
|
||||||
blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55))
|
blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55))
|
||||||
end
|
|
||||||
if blocks[148] == nil or blocks[148] == '00000000' then
|
|
||||||
blocks[148] = "80800000"
|
blocks[148] = "80800000"
|
||||||
end
|
|
||||||
|
|
||||||
err = LoadEmulator(uid, blocks)
|
err = LoadEmulator(uid, blocks)
|
||||||
if err then return oops(err) end
|
if err then return oops(err) end
|
||||||
|
|
|
@ -424,8 +424,8 @@ static int CmdrevengSearch(const char *Cmd) {
|
||||||
uint8_t width[NMODELS] = {0};
|
uint8_t width[NMODELS] = {0};
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
char result[30];
|
char result[50 + 1] = {0};
|
||||||
char revResult[30];
|
char revResult[50 + 1] = {0};
|
||||||
int ans = GetModels(Models, &count, width);
|
int ans = GetModels(Models, &count, width);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (!ans) {
|
if (!ans) {
|
||||||
|
@ -461,7 +461,7 @@ static int CmdrevengSearch(const char *Cmd) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(result, 0, 30);
|
memset(result, 0, sizeof(result));
|
||||||
char *inCRC = calloc(crcChars + 1, sizeof(char));
|
char *inCRC = calloc(crcChars + 1, sizeof(char));
|
||||||
if (inCRC == NULL) {
|
if (inCRC == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#include "cmdlft55xx.h" // print...
|
#include "cmdlft55xx.h" // print...
|
||||||
#include "crypto/asn1utils.h" // ASN1 decode / print
|
#include "crypto/asn1utils.h" // ASN1 decode / print
|
||||||
#include "cmdflashmemspiffs.h" // SPIFFS flash memory download
|
#include "cmdflashmemspiffs.h" // SPIFFS flash memory download
|
||||||
|
#include "mbedtls/bignum.h" // big num
|
||||||
|
#include "mbedtls/entropy.h" //
|
||||||
|
#include "mbedtls/ctr_drbg.h" // random generator
|
||||||
|
|
||||||
uint8_t g_DemodBuffer[MAX_DEMOD_BUF_LEN];
|
uint8_t g_DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||||
size_t g_DemodBufferLen = 0;
|
size_t g_DemodBufferLen = 0;
|
||||||
|
@ -1230,7 +1233,7 @@ int FSKrawDemod(uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow, bo
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(SUCCESS, _YELLOW_("%s") " decoded bitstream", GetFSKType(fchigh, fclow, invert));
|
PrintAndLogEx(SUCCESS, _YELLOW_("%s") " decoded bitstream", GetFSKType(fchigh, fclow, invert));
|
||||||
PrintAndLogEx(INFO, "-----------------------");
|
PrintAndLogEx(INFO, "-----------------------");
|
||||||
printDemodBuff(0, false, invert, false);
|
printDemodBuff(0, false, false, false);
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1779,7 +1782,7 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose, bool ignore_lf_conf
|
||||||
|
|
||||||
BitstreamOut_t bout = { got, bits_per_sample * n, 0};
|
BitstreamOut_t bout = { got, bits_per_sample * n, 0};
|
||||||
uint32_t j = 0;
|
uint32_t j = 0;
|
||||||
for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
|
for (j = 0; j * bits_per_sample < n * 8 && j * bits_per_sample < MAX_GRAPH_TRACE_LEN * 8; j++) {
|
||||||
uint8_t sample = getByte(bits_per_sample, &bout);
|
uint8_t sample = getByte(bits_per_sample, &bout);
|
||||||
g_GraphBuffer[j] = ((int) sample) - 127;
|
g_GraphBuffer[j] = ((int) sample) - 127;
|
||||||
}
|
}
|
||||||
|
@ -2425,6 +2428,19 @@ static int CmdZerocrossings(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool data_verify_hex(uint8_t *d, size_t n) {
|
||||||
|
if (d == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
if (isxdigit(d[i]) == false) {
|
||||||
|
PrintAndLogEx(ERR, "Non hex digit found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility for conversion via cmdline.
|
* @brief Utility for conversion via cmdline.
|
||||||
* @param Cmd
|
* @param Cmd
|
||||||
|
@ -2501,13 +2517,9 @@ static int Cmdhex2bin(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < dlen; i++) {
|
if (data_verify_hex((uint8_t*)data, dlen) == false) {
|
||||||
char x = data[i];
|
|
||||||
if (isxdigit(x) == false) {
|
|
||||||
PrintAndLogEx(ERR, "Non hex digit found");
|
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "" NOLF);
|
PrintAndLogEx(SUCCESS, "" NOLF);
|
||||||
for (int i = 0; i < dlen; i++) {
|
for (int i = 0; i < dlen; i++) {
|
||||||
|
@ -3166,6 +3178,129 @@ static int CmdDiff(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdNumCon(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "data num",
|
||||||
|
"Function takes a decimal or hexdecimal number and print it in decimal/hex/binary\n"
|
||||||
|
"Will print message if number is a prime number\n",
|
||||||
|
"data num --dec 2023\n"
|
||||||
|
"data num --hex 0x1000\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0(NULL, "dec", "<dec>", "decimal value"),
|
||||||
|
arg_str0(NULL, "hex", "<hex>", "hexadecimal value"),
|
||||||
|
arg_str0(NULL, "bin", "<bin>", "binary value"),
|
||||||
|
arg_lit0("i", NULL, "print inverted value"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
int dlen = 256;
|
||||||
|
char dec[256];
|
||||||
|
memset(dec, 0, sizeof(dec));
|
||||||
|
int res = CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)dec, sizeof(dec), &dlen);
|
||||||
|
|
||||||
|
|
||||||
|
int hlen = 256;
|
||||||
|
char hex[256];
|
||||||
|
memset(hex, 0, sizeof(hex));
|
||||||
|
res = CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)hex, sizeof(hex), &hlen);
|
||||||
|
|
||||||
|
int blen = 256;
|
||||||
|
char bin[256];
|
||||||
|
memset(bin, 0, sizeof(bin));
|
||||||
|
res = CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)bin, sizeof(bin), &blen);
|
||||||
|
|
||||||
|
bool shall_invert = arg_get_lit(ctx, 4);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
// sanity checks
|
||||||
|
if (res) {
|
||||||
|
PrintAndLogEx(FAILED, "Error parsing bytes");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// results for MPI actions
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
// container of big number
|
||||||
|
mbedtls_mpi N;
|
||||||
|
mbedtls_mpi_init(&N);
|
||||||
|
|
||||||
|
|
||||||
|
// hex
|
||||||
|
if (hlen > 0) {
|
||||||
|
if (data_verify_hex((uint8_t*)hex, hlen) == false) {
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16, hex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// decimal
|
||||||
|
if (dlen > 0) {
|
||||||
|
// should have decimal string check here too
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 10, dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
// binary
|
||||||
|
if (blen > 0) {
|
||||||
|
// should have bianry string check here too
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 2, bin));
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_mpi base;
|
||||||
|
mbedtls_mpi_init(&base);
|
||||||
|
mbedtls_mpi_add_int(&base, &base, 10);
|
||||||
|
|
||||||
|
if (shall_invert) {
|
||||||
|
PrintAndLogEx(INFO, "should invert");
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&N, &N, &base));
|
||||||
|
}
|
||||||
|
|
||||||
|
// printing
|
||||||
|
typedef struct {
|
||||||
|
const char* desc;
|
||||||
|
uint8_t radix;
|
||||||
|
} radix_t;
|
||||||
|
|
||||||
|
radix_t radix[] = {
|
||||||
|
{"dec..... ", 10},
|
||||||
|
{"hex..... 0x", 16},
|
||||||
|
{"bin..... 0b", 2}
|
||||||
|
};
|
||||||
|
|
||||||
|
char s[600] = {0};
|
||||||
|
size_t slen = 0;
|
||||||
|
|
||||||
|
for (uint8_t i=0; i < ARRAYLEN(radix); i++) {
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, radix[i].radix, s, sizeof(s), &slen));
|
||||||
|
if (slen > 0) {
|
||||||
|
PrintAndLogEx(INFO, "%s%s", radix[i].desc, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if number is a prime
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0 ));
|
||||||
|
|
||||||
|
res = mbedtls_mpi_is_prime_ext( &N, 50, mbedtls_ctr_drbg_random, &ctr_drbg );
|
||||||
|
if (res == 0) {
|
||||||
|
PrintAndLogEx(INFO, "prime... " _YELLOW_("yes"));
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free(&N);
|
||||||
|
mbedtls_mpi_free(&base);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
@ -3209,6 +3344,7 @@ static command_t CommandTable[] = {
|
||||||
{"hexsamples", CmdHexsamples, IfPm3Present, "Dump big buffer as hex bytes"},
|
{"hexsamples", CmdHexsamples, IfPm3Present, "Dump big buffer as hex bytes"},
|
||||||
{"hex2bin", Cmdhex2bin, AlwaysAvailable, "Converts hexadecimal to binary"},
|
{"hex2bin", Cmdhex2bin, AlwaysAvailable, "Converts hexadecimal to binary"},
|
||||||
{"load", CmdLoad, AlwaysAvailable, "Load contents of file into graph window"},
|
{"load", CmdLoad, AlwaysAvailable, "Load contents of file into graph window"},
|
||||||
|
{"num", CmdNumCon, AlwaysAvailable, "Converts dec/hex/bin"},
|
||||||
{"print", CmdPrintDemodBuff, AlwaysAvailable, "Print the data in the DemodBuffer"},
|
{"print", CmdPrintDemodBuff, AlwaysAvailable, "Print the data in the DemodBuffer"},
|
||||||
{"samples", CmdSamples, IfPm3Present, "Get raw samples for graph window (GraphBuffer)"},
|
{"samples", CmdSamples, IfPm3Present, "Get raw samples for graph window (GraphBuffer)"},
|
||||||
{"save", CmdSave, AlwaysAvailable, "Save signal trace data (from graph window)"},
|
{"save", CmdSave, AlwaysAvailable, "Save signal trace data (from graph window)"},
|
||||||
|
|
|
@ -641,6 +641,11 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
// Verify (public key)
|
// Verify (public key)
|
||||||
bool is_verified = (mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0);
|
bool is_verified = (mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0);
|
||||||
|
|
||||||
|
if (got_private == false) {
|
||||||
|
mbedtls_rsa_free(rsa);
|
||||||
|
free(rsa);
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_pk_free(&pkctx);
|
mbedtls_pk_free(&pkctx);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
|
@ -1460,8 +1460,9 @@ static int CmdHF14AChaining(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf 14a chaining",
|
CLIParserInit(&ctx, "hf 14a chaining",
|
||||||
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
||||||
|
"hf 14a chaining -> show chaining enable/disable state\n"
|
||||||
"hf 14a chaining --off -> disable chaining\n"
|
"hf 14a chaining --off -> disable chaining\n"
|
||||||
"hf 14a chaining -> show chaining enable/disable state\n");
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -1473,6 +1474,7 @@ static int CmdHF14AChaining(const char *Cmd) {
|
||||||
|
|
||||||
bool on = arg_get_lit(ctx, 1);
|
bool on = arg_get_lit(ctx, 1);
|
||||||
bool off = arg_get_lit(ctx, 2);
|
bool off = arg_get_lit(ctx, 2);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if ((on + off) > 1) {
|
if ((on + off) > 1) {
|
||||||
PrintAndLogEx(INFO, "Select only one option");
|
PrintAndLogEx(INFO, "Select only one option");
|
||||||
|
@ -1485,8 +1487,6 @@ static int CmdHF14AChaining(const char *Cmd) {
|
||||||
if (off)
|
if (off)
|
||||||
Set_apdu_in_framing(false);
|
Set_apdu_in_framing(false);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", g_apdu_in_framing_enable ? "enabled" : "disabled");
|
PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", g_apdu_in_framing_enable ? "enabled" : "disabled");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#define Logic1 Iso15693Logic1
|
#define Logic1 Iso15693Logic1
|
||||||
#define FrameEOF Iso15693FrameEOF
|
#define FrameEOF Iso15693FrameEOF
|
||||||
#define CARD_MEMORY_SIZE 4096
|
#define CARD_MEMORY_SIZE 4096
|
||||||
|
#define HF15_UID_LENGTH 8
|
||||||
|
|
||||||
#ifndef Crc15
|
#ifndef Crc15
|
||||||
# define Crc15(data, len) Crc16ex(CRC_15693, (data), (len))
|
# define Crc15(data, len) Crc16ex(CRC_15693, (data), (len))
|
||||||
|
@ -276,16 +277,14 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
uint8_t i;
|
|
||||||
uint8_t revuid[8];
|
|
||||||
for (i = 0; i < sizeof(revuid); i++) {
|
|
||||||
revuid[i] = uid[7 - i];
|
|
||||||
}
|
|
||||||
uint8_t revsign[32];
|
|
||||||
for (i = 0; i < sizeof(revsign); i++) {
|
|
||||||
revsign[i] = signature[31 - i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uint8_t revuid[8] = {0};
|
||||||
|
reverse_array_copy(uid, sizeof(revuid), revuid);
|
||||||
|
|
||||||
|
uint8_t revsign[32] = {0};
|
||||||
|
reverse_array_copy(signature, sizeof(revsign), revsign);
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
int reason = 0;
|
int reason = 0;
|
||||||
bool is_valid = false;
|
bool is_valid = false;
|
||||||
for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) {
|
for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) {
|
||||||
|
@ -652,8 +651,7 @@ static int CmdHF15Samples(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int NxpTestEAS(uint8_t *uid)
|
static int NxpTestEAS(uint8_t *uid) {
|
||||||
{
|
|
||||||
uint8_t fast = 1;
|
uint8_t fast = 1;
|
||||||
uint8_t reply = 1;
|
uint8_t reply = 1;
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
@ -681,7 +679,7 @@ static int NxpTestEAS(uint8_t *uid)
|
||||||
if (resp.length < 2) {
|
if (resp.length < 2) {
|
||||||
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active");
|
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active");
|
||||||
} else {
|
} else {
|
||||||
uint8_t * recv = resp.data.asBytes;
|
uint8_t *recv = resp.data.asBytes;
|
||||||
|
|
||||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||||
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active.");
|
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active.");
|
||||||
|
@ -790,14 +788,14 @@ static int NxpSysInfo(uint8_t *uid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool support_signature = (recv[5] & 0x01);
|
bool support_signature = (recv[5] & 0x01);
|
||||||
bool support_easmode = (recv[4] & 0x03);
|
bool support_easmode = (recv[4] & 0x04);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "--------- " _CYAN_("NXP Sysinfo") " ---------");
|
PrintAndLogEx(INFO, "--------- " _CYAN_("NXP Sysinfo") " ---------");
|
||||||
PrintAndLogEx(INFO, " raw : %s", sprint_hex(recv, 8));
|
PrintAndLogEx(INFO, " raw : %s", sprint_hex(recv, 8));
|
||||||
PrintAndLogEx(INFO, " Password protection configuration:");
|
PrintAndLogEx(INFO, " Password protection configuration:");
|
||||||
PrintAndLogEx(INFO, " * Page L read%s password protected", ((recv[2] & 0x01) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Page L read%s password protected", ((recv[2] & 0x01) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * Page L write%s password protected", ((recv[2] & 0x02) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Page L write%s password protected", ((recv[2] & 0x02) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * Page H read%s password protected", ((recv[2] & 0x08) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Page H read%s password protected", ((recv[2] & 0x10) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * Page H write%s password protected", ((recv[2] & 0x20) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Page H write%s password protected", ((recv[2] & 0x20) ? "" : " not"));
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " Lock bits:");
|
PrintAndLogEx(INFO, " Lock bits:");
|
||||||
|
@ -810,16 +808,16 @@ static int NxpSysInfo(uint8_t *uid) {
|
||||||
PrintAndLogEx(INFO, " * User memory password protection%s supported", ((recv[4] & 0x01) ? "" : " not"));
|
PrintAndLogEx(INFO, " * User memory password protection%s supported", ((recv[4] & 0x01) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * Counter feature%s supported", ((recv[4] & 0x02) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Counter feature%s supported", ((recv[4] & 0x02) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * EAS ID%s supported by EAS ALARM command", support_easmode ? "" : " not");
|
PrintAndLogEx(INFO, " * EAS ID%s supported by EAS ALARM command", support_easmode ? "" : " not");
|
||||||
PrintAndLogEx(INFO, " * EAS password protection%s supported", ((recv[4] & 0x04) ? "" : " not"));
|
PrintAndLogEx(INFO, " * EAS password protection%s supported", ((recv[4] & 0x08) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * AFI password protection%s supported", ((recv[4] & 0x10) ? "" : " not"));
|
PrintAndLogEx(INFO, " * AFI password protection%s supported", ((recv[4] & 0x10) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * Extended mode%s supported by INVENTORY READ command", ((recv[4] & 0x20) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Extended mode%s supported by INVENTORY READ command", ((recv[4] & 0x20) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * EAS selection%s supported by extended mode in INVENTORY READ command", ((recv[4] & 0x40) ? "" : " not"));
|
PrintAndLogEx(INFO, " * EAS selection%s supported by extended mode in INVENTORY READ command", ((recv[4] & 0x40) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * READ SIGNATURE command%s supported", support_signature ? "" : " not");
|
PrintAndLogEx(INFO, " * READ SIGNATURE command%s supported", support_signature ? "" : " not");
|
||||||
PrintAndLogEx(INFO, " * Password protection for READ SIGNATURE command%s supported", ((recv[5] & 0x02) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Password protection for READ SIGNATURE command%s supported", ((recv[5] & 0x02) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x03) ? "" : " not"));
|
PrintAndLogEx(INFO, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x04) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * ENABLE PRIVACY command%s supported", ((recv[5] & 0x10) ? "" : " not"));
|
PrintAndLogEx(INFO, " * ENABLE PRIVACY command%s supported", ((recv[5] & 0x10) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * DESTROY command%s supported", ((recv[5] & 0x20) ? "" : " not"));
|
PrintAndLogEx(INFO, " * DESTROY command%s supported", ((recv[5] & 0x20) ? "" : " not"));
|
||||||
PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not"));
|
PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[7] & 0x80) ? "" : " not"));
|
||||||
|
|
||||||
if (support_easmode) {
|
if (support_easmode) {
|
||||||
NxpTestEAS(uid);
|
NxpTestEAS(uid);
|
||||||
|
@ -968,14 +966,10 @@ static int CmdHF15Info(const char *Cmd) {
|
||||||
if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x08) {
|
if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x08) {
|
||||||
PrintAndLogEx(DEBUG, "SLIX2 Detected, getting NXP System Info");
|
PrintAndLogEx(DEBUG, "SLIX2 Detected, getting NXP System Info");
|
||||||
return NxpSysInfo(uid);
|
return NxpSysInfo(uid);
|
||||||
}
|
} else if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) { //If it is an NTAG 5
|
||||||
else if(data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) //If it is an NTAG 5
|
|
||||||
{
|
|
||||||
PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info");
|
PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info");
|
||||||
return NxpSysInfo(uid);
|
return NxpSysInfo(uid);
|
||||||
}
|
} else if (data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) { //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status
|
||||||
else if(data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status
|
|
||||||
{
|
|
||||||
PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status");
|
PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status");
|
||||||
return NxpTestEAS(uid);
|
return NxpTestEAS(uid);
|
||||||
}
|
}
|
||||||
|
@ -1357,94 +1351,81 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf 15 writeafi",
|
CLIParserInit(&ctx, "hf 15 writeafi",
|
||||||
"Write AFI on card",
|
"Write AFI on card",
|
||||||
"hf 15 writeafi -* --afi 12\n"
|
"hf 15 writeafi -* --afi 12\n"
|
||||||
"hf 15 writeafi -u E011223344556677 --afi 12"
|
"hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[6 + 2] = {};
|
void *argtable[5] = {};
|
||||||
uint8_t arglen = arg_add_default(argtable);
|
argtable[0] = arg_param_begin;
|
||||||
argtable[arglen++] = arg_int1(NULL, "afi", "<dec>", "AFI number (0-255)");
|
argtable[1] = arg_str0("u", "uid", "<hex>", "full UID, 8 bytes");
|
||||||
argtable[arglen++] = arg_param_end;
|
argtable[2] = arg_int1(NULL, "afi", "<dec>", "AFI number (0-255)");
|
||||||
|
argtable[3] = arg_str0("p", "pwd", "<hex>", "optional AFI/EAS password");
|
||||||
|
argtable[4] = arg_param_end;
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool use_pwd;
|
||||||
uint8_t uid[8];
|
uint8_t uid[8];
|
||||||
int uidlen = 0;
|
bool use_uid;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
uint8_t afi;
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
} PACKED payload;
|
||||||
bool scan = arg_get_lit(ctx, 3);
|
|
||||||
int fast = (arg_get_lit(ctx, 4) == false);
|
int uidlen = 0;
|
||||||
bool add_option = arg_get_lit(ctx, 5);
|
CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen);
|
||||||
|
|
||||||
|
payload.afi = arg_get_int_def(ctx, 2, 0);
|
||||||
|
|
||||||
|
int pwdlen;
|
||||||
|
CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen);
|
||||||
|
|
||||||
int afi = arg_get_int_def(ctx, 6, 0);
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// sanity checks
|
payload.use_pwd = false;
|
||||||
if ((scan + unaddressed + uidlen) > 1) {
|
if (pwdlen == 4) {
|
||||||
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
payload.use_pwd = true;
|
||||||
return PM3_EINVARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// request to be sent to device/card
|
|
||||||
uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option);
|
|
||||||
uint8_t req[16] = {flags, ISO15693_WRITE_AFI};
|
|
||||||
uint16_t reqlen = 2;
|
|
||||||
|
|
||||||
if (unaddressed == false) {
|
|
||||||
if (scan) {
|
|
||||||
if (getUID(false, uid) != PM3_SUCCESS) {
|
|
||||||
PrintAndLogEx(WARNING, "no tag found");
|
|
||||||
return PM3_EINVARG;
|
|
||||||
}
|
|
||||||
uidlen = 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payload.use_uid = false;
|
||||||
if (uidlen == 8) {
|
if (uidlen == 8) {
|
||||||
// add UID (scan, uid)
|
payload.use_uid = true;
|
||||||
memcpy(req + reqlen, uid, sizeof(uid));
|
|
||||||
reqlen += sizeof(uid);
|
|
||||||
}
|
|
||||||
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforce, since we are writing
|
// sanity checks
|
||||||
req[0] |= ISO15_REQ_OPTION;
|
if (uidlen != 0 && uidlen != 8) {
|
||||||
|
PrintAndLogEx(WARNING, "uid must be 8 hex bytes if provided");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
req[reqlen++] = (uint8_t)afi;
|
if (pwdlen > 0 && pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided");
|
||||||
AddCrc15(req, reqlen);
|
return PM3_ESOFT;
|
||||||
reqlen += 2;
|
}
|
||||||
|
|
||||||
// arg: len, speed, recv?
|
|
||||||
// arg0 (datalen, cmd len? .arg0 == crc?)
|
|
||||||
// arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 )
|
|
||||||
// arg2 (recv == 1 == expect a response)
|
|
||||||
uint8_t read_response = 1;
|
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen);
|
SendCommandNG(CMD_HF_ISO15693_WRITE_AFI, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_WRITE_AFI, &resp, 2000) == false) {
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
PrintAndLogEx(ERR, "iso15693 timeout");
|
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
DropField();
|
|
||||||
|
|
||||||
if (resp.status == PM3_ETEAROFF) {
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "error writing AFI");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", payload.afi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *data = resp.data.asBytes;
|
|
||||||
|
|
||||||
if ((data[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) {
|
|
||||||
PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", data[0], TagErrorStr(data[0]));
|
|
||||||
return PM3_EWRONGANSWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", afi);
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes the DSFID (Data Storage Format Identifier) of a card
|
// Writes the DSFID (Data Storage Format Identifier) of a card
|
||||||
|
@ -1792,11 +1773,13 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[8];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = arg_get_lit(ctx, 3);
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
int fast = (arg_get_lit(ctx, 4) == false);
|
int fast = (arg_get_lit(ctx, 4) == false);
|
||||||
bool add_option = arg_get_lit(ctx, 5);
|
bool add_option = arg_get_lit(ctx, 5);
|
||||||
|
|
||||||
|
@ -1811,7 +1794,7 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scan + unaddressed + uidlen) > 1) {
|
if ((scan + unaddressed + uid_set) > 1) {
|
||||||
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1827,14 +1810,13 @@ static int CmdHF15Readmulti(const char *Cmd) {
|
||||||
PrintAndLogEx(WARNING, "no tag found");
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uidlen = 8;
|
} else {
|
||||||
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uidlen == 8) {
|
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(req + reqlen, uid, sizeof(uid));
|
memcpy(req + reqlen, uid, HF15_UID_LENGTH);
|
||||||
reqlen += sizeof(uid);
|
reqlen += HF15_UID_LENGTH;
|
||||||
}
|
|
||||||
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
||||||
}
|
}
|
||||||
// add OPTION flag, in order to get lock-info
|
// add OPTION flag, in order to get lock-info
|
||||||
|
@ -1926,11 +1908,13 @@ static int CmdHF15Readblock(const char *Cmd) {
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[8];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = arg_get_lit(ctx, 3);
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
int fast = (arg_get_lit(ctx, 4) == false);
|
int fast = (arg_get_lit(ctx, 4) == false);
|
||||||
bool add_option = arg_get_lit(ctx, 5);
|
bool add_option = arg_get_lit(ctx, 5);
|
||||||
|
|
||||||
|
@ -1938,36 +1922,31 @@ static int CmdHF15Readblock(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if ((scan + unaddressed + uidlen) > 1) {
|
if ((scan + unaddressed + uid_set) > 1) {
|
||||||
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default fallback to scan for tag.
|
|
||||||
// overriding unaddress parameter :)
|
|
||||||
if (uidlen != 8) {
|
|
||||||
scan = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// request to be sent to device/card
|
// request to be sent to device/card
|
||||||
uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option);
|
uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option);
|
||||||
uint8_t req[PM3_CMD_DATA_SIZE] = {flags, ISO15693_READBLOCK};
|
uint8_t req[PM3_CMD_DATA_SIZE] = {flags, ISO15693_READBLOCK};
|
||||||
uint16_t reqlen = 2;
|
uint16_t reqlen = 2;
|
||||||
|
|
||||||
if (unaddressed == false) {
|
if (unaddressed == false) {
|
||||||
|
// default fallback to scan for tag.
|
||||||
|
// overriding unaddress parameter :)
|
||||||
if (scan) {
|
if (scan) {
|
||||||
if (getUID(false, uid) != PM3_SUCCESS) {
|
if (getUID(false, uid) != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(WARNING, "no tag found");
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uidlen = 8;
|
} else {
|
||||||
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uidlen == 8) {
|
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(req + reqlen, uid, sizeof(uid));
|
memcpy(req + reqlen, uid, HF15_UID_LENGTH);
|
||||||
reqlen += sizeof(uid);
|
reqlen += HF15_UID_LENGTH;
|
||||||
}
|
|
||||||
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
||||||
}
|
}
|
||||||
// add OPTION flag, in order to get lock-info
|
// add OPTION flag, in order to get lock-info
|
||||||
|
@ -2091,11 +2070,13 @@ static int CmdHF15Write(const char *Cmd) {
|
||||||
argtable[arglen++] = arg_param_end;
|
argtable[arglen++] = arg_param_end;
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint8_t uid[8];
|
uint8_t uid[HF15_UID_LENGTH];
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false;
|
||||||
|
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
bool unaddressed = arg_get_lit(ctx, 2);
|
||||||
bool scan = arg_get_lit(ctx, 3);
|
bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter.
|
||||||
int fast = (arg_get_lit(ctx, 4) == false);
|
int fast = (arg_get_lit(ctx, 4) == false);
|
||||||
bool add_option = arg_get_lit(ctx, 5);
|
bool add_option = arg_get_lit(ctx, 5);
|
||||||
|
|
||||||
|
@ -2108,7 +2089,7 @@ static int CmdHF15Write(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if ((scan + unaddressed + uidlen) > 1) {
|
if ((scan + unaddressed + uid_set) > 1) {
|
||||||
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -2120,9 +2101,6 @@ static int CmdHF15Write(const char *Cmd) {
|
||||||
|
|
||||||
// default fallback to scan for tag.
|
// default fallback to scan for tag.
|
||||||
// overriding unaddress parameter :)
|
// overriding unaddress parameter :)
|
||||||
if (uidlen != 8) {
|
|
||||||
scan = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// request to be sent to device/card
|
// request to be sent to device/card
|
||||||
uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option);
|
uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option);
|
||||||
|
@ -2138,18 +2116,16 @@ static int CmdHF15Write(const char *Cmd) {
|
||||||
PrintAndLogEx(WARNING, "no tag found");
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uidlen = 8;
|
} else {
|
||||||
|
reverse_array(uid, HF15_UID_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uidlen == 8) {
|
|
||||||
// add UID (scan, uid)
|
// add UID (scan, uid)
|
||||||
memcpy(req + reqlen, uid, sizeof(uid));
|
memcpy(req + reqlen, uid, HF15_UID_LENGTH);
|
||||||
reqlen += sizeof(uid);
|
reqlen += HF15_UID_LENGTH;
|
||||||
}
|
|
||||||
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
req[reqlen++] = (uint8_t)block;
|
req[reqlen++] = (uint8_t)block;
|
||||||
memcpy(req + reqlen, d, sizeof(d));
|
memcpy(req + reqlen, d, sizeof(d));
|
||||||
reqlen += sizeof(d);
|
reqlen += sizeof(d);
|
||||||
|
@ -2368,11 +2344,7 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
|
|
||||||
// reverse cardUID to compare
|
// reverse cardUID to compare
|
||||||
uint8_t revuid[8] = {0};
|
uint8_t revuid[8] = {0};
|
||||||
uint8_t i = 0;
|
reverse_array_copy(carduid, sizeof(carduid), revuid);
|
||||||
while (i < sizeof(revuid)) {
|
|
||||||
revuid[i] = carduid[7 - i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(revuid, payload.uid, 8) != 0) {
|
if (memcmp(revuid, payload.uid, 8) != 0) {
|
||||||
PrintAndLogEx(FAILED, "setting new UID ( " _RED_("fail") " )");
|
PrintAndLogEx(FAILED, "setting new UID ( " _RED_("fail") " )");
|
||||||
|
@ -2383,10 +2355,148 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixEASEnable(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixeasenable",
|
||||||
|
"Enable EAS mode on SLIX ISO-15693 tag",
|
||||||
|
"hf 15 slixeasenable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen);
|
||||||
|
if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) {
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (pwdlen > 0) {
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s")
|
||||||
|
, sprint_hex_inrow(payload.pwd, sizeof(payload.pwd))
|
||||||
|
);
|
||||||
|
payload.usepwd = true;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password");
|
||||||
|
payload.usepwd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_EAS, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_EAS, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
if (pwdlen > 0) {
|
||||||
|
PrintAndLogEx(WARNING, "the password provided was not accepted");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "EAS mode is now enabled ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixEASDisable(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixeasdisable",
|
||||||
|
"Disable EAS mode on SLIX ISO-15693 tag",
|
||||||
|
"hf 15 slixeasdisable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
|
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) {
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pwdlen > 0) {
|
||||||
|
PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s")
|
||||||
|
, sprint_hex_inrow(payload.pwd, sizeof(payload.pwd))
|
||||||
|
);
|
||||||
|
payload.usepwd = true;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password");
|
||||||
|
payload.usepwd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_EAS, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_EAS, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
if (pwdlen > 0) {
|
||||||
|
PrintAndLogEx(WARNING, "the password provided was not accepted");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "EAS mode is now disabled ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHF15SlixDisable(const char *Cmd) {
|
static int CmdHF15SlixDisable(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf 15 slixdisable",
|
CLIParserInit(&ctx, "hf 15 slixprivacydisable",
|
||||||
"Disable privacy mode on SLIX ISO-15693 tag",
|
"Disable privacy mode on SLIX ISO-15693 tag",
|
||||||
"hf 15 slixdisable -p 0F0F0F0F");
|
"hf 15 slixdisable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
@ -2409,8 +2519,8 @@ static int CmdHF15SlixDisable(const char *Cmd) {
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, &resp, 2000) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, &resp, 2000) == false) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -2433,6 +2543,283 @@ static int CmdHF15SlixDisable(const char *Cmd) {
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixEnable(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixprivacyenable",
|
||||||
|
"Enable privacy mode on SLIX ISO-15693 tag",
|
||||||
|
"hf 15 slixenable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("p", "pwd", "<hex>", "password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable privacy mode using password " _GREEN_("%s")
|
||||||
|
, sprint_hex_inrow(payload.pwd, sizeof(payload.pwd))
|
||||||
|
);
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "password was not accepted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "privacy mode is now enabled ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixWritePassword(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixwritepwd",
|
||||||
|
"Write a password on a SLIX family ISO-15693 tag.n"
|
||||||
|
"Some tags do not support all different password types.",
|
||||||
|
"hf 15 slixwritepwd -t READ -o 00000000 -n 12131415");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("t", "type", "<read|write|privacy|destroy|easafi>", "which password field to write to"),
|
||||||
|
arg_str0("o", "old", "<hex>", "old password (if present), 8 hex bytes"),
|
||||||
|
arg_str1("n", "new", "<hex>", "new password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t old_pwd[4];
|
||||||
|
uint8_t new_pwd[4];
|
||||||
|
uint8_t pwd_id;
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 2, payload.old_pwd, &pwdlen);
|
||||||
|
|
||||||
|
if (pwdlen > 0 && pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "old password must be 4 hex bytes if provided");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 3, payload.new_pwd, &pwdlen);
|
||||||
|
|
||||||
|
if (pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "new password must be 4 hex bytes");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vlen = 0;
|
||||||
|
char value[10];
|
||||||
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (vlen > 0) {
|
||||||
|
if (strcmp(value, "read") == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected read pass");
|
||||||
|
payload.pwd_id = 0x01;
|
||||||
|
} else if (strcmp(value, "write") == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected write pass");
|
||||||
|
payload.pwd_id = 0x02;
|
||||||
|
} else if (strcmp(value, "privacy") == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected privacy pass");
|
||||||
|
payload.pwd_id = 0x04;
|
||||||
|
} else if (strcmp(value, "destroy") == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected destroy pass");
|
||||||
|
payload.pwd_id = 0x08;
|
||||||
|
} else if (strcmp(value, "easafi") == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected easafi pass");
|
||||||
|
payload.pwd_id = 0x10;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(ERR, "t argument must be 'read', 'write', 'privacy', 'destroy', or 'easafi'");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password"
|
||||||
|
, sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value);
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_WRITE_PWD, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_WRITE_PWD, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "password was not accepted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "password written ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15AFIPassProtect(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 passprotectafi",
|
||||||
|
"This command enables the password protect of AFI.\n"
|
||||||
|
"*** OBS! This action can not be undone! ***",
|
||||||
|
"hf 15 passprotectafi -p 00000000 --force");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("p", "pwd", "<hex>", "EAS/AFI password, 8 hex bytes"),
|
||||||
|
arg_lit0(NULL, "force", "Force execution of command (irreversible) "),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
|
||||||
|
bool force = arg_get_lit(ctx, 2);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (force == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Use `--force` flag to override. OBS! Irreversable command");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable AFI password protection...");
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "error enabling AFI password protection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "AFI password protected ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15EASPassProtect(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 passprotecteas",
|
||||||
|
"This command enables the password protect of EAS.\n"
|
||||||
|
"*** OBS! This action can not be undone! ***",
|
||||||
|
"hf 15 passprotecteas -p 00000000 --force");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("p", "pwd", "<hex>", "EAS/AFI password, 8 hex bytes"),
|
||||||
|
arg_lit0(NULL, "force", "Force execution of command (irreversible) "),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
|
||||||
|
bool force = arg_get_lit(ctx, 2);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (force == false) {
|
||||||
|
PrintAndLogEx(WARNING, "Use `--force` flag to override. OBS! Irreversable command");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS password protection...");
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "error enabling EAS password protection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "EAS password protected ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
{"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
||||||
{"help", CmdHF15Help, AlwaysAvailable, "This help"},
|
{"help", CmdHF15Help, AlwaysAvailable, "This help"},
|
||||||
|
@ -2451,7 +2838,13 @@ static command_t CommandTable[] = {
|
||||||
{"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"},
|
{"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"},
|
||||||
{"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"},
|
{"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"},
|
||||||
{"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"},
|
{"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"},
|
||||||
{"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"},
|
{"slixwritepwd", CmdHF15SlixWritePassword, IfPm3Iso15693, "Writes a password on a SLIX ISO-15693 tag"},
|
||||||
|
{"slixeasdisable", CmdHF15SlixEASDisable, IfPm3Iso15693, "Disable EAS mode on SLIX ISO-15693 tag"},
|
||||||
|
{"slixeasenable", CmdHF15SlixEASEnable, IfPm3Iso15693, "Enable EAS mode on SLIX ISO-15693 tag"},
|
||||||
|
{"slixprivacydisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"},
|
||||||
|
{"slixprivacyenable", CmdHF15SlixEnable, IfPm3Iso15693, "Enable privacy mode on SLIX ISO-15693 tag"},
|
||||||
|
{"passprotectafi", CmdHF15AFIPassProtect, IfPm3Iso15693, "Password protect AFI - Cannot be undone"},
|
||||||
|
{"passprotecteas", CmdHF15EASPassProtect, IfPm3Iso15693, "Password protect EAS - Cannot be undone"},
|
||||||
{"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"},
|
{"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"},
|
||||||
{"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"},
|
{"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"},
|
||||||
{"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"},
|
{"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"},
|
||||||
|
|
|
@ -2018,7 +2018,7 @@ int infoHF_EMRTD_offline(const char *path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// coverity scan CID 395630,
|
// coverity scan CID 395630,
|
||||||
if (data != NULL) {
|
if (data == NULL) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -702,7 +702,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Reader challenge (unencrypted): %s", sprint_hex(nonce, 8));
|
PrintAndLogEx(INFO, "Reader challenge (unencrypted): %s", sprint_hex(nonce, 8));
|
||||||
|
|
||||||
// Create M1c Challenge with 3DES (3 Keys = 24, 2 Keys = 16)
|
// Create M1c Challenge with 3DES (3 Keys = 24, 2 Keys = 16)
|
||||||
uint8_t master_key[24];
|
uint8_t master_key[24] = {0};
|
||||||
mbedtls_des3_context des3_ctx;
|
mbedtls_des3_context des3_ctx;
|
||||||
mbedtls_des3_init(&des3_ctx);
|
mbedtls_des3_init(&des3_ctx);
|
||||||
|
|
||||||
|
|
|
@ -594,17 +594,17 @@ static void mem_app_config(const picopass_hdr_t *hdr) {
|
||||||
PrintAndLogEx(INFO, " * Kd, Debit key, AA1 Kc, Credit key, AA2 *");
|
PrintAndLogEx(INFO, " * Kd, Debit key, AA1 Kc, Credit key, AA2 *");
|
||||||
uint8_t keyAccess = isset(mem, 0x01);
|
uint8_t keyAccess = isset(mem, 0x01);
|
||||||
if (keyAccess) {
|
if (keyAccess) {
|
||||||
PrintAndLogEx(INFO, " Read A....... debit");
|
PrintAndLogEx(INFO, " Read AA1....... debit");
|
||||||
PrintAndLogEx(INFO, " Read B....... credit");
|
PrintAndLogEx(INFO, " Write AA1...... debit");
|
||||||
PrintAndLogEx(INFO, " Write A...... debit");
|
PrintAndLogEx(INFO, " Read AA2....... credit");
|
||||||
PrintAndLogEx(INFO, " Write B...... credit");
|
PrintAndLogEx(INFO, " Write AA2...... credit");
|
||||||
PrintAndLogEx(INFO, " Debit........ debit or credit");
|
PrintAndLogEx(INFO, " Debit........ debit or credit");
|
||||||
PrintAndLogEx(INFO, " Credit....... credit");
|
PrintAndLogEx(INFO, " Credit....... credit");
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, " Read A....... debit or credit");
|
PrintAndLogEx(INFO, " Read AA1....... debit or credit");
|
||||||
PrintAndLogEx(INFO, " Read B....... debit or credit");
|
PrintAndLogEx(INFO, " Write AA1...... credit");
|
||||||
PrintAndLogEx(INFO, " Write A...... credit");
|
PrintAndLogEx(INFO, " Read AA2....... debit or credit");
|
||||||
PrintAndLogEx(INFO, " Write B...... credit");
|
PrintAndLogEx(INFO, " Write AA2...... credit");
|
||||||
PrintAndLogEx(INFO, " Debit........ debit or credit");
|
PrintAndLogEx(INFO, " Debit........ debit or credit");
|
||||||
PrintAndLogEx(INFO, " Credit....... credit");
|
PrintAndLogEx(INFO, " Credit....... credit");
|
||||||
}
|
}
|
||||||
|
@ -1202,6 +1202,35 @@ static int CmdHFiClassEView(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iclass_decode_credentials(uint8_t *data) {
|
||||||
|
BLOCK79ENCRYPTION encryption = (data[(6 * 8) + 7] & 0x03);
|
||||||
|
bool has_values = (memcmp(data + (8 * 7), empty, 8) != 0) && (memcmp(data + (8 * 7), zeros, 8) != 0);
|
||||||
|
if (has_values && encryption == None) {
|
||||||
|
|
||||||
|
//todo: remove preamble/sentinel
|
||||||
|
uint32_t top = 0, mid = 0, bot = 0;
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Block 7 decoder");
|
||||||
|
|
||||||
|
char hexstr[16 + 1] = {0};
|
||||||
|
hex_to_buffer((uint8_t *)hexstr, data + (8 * 7), 8, sizeof(hexstr) - 1, 0, 0, true);
|
||||||
|
hexstring_to_u96(&top, &mid, &bot, hexstr);
|
||||||
|
|
||||||
|
char binstr[64 + 1];
|
||||||
|
hextobinstring(binstr, hexstr);
|
||||||
|
char *pbin = binstr;
|
||||||
|
while (strlen(pbin) && *(++pbin) == '0');
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), pbin);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Wiegand decode");
|
||||||
|
wiegand_message_t packed = initialize_message_object(top, mid, bot, 0);
|
||||||
|
HIDTryUnpack(&packed);
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "No credential found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHFiClassDecrypt(const char *Cmd) {
|
static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
CLIParserContext *clictx;
|
CLIParserContext *clictx;
|
||||||
CLIParserInit(&clictx, "hf iclass decrypt",
|
CLIParserInit(&clictx, "hf iclass decrypt",
|
||||||
|
@ -1356,21 +1385,36 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
|
|
||||||
//uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8));
|
//uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8));
|
||||||
|
|
||||||
|
bool decrypted_block789 = false;
|
||||||
for (uint8_t blocknum = 0; blocknum < limit; ++blocknum) {
|
for (uint8_t blocknum = 0; blocknum < limit; ++blocknum) {
|
||||||
|
|
||||||
uint16_t idx = blocknum * 8;
|
uint16_t idx = blocknum * 8;
|
||||||
memcpy(enc_data, decrypted + idx, 8);
|
memcpy(enc_data, decrypted + idx, 8);
|
||||||
|
|
||||||
if (aa1_encryption == RFU || aa1_encryption == None)
|
switch (aa1_encryption) {
|
||||||
continue;
|
// Right now, only 3DES is supported
|
||||||
|
case TRIPLEDES:
|
||||||
// Decrypted block 7,8,9 if configured.
|
// Decrypt block 7,8,9 if configured.
|
||||||
if (blocknum > 6 && blocknum <= 9 && memcmp(enc_data, empty, 8) != 0) {
|
if (blocknum > 6 && blocknum <= 9 && memcmp(enc_data, empty, 8) != 0) {
|
||||||
if (use_sc) {
|
if (use_sc) {
|
||||||
Decrypt(enc_data, decrypted + idx);
|
Decrypt(enc_data, decrypted + idx);
|
||||||
} else {
|
} else {
|
||||||
mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx);
|
mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx);
|
||||||
}
|
}
|
||||||
|
decrypted_block789 = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DES:
|
||||||
|
case RFU:
|
||||||
|
case None:
|
||||||
|
// Nothing to do for None anyway...
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decrypted_block789) {
|
||||||
|
// Set the 2 last bits of block6 to 0 to mark the data as decrypted
|
||||||
|
decrypted[(6 * 8) + 7] &= 0xFC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1404,31 +1448,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode block 7-8-9
|
// decode block 7-8-9
|
||||||
has_values = (memcmp(decrypted + (8 * 7), empty, 8) != 0) && (memcmp(decrypted + (8 * 7), zeros, 8) != 0);
|
iclass_decode_credentials(decrypted);
|
||||||
if (has_values) {
|
|
||||||
|
|
||||||
//todo: remove preamble/sentinel
|
|
||||||
uint32_t top = 0, mid = 0, bot = 0;
|
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Block 7 decoder");
|
|
||||||
|
|
||||||
char hexstr[16 + 1] = {0};
|
|
||||||
hex_to_buffer((uint8_t *)hexstr, decrypted + (8 * 7), 8, sizeof(hexstr) - 1, 0, 0, true);
|
|
||||||
hexstring_to_u96(&top, &mid, &bot, hexstr);
|
|
||||||
|
|
||||||
char binstr[64 + 1];
|
|
||||||
hextobinstring(binstr, hexstr);
|
|
||||||
char *pbin = binstr;
|
|
||||||
while (strlen(pbin) && *(++pbin) == '0');
|
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), pbin);
|
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Wiegand decode");
|
|
||||||
wiegand_message_t packed = initialize_message_object(top, mid, bot, 0);
|
|
||||||
HIDTryUnpack(&packed);
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(INFO, "No credential found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// decode block 9
|
// decode block 9
|
||||||
has_values = (memcmp(decrypted + (8 * 9), empty, 8) != 0) && (memcmp(decrypted + (8 * 9), zeros, 8) != 0);
|
has_values = (memcmp(decrypted + (8 * 9), empty, 8) != 0) && (memcmp(decrypted + (8 * 9), zeros, 8) != 0);
|
||||||
|
@ -2840,6 +2860,7 @@ static int CmdHFiClassView(const char *Cmd) {
|
||||||
print_picopass_header((picopass_hdr_t *) dump);
|
print_picopass_header((picopass_hdr_t *) dump);
|
||||||
print_picopass_info((picopass_hdr_t *) dump);
|
print_picopass_info((picopass_hdr_t *) dump);
|
||||||
printIclassDumpContents(dump, startblock, endblock, bytes_read, dense_output);
|
printIclassDumpContents(dump, startblock, endblock, bytes_read, dense_output);
|
||||||
|
iclass_decode_credentials(dump);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printIclassSIO(dump);
|
printIclassSIO(dump);
|
||||||
|
@ -3832,6 +3853,7 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
||||||
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
||||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
||||||
|
arg_lit0("v", NULL, "verbose (print encoded blocks)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -3877,6 +3899,7 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len);
|
CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len);
|
||||||
|
|
||||||
bool shallow_mod = arg_get_lit(ctx, 10);
|
bool shallow_mod = arg_get_lit(ctx, 10);
|
||||||
|
bool verbose = arg_get_lit(ctx, 11);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -3996,6 +4019,17 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
iclass_encrypt_block_data(credential + 24, enc_key);
|
iclass_encrypt_block_data(credential + 24, enc_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
PrintAndLogEx(INFO, "Block %d/0x0%x -> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_session.pm3_present) {
|
||||||
|
PrintAndLogEx(ERR, "Device offline\n");
|
||||||
|
return PM3_EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
int isok = PM3_SUCCESS;
|
int isok = PM3_SUCCESS;
|
||||||
// write
|
// write
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -318,7 +318,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i
|
||||||
snprintf(exp, size, "AUTH-B(%d)", cmd[1]);
|
snprintf(exp, size, "AUTH-B(%d)", cmd[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MIFARE_MAGIC_GDM_AUTH_KEYA:{
|
case MIFARE_MAGIC_GDM_AUTH_KEYA: {
|
||||||
if (cmdsize > 3) {
|
if (cmdsize > 3) {
|
||||||
snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]);
|
snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]);
|
||||||
MifareAuthState = masNt;
|
MifareAuthState = masNt;
|
||||||
|
@ -898,7 +898,7 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
snprintf(exp, size, "R-block NACK(%d)", (cmd[0] & 0x01));
|
snprintf(exp, size, "R-block NACK(%d)", (cmd[0] & 0x01));
|
||||||
}
|
}
|
||||||
// I-block 000xCN1x
|
// I-block 000xCN1x
|
||||||
else if ((cmd[0] & 0xC0) == 0x00) {
|
else if (((cmd[0] & 0xC0) == 0x00) && (cmdsize > 2)) {
|
||||||
|
|
||||||
// PCB [CID] [NAD] [INF] CRC CRC
|
// PCB [CID] [NAD] [INF] CRC CRC
|
||||||
int pos = 1;
|
int pos = 1;
|
||||||
|
|
|
@ -884,7 +884,7 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
strcpy(keyFilename, fptr);
|
strncpy(keyFilename, fptr, sizeof(keyFilename) - 1);
|
||||||
free(fptr);
|
free(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1179,7 +1179,7 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
strcpy(keyfilename, fptr);
|
strncpy(keyfilename, fptr, sizeof(keyfilename) - 1);
|
||||||
free(fptr);
|
free(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2973,7 +2973,8 @@ all_found:
|
||||||
free(fptr);
|
free(fptr);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
strcpy(filename, fptr);
|
|
||||||
|
strncpy(filename, fptr, sizeof(filename) - 1);
|
||||||
free(fptr);
|
free(fptr);
|
||||||
|
|
||||||
saveFile(filename, ".bin", dump, bytes);
|
saveFile(filename, ".bin", dump, bytes);
|
||||||
|
@ -5411,7 +5412,7 @@ static int CmdHF14AMfice(const char *Cmd) {
|
||||||
fptr = GenerateFilename("hf-mf-", "-nonces.bin");
|
fptr = GenerateFilename("hf-mf-", "-nonces.bin");
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
strcpy(filename, fptr);
|
strncpy(filename, fptr, sizeof(filename) - 1);
|
||||||
free(fptr);
|
free(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6009,7 +6010,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) {
|
||||||
if (keyfnlen == 0) {
|
if (keyfnlen == 0) {
|
||||||
char *fptr = GenerateFilename("hf-mf-", "-key.bin");
|
char *fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
if (fptr) {
|
if (fptr) {
|
||||||
strcpy(keyFilename, fptr);
|
strncpy(keyFilename, fptr, sizeof(keyFilename) - 1);
|
||||||
}
|
}
|
||||||
free(fptr);
|
free(fptr);
|
||||||
DropField();
|
DropField();
|
||||||
|
@ -6733,7 +6734,7 @@ static int CmdHF14AMfWipe(const char *Cmd) {
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
strcpy(keyFilename, fptr);
|
strncpy(keyFilename, fptr, sizeof(keyFilename) - 1);
|
||||||
free(fptr);
|
free(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2196,9 +2196,9 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
|
||||||
"\n"
|
"\n"
|
||||||
"hf mfdes setconfig --param 03 --data 0428 -> set SAK\n"
|
"hf mfdes setconfig --param 03 --data 0428 -> set SAK\n"
|
||||||
"hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)\n"
|
"hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)\n"
|
||||||
"hf mfdes setconfig --isoid df01 -t aes -s ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light\n"
|
"hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light\n"
|
||||||
"hf mfdes setconfig --isoid df01 -t aes -s ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light\n"
|
"hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light\n"
|
||||||
"hf mfdes setconfig --isoid df01 -t aes -s lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp");
|
"hf mfdes setconfig --isoid df01 -t aes --schann lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -2305,7 +2305,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
|
||||||
"but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete\n"
|
"but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete\n"
|
||||||
"\n"
|
"\n"
|
||||||
"hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00\n"
|
"hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00\n"
|
||||||
"hf mfdes changekey --isoid df01 -t aes -s lrp --newkeyno 01 -> change key 01 via lrp channel"
|
"hf mfdes changekey --isoid df01 -t aes --schann lrp --newkeyno 01 -> change key 01 via lrp channel"
|
||||||
"hf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one\n"
|
"hf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one\n"
|
||||||
"hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key\n"
|
"hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key\n"
|
||||||
"hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0\n"
|
"hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0\n"
|
||||||
|
@ -2706,7 +2706,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes getuid",
|
CLIParserInit(&ctx, "hf mfdes getuid",
|
||||||
"Get UID from card. Get the real UID if the random UID bit is on and get the same UID as in anticollision if not. Any card's key needs to be provided. ",
|
"Get UID from card. Get the real UID if the random UID bit is on and get the same UID as in anticollision if not. Any card's key needs to be provided. ",
|
||||||
"hf mfdes getuid -> execute with default factory setup\n"
|
"hf mfdes getuid -> execute with default factory setup\n"
|
||||||
"hf mfdes getuid --isoid df01 -t aes -s lrp -> for desfire lights default settings");
|
"hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3375,7 +3375,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
|
||||||
"hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n"
|
"hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n"
|
||||||
"hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup\n"
|
"hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup\n"
|
||||||
"hf mfdes getfileisoids --isoid df01 -> get iso file ids from Desfire Light with factory card settings\n"
|
"hf mfdes getfileisoids --isoid df01 -> get iso file ids from Desfire Light with factory card settings\n"
|
||||||
"hf mfdes getfileisoids --isoid df01 -s lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication");
|
"hf mfdes getfileisoids --isoid df01 --schann lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -3572,7 +3572,6 @@ static int DesfireCreateFileParameters(
|
||||||
bool userawfrights = false;
|
bool userawfrights = false;
|
||||||
if (frightsid) {
|
if (frightsid) {
|
||||||
if (CLIGetUint32Hex(ctx, frightsid, 0xeeee, &frights, &userawfrights, 2, "File rights must have 2 bytes length")) {
|
if (CLIGetUint32Hex(ctx, frightsid, 0xeeee, &frights, &userawfrights, 2, "File rights must have 2 bytes length")) {
|
||||||
CLIParserFree(ctx);
|
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3618,7 +3617,7 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) {
|
||||||
"hf mfdes chfilesettings --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> change file settings app=123456, file=01 with defaults from `default` command\n"
|
"hf mfdes chfilesettings --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> change file settings app=123456, file=01 with defaults from `default` command\n"
|
||||||
"hf mfdes chfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --rawdata 00EEEE -> execute with default factory setup\n"
|
"hf mfdes chfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --rawdata 00EEEE -> execute with default factory setup\n"
|
||||||
"hf mfdes chfilesettings --aid 123456 --fid 01 --rawdata 810000021f112f22 -> change file settings with additional rights for keys 1 and 2\n"
|
"hf mfdes chfilesettings --aid 123456 --fid 01 --rawdata 810000021f112f22 -> change file settings with additional rights for keys 1 and 2\n"
|
||||||
"hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 -s lrp -t aes -> change file settings via lrp channel");
|
"hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 --schann lrp -t aes -> change file settings via lrp channel");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4143,8 +4142,8 @@ static int CmdHF14ADesCreateTrMACFile(const char *Cmd) {
|
||||||
"hf mfdes createmacfile --aid 123456 --fid 01 --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file with parameters. Rights from default. Authentication with defaults from `default` command\n"
|
"hf mfdes createmacfile --aid 123456 --fid 01 --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file with parameters. Rights from default. Authentication with defaults from `default` command\n"
|
||||||
"hf mfdes createmacfile --aid 123456 --fid 01 --amode plain --rrights free --wrights deny --rwrights free --chrights key0 --mackey 00112233445566778899aabbccddeeff -> create file app=123456, file=01, with key, and mentioned rights with defaults from `default` command\n"
|
"hf mfdes createmacfile --aid 123456 --fid 01 --amode plain --rrights free --wrights deny --rwrights free --chrights key0 --mackey 00112233445566778899aabbccddeeff -> create file app=123456, file=01, with key, and mentioned rights with defaults from `default` command\n"
|
||||||
"hf mfdes createmacfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup. key and keyver == 0x00..00\n"
|
"hf mfdes createmacfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup. key and keyver == 0x00..00\n"
|
||||||
"hf mfdes createmacfile --isoid df01 --fid 0f -s lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel\n"
|
"hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel\n"
|
||||||
"hf mfdes createmacfile --isoid df01 --fid 0f -s lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable");
|
"hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4261,7 +4260,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes deletefile",
|
CLIParserInit(&ctx, "hf mfdes deletefile",
|
||||||
"Delete file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
"Delete file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
||||||
"hf mfdes deletefile --aid 123456 --fid 01 -> delete file for: app=123456, file=01 with defaults from `default` command\n"
|
"hf mfdes deletefile --aid 123456 --fid 01 -> delete file for: app=123456, file=01 with defaults from `default` command\n"
|
||||||
"hf mfdes deletefile --isoid df01 --fid 0f -s lrp -t aes -> delete file for lrp channel");
|
"hf mfdes deletefile --isoid df01 --fid 0f --schann lrp -t aes -> delete file for lrp channel");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4307,7 +4306,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (fnum > 0x1F) {
|
if (fnum > 0x1F) {
|
||||||
PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum);
|
PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4338,8 +4337,8 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
|
||||||
"hf mfdes value --aid 123456 --fid 01 -> get value app=123456, file=01 with defaults from `default` command\n"
|
"hf mfdes value --aid 123456 --fid 01 -> get value app=123456, file=01 with defaults from `default` command\n"
|
||||||
"hf mfdes value --aid 123456 --fid 01 --op credit -d 00000001 -> credit value app=123456, file=01 with defaults from `default` command\n"
|
"hf mfdes value --aid 123456 --fid 01 --op credit -d 00000001 -> credit value app=123456, file=01 with defaults from `default` command\n"
|
||||||
"hf mfdes value -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> get value with default factory setup\n"
|
"hf mfdes value -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> get value with default factory setup\n"
|
||||||
"hf mfdes val --isoid df01 --fid 03 -s lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode\n"
|
"hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode\n"
|
||||||
"hf mfdes val --isoid df01 --fid 03 -s lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)");
|
"hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4511,7 +4510,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes clearrecfile",
|
CLIParserInit(&ctx, "hf mfdes clearrecfile",
|
||||||
"Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
"Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
||||||
"hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command\n"
|
"hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command\n"
|
||||||
"hf mfdes clearrecfile --isoid df01 --fid 01 -s lrp -t aes -n 3 -> clear record file for lrp channel with key number 3");
|
"hf mfdes clearrecfile --isoid df01 --fid 01 --schann lrp -t aes -n 3 -> clear record file for lrp channel with key number 3");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4557,7 +4556,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (fnum > 0x1F) {
|
if (fnum > 0x1F) {
|
||||||
PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum);
|
PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4843,14 +4842,17 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resplen > 0) {
|
if (resplen > 0 && reclen > 0) {
|
||||||
size_t reccount = resplen / reclen;
|
size_t reccount = resplen / reclen;
|
||||||
PrintAndLogEx(SUCCESS, "Read %zu bytes from file 0x%02x from record %d record count %zu record length %zu", resplen, fnum, offset, reccount, reclen);
|
PrintAndLogEx(SUCCESS, "Read %zu bytes from file 0x%02x from record %d record count %zu record length %zu", resplen, fnum, offset, reccount, reclen);
|
||||||
if (reccount > 1)
|
if (reccount > 1) {
|
||||||
PrintAndLogEx(SUCCESS, "Lastest record at the bottom.");
|
PrintAndLogEx(SUCCESS, "Lastest record at the bottom.");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < reccount; i++) {
|
for (int i = 0; i < reccount; i++) {
|
||||||
if (i != 0)
|
if (i != 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Record %zu", reccount - (i + offset + 1));
|
PrintAndLogEx(SUCCESS, "Record %zu", reccount - (i + offset + 1));
|
||||||
|
}
|
||||||
print_buffer_with_offset(&resp[i * reclen], reclen, offset, (i == 0));
|
print_buffer_with_offset(&resp[i * reclen], reclen, offset, (i == 0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -4910,8 +4912,8 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
||||||
"hf mfdes read --isoid 0102 --fileisoid 1000 --type data -c iso -> read file via ISO channel: app iso id=0102, iso id=1000, offset=0. Select via ISO commands\n"
|
"hf mfdes read --isoid 0102 --fileisoid 1000 --type data -c iso -> read file via ISO channel: app iso id=0102, iso id=1000, offset=0. Select via ISO commands\n"
|
||||||
"hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000001 -> get one record (number 5) from file 1100 via iso commands\n"
|
"hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000001 -> get one record (number 5) from file 1100 via iso commands\n"
|
||||||
"hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000000 -> get all record (from 5 to 1) from file 1100 via iso commands\n"
|
"hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000000 -> get all record (from 5 to 1) from file 1100 via iso commands\n"
|
||||||
"hf mfdes read --isoid df01 --fid 00 -s lrp -t aes --length 000010 -> read via lrp channel\n"
|
"hf mfdes read --isoid df01 --fid 00 --schann lrp -t aes --length 000010 -> read via lrp channel\n"
|
||||||
"hf mfdes read --isoid df01 --fid 00 -s ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel");
|
"hf mfdes read --isoid df01 --fid 00 --schann ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4989,7 +4991,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (fnum > 0x1F) {
|
if (fnum > 0x1F) {
|
||||||
PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum);
|
PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5082,7 +5084,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
||||||
"hf mfdes write --isoid 1234 --fileisoid 1000 --type data -c iso -d 01020304 -> write data to std/backup file via iso commandset\n"
|
"hf mfdes write --isoid 1234 --fileisoid 1000 --type data -c iso -d 01020304 -> write data to std/backup file via iso commandset\n"
|
||||||
"hf mfdes write --isoid 1234 --fileisoid 2000 --type record -c iso -d 01020304 -> send record to record file via iso commandset\n"
|
"hf mfdes write --isoid 1234 --fileisoid 2000 --type record -c iso -d 01020304 -> send record to record file via iso commandset\n"
|
||||||
"hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write\n"
|
"hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write\n"
|
||||||
"hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes -s lrp -> advanced CommitReaderID via lrp channel sample");
|
"hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes --schann lrp -> advanced CommitReaderID via lrp channel sample");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -5188,7 +5190,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (fnum > 0x1F) {
|
if (fnum > 0x1F) {
|
||||||
PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum);
|
PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5560,7 +5562,7 @@ static int CmdHF14ADesDump(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mfdes dump",
|
CLIParserInit(&ctx, "hf mfdes dump",
|
||||||
"For each application show fil list and then file content. Key needs to be provided for authentication or flag --no-auth set (depend on cards settings).",
|
"For each application show fil list and then file content. Key needs to be provided for authentication or flag --no-auth set (depend on cards settings).",
|
||||||
"hf mfdes dump --aid 123456 -> show file dump for: app=123456 with channel defaults from `default` command/n"
|
"hf mfdes dump --aid 123456 -> show file dump for: app=123456 with channel defaults from `default` command/n"
|
||||||
"hf mfdes dump --isoid df01 -s lrp -t aes --length 000090 -> lrp default settings with length limit");
|
"hf mfdes dump --isoid df01 --schann lrp -t aes --length 000090 -> lrp default settings with length limit");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
|
|
@ -1481,6 +1481,9 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_
|
||||||
|
|
||||||
if (got_match == false) {
|
if (got_match == false) {
|
||||||
PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum);
|
PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum);
|
||||||
|
if (nonce_file_write) {
|
||||||
|
fclose(fnonces);
|
||||||
|
}
|
||||||
return PM3_EWRONGANSWER;
|
return PM3_EWRONGANSWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,6 +392,12 @@ static int ul_auth_select(iso14a_card_select_t *card, TagTypeUL_t tagtype, bool
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ntagtt_getTamperStatus(uint8_t *response, uint16_t responseLength) {
|
||||||
|
uint8_t cmd[] = {NTAGTT_CMD_READ_TT, 0x00};
|
||||||
|
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static int ulev1_getVersion(uint8_t *response, uint16_t responseLength) {
|
static int ulev1_getVersion(uint8_t *response, uint16_t responseLength) {
|
||||||
uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
|
uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
|
||||||
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
|
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
|
||||||
|
@ -748,8 +754,75 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4));
|
PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4));
|
||||||
|
|
||||||
if ((tagtype & (NTAG_213_F | NTAG_213_TT | NTAG_216_F))) {
|
//NTAG213TT has different ASCII mirroring options and config bytes interpretation from other ulev1 class tags
|
||||||
uint8_t mirror_conf = (data[0] & 0xC0);
|
if (tagtype & NTAG_213_TT) {
|
||||||
|
uint8_t mirror_conf = ((data[0] & 0xE0) >> 5);
|
||||||
|
uint8_t mirror_byte = ((data[0] & 0x18) >> 3);
|
||||||
|
uint8_t mirror_page = data[2];
|
||||||
|
|
||||||
|
switch (mirror_conf) {
|
||||||
|
case 0:
|
||||||
|
PrintAndLogEx(INFO, " - no ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
PrintAndLogEx(INFO, " - UID ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PrintAndLogEx(INFO, " - NFC counter ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PrintAndLogEx(INFO, " - UID and NFC counter ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
PrintAndLogEx(INFO, " - tag tamper ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
PrintAndLogEx(INFO, " - UID and tag tamper ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
PrintAndLogEx(INFO, " - NFC counter and tag tamper ASCII mirror");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
PrintAndLogEx(INFO, " - UID, NFC counter, and tag tamper ASCII mirror");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mirror_conf) {
|
||||||
|
uint8_t mirror_user_mem_start_byte = (4 * (mirror_page - 4)) + mirror_byte;
|
||||||
|
uint8_t bytes_required_for_mirror_data = 0;
|
||||||
|
|
||||||
|
switch (mirror_conf) {
|
||||||
|
case 1:
|
||||||
|
bytes_required_for_mirror_data = 14;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bytes_required_for_mirror_data = 6;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
bytes_required_for_mirror_data = 8;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
bytes_required_for_mirror_data = 21;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
bytes_required_for_mirror_data = 23;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
bytes_required_for_mirror_data = 15;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
bytes_required_for_mirror_data = 30;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, " mirror start page %02X | byte pos %02X - %s", mirror_page, mirror_byte, (mirror_page >= 0x4 && ((mirror_user_mem_start_byte + bytes_required_for_mirror_data) <= 144)) ? _GREEN_("OK") : _YELLOW_("Invalid value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (tagtype & (NTAG_213_F | NTAG_216_F)) {
|
||||||
|
uint8_t mirror_conf = ((data[0] & 0xC0) >> 6);
|
||||||
uint8_t mirror_byte = (data[0] & 0x30);
|
uint8_t mirror_byte = (data[0] & 0x30);
|
||||||
bool sleep_en = (data[0] & 0x08);
|
bool sleep_en = (data[0] & 0x08);
|
||||||
strg_mod_en = (data[0] & 0x04);
|
strg_mod_en = (data[0] & 0x04);
|
||||||
|
@ -791,7 +864,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// valid mirror start page and byte position within start page.
|
// valid mirror start page and byte position within start page.
|
||||||
if ((tagtype & NTAG_213_F) || (tagtype & NTAG_213_TT)) {
|
if (tagtype & NTAG_213_F) {
|
||||||
switch (mirror_conf) {
|
switch (mirror_conf) {
|
||||||
case 1:
|
case 1:
|
||||||
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
|
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
|
||||||
|
@ -822,6 +895,35 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
|
||||||
else
|
else
|
||||||
PrintAndLogEx(INFO, " - pages don't need authentication");
|
PrintAndLogEx(INFO, " - pages don't need authentication");
|
||||||
|
|
||||||
|
uint8_t tt_enabled = 0;
|
||||||
|
uint8_t tt_message[4] = {0x00};
|
||||||
|
uint8_t tt_msg_resp_len = 0;
|
||||||
|
uint8_t tt_status_resp[5] = {0x00};
|
||||||
|
|
||||||
|
if (tagtype & NTAG_213_TT) {
|
||||||
|
tt_enabled = (data[1] & 0x02);
|
||||||
|
tt_msg_resp_len = ul_read(45, tt_message, 4);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, " - tamper detection feature is %s"
|
||||||
|
, (tt_enabled) ? _GREEN_("ENABLED") : "disabled"
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (data[1] & 0x06) {
|
||||||
|
case 0x00:
|
||||||
|
PrintAndLogEx(INFO, " - tamper message is unlocked and read/write enabled");
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
PrintAndLogEx(INFO, " - tamper message is reversibly read/write locked in memory while the tamper feature is enabled");
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
case 0x06:
|
||||||
|
PrintAndLogEx(INFO, " - tamper message is permanently read/write locked in memory");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " cfg1 [%u/0x%02X]: %s", startPage + 1, startPage + 1, sprint_hex(data + 4, 4));
|
PrintAndLogEx(INFO, " cfg1 [%u/0x%02X]: %s", startPage + 1, startPage + 1, sprint_hex(data + 4, 4));
|
||||||
if (authlim == 0)
|
if (authlim == 0)
|
||||||
PrintAndLogEx(INFO, " - " _GREEN_("Unlimited password attempts"));
|
PrintAndLogEx(INFO, " - " _GREEN_("Unlimited password attempts"));
|
||||||
|
@ -837,6 +939,55 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
|
||||||
PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4));
|
PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4));
|
||||||
PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2));
|
PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2));
|
||||||
PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2));
|
PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2));
|
||||||
|
|
||||||
|
if (tagtype & NTAG_213_TT) {
|
||||||
|
if (data[1] & 0x06) {
|
||||||
|
PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s- (cannot be read)", sprint_hex(tt_message, tt_msg_resp_len));
|
||||||
|
PrintAndLogEx(INFO, " - tamper message is masked in memory");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s", sprint_hex(tt_message, tt_msg_resp_len));
|
||||||
|
PrintAndLogEx(INFO, " - tamper message is %s and is readable/writablbe in memory", sprint_hex(tt_message, tt_msg_resp_len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//The NTAG213TT only returns meaningful information for the fields below if the tamper feature is enabled
|
||||||
|
if ((tagtype & NTAG_213_TT) && tt_enabled) {
|
||||||
|
|
||||||
|
uint8_t tt_status_len = ntagtt_getTamperStatus(tt_status_resp, 5);
|
||||||
|
|
||||||
|
if (tt_status_len != 5) {
|
||||||
|
PrintAndLogEx(WARNING, "Error sending the READ_TT_STATUS command to tag\n");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tamper Status"));
|
||||||
|
PrintAndLogEx(INFO, " READ_TT_STATUS: %s", sprint_hex(tt_status_resp, 5));
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, " Tamper status result from this power-up:");
|
||||||
|
switch (tt_status_resp[4]) {
|
||||||
|
case 0x43:
|
||||||
|
PrintAndLogEx(INFO, " - Tamper loop was detcted as closed during this power-up");
|
||||||
|
break;
|
||||||
|
case 0x4F:
|
||||||
|
PrintAndLogEx(INFO, " - Tamper loop was detected as open during this power-up");
|
||||||
|
break;
|
||||||
|
case 0x49:
|
||||||
|
PrintAndLogEx(INFO, " - Tamper loop measurement was not enabled or not valid during this power-up");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, " Tamper detection permanent memory:");
|
||||||
|
if ((tt_status_resp[0] | tt_status_resp [1] | tt_status_resp[2] | tt_status_resp[3]) == 0x00)
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, " - Tamper loop has never been detected as open during power-up");
|
||||||
|
else {
|
||||||
|
PrintAndLogEx(INFO, " - Tamper loop was detected as open during power-up at least once");
|
||||||
|
PrintAndLogEx(INFO, " - Tamper message returned by READ_TT_STATUS command: %s", sprint_hex(tt_status_resp, 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1472,6 +1623,7 @@ uint32_t GetHF14AMfU_Type(void) {
|
||||||
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; } // Mikron JSC Russia EV1 41 pages tag
|
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; } // Mikron JSC Russia EV1 41 pages tag
|
||||||
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = NTAG_210; break; }
|
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = NTAG_210; break; }
|
||||||
else if (memcmp(version, "\x00\x04\x04\x01\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; }
|
else if (memcmp(version, "\x00\x04\x04\x01\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; }
|
||||||
|
else if (memcmp(version, "\x00\x04\x04\x02\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; }
|
||||||
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = NTAG_212; break; }
|
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = NTAG_212; break; }
|
||||||
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; }
|
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; }
|
||||||
else if (memcmp(version, "\x00\x53\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } //Shanghai Feiju Microelectronics Co. Ltd. China (Xiaomi Air Purifier filter)
|
else if (memcmp(version, "\x00\x53\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } //Shanghai Feiju Microelectronics Co. Ltd. China (Xiaomi Air Purifier filter)
|
||||||
|
@ -1756,7 +1908,6 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
uint8_t startconfigblock = 0;
|
uint8_t startconfigblock = 0;
|
||||||
uint8_t ulev1_conf[16] = {0x00};
|
uint8_t ulev1_conf[16] = {0x00};
|
||||||
|
|
||||||
// config blocks always are last 4 pages
|
|
||||||
for (uint8_t i = 0; i < ARRAYLEN(UL_TYPES_ARRAY); i++) {
|
for (uint8_t i = 0; i < ARRAYLEN(UL_TYPES_ARRAY); i++) {
|
||||||
if (tagtype & UL_TYPES_ARRAY[i]) {
|
if (tagtype & UL_TYPES_ARRAY[i]) {
|
||||||
startconfigblock = UL_MEMORY_ARRAY[i] - 3;
|
startconfigblock = UL_MEMORY_ARRAY[i] - 3;
|
||||||
|
@ -2528,6 +2679,142 @@ static void wait4response(uint8_t b) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//Configure tamper feature of NTAG 213TT
|
||||||
|
//
|
||||||
|
int CmdHF14MfUTamper(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf mfu tamper",
|
||||||
|
"Set the congiguration of the NTAG 213TT tamper feature\n"
|
||||||
|
"Supports:\n"
|
||||||
|
"NTAG 213TT\n",
|
||||||
|
"hf mfu tamper -e -> enable tamper feature\n"
|
||||||
|
"hf mfu tamper -d -> disable tamper feature\n"
|
||||||
|
"hf mfu tamper -m 0A0A0A0A -> set the tamper message to 0A0A0A0A\n"
|
||||||
|
"hf mfu tamper --lockmessage -> permanently lock the tamper message and mask it from memory\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_lit0("e", "enable", "Enable the tamper feature"),
|
||||||
|
arg_lit0("d", "disable", "Disable the tamper feature"),
|
||||||
|
arg_str0("m", "message", "<hex>", "Set the tamper message (4 bytes)"),
|
||||||
|
arg_lit0(NULL, "lockmessage", "Permanently lock the tamper message and mask it from memory (does not lock tamper feature itself)"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
int tt_cfg_page = 41;
|
||||||
|
int tt_msg_page = 45;
|
||||||
|
int msg_len = 0;
|
||||||
|
uint8_t msg_data[4] = {0x00};
|
||||||
|
CLIGetHexWithReturn(ctx, 3, msg_data, &msg_len);
|
||||||
|
bool use_msg = (msg_len > 0);
|
||||||
|
|
||||||
|
if (use_msg && msg_len != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "The tamper message must be 4 hex bytes if provided");
|
||||||
|
DropField();
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lock_msg = arg_get_lit(ctx, 4);
|
||||||
|
bool enable = arg_get_lit(ctx, 1);
|
||||||
|
bool disable = arg_get_lit(ctx, 2);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
TagTypeUL_t tagtype = GetHF14AMfU_Type();
|
||||||
|
if (tagtype == UL_ERROR) {
|
||||||
|
PrintAndLogEx(WARNING, "Tag type not detected");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
if (tagtype != NTAG_213_TT) {
|
||||||
|
PrintAndLogEx(WARNING, "Tag type not NTAG 213TT");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
DropField();
|
||||||
|
iso14a_card_select_t card;
|
||||||
|
|
||||||
|
if (enable && disable) {
|
||||||
|
PrintAndLogEx(WARNING, "You can only select one of the options enable/disable tamper feature");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_msg) {
|
||||||
|
if (ul_select(&card) == false) {
|
||||||
|
DropField();
|
||||||
|
return UL_ERROR;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, "Trying to write tamper message\n");
|
||||||
|
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, tt_msg_page, 0, 0, msg_data, 4);
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
|
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||||
|
if (!isOK)
|
||||||
|
PrintAndLogEx(WARNING, "Failed to write tamper message");
|
||||||
|
else
|
||||||
|
PrintAndLogEx(SUCCESS, "Tamper message written successfully");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable | disable | lock_msg) {
|
||||||
|
|
||||||
|
if (ul_select(&card) == false) {
|
||||||
|
PrintAndLogEx(ERR, "Unable to select tag");
|
||||||
|
DropField();
|
||||||
|
return UL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cfg_page[4] = {0x00};
|
||||||
|
uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, tt_cfg_page};
|
||||||
|
int status = ul_send_cmd_raw(cmd, sizeof(cmd), cfg_page, 4);
|
||||||
|
DropField();
|
||||||
|
|
||||||
|
if (status <= 0) {
|
||||||
|
PrintAndLogEx(WARNING, "Problem reading current config from tag");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
cfg_page[1] = cfg_page[1] | 0x02;
|
||||||
|
PrintAndLogEx(INFO, "Enabling tamper feature");
|
||||||
|
}
|
||||||
|
if (disable) {
|
||||||
|
cfg_page[1] = cfg_page[1] & 0xFD;
|
||||||
|
PrintAndLogEx(INFO, "Disabling tamper feature");
|
||||||
|
}
|
||||||
|
if (lock_msg) {
|
||||||
|
cfg_page[1] = cfg_page[1] | 0x04;
|
||||||
|
PrintAndLogEx(INFO, "Locking tamper message");
|
||||||
|
}
|
||||||
|
|
||||||
|
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, tt_cfg_page, 0, 0, cfg_page, 4);
|
||||||
|
PacketResponseNG resp;
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
|
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||||
|
if (!isOK)
|
||||||
|
PrintAndLogEx(WARNING, "Failed to write tamper configuration");
|
||||||
|
else
|
||||||
|
PrintAndLogEx(SUCCESS, "Tamper configuration written successfully");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropField();
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Restore dump file onto tag
|
// Restore dump file onto tag
|
||||||
//
|
//
|
||||||
|
@ -2583,7 +2870,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||||
if (fnlen == 0) {
|
if (fnlen == 0) {
|
||||||
char *fptr = GenerateFilename("hf-mfu-", "-dump.bin");
|
char *fptr = GenerateFilename("hf-mfu-", "-dump.bin");
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
strcpy(filename, fptr);
|
strncpy(filename, fptr, sizeof(filename) - 1);
|
||||||
} else {
|
} else {
|
||||||
snprintf(filename, sizeof(filename), "dumpdata.bin");
|
snprintf(filename, sizeof(filename), "dumpdata.bin");
|
||||||
}
|
}
|
||||||
|
@ -4405,6 +4692,7 @@ static command_t CommandTable[] = {
|
||||||
{"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"},
|
{"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"},
|
||||||
{"view", CmdHF14AMfuView, AlwaysAvailable, "Display content from tag dump file"},
|
{"view", CmdHF14AMfuView, AlwaysAvailable, "Display content from tag dump file"},
|
||||||
{"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"},
|
{"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"},
|
||||||
|
{"tamper", CmdHF14MfUTamper, IfPm3Iso14443a, "Cofigure the tamper feature on an NTAG 213TT"},
|
||||||
{"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
{"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
||||||
{"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight dump file into emulator memory"},
|
{"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight dump file into emulator memory"},
|
||||||
{"esave", CmdHF14AMfuESave, IfPm3Iso14443a, "Save Ultralight dump file from emulator memory"},
|
{"esave", CmdHF14AMfuESave, IfPm3Iso14443a, "Save Ultralight dump file from emulator memory"},
|
||||||
|
|
|
@ -50,6 +50,7 @@ int trace_mfuc_try_default_3des_keys(uint8_t **correct_key, int state, uint8_t (
|
||||||
|
|
||||||
int CmdHFMFUltra(const char *Cmd);
|
int CmdHFMFUltra(const char *Cmd);
|
||||||
int CmdHF14MfuNDEFRead(const char *Cmd);
|
int CmdHF14MfuNDEFRead(const char *Cmd);
|
||||||
|
int CmdHF14MfUTamper(const char *Cmd);
|
||||||
|
|
||||||
uint16_t ul_ev1_packgen_VCNEW(uint8_t *uid, uint32_t pwd);
|
uint16_t ul_ev1_packgen_VCNEW(uint8_t *uid, uint32_t pwd);
|
||||||
uint32_t ul_ev1_otpgenA(uint8_t *uid);
|
uint32_t ul_ev1_otpgenA(uint8_t *uid);
|
||||||
|
|
|
@ -147,7 +147,7 @@ static int info_hf_tesla(void) {
|
||||||
|
|
||||||
// --------------- CERT reading ----------------
|
// --------------- CERT reading ----------------
|
||||||
Set_apdu_in_framing(true);
|
Set_apdu_in_framing(true);
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 5; i++) {
|
||||||
|
|
||||||
uint8_t aSELECT_CERT[PM3_CMD_DATA_SIZE] = {0x80, 0x06, i, 0x00, 0x00, 0x00, 0xFF};
|
uint8_t aSELECT_CERT[PM3_CMD_DATA_SIZE] = {0x80, 0x06, i, 0x00, 0x00, 0x00, 0xFF};
|
||||||
int aSELECT_CERT_n = 7;
|
int aSELECT_CERT_n = 7;
|
||||||
|
@ -160,7 +160,7 @@ static int info_hf_tesla(void) {
|
||||||
sw = get_sw(response, resplen);
|
sw = get_sw(response, resplen);
|
||||||
|
|
||||||
if (sw == ISO7816_OK) {
|
if (sw == ISO7816_OK) {
|
||||||
// save CETT for later
|
// save CERT for later
|
||||||
uint8_t cert[515] = {0};
|
uint8_t cert[515] = {0};
|
||||||
memcpy(cert, response, resplen - 2);
|
memcpy(cert, response, resplen - 2);
|
||||||
|
|
||||||
|
@ -198,13 +198,26 @@ static int info_hf_tesla(void) {
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "PUBLIC KEY");
|
PrintAndLogEx(INFO, "PUBLIC KEY");
|
||||||
for (int i=0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65));
|
PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65));
|
||||||
}
|
}
|
||||||
if (form_factor[1] == 1) {
|
PrintAndLogEx(INFO, "Form factor... %s " NOLF, sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
||||||
PrintAndLogEx(INFO, "Form factor... %s (card)", sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
|
||||||
} else if (form_factor[1] == 2){
|
uint16_t form_factor_value = MemBeToUint2byte(form_factor);
|
||||||
PrintAndLogEx(INFO, "Form factor... %s (phone app)", sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
|
||||||
|
switch (form_factor_value) {
|
||||||
|
case 0x0001:
|
||||||
|
PrintAndLogEx(NORMAL, "( card )");
|
||||||
|
break;
|
||||||
|
case 0x0022:
|
||||||
|
PrintAndLogEx(NORMAL, "( fob )");
|
||||||
|
break;
|
||||||
|
case 0x0031:
|
||||||
|
PrintAndLogEx(NORMAL, "( phone app )");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(NORMAL, "( unknown )");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeof(version) > 0) {
|
if (sizeof(version) > 0) {
|
||||||
|
@ -238,7 +251,6 @@ static int CmdHFTeslaInfo(const char *Cmd) {
|
||||||
return info_hf_tesla();
|
return info_hf_tesla();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int CmdHFTeslaList(const char *Cmd) {
|
static int CmdHFTeslaList(const char *Cmd) {
|
||||||
return CmdTraceListAlias(Cmd, "hf tesla", "7816");
|
return CmdTraceListAlias(Cmd, "hf tesla", "7816");
|
||||||
}
|
}
|
||||||
|
|
|
@ -712,17 +712,17 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((card.uidlen != 7) || ((memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "WSDZ10m", 7) != 0))) {
|
if ((card.uidlen != 7) || ((memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "FSTN11m", 7) != 0) && (memcmp(card.uid, "WSDZ10m", 7) != 0))) {
|
||||||
PrintAndLogEx(WARNING, "Card doesn't look like Waveshare tag");
|
PrintAndLogEx(WARNING, "Card doesn't look like Waveshare tag");
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
if (((model_nr != M1in54B) && (memcmp(card.uid, "FSTN10m", 7) == 0))) {
|
if (((model_nr != M1in54B) && ((memcmp(card.uid, "FSTN10m", 7) == 0) || (memcmp(card.uid, "FSTN11m", 7) == 0)))) {
|
||||||
PrintAndLogEx(WARNING, "Card is a Waveshare tag 1.54\", not %s", models[model_nr].desc);
|
PrintAndLogEx(WARNING, "Card is a Waveshare tag 1.54\", not %s", models[model_nr].desc);
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
if (((model_nr == M1in54B) && (memcmp(card.uid, "FSTN10m", 7) != 0))) {
|
if (((model_nr == M1in54B) && (memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "FSTN11m", 7) != 0))) {
|
||||||
PrintAndLogEx(WARNING, "Card is not a Waveshare tag 1.54\", check your model number");
|
PrintAndLogEx(WARNING, "Card is not a Waveshare tag 1.54\", check your model number");
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
|
@ -1298,6 +1298,10 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||||
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
|
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, " firmware.................. %s", _YELLOW_("PM3 GENERIC"));
|
PrintAndLogEx(NORMAL, " firmware.................. %s", _YELLOW_("PM3 GENERIC"));
|
||||||
|
if (IfPm3Flash()) {
|
||||||
|
PrintAndLogEx(NORMAL, " external flash............ %s", _GREEN_("present"));
|
||||||
|
}
|
||||||
|
|
||||||
if (IfPm3FpcUsartHost()) {
|
if (IfPm3FpcUsartHost()) {
|
||||||
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", _GREEN_("present"));
|
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", _GREEN_("present"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,8 @@ int demodAWID(bool verbose) {
|
||||||
}
|
}
|
||||||
free(bits);
|
free(bits);
|
||||||
|
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu Printing DemodBuffer:", idx, size);
|
PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu", idx, size);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Printing DemodBuffer:");
|
||||||
if (g_debugMode) {
|
if (g_debugMode) {
|
||||||
printDemodBuff(0, false, false, true);
|
printDemodBuff(0, false, false, true);
|
||||||
printDemodBuff(0, false, false, false);
|
printDemodBuff(0, false, false, false);
|
||||||
|
|
|
@ -1265,7 +1265,8 @@ int CmdEM4x05Info(const char *Cmd) {
|
||||||
|
|
||||||
// read word 1 (serial #) doesn't need pwd
|
// read word 1 (serial #) doesn't need pwd
|
||||||
// continue if failed, .. non blocking fail.
|
// continue if failed, .. non blocking fail.
|
||||||
em4x05_read_word_ext(EM_SERIAL_BLOCK, 0, false, &serial);
|
int res = em4x05_read_word_ext(EM_SERIAL_BLOCK, 0, false, &serial);
|
||||||
|
(void)res;
|
||||||
|
|
||||||
printEM4x05info(block0, serial);
|
printEM4x05info(block0, serial);
|
||||||
|
|
||||||
|
|
|
@ -555,7 +555,7 @@ int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
uint8_t *data = resp.data.asBytes;
|
uint8_t *data = resp.data.asBytes;
|
||||||
em4x50_word_t words[EM4X50_NO_WORDS];
|
em4x50_word_t words[EM4X50_NO_WORDS] = {0};
|
||||||
prepare_result(data, etd->addresses & 0xFF, (etd->addresses >> 8) & 0xFF, words);
|
prepare_result(data, etd->addresses & 0xFF, (etd->addresses >> 8) & 0xFF, words);
|
||||||
|
|
||||||
if (out != NULL)
|
if (out != NULL)
|
||||||
|
|
|
@ -200,7 +200,7 @@ int CmdEM4x70Write(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
etd.address = (uint8_t) addr;
|
etd.address = (uint8_t) addr;
|
||||||
etd.word = BYTES2UINT16(word);;
|
etd.word = BYTES2UINT16(word);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X70_WRITE, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X70_WRITE, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
@ -220,6 +220,105 @@ int CmdEM4x70Write(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdEM4x70Brute(const char *Cmd) {
|
||||||
|
|
||||||
|
// From paper "Dismantling Megamos Crypto", Roel Verdult, Flavio D. Garcia and Barıs¸ Ege.
|
||||||
|
// Partial Key-Update Attack (optimized version)
|
||||||
|
em4x70_data_t etd = {0};
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
|
||||||
|
CLIParserInit(&ctx, "lf em 4x70 brute",
|
||||||
|
"Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70\n"
|
||||||
|
"This attack does NOT write anything to the tag.\n"
|
||||||
|
"Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'.\n"
|
||||||
|
"After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'\n",
|
||||||
|
"lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 --> bruteforcing key bits k95...k80\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_lit0(NULL, "par", "Add parity bit when sending commands"),
|
||||||
|
arg_int1("b", "block", "<dec>", "block/word address, dec"),
|
||||||
|
arg_str1(NULL, "rnd", "<hex>", "Random 56-bit"),
|
||||||
|
arg_str1(NULL, "frn", "<hex>", "F(RN) 28-bit as 4 hex bytes"),
|
||||||
|
arg_str0("s", "start", "<hex>", "Start bruteforce enumeration from this key value"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
etd.parity = arg_get_lit(ctx, 1);
|
||||||
|
|
||||||
|
int addr = arg_get_int_def(ctx, 2, 0);
|
||||||
|
if (addr < 7 || addr > 9) {
|
||||||
|
PrintAndLogEx(FAILED, "block has to be within range [7, 9] got: %d", addr);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
etd.address = (uint8_t) addr;
|
||||||
|
|
||||||
|
int rnd_len = 7;
|
||||||
|
CLIGetHexWithReturn(ctx, 3, etd.rnd, &rnd_len);
|
||||||
|
|
||||||
|
int frnd_len = 4;
|
||||||
|
CLIGetHexWithReturn(ctx, 4, etd.frnd, &frnd_len);
|
||||||
|
|
||||||
|
uint32_t start_key = 0;
|
||||||
|
int res = arg_get_u32_hexstr_def_nlen(ctx, 5, 0, &start_key, 2, true);
|
||||||
|
if (res == 2) {
|
||||||
|
PrintAndLogEx(WARNING, "start key parameter must be in range [0, FFFF]");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
etd.start_key = start_key;
|
||||||
|
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (rnd_len != 7) {
|
||||||
|
PrintAndLogEx(FAILED, "Random number length must be 7 bytes instead of %d", rnd_len);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frnd_len != 4) {
|
||||||
|
PrintAndLogEx(FAILED, "F(RN) length must be 4 bytes instead of %d", frnd_len);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit");
|
||||||
|
clearCommandBuffer();
|
||||||
|
PacketResponseNG resp;
|
||||||
|
SendCommandNG(CMD_LF_EM4X70_BRUTE, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
|
||||||
|
uint32_t timeout = 0;
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
if (kbd_enter_pressed()) {
|
||||||
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
|
PrintAndLogEx(DEBUG, "User aborted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_LF_EM4X70_BRUTE, &resp, TIMEOUT)) {
|
||||||
|
if (resp.status) {
|
||||||
|
// Response is 16-bit partial key
|
||||||
|
PrintAndLogEx(INFO, "Partial Key Response: %02X %02X", resp.data.asBytes[0], resp.data.asBytes[1]);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be done in about 60 minutes.
|
||||||
|
if (timeout > ((60 * 60000) / TIMEOUT)) {
|
||||||
|
PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(FAILED, "Bruteforce of partial key " _RED_("failed"));
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
int CmdEM4x70Unlock(const char *Cmd) {
|
int CmdEM4x70Unlock(const char *Cmd) {
|
||||||
|
|
||||||
// send pin code to device, unlocking it for writing
|
// send pin code to device, unlocking it for writing
|
||||||
|
@ -452,6 +551,7 @@ int CmdEM4x70WriteKey(const char *Cmd) {
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"brute", CmdEM4x70Brute, IfPm3EM4x70, "Bruteforce EM4X70 to find partial Crypt Key"},
|
||||||
{"info", CmdEM4x70Info, IfPm3EM4x70, "Tag information EM4x70"},
|
{"info", CmdEM4x70Info, IfPm3EM4x70, "Tag information EM4x70"},
|
||||||
{"write", CmdEM4x70Write, IfPm3EM4x70, "Write EM4x70"},
|
{"write", CmdEM4x70Write, IfPm3EM4x70, "Write EM4x70"},
|
||||||
{"unlock", CmdEM4x70Unlock, IfPm3EM4x70, "Unlock EM4x70 for writing"},
|
{"unlock", CmdEM4x70Unlock, IfPm3EM4x70, "Unlock EM4x70 for writing"},
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
int CmdLFEM4X70(const char *Cmd);
|
int CmdLFEM4X70(const char *Cmd);
|
||||||
int CmdEM4x70Info(const char *Cmd);
|
int CmdEM4x70Info(const char *Cmd);
|
||||||
int CmdEM4x70Write(const char *Cmd);
|
int CmdEM4x70Write(const char *Cmd);
|
||||||
|
int CmdEM4x70Brute(const char *Cmd);
|
||||||
int CmdEM4x70Unlock(const char *Cmd);
|
int CmdEM4x70Unlock(const char *Cmd);
|
||||||
int CmdEM4x70Auth(const char *Cmd);
|
int CmdEM4x70Auth(const char *Cmd);
|
||||||
int CmdEM4x70WritePIN(const char *Cmd);
|
int CmdEM4x70WritePIN(const char *Cmd);
|
||||||
|
|
|
@ -86,9 +86,9 @@ static int demod_guard_raw(uint8_t *raw, uint8_t rlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unknown)
|
if (unknown)
|
||||||
PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") ", Raw: %s", fmtlen, sprint_hex_inrow(raw, rlen));
|
PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") "xor: " _GREEN_("%u")", Raw: %s", fmtlen, xorKey, sprint_hex_inrow(raw, rlen));
|
||||||
else
|
else
|
||||||
PrintAndLogEx(SUCCESS, "G-Prox-II - len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %s", fmtlen, FC, Card, sprint_hex_inrow(raw, rlen));
|
PrintAndLogEx(SUCCESS, "G-Prox-II - Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") "xor: " _GREEN_("%u")", Raw: %s", fmtlen, FC, Card, xorKey, sprint_hex_inrow(raw, rlen));
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,11 @@ int demodGuard(bool verbose) {
|
||||||
|
|
||||||
// get key and then get all 8 bytes of payload decoded
|
// get key and then get all 8 bytes of payload decoded
|
||||||
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
|
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: gProxII xorKey: %u", xorKey);
|
||||||
|
|
||||||
for (size_t idx = 0; idx < 8; idx++) {
|
for (size_t idx = 0; idx < 8; idx++) {
|
||||||
plain[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey;
|
plain[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey;
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %zu after xor: %02x", idx, plain[idx]);
|
PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %zu after xor: %02x (%02x before xor)", idx, plain[idx], bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
setDemodBuff(g_DemodBuffer, 96, preambleIndex);
|
setDemodBuff(g_DemodBuffer, 96, preambleIndex);
|
||||||
|
@ -161,6 +163,12 @@ int demodGuard(bool verbose) {
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
switch (fmtLen) {
|
switch (fmtLen) {
|
||||||
case 36:
|
case 36:
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: FC 1: %x", (plain[3] & 0x7F) << 7);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: FC 2: %x", plain[4] >> 1);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Card 1: %x", (plain[4] & 1) << 19);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Card 2: %x", plain[5] << 11);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Card 3: %x", plain[6] << 3);
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Card 4: %x", (plain[7] & 0xE0) >> 5);
|
||||||
FC = ((plain[3] & 0x7F) << 7) | (plain[4] >> 1);
|
FC = ((plain[3] & 0x7F) << 7) | (plain[4] >> 1);
|
||||||
Card = ((plain[4] & 1) << 19) | (plain[5] << 11) | (plain[6] << 3) | ((plain[7] & 0xE0) >> 5);
|
Card = ((plain[4] & 1) << 19) | (plain[5] << 11) | (plain[6] << 3) | ((plain[7] & 0xE0) >> 5);
|
||||||
break;
|
break;
|
||||||
|
@ -172,10 +180,10 @@ int demodGuard(bool verbose) {
|
||||||
unknown = true;
|
unknown = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!unknown)
|
if (unknown)
|
||||||
PrintAndLogEx(SUCCESS, "G-Prox-II - len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3);
|
PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") " xor: " _GREEN_("%u")", Raw: %08x%08x%08x ", fmtLen, xorKey, raw1, raw2, raw3);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") ", Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3);
|
PrintAndLogEx(SUCCESS, "G-Prox-II - Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") " xor: " _GREEN_("%u") ", Raw: %08x%08x%08x", fmtLen, FC, Card, xorKey, raw1, raw2, raw3);
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -243,16 +251,17 @@ static int CmdGuardReader(const char *Cmd) {
|
||||||
static int CmdGuardClone(const char *Cmd) {
|
static int CmdGuardClone(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf gproxii clone",
|
CLIParserInit(&ctx, "lf gproxii clone",
|
||||||
"clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
|
"Clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
|
||||||
"The facility-code is 8-bit and the card number is 20-bit. Larger values are truncated.\n"
|
"The facility-code is 8-bit and the card number is 20-bit. Larger values are truncated.\n"
|
||||||
"Currently work only on 26 | 36 bit format",
|
"Currently work only on 26 | 36 bit format",
|
||||||
"lf gproxii clone --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag\n"
|
"lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag\n"
|
||||||
"lf gproxii clone --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag\n"
|
"lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag\n"
|
||||||
"lf gproxii clone --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469"
|
"lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
arg_u64_1(NULL, "xor", "<dec>", "8-bit xor value (installation dependant)"),
|
||||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
||||||
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
||||||
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
||||||
|
@ -262,11 +271,13 @@ static int CmdGuardClone(const char *Cmd) {
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
uint32_t xorval = arg_get_u32_def(ctx, 1, 0);
|
||||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
uint32_t fmtlen = arg_get_u32_def(ctx, 2, 0);
|
||||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
uint32_t fc = arg_get_u32_def(ctx, 3, 0);
|
||||||
bool q5 = arg_get_lit(ctx, 4);
|
uint32_t cn = arg_get_u32_def(ctx, 4, 0);
|
||||||
bool em = arg_get_lit(ctx, 5);
|
|
||||||
|
bool q5 = arg_get_lit(ctx, 5);
|
||||||
|
bool em = arg_get_lit(ctx, 6);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (q5 && em) {
|
if (q5 && em) {
|
||||||
|
@ -280,7 +291,7 @@ static int CmdGuardClone(const char *Cmd) {
|
||||||
|
|
||||||
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
|
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
|
||||||
uint8_t *bs = calloc(96, sizeof(uint8_t));
|
uint8_t *bs = calloc(96, sizeof(uint8_t));
|
||||||
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
|
if (getGuardBits(xorval, fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||||
free(bs);
|
free(bs);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -306,10 +317,11 @@ static int CmdGuardClone(const char *Cmd) {
|
||||||
|
|
||||||
free(bs);
|
free(bs);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: " _GREEN_("%u") " Card Number: " _GREEN_("%u")
|
PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: " _GREEN_("%u") " Card Number: " _GREEN_("%u") " xorKey: " _GREEN_("%u")
|
||||||
, cardtype
|
, cardtype
|
||||||
, facilitycode
|
, facilitycode
|
||||||
, cardnumber
|
, cardnumber
|
||||||
|
, xorval
|
||||||
);
|
);
|
||||||
print_blocks(blocks, ARRAYLEN(blocks));
|
print_blocks(blocks, ARRAYLEN(blocks));
|
||||||
|
|
||||||
|
@ -332,11 +344,12 @@ static int CmdGuardSim(const char *Cmd) {
|
||||||
"Simulation runs until the button is pressed or another USB command is issued.\n"
|
"Simulation runs until the button is pressed or another USB command is issued.\n"
|
||||||
"The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
|
"The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
|
||||||
"Currently work only on 26 | 36 bit format",
|
"Currently work only on 26 | 36 bit format",
|
||||||
"lf gproxii sim --fmt 26 --fc 123 --cn 1337\n"
|
"lf gproxii sim --xor 141 --fmt 26 --fc 123 --cn 1337\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
arg_u64_1(NULL, "xor", "<dec>", "8-bit xor value (installation dependant)"),
|
||||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
||||||
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
||||||
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
||||||
|
@ -344,9 +357,10 @@ static int CmdGuardSim(const char *Cmd) {
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
uint32_t xorval = arg_get_u32_def(ctx, 1, 0);
|
||||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
uint32_t fmtlen = arg_get_u32_def(ctx, 2, 0);
|
||||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
uint32_t fc = arg_get_u32_def(ctx, 3, 0);
|
||||||
|
uint32_t cn = arg_get_u32_def(ctx, 4, 0);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
fmtlen &= 0x7F;
|
fmtlen &= 0x7F;
|
||||||
|
@ -356,12 +370,13 @@ static int CmdGuardSim(const char *Cmd) {
|
||||||
uint8_t bs[96];
|
uint8_t bs[96];
|
||||||
memset(bs, 0x00, sizeof(bs));
|
memset(bs, 0x00, sizeof(bs));
|
||||||
|
|
||||||
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
|
if (getGuardBits(xorval, fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u")
|
PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - xorKey: " _YELLOW_("%u") " Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u")
|
||||||
|
, xorval
|
||||||
, facilitycode
|
, facilitycode
|
||||||
, cardnumber
|
, cardnumber
|
||||||
);
|
);
|
||||||
|
@ -435,9 +450,8 @@ int detectGProxII(uint8_t *bits, size_t *size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Works for 26bits.
|
// Works for 26bits.
|
||||||
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
int getGuardBits(uint8_t xorKey, uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
||||||
|
|
||||||
uint8_t xorKey = 0x66;
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint8_t pre[96];
|
uint8_t pre[96];
|
||||||
uint8_t rawbytes[12];
|
uint8_t rawbytes[12];
|
||||||
|
@ -448,7 +462,6 @@ int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
||||||
switch (fmtlen) {
|
switch (fmtlen) {
|
||||||
case 32: {
|
case 32: {
|
||||||
rawbytes[1] = (32 << 2);
|
rawbytes[1] = (32 << 2);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 36: {
|
case 36: {
|
||||||
|
@ -456,6 +469,7 @@ int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
|
||||||
// Get wiegand from FacilityCode 14bits, CardNumber 20bits
|
// Get wiegand from FacilityCode 14bits, CardNumber 20bits
|
||||||
uint8_t wiegand[36];
|
uint8_t wiegand[36];
|
||||||
memset(wiegand, 0x00, sizeof(wiegand));
|
memset(wiegand, 0x00, sizeof(wiegand));
|
||||||
|
|
||||||
num_to_bytebits(fc, 14, wiegand);
|
num_to_bytebits(fc, 14, wiegand);
|
||||||
num_to_bytebits(cn, 20, wiegand + 14);
|
num_to_bytebits(cn, 20, wiegand + 14);
|
||||||
|
|
||||||
|
|
|
@ -23,5 +23,5 @@
|
||||||
int CmdLFGuard(const char *Cmd);
|
int CmdLFGuard(const char *Cmd);
|
||||||
int detectGProxII(uint8_t *bits, size_t *size);
|
int detectGProxII(uint8_t *bits, size_t *size);
|
||||||
int demodGuard(bool verbose);
|
int demodGuard(bool verbose);
|
||||||
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits);
|
int getGuardBits(uint8_t xorKey, uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits);
|
||||||
#endif
|
#endif
|
||||||
|
|
122
client/src/cmdlfhid.c
Normal file → Executable file
122
client/src/cmdlfhid.c
Normal file → Executable file
|
@ -80,12 +80,14 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
lf_hidsim_t payload;
|
lf_hidsim_t payload = {
|
||||||
payload.Q5 = false;
|
.EM = false,
|
||||||
payload.hi2 = packed.Top;
|
.Q5 = false,
|
||||||
payload.hi = packed.Mid;
|
.hi2 = packed.Top,
|
||||||
payload.lo = packed.Bot;
|
.hi = packed.Mid,
|
||||||
payload.longFMT = (packed.Mid > 0xFFF);
|
.lo = packed.Bot,
|
||||||
|
.longFMT = (packed.Mid > 0xFFF)
|
||||||
|
};
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
@ -473,26 +475,27 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
static int CmdHIDBrute(const char *Cmd) {
|
static int CmdHIDBrute(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hid brute",
|
CLIParserInit(&ctx, "lf hid brute",
|
||||||
"Enables bruteforce of HID readers with specified facility code.\n"
|
"Enables bruteforce of HID readers with specified facility code or card number. This is an attack against the reader.\n"
|
||||||
"This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
|
"If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values.\n"
|
||||||
"if cardnumber is not given, it starts with 1 and goes up to 65535",
|
"If the field being bruteforced is not provided, it will iterate through the full range while maintaining other supplied values.",
|
||||||
"lf hid brute -w H10301 --fc 224\n"
|
"lf hid brute -w H10301 --field fc --fc 224 --cn 6278\n"
|
||||||
"lf hid brute -w H10301 --fc 21 -d 2000\n"
|
"lf hid brute -w H10301 --field cn --fc 21 -d 2000\n"
|
||||||
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000\n"
|
"lf hid brute -v -w H10301 --field cn --fc 21 --cn 200 -d 2000\n"
|
||||||
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000 --up\n"
|
"lf hid brute -v -w H10301 --field fc --fc 21 --cn 200 -d 2000 --up\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_str1("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
arg_str1("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
||||||
|
arg_str1(NULL, "field", "<fc|cn>", "field to bruteforce"),
|
||||||
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
||||||
arg_u64_0(NULL, "cn", "<dec>", "card number to start with"),
|
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
||||||
arg_u64_0("i", "issue", "<dec>", "issue level"),
|
arg_u64_0("i", "issue", "<dec>", "issue level"),
|
||||||
arg_u64_0("o", "oem", "<dec>", "OEM code"),
|
arg_u64_0("o", "oem", "<dec>", "OEM code"),
|
||||||
arg_u64_0("d", "delay", "<dec>", "delay betweens attempts in ms. Default 1000ms"),
|
arg_u64_0("d", "delay", "<dec>", "delay betweens attempts in ms. (def is 1000)"),
|
||||||
arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"),
|
arg_lit0(NULL, "up", "direction to increment field value. (def is both directions)"),
|
||||||
arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"),
|
arg_lit0(NULL, "down", "direction to decrement field value. (def is both directions)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -510,22 +513,26 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
wiegand_card_t cn_hi, cn_low;
|
wiegand_card_t card_hi, card_low;
|
||||||
memset(&cn_hi, 0, sizeof(wiegand_card_t));
|
memset(&card_hi, 0, sizeof(wiegand_card_t));
|
||||||
|
|
||||||
cn_hi.FacilityCode = arg_get_u32_def(ctx, 3, 0);
|
char field[3] = {0};
|
||||||
cn_hi.CardNumber = arg_get_u32_def(ctx, 4, 0);
|
int field_len = 0;
|
||||||
cn_hi.IssueLevel = arg_get_u32_def(ctx, 5, 0);
|
CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)field, sizeof(field), &field_len);
|
||||||
cn_hi.OEM = arg_get_u32_def(ctx, 6, 0);
|
|
||||||
|
|
||||||
uint32_t delay = arg_get_u32_def(ctx, 7, 1000);
|
card_hi.FacilityCode = arg_get_u32_def(ctx, 4, 0);
|
||||||
|
card_hi.CardNumber = arg_get_u32_def(ctx, 5, 0);
|
||||||
|
card_hi.IssueLevel = arg_get_u32_def(ctx, 6, 0);
|
||||||
|
card_hi.OEM = arg_get_u32_def(ctx, 7, 0);
|
||||||
|
|
||||||
|
uint32_t delay = arg_get_u32_def(ctx, 8, 1000);
|
||||||
|
|
||||||
int direction = 0;
|
int direction = 0;
|
||||||
if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) {
|
if (arg_get_lit(ctx, 9) && arg_get_lit(ctx, 10)) {
|
||||||
direction = 0;
|
direction = 0;
|
||||||
} else if (arg_get_lit(ctx, 8)) {
|
|
||||||
direction = 1;
|
|
||||||
} else if (arg_get_lit(ctx, 9)) {
|
} else if (arg_get_lit(ctx, 9)) {
|
||||||
|
direction = 1;
|
||||||
|
} else if (arg_get_lit(ctx, 10)) {
|
||||||
direction = 2;
|
direction = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,34 +540,38 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "Wiegand format... %i", format_idx);
|
PrintAndLogEx(INFO, "Wiegand format... %i", format_idx);
|
||||||
PrintAndLogEx(INFO, "OEM.............. %u", cn_hi.OEM);
|
PrintAndLogEx(INFO, "OEM.............. %u", card_hi.OEM);
|
||||||
PrintAndLogEx(INFO, "ISSUE............ %u", cn_hi.IssueLevel);
|
PrintAndLogEx(INFO, "ISSUE............ %u", card_hi.IssueLevel);
|
||||||
PrintAndLogEx(INFO, "Facility code.... %u", cn_hi.FacilityCode);
|
PrintAndLogEx(INFO, "Facility code.... %u", card_hi.FacilityCode);
|
||||||
PrintAndLogEx(INFO, "Card number...... %" PRIu64, cn_hi.CardNumber);
|
PrintAndLogEx(INFO, "Card number...... %" PRIu64, card_hi.CardNumber);
|
||||||
PrintAndLogEx(INFO, "Delay............ " _YELLOW_("%d"), delay);
|
PrintAndLogEx(INFO, "Delay............ " _YELLOW_("%d"), delay);
|
||||||
|
if (strcmp(field, "fc") == 0) {
|
||||||
|
PrintAndLogEx(INFO, "Field............ " _YELLOW_("fc"));
|
||||||
|
} else if (strcmp(field, "cn") == 0) {
|
||||||
|
PrintAndLogEx(INFO, "Field............ " _YELLOW_("cn"));
|
||||||
|
}
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 0:
|
case 0:
|
||||||
PrintAndLogEx(INFO, "Direction........ " _YELLOW_("BOTH"));
|
PrintAndLogEx(INFO, "Direction........ " _YELLOW_("both"));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
PrintAndLogEx(INFO, "Direction........ " _YELLOW_("UP"));
|
PrintAndLogEx(INFO, "Direction........ " _YELLOW_("up"));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
PrintAndLogEx(INFO, "Direction........ " _YELLOW_("DOWN"));
|
PrintAndLogEx(INFO, "Direction........ " _YELLOW_("down"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "Started brute-forcing HID Prox reader");
|
PrintAndLogEx(INFO, "Started bruteforcing HID Prox reader");
|
||||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " or pm3-button to abort simulation");
|
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " or pm3-button to abort simulation");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
// copy values to low.
|
// copy values to low.
|
||||||
cn_low = cn_hi;
|
card_low = card_hi;
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
// iceman: could add options for bruteforcing OEM, ISSUE or FC as well..
|
|
||||||
bool exitloop = false;
|
bool exitloop = false;
|
||||||
bool fin_hi, fin_low;
|
bool fin_hi, fin_low;
|
||||||
fin_hi = fin_low = false;
|
fin_hi = fin_low = false;
|
||||||
|
@ -577,27 +588,43 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// do one up
|
// do one up
|
||||||
if (direction != 2) {
|
if (direction != 2 && fin_hi != true) {
|
||||||
if (cn_hi.CardNumber < 0xFFFF) {
|
if (sendTry(format_idx, &card_hi, delay, verbose) != PM3_SUCCESS) {
|
||||||
if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) {
|
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
cn_hi.CardNumber++;
|
if (strcmp(field, "fc") == 0) {
|
||||||
|
if (card_hi.FacilityCode < 0xFF) {
|
||||||
|
card_hi.FacilityCode++;
|
||||||
|
} else {
|
||||||
|
fin_hi = true;
|
||||||
|
}
|
||||||
|
} else if (strcmp(field, "cn") == 0) {
|
||||||
|
if (card_hi.CardNumber < 0xFFFF) {
|
||||||
|
card_hi.CardNumber++;
|
||||||
} else {
|
} else {
|
||||||
fin_hi = true;
|
fin_hi = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// do one down
|
// do one down
|
||||||
if (direction != 1) {
|
if (direction != 1 && fin_low != true) {
|
||||||
if (cn_low.CardNumber > 0) {
|
if (sendTry(format_idx, &card_low, delay, verbose) != PM3_SUCCESS) {
|
||||||
cn_low.CardNumber--;
|
|
||||||
if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) {
|
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
if (strcmp(field, "fc") == 0) {
|
||||||
|
if (card_low.FacilityCode > 0) {
|
||||||
|
card_low.FacilityCode--;
|
||||||
} else {
|
} else {
|
||||||
fin_low = true;
|
fin_low = true;
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(field, "cn") == 0) {
|
||||||
|
if (card_low.CardNumber > 0) {
|
||||||
|
card_low.CardNumber--;
|
||||||
|
} else {
|
||||||
|
fin_low = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
|
@ -618,7 +645,8 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
|
|
||||||
} while (exitloop == false);
|
} while (exitloop == false);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Brute forcing finished");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, "Bruteforcing finished");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,7 +656,7 @@ static command_t CommandTable[] = {
|
||||||
{"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"},
|
{"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"},
|
||||||
{"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
|
{"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"},
|
||||||
{"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
|
{"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"},
|
||||||
{"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"},
|
{"brute", CmdHIDBrute, IfPm3Lf, "bruteforce facility code or card number against reader"},
|
||||||
{"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
|
{"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -300,15 +300,23 @@ static int CmdClear(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "clear",
|
CLIParserInit(&ctx, "clear",
|
||||||
"Clear the Proxmark3 client terminal screen",
|
"Clear the Proxmark3 client terminal screen",
|
||||||
"clear"
|
"clear -> clear the terminal screen\n"
|
||||||
|
"clear -b -> clear the terminal screen and the scrollback buffer"
|
||||||
);
|
);
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
arg_lit0("b", "back", "also clear the scrollback buffer"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
bool scrollback = arg_get_lit(ctx, 1);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (!scrollback)
|
||||||
PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ "");
|
PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ "");
|
||||||
|
else
|
||||||
|
PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ _CLEAR_SCROLLBACK_ "");
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ bool IfPm3Present(void) {
|
||||||
bool IfPm3Rdv4Fw(void) {
|
bool IfPm3Rdv4Fw(void) {
|
||||||
if (!IfPm3Present())
|
if (!IfPm3Present())
|
||||||
return false;
|
return false;
|
||||||
return (g_pm3_capabilities.compiled_with_flash) || (g_pm3_capabilities.compiled_with_smartcard);
|
return (g_pm3_capabilities.is_rdv4);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfPm3Flash(void) {
|
bool IfPm3Flash(void) {
|
||||||
|
|
|
@ -698,10 +698,12 @@ static int PivSelect(Iso7816CommandChannel channel, bool activateField, bool lea
|
||||||
if ((sw != 0) && (silent == false)) {
|
if ((sw != 0) && (silent == false)) {
|
||||||
PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != PM3_SUCCESS || sw != ISO7816_OK) {
|
if (res != PM3_SUCCESS || sw != ISO7816_OK) {
|
||||||
PrintAndLogEx(FAILED, "Applet selection failed. Card is not a PIV card.");
|
PrintAndLogEx(FAILED, "Applet selection failed. Card is not a PIV card.");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (silent == false) {
|
if (silent == false) {
|
||||||
if (decodeTLV == true) {
|
if (decodeTLV == true) {
|
||||||
PrintTLVFromBuffer(buf, len);
|
PrintTLVFromBuffer(buf, len);
|
||||||
|
@ -736,8 +738,10 @@ static int CmdPIVSelect(const char *Cmd) {
|
||||||
bool APDULogging = arg_get_lit(ctx, 3);
|
bool APDULogging = arg_get_lit(ctx, 3);
|
||||||
bool decodeTLV = arg_get_lit(ctx, 4);
|
bool decodeTLV = arg_get_lit(ctx, 4);
|
||||||
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
Iso7816CommandChannel channel = CC_CONTACTLESS;
|
||||||
if (arg_get_lit(ctx, 5))
|
if (arg_get_lit(ctx, 5)) {
|
||||||
channel = CC_CONTACT;
|
channel = CC_CONTACT;
|
||||||
|
}
|
||||||
|
|
||||||
PrintChannel(channel);
|
PrintChannel(channel);
|
||||||
|
|
||||||
uint8_t applet_id[APDU_AID_LEN] = {0};
|
uint8_t applet_id[APDU_AID_LEN] = {0};
|
||||||
|
@ -970,7 +974,6 @@ static command_t CommandTable[] = {
|
||||||
{"getdata", CmdPIVGetData, IfPm3Iso14443, "Gets a container on a PIV card"},
|
{"getdata", CmdPIVGetData, IfPm3Iso14443, "Gets a container on a PIV card"},
|
||||||
{"authsign", CmdPIVAuthenticateSign, IfPm3Iso14443, "Authenticate with the card"},
|
{"authsign", CmdPIVAuthenticateSign, IfPm3Iso14443, "Authenticate with the card"},
|
||||||
{"scan", CmdPIVScan, IfPm3Iso14443, "Scan PIV card for known containers"},
|
{"scan", CmdPIVScan, IfPm3Iso14443, "Scan PIV card for known containers"},
|
||||||
|
|
||||||
{"list", CmdPIVList, AlwaysAvailable, "List ISO7816 history"},
|
{"list", CmdPIVList, AlwaysAvailable, "List ISO7816 history"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -164,11 +164,18 @@ static void set_python_path(const char *path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_python_paths(void) {
|
static void set_python_paths(void) {
|
||||||
//--add to the LUA_PATH (package.path in lua)
|
// Prepending to sys.path so we can load scripts from various places.
|
||||||
// so we can load scripts from various places:
|
// This means the following directories are in reverse order of
|
||||||
|
// priority for search python modules.
|
||||||
|
|
||||||
|
// Allow current working directory because it seems that's what users want.
|
||||||
|
// But put it with lower search priority than the typical pm3 scripts directories
|
||||||
|
// but still with a higher priority than the pip installed libraries to mimic
|
||||||
|
// Python interpreter behavior. That should be confusing the users the least.
|
||||||
|
set_python_path(".");
|
||||||
const char *exec_path = get_my_executable_directory();
|
const char *exec_path = get_my_executable_directory();
|
||||||
if (exec_path != NULL) {
|
if (exec_path != NULL) {
|
||||||
// from the ./luascripts/ directory
|
// from the ./pyscripts/ directory
|
||||||
char scripts_path[strlen(exec_path) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
char scripts_path[strlen(exec_path) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
||||||
strcpy(scripts_path, exec_path);
|
strcpy(scripts_path, exec_path);
|
||||||
strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR);
|
strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR);
|
||||||
|
@ -178,7 +185,7 @@ static void set_python_paths(void) {
|
||||||
|
|
||||||
const char *user_path = get_my_user_directory();
|
const char *user_path = get_my_user_directory();
|
||||||
if (user_path != NULL) {
|
if (user_path != NULL) {
|
||||||
// from the $HOME/.proxmark3/luascripts/ directory
|
// from the $HOME/.proxmark3/pyscripts/ directory
|
||||||
char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
||||||
strcpy(scripts_path, user_path);
|
strcpy(scripts_path, user_path);
|
||||||
strcat(scripts_path, PM3_USER_DIRECTORY);
|
strcat(scripts_path, PM3_USER_DIRECTORY);
|
||||||
|
@ -189,7 +196,7 @@ static void set_python_paths(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exec_path != NULL) {
|
if (exec_path != NULL) {
|
||||||
// from the $PREFIX/share/proxmark3/luascripts/ directory
|
// from the $PREFIX/share/proxmark3/pyscripts/ directory
|
||||||
char scripts_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
char scripts_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
||||||
strcpy(scripts_path, exec_path);
|
strcpy(scripts_path, exec_path);
|
||||||
strcat(scripts_path, PM3_SHARE_RELPATH);
|
strcat(scripts_path, PM3_SHARE_RELPATH);
|
||||||
|
|
|
@ -29,21 +29,39 @@ int g_GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
||||||
size_t g_GraphTraceLen;
|
size_t g_GraphTraceLen;
|
||||||
|
|
||||||
/* write a manchester bit to the graph
|
/* write a manchester bit to the graph
|
||||||
TODO, verfy that this doesn't overflow buffer (iceman)
|
|
||||||
*/
|
*/
|
||||||
void AppendGraph(bool redraw, uint16_t clock, int bit) {
|
void AppendGraph(bool redraw, uint16_t clock, int bit) {
|
||||||
uint8_t half = clock / 2;
|
uint16_t half = clock / 2;
|
||||||
|
uint16_t end = clock;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
|
// overflow/underflow safe checks ... Assumptions:
|
||||||
|
// _Assert(g_GraphTraceLen >= 0);
|
||||||
|
// _Assert(g_GraphTraceLen <= MAX_GRAPH_TRACE_LEN);
|
||||||
|
// If this occurs, allow partial rendering, up to the last sample...
|
||||||
|
if ((MAX_GRAPH_TRACE_LEN - g_GraphTraceLen) < half) {
|
||||||
|
PrintAndLogEx(DEBUG, "WARNING: AppendGraph() - Request exceeds max graph length");
|
||||||
|
end = MAX_GRAPH_TRACE_LEN - g_GraphTraceLen;
|
||||||
|
half = end;
|
||||||
|
}
|
||||||
|
if ((MAX_GRAPH_TRACE_LEN - g_GraphTraceLen) < end) {
|
||||||
|
PrintAndLogEx(DEBUG, "WARNING: AppendGraph() - Request exceeds max graph length");
|
||||||
|
end = MAX_GRAPH_TRACE_LEN - g_GraphTraceLen;
|
||||||
|
}
|
||||||
|
|
||||||
//set first half the clock bit (all 1's or 0's for a 0 or 1 bit)
|
//set first half the clock bit (all 1's or 0's for a 0 or 1 bit)
|
||||||
for (i = 0; i < half; ++i)
|
for (i = 0; i < half; ++i) {
|
||||||
g_GraphBuffer[g_GraphTraceLen++] = bit;
|
g_GraphBuffer[g_GraphTraceLen++] = bit;
|
||||||
|
}
|
||||||
|
|
||||||
//set second half of the clock bit (all 0's or 1's for a 0 or 1 bit)
|
//set second half of the clock bit (all 0's or 1's for a 0 or 1 bit)
|
||||||
for (; i < clock; ++i)
|
for (; i < end; ++i) {
|
||||||
g_GraphBuffer[g_GraphTraceLen++] = bit ^ 1;
|
g_GraphBuffer[g_GraphTraceLen++] = bit ^ 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (redraw)
|
if (redraw) {
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear out our graph window
|
// clear out our graph window
|
||||||
|
|
|
@ -1493,13 +1493,9 @@ const char *vigik_get_service(uint16_t service_code) {
|
||||||
return vigik_rsa_pk[ARRAYLEN(vigik_rsa_pk) - 1].desc;
|
return vigik_rsa_pk[ARRAYLEN(vigik_rsa_pk) - 1].desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reverse_array(const uint8_t *src, int src_len, uint8_t *dest) {
|
|
||||||
for (int i = 0; i < src_len; i++) {
|
|
||||||
dest[i] = src[(src_len - 1) - i];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int vigik_verify(mfc_vigik_t *d) {
|
int vigik_verify(mfc_vigik_t *d) {
|
||||||
|
#define PUBLIC_VIGIK_KEYLEN 128
|
||||||
|
|
||||||
// iso9796
|
// iso9796
|
||||||
// Exponent V = 2
|
// Exponent V = 2
|
||||||
|
@ -1512,8 +1508,18 @@ int vigik_verify(mfc_vigik_t *d) {
|
||||||
PrintAndLogEx(INFO, "Raw signature");
|
PrintAndLogEx(INFO, "Raw signature");
|
||||||
print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int dl = 0;
|
||||||
|
|
||||||
|
param_gethex_to_eol("1C07D46DA3849326D24B3468BD76673F4F3C41827DC413E81E4F3C7804FAC727213059B21D047510D6432448643A92EBFC67FBEDDAB468D13D948B172F5EBC79A0E3FEFDFAF4E81FC7108E070F1E3CD0", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl);
|
||||||
|
|
||||||
|
param_gethex_to_eol("1AB86FE0C17FFFFE4379D5E15A4B2FAFFEFCFA0F1F3F7FA03E7DDDF1E3C78FFFB1F0E23F7FFF51584771C5C18307FEA36CA74E60AA6B0409ACA66A9EC155F4E9112345708A2B8457E722608EE1157408", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl);
|
||||||
|
signature_len = dl;
|
||||||
|
*/
|
||||||
|
|
||||||
uint8_t rev_sig[128];
|
uint8_t rev_sig[128];
|
||||||
reverse_array(d->rsa_signature, sizeof(d->rsa_signature), rev_sig);
|
reverse_array_copy(d->rsa_signature, sizeof(d->rsa_signature), rev_sig);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Raw signature reverse");
|
PrintAndLogEx(INFO, "Raw signature reverse");
|
||||||
print_hex_noascii_break(rev_sig, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
print_hex_noascii_break(rev_sig, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||||
|
@ -1532,10 +1538,6 @@ int vigik_verify(mfc_vigik_t *d) {
|
||||||
// sha1 hash H = 20 bytes, 160 bits
|
// sha1 hash H = 20 bytes, 160 bits
|
||||||
// padding = 20 bytes, 96 bits
|
// padding = 20 bytes, 96 bits
|
||||||
|
|
||||||
|
|
||||||
// ref: MIFARE Classic EV1 Originality Signature Validation
|
|
||||||
#define PUBLIC_VIGIK_KEYLEN 128
|
|
||||||
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
bool is_valid = false;
|
bool is_valid = false;
|
||||||
|
|
||||||
|
|
|
@ -1069,16 +1069,16 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---");
|
PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---");
|
||||||
if (len != 3) {
|
if (len != 3) {
|
||||||
PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d", len);
|
PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %u", len);
|
||||||
} else {
|
} else {
|
||||||
uint8_t pages_addr = (ndef[indx] >> 4) & 0x0f;
|
uint8_t pages_addr = (ndef[indx] >> 4) & 0x0f;
|
||||||
uint8_t byte_offset = ndef[indx] & 0x0f;
|
uint8_t byte_offset = ndef[indx] & 0x0f;
|
||||||
uint8_t Size = ndef[indx + 1];
|
uint8_t Size = ndef[indx + 1];
|
||||||
uint8_t bytes_per_page = ndef[indx + 2] & 0x0f;
|
uint8_t bytes_per_page = ndef[indx + 2] & 0x0f;
|
||||||
PrintAndLogEx(SUCCESS, "Pages addr (number of pages).... %d", pages_addr);
|
PrintAndLogEx(SUCCESS, "Pages addr (number of pages).... %u", pages_addr);
|
||||||
PrintAndLogEx(SUCCESS, "Byte offset (number of bytes)... %d", byte_offset);
|
PrintAndLogEx(SUCCESS, "Byte offset (number of bytes)... %u", byte_offset);
|
||||||
PrintAndLogEx(SUCCESS, "Reserved area size in bits...... %d ( %d bytes )", Size, Size / 8);
|
PrintAndLogEx(SUCCESS, "Reserved area size in bits...... %u ( %u bytes )", Size, Size / 8);
|
||||||
PrintAndLogEx(SUCCESS, " Number of bytes / page... %d", bytes_per_page);
|
PrintAndLogEx(SUCCESS, " Number of bytes / page... %u", bytes_per_page);
|
||||||
}
|
}
|
||||||
indx += len;
|
indx += len;
|
||||||
break;
|
break;
|
||||||
|
@ -1091,7 +1091,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) {
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Found NDEF message w zero length");
|
PrintAndLogEx(SUCCESS, "Found NDEF message w zero length");
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%d") " bytes )", len);
|
PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%u") " bytes )", len);
|
||||||
|
|
||||||
int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len, verbose);
|
int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len, verbose);
|
||||||
if (res != PM3_SUCCESS)
|
if (res != PM3_SUCCESS)
|
||||||
|
|
|
@ -177,7 +177,13 @@ const static vocabulory_t vocabulory[] = {
|
||||||
{ 0, "hf 15 esave" },
|
{ 0, "hf 15 esave" },
|
||||||
{ 0, "hf 15 eview" },
|
{ 0, "hf 15 eview" },
|
||||||
{ 0, "hf 15 sim" },
|
{ 0, "hf 15 sim" },
|
||||||
{ 0, "hf 15 slixdisable" },
|
{ 0, "hf 15 slixwritepwd" },
|
||||||
|
{ 0, "hf 15 slixeasdisable" },
|
||||||
|
{ 0, "hf 15 slixeasenable" },
|
||||||
|
{ 0, "hf 15 slixprivacydisable" },
|
||||||
|
{ 0, "hf 15 slixprivacyenable" },
|
||||||
|
{ 0, "hf 15 passprotectafi" },
|
||||||
|
{ 0, "hf 15 passprotecteas" },
|
||||||
{ 0, "hf 15 wrbl" },
|
{ 0, "hf 15 wrbl" },
|
||||||
{ 0, "hf 15 findafi" },
|
{ 0, "hf 15 findafi" },
|
||||||
{ 0, "hf 15 writeafi" },
|
{ 0, "hf 15 writeafi" },
|
||||||
|
@ -378,6 +384,7 @@ const static vocabulory_t vocabulory[] = {
|
||||||
{ 0, "hf mfu rdbl" },
|
{ 0, "hf mfu rdbl" },
|
||||||
{ 0, "hf mfu restore" },
|
{ 0, "hf mfu restore" },
|
||||||
{ 1, "hf mfu view" },
|
{ 1, "hf mfu view" },
|
||||||
|
{ 0, "hf mfu tamper" },
|
||||||
{ 0, "hf mfu wrbl" },
|
{ 0, "hf mfu wrbl" },
|
||||||
{ 0, "hf mfu eload" },
|
{ 0, "hf mfu eload" },
|
||||||
{ 0, "hf mfu esave" },
|
{ 0, "hf mfu esave" },
|
||||||
|
@ -438,6 +445,12 @@ const static vocabulory_t vocabulory[] = {
|
||||||
{ 0, "hf st25ta protect" },
|
{ 0, "hf st25ta protect" },
|
||||||
{ 0, "hf st25ta pwd" },
|
{ 0, "hf st25ta pwd" },
|
||||||
{ 0, "hf st25ta sim" },
|
{ 0, "hf st25ta sim" },
|
||||||
|
{ 1, "hf tesla help" },
|
||||||
|
{ 0, "hf tesla info" },
|
||||||
|
{ 1, "hf tesla list" },
|
||||||
|
{ 1, "hf texkom help" },
|
||||||
|
{ 0, "hf texkom reader" },
|
||||||
|
{ 0, "hf texkom sim" },
|
||||||
{ 1, "hf thinfilm help" },
|
{ 1, "hf thinfilm help" },
|
||||||
{ 0, "hf thinfilm info" },
|
{ 0, "hf thinfilm info" },
|
||||||
{ 1, "hf thinfilm list" },
|
{ 1, "hf thinfilm list" },
|
||||||
|
@ -453,9 +466,6 @@ const static vocabulory_t vocabulory[] = {
|
||||||
{ 0, "hf topaz rdbl" },
|
{ 0, "hf topaz rdbl" },
|
||||||
{ 1, "hf topaz view" },
|
{ 1, "hf topaz view" },
|
||||||
{ 0, "hf topaz wrbl" },
|
{ 0, "hf topaz wrbl" },
|
||||||
{ 1, "hf texkom help" },
|
|
||||||
{ 0, "hf texkom reader" },
|
|
||||||
{ 0, "hf texkom sim" },
|
|
||||||
{ 1, "hf xerox help" },
|
{ 1, "hf xerox help" },
|
||||||
{ 0, "hf xerox info" },
|
{ 0, "hf xerox info" },
|
||||||
{ 0, "hf xerox reader" },
|
{ 0, "hf xerox reader" },
|
||||||
|
@ -545,6 +555,7 @@ const static vocabulory_t vocabulory[] = {
|
||||||
{ 0, "lf em 4x50 eview" },
|
{ 0, "lf em 4x50 eview" },
|
||||||
{ 0, "lf em 4x50 sim" },
|
{ 0, "lf em 4x50 sim" },
|
||||||
{ 1, "lf em 4x70 help" },
|
{ 1, "lf em 4x70 help" },
|
||||||
|
{ 0, "lf em 4x70 brute" },
|
||||||
{ 0, "lf em 4x70 info" },
|
{ 0, "lf em 4x70 info" },
|
||||||
{ 0, "lf em 4x70 write" },
|
{ 0, "lf em 4x70 write" },
|
||||||
{ 0, "lf em 4x70 unlock" },
|
{ 0, "lf em 4x70 unlock" },
|
||||||
|
|
|
@ -152,7 +152,7 @@ int preferences_save(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t dummyData = 0x00;
|
uint8_t dummyData = 0x00;
|
||||||
size_t dummyDL = 0x00;
|
size_t dummyDL = 0x01;
|
||||||
|
|
||||||
if (saveFileJSON(fn, jsfCustom, &dummyData, dummyDL, &preferences_save_callback) != PM3_SUCCESS)
|
if (saveFileJSON(fn, jsfCustom, &dummyData, dummyDL, &preferences_save_callback) != PM3_SUCCESS)
|
||||||
PrintAndLogEx(ERR, "Error saving preferences to \"%s\"", fn);
|
PrintAndLogEx(ERR, "Error saving preferences to \"%s\"", fn);
|
||||||
|
|
|
@ -41,7 +41,7 @@ static int mainret = PM3_ESOFT;
|
||||||
|
|
||||||
#ifndef LIBPM3
|
#ifndef LIBPM3
|
||||||
#define BANNERMSG1 ""
|
#define BANNERMSG1 ""
|
||||||
#define BANNERMSG2 " [ :snowflake: ]"
|
#define BANNERMSG2 " [ :coffee: ]"
|
||||||
#define BANNERMSG3 ""
|
#define BANNERMSG3 ""
|
||||||
|
|
||||||
typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode;
|
typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode;
|
||||||
|
|
|
@ -27,14 +27,24 @@
|
||||||
|
|
||||||
// The windows serial port implementation
|
// The windows serial port implementation
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HANDLE hPort; // Serial port handle
|
HANDLE hPort; // Serial port handle
|
||||||
DCB dcb; // Device control settings
|
DCB dcb; // Device control settings
|
||||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||||
|
SOCKET hSocket; // Socket handle
|
||||||
} serial_port_windows_t;
|
} serial_port_windows_t;
|
||||||
|
|
||||||
|
// this is for TCP connection
|
||||||
|
struct timeval timeout = {
|
||||||
|
.tv_sec = 0, // 0 second
|
||||||
|
.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000
|
||||||
|
};
|
||||||
|
|
||||||
uint32_t newtimeout_value = 0;
|
uint32_t newtimeout_value = 0;
|
||||||
bool newtimeout_pending = false;
|
bool newtimeout_pending = false;
|
||||||
|
|
||||||
|
@ -69,11 +79,111 @@ static int uart_reconfigure_timeouts_polling(serial_port sp) {
|
||||||
serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
char acPortName[255] = {0};
|
char acPortName[255] = {0};
|
||||||
serial_port_windows_t *sp = calloc(sizeof(serial_port_windows_t), sizeof(uint8_t));
|
serial_port_windows_t *sp = calloc(sizeof(serial_port_windows_t), sizeof(uint8_t));
|
||||||
|
sp->hSocket = INVALID_SOCKET; // default: serial port
|
||||||
|
|
||||||
if (sp == 0) {
|
if (sp == 0) {
|
||||||
PrintAndLogEx(WARNING, "UART failed to allocate memory\n");
|
PrintAndLogEx(WARNING, "UART failed to allocate memory\n");
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *prefix = strdup(pcPortName);
|
||||||
|
if (prefix == NULL) {
|
||||||
|
PrintAndLogEx(ERR, "error: string duplication");
|
||||||
|
free(sp);
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
str_lower(prefix);
|
||||||
|
|
||||||
|
if (memcmp(prefix, "tcp:", 4) == 0) {
|
||||||
|
free(prefix);
|
||||||
|
|
||||||
|
if (strlen(pcPortName) <= 4) {
|
||||||
|
free(sp);
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo *addr = NULL, *rp;
|
||||||
|
|
||||||
|
char *addrstr = strdup(pcPortName + 4);
|
||||||
|
if (addrstr == NULL) {
|
||||||
|
PrintAndLogEx(ERR, "error: string duplication");
|
||||||
|
free(sp);
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
|
||||||
|
|
||||||
|
char *colon = strrchr(addrstr, ':');
|
||||||
|
const char *portstr;
|
||||||
|
if (colon) {
|
||||||
|
portstr = colon + 1;
|
||||||
|
*colon = '\0';
|
||||||
|
} else {
|
||||||
|
portstr = "18888";
|
||||||
|
}
|
||||||
|
|
||||||
|
WSADATA wsaData;
|
||||||
|
struct addrinfo info;
|
||||||
|
int iResult;
|
||||||
|
|
||||||
|
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||||
|
if (iResult != 0) {
|
||||||
|
PrintAndLogEx(ERR, "error: WSAStartup failed with error: %d", iResult);
|
||||||
|
free(sp);
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.ai_socktype = SOCK_STREAM;
|
||||||
|
info.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
int s = getaddrinfo(addrstr, portstr, &info, &addr);
|
||||||
|
if (s != 0) {
|
||||||
|
PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s));
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
free(addrstr);
|
||||||
|
free(sp);
|
||||||
|
WSACleanup();
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET hSocket = INVALID_SOCKET;
|
||||||
|
for (rp = addr; rp != NULL; rp = rp->ai_next) {
|
||||||
|
hSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
|
|
||||||
|
if (hSocket == INVALID_SOCKET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (connect(hSocket, rp->ai_addr, (int)rp->ai_addrlen) != INVALID_SOCKET)
|
||||||
|
break;
|
||||||
|
|
||||||
|
closesocket(hSocket);
|
||||||
|
hSocket = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
free(addrstr);
|
||||||
|
|
||||||
|
if (rp == NULL) { /* No address succeeded */
|
||||||
|
PrintAndLogEx(ERR, "error: Could not connect");
|
||||||
|
WSACleanup();
|
||||||
|
free(sp);
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp->hSocket = hSocket;
|
||||||
|
|
||||||
|
int one = 1;
|
||||||
|
int res = setsockopt(sp->hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));
|
||||||
|
if (res != 0) {
|
||||||
|
closesocket(hSocket);
|
||||||
|
WSACleanup();
|
||||||
|
free(sp);
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the input "com?" to "\\.\COM?" format
|
// Copy the input "com?" to "\\.\COM?" format
|
||||||
snprintf(acPortName, sizeof(acPortName), "\\\\.\\%s", pcPortName);
|
snprintf(acPortName, sizeof(acPortName), "\\\\.\\%s", pcPortName);
|
||||||
_strupr(acPortName);
|
_strupr(acPortName);
|
||||||
|
@ -120,8 +230,14 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_close(const serial_port sp) {
|
void uart_close(const serial_port sp) {
|
||||||
if (((serial_port_windows_t *)sp)->hPort != INVALID_HANDLE_VALUE)
|
serial_port_windows_t *spw = (serial_port_windows_t *)sp;
|
||||||
CloseHandle(((serial_port_windows_t *)sp)->hPort);
|
if (spw->hSocket != INVALID_SOCKET){
|
||||||
|
shutdown(spw->hSocket, SD_BOTH);
|
||||||
|
closesocket(spw->hSocket);
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
if (spw->hPort != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(spw->hPort);
|
||||||
free(sp);
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +279,10 @@ uint32_t uart_get_speed(const serial_port sp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) {
|
int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) {
|
||||||
|
serial_port_windows_t *spw = (serial_port_windows_t *)sp;
|
||||||
|
if (spw->hSocket == INVALID_SOCKET) { // serial port
|
||||||
uart_reconfigure_timeouts_polling(sp);
|
uart_reconfigure_timeouts_polling(sp);
|
||||||
|
|
||||||
int res = ReadFile(((serial_port_windows_t *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
|
int res = ReadFile(((serial_port_windows_t *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
|
||||||
if (res)
|
if (res)
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -175,9 +294,76 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
return PM3_ENOTTY;
|
return PM3_ENOTTY;
|
||||||
|
}
|
||||||
|
else { // TCP
|
||||||
|
uint32_t byteCount; // FIONREAD returns size on 32b
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
if (newtimeout_pending) {
|
||||||
|
timeout.tv_usec = newtimeout_value * 1000;
|
||||||
|
newtimeout_pending = false;
|
||||||
|
}
|
||||||
|
// Reset the output count
|
||||||
|
*pszRxLen = 0;
|
||||||
|
do {
|
||||||
|
// Reset file descriptor
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(spw->hSocket, &rfds);
|
||||||
|
tv = timeout;
|
||||||
|
// the first argument nfds is ignored in Windows
|
||||||
|
int res = select(0, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
// Read error
|
||||||
|
if (res == SOCKET_ERROR) {
|
||||||
|
return PM3_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read time-out
|
||||||
|
if (res == 0) {
|
||||||
|
if (*pszRxLen == 0) {
|
||||||
|
// We received no data
|
||||||
|
return PM3_ENODATA;
|
||||||
|
} else {
|
||||||
|
// We received some data, but nothing more is available
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the count of the incoming bytes
|
||||||
|
res = ioctlsocket(spw->hSocket, FIONREAD, (u_long *)&byteCount);
|
||||||
|
// PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount);
|
||||||
|
if (res == SOCKET_ERROR) return PM3_ENOTTY;
|
||||||
|
|
||||||
|
// Cap the number of bytes, so we don't overrun the buffer
|
||||||
|
if (pszMaxRxLen - (*pszRxLen) < byteCount) {
|
||||||
|
// PrintAndLogEx(ERR, "UART:: RX prevent overrun (have %u, need %u)", pszMaxRxLen - (*pszRxLen), byteCount);
|
||||||
|
byteCount = pszMaxRxLen - (*pszRxLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is something available, read the data
|
||||||
|
res = recv(spw->hSocket, (char *)pbtRx + (*pszRxLen), byteCount, 0);
|
||||||
|
|
||||||
|
// Stop if the OS has some troubles reading the data
|
||||||
|
if (res <= 0) { // includes 0(gracefully closed) and -1(SOCKET_ERROR)
|
||||||
|
return PM3_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pszRxLen += res;
|
||||||
|
|
||||||
|
if (*pszRxLen == pszMaxRxLen) {
|
||||||
|
// We have all the data we wanted.
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
} while (byteCount);
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) {
|
int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) {
|
||||||
|
serial_port_windows_t *spw = (serial_port_windows_t *)sp;
|
||||||
|
if (spw->hSocket == INVALID_SOCKET) { // serial port
|
||||||
DWORD txlen = 0;
|
DWORD txlen = 0;
|
||||||
int res = WriteFile(((serial_port_windows_t *)sp)->hPort, p_tx, len, &txlen, NULL);
|
int res = WriteFile(((serial_port_windows_t *)sp)->hPort, p_tx, len, &txlen, NULL);
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -188,6 +374,44 @@ int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) {
|
||||||
return PM3_EIO;
|
return PM3_EIO;
|
||||||
}
|
}
|
||||||
return PM3_ENOTTY;
|
return PM3_ENOTTY;
|
||||||
|
}
|
||||||
|
else { // TCP
|
||||||
|
uint32_t pos = 0;
|
||||||
|
fd_set wfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
while (pos < len) {
|
||||||
|
// Reset file descriptor
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(spw->hSocket, &wfds);
|
||||||
|
tv = timeout;
|
||||||
|
// the first argument nfds is ignored in Windows
|
||||||
|
int res = select(0, NULL, &wfds, NULL, &tv);
|
||||||
|
|
||||||
|
// Write error
|
||||||
|
if (res == SOCKET_ERROR) {
|
||||||
|
PrintAndLogEx(ERR, "UART:: write error (%d)", res);
|
||||||
|
return PM3_ENOTTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write time-out
|
||||||
|
if (res == 0) {
|
||||||
|
PrintAndLogEx(ERR, "UART:: write time-out");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send away the bytes
|
||||||
|
res = send(spw->hSocket, (const char *)p_tx + pos, len - pos, 0);
|
||||||
|
|
||||||
|
// Stop if the OS has some troubles sending the data
|
||||||
|
if (res <= 0)
|
||||||
|
return PM3_EIO;
|
||||||
|
|
||||||
|
pos += res;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -266,7 +266,7 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) {
|
||||||
uint8_t mod = len % breaks;
|
uint8_t mod = len % breaks;
|
||||||
|
|
||||||
if (mod) {
|
if (mod) {
|
||||||
char buf[UTIL_BUFFER_SIZE_SPRINT + 3];
|
char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0};
|
||||||
hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 1, true);
|
hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 1, true);
|
||||||
|
|
||||||
// add the spaces...
|
// add the spaces...
|
||||||
|
@ -291,7 +291,7 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea
|
||||||
uint8_t mod = len % breaks;
|
uint8_t mod = len % breaks;
|
||||||
|
|
||||||
if (mod) {
|
if (mod) {
|
||||||
char buf[UTIL_BUFFER_SIZE_SPRINT + 3];
|
char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0};
|
||||||
hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true);
|
hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true);
|
||||||
|
|
||||||
// add the spaces...
|
// add the spaces...
|
||||||
|
@ -300,14 +300,13 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) {
|
static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) {
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if ((data == NULL) || (len < 1))
|
if ((data == NULL) || (len < 1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buf[UTIL_BUFFER_SIZE_SPRINT + 3];
|
char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0};
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i += breaks) {
|
for (i = 0; i < len; i += breaks) {
|
||||||
|
|
||||||
|
@ -614,7 +613,7 @@ void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) {
|
||||||
// hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii
|
// hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii
|
||||||
// up to 64 bytes or 512 bits
|
// up to 64 bytes or 512 bits
|
||||||
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize) {
|
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize) {
|
||||||
static uint8_t buf[64];
|
static uint8_t buf[64] = {0};
|
||||||
memset(buf, 0x00, 64);
|
memset(buf, 0x00, 64);
|
||||||
uint8_t *tmp = buf;
|
uint8_t *tmp = buf;
|
||||||
for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) {
|
for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) {
|
||||||
|
|
|
@ -269,3 +269,27 @@ uint16_t get_sw(const uint8_t *d, uint16_t n) {
|
||||||
n -= 2;
|
n -= 2;
|
||||||
return (d[n] << 8 | d[n + 1]);
|
return (d[n] << 8 | d[n + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reverse same array
|
||||||
|
void reverse_array(uint8_t *d, size_t n) {
|
||||||
|
if (d == NULL || n < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, j = n - 1; i < j; ++i, --j) {
|
||||||
|
d[i] ^= d[j];
|
||||||
|
d[j] ^= d[i];
|
||||||
|
d[i] ^= d[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse src array into dest array
|
||||||
|
void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest) {
|
||||||
|
if (src == NULL || src_len == 0 || dest == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < src_len; i++) {
|
||||||
|
dest[i] = src[(src_len - 1) - i];
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,4 +86,8 @@ uint32_t rotl(uint32_t a, uint8_t n);
|
||||||
uint32_t rotr(uint32_t a, uint8_t n);
|
uint32_t rotr(uint32_t a, uint8_t n);
|
||||||
|
|
||||||
uint16_t get_sw(const uint8_t *d, uint16_t n);
|
uint16_t get_sw(const uint8_t *d, uint16_t n);
|
||||||
|
|
||||||
|
void reverse_array(uint8_t *d, size_t n);
|
||||||
|
void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -95,6 +95,7 @@ ifeq ($(PLATFORM),PM3RDV4)
|
||||||
PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4
|
PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4
|
||||||
PLTNAME = Proxmark3 RDV4
|
PLTNAME = Proxmark3 RDV4
|
||||||
PLATFORM_FPGA = xc2s30
|
PLATFORM_FPGA = xc2s30
|
||||||
|
RDV4 = yes
|
||||||
else ifeq ($(PLATFORM),PM3OTHER)
|
else ifeq ($(PLATFORM),PM3OTHER)
|
||||||
$(warning PLATFORM=PM3OTHER is deprecated, please use PLATFORM=PM3GENERIC)
|
$(warning PLATFORM=PM3OTHER is deprecated, please use PLATFORM=PM3GENERIC)
|
||||||
PLTNAME = Proxmark3 generic target
|
PLTNAME = Proxmark3 generic target
|
||||||
|
@ -113,6 +114,10 @@ endif
|
||||||
|
|
||||||
# parsing additional PLATFORM_EXTRAS tokens
|
# parsing additional PLATFORM_EXTRAS tokens
|
||||||
PLATFORM_EXTRAS_TMP:=$(PLATFORM_EXTRAS)
|
PLATFORM_EXTRAS_TMP:=$(PLATFORM_EXTRAS)
|
||||||
|
ifneq (,$(findstring FLASH,$(PLATFORM_EXTRAS_TMP)))
|
||||||
|
PLATFORM_DEFS += -DWITH_FLASH
|
||||||
|
PLATFORM_EXTRAS_TMP := $(strip $(filter-out FLASH,$(PLATFORM_EXTRAS_TMP)))
|
||||||
|
endif
|
||||||
ifneq (,$(findstring BTADDON,$(PLATFORM_EXTRAS_TMP)))
|
ifneq (,$(findstring BTADDON,$(PLATFORM_EXTRAS_TMP)))
|
||||||
PLATFORM_DEFS += -DWITH_FPC_USART_HOST
|
PLATFORM_DEFS += -DWITH_FPC_USART_HOST
|
||||||
PLATFORM_EXTRAS_TMP := $(strip $(filter-out BTADDON,$(PLATFORM_EXTRAS_TMP)))
|
PLATFORM_EXTRAS_TMP := $(strip $(filter-out BTADDON,$(PLATFORM_EXTRAS_TMP)))
|
||||||
|
|
|
@ -20,9 +20,13 @@
|
||||||
|
|
||||||
#include "proxmark3_arm.h"
|
#include "proxmark3_arm.h"
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
|
#endif // AS_BOOTROM
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "spiffs.h"
|
#include "usb_cdc.h"
|
||||||
|
|
||||||
/* here: use NCPS2 @ PA10: */
|
/* here: use NCPS2 @ PA10: */
|
||||||
#define SPI_CSR_NUM 2
|
#define SPI_CSR_NUM 2
|
||||||
|
@ -37,11 +41,392 @@
|
||||||
static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
||||||
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
|
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read ID out
|
||||||
|
bool Flash_ReadID_90(flash_device_type_90_t *result) {
|
||||||
|
|
||||||
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) return false;
|
||||||
|
|
||||||
|
// Manufacture ID / device ID
|
||||||
|
FlashSendByte(ID);
|
||||||
|
FlashSendByte(0x00);
|
||||||
|
FlashSendByte(0x00);
|
||||||
|
FlashSendByte(0x00);
|
||||||
|
|
||||||
|
result->manufacturer_id = FlashSendByte(0xFF);
|
||||||
|
result->device_id = FlashSendLastByte(0xFF);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
|
if (!FlashInit()) return 0;
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||||
|
|
||||||
|
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||||
|
|
||||||
|
FlashSendByte(cmd);
|
||||||
|
Flash_TransferAdresse(address);
|
||||||
|
|
||||||
|
if (FASTFLASH) {
|
||||||
|
FlashSendByte(DUMMYBYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
|
FlashStop();
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Flash_TransferAdresse(uint32_t address) {
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This ensures we can ReadData without having to cycle through initialization every time */
|
||||||
|
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
if (!len) return 0;
|
||||||
|
|
||||||
|
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||||
|
|
||||||
|
FlashSendByte(cmd);
|
||||||
|
Flash_TransferAdresse(address);
|
||||||
|
|
||||||
|
if (FASTFLASH) {
|
||||||
|
FlashSendByte(DUMMYBYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Write data can only program one page. A page has 256 bytes.
|
||||||
|
// if len > 256, it might wrap around and overwrite pos 0.
|
||||||
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
if (!len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Max 256 bytes write
|
||||||
|
if (((address & 0xFF) + len) > 256) {
|
||||||
|
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// out-of-range
|
||||||
|
if (((address >> 16) & 0xFF) > MAX_BLOCKS) {
|
||||||
|
Dbprintf("Flash_WriteData, block out-of-range");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FlashInit()) {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
|
Flash_WriteEnable();
|
||||||
|
|
||||||
|
FlashSendByte(PAGEPROG);
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
FlashSendByte(in[i]);
|
||||||
|
|
||||||
|
FlashSendLastByte(in[i]);
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
// Max 256 bytes write
|
||||||
|
// out-of-range
|
||||||
|
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (((address & 0xFF) + len) > 256) {
|
||||||
|
Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((address >> 16) & 0xFF) > MAX_BLOCKS) {
|
||||||
|
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashSendByte(PAGEPROG);
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
FlashSendByte(in[i]);
|
||||||
|
|
||||||
|
FlashSendLastByte(in[i]);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assumes valid start 256 based 00 address
|
||||||
|
//
|
||||||
|
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
|
bool isok;
|
||||||
|
uint16_t res, bytes_sent = 0, bytes_remaining = len;
|
||||||
|
uint8_t buf[FLASH_MEM_BLOCK_SIZE];
|
||||||
|
while (bytes_remaining > 0) {
|
||||||
|
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
Flash_WriteEnable();
|
||||||
|
|
||||||
|
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||||
|
|
||||||
|
memcpy(buf, in + bytes_sent, bytes_in_packet);
|
||||||
|
|
||||||
|
res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet);
|
||||||
|
|
||||||
|
bytes_remaining -= bytes_in_packet;
|
||||||
|
bytes_sent += bytes_in_packet;
|
||||||
|
|
||||||
|
isok = (res == bytes_in_packet);
|
||||||
|
|
||||||
|
if (!isok)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
FlashStop();
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING -- if callers are using a file system (such as SPIFFS),
|
||||||
|
// they should inform the file system of this change
|
||||||
|
// e.g., rdv40_spiffs_check()
|
||||||
|
bool Flash_WipeMemoryPage(uint8_t page) {
|
||||||
|
if (!FlashInit()) {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Flash_ReadStat1();
|
||||||
|
|
||||||
|
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
||||||
|
Flash_WriteEnable();
|
||||||
|
Flash_Erase64k(page);
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Wipes flash memory completely, fills with 0xFF
|
||||||
|
bool Flash_WipeMemory(void) {
|
||||||
|
if (!FlashInit()) {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Flash_ReadStat1();
|
||||||
|
|
||||||
|
// Each block is 64Kb. Four blocks
|
||||||
|
// one block erase takes 1s ( 1000ms )
|
||||||
|
Flash_WriteEnable();
|
||||||
|
Flash_Erase64k(0);
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
Flash_WriteEnable();
|
||||||
|
Flash_Erase64k(1);
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
Flash_WriteEnable();
|
||||||
|
Flash_Erase64k(2);
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
Flash_WriteEnable();
|
||||||
|
Flash_Erase64k(3);
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable the flash write
|
||||||
|
void Flash_WriteEnable(void) {
|
||||||
|
FlashSendLastByte(WRITEENABLE);
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash Write enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
// erase 4K at one time
|
||||||
|
// execution time: 0.8ms / 800us
|
||||||
|
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
||||||
|
|
||||||
|
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
||||||
|
|
||||||
|
FlashSendByte(SECTORERASE);
|
||||||
|
FlashSendByte(block);
|
||||||
|
FlashSendByte(sector << 4);
|
||||||
|
FlashSendLastByte(00);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// erase 32K at one time
|
||||||
|
// execution time: 0,3s / 300ms
|
||||||
|
bool Flash_Erase32k(uint32_t address) {
|
||||||
|
if (address & (32*1024 - 1)) {
|
||||||
|
if ( g_dbglevel > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FlashSendByte(BLOCK32ERASE);
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendLastByte((address >> 0) & 0xFF);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// erase 64k at one time
|
||||||
|
// since a block is 64kb, and there is four blocks.
|
||||||
|
// we only need block number, as MSB
|
||||||
|
// execution time: 1s / 1000ms
|
||||||
|
// 0x00 00 00 -- 0x 00 FF FF == block 0
|
||||||
|
// 0x01 00 00 -- 0x 01 FF FF == block 1
|
||||||
|
// 0x02 00 00 -- 0x 02 FF FF == block 2
|
||||||
|
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
||||||
|
bool Flash_Erase64k(uint8_t block) {
|
||||||
|
|
||||||
|
if (block > MAX_BLOCKS) return false;
|
||||||
|
|
||||||
|
FlashSendByte(BLOCK64ERASE);
|
||||||
|
FlashSendByte(block);
|
||||||
|
FlashSendByte(0x00);
|
||||||
|
FlashSendLastByte(0x00);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Erase chip
|
||||||
|
void Flash_EraseChip(void) {
|
||||||
|
FlashSendLastByte(CHIPERASE);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Flashmem_print_status(void) {
|
||||||
|
DbpString(_CYAN_("Flash memory"));
|
||||||
|
Dbprintf(" Baudrate................ " _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
|
||||||
|
|
||||||
|
if (!FlashInit()) {
|
||||||
|
DbpString(" Init.................... " _RED_("FAILED"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DbpString(" Init.................... " _GREEN_("OK"));
|
||||||
|
|
||||||
|
// NOTE: It would likely be more useful to use JDEC ID command 9F,
|
||||||
|
// as it provides a third byte indicative of capacity.
|
||||||
|
flash_device_type_90_t device_type = {0};
|
||||||
|
if (!Flash_ReadID_90(&device_type)) {
|
||||||
|
DbpString(" Device ID............... " _RED_(" --> Not Found <--"));
|
||||||
|
} else {
|
||||||
|
if (device_type.manufacturer_id == WINBOND_MANID) {
|
||||||
|
switch (device_type.device_id) {
|
||||||
|
case WINBOND_2MB_DEVID:
|
||||||
|
DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb"));
|
||||||
|
break;
|
||||||
|
case WINBOND_1MB_DEVID:
|
||||||
|
DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb"));
|
||||||
|
break;
|
||||||
|
case WINBOND_512KB_DEVID:
|
||||||
|
DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"),
|
||||||
|
device_type.manufacturer_id,
|
||||||
|
device_type.device_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
Flash_UniqueID(uid);
|
||||||
|
Dbprintf(" Unique ID (be).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"),
|
||||||
|
uid[0], uid[1], uid[2], uid[3],
|
||||||
|
uid[4], uid[5], uid[6], uid[7]
|
||||||
|
);
|
||||||
|
if (g_dbglevel > 3) {
|
||||||
|
Dbprintf(" Unique ID (le).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"),
|
||||||
|
uid[7], uid[6], uid[5], uid[4],
|
||||||
|
uid[3], uid[2], uid[1], uid[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
FlashStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Flashmem_print_info(void) {
|
||||||
|
|
||||||
|
if (!FlashInit()) return;
|
||||||
|
|
||||||
|
DbpString(_CYAN_("Flash memory dictionary loaded"));
|
||||||
|
|
||||||
|
// load dictionary offsets.
|
||||||
|
uint8_t keysum[2];
|
||||||
|
uint16_t num;
|
||||||
|
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET, keysum, 2);
|
||||||
|
if (isok == 2) {
|
||||||
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
|
if (num != 0xFFFF && num != 0x0)
|
||||||
|
Dbprintf(" Mifare.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_MF_KEYS_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET, keysum, 2);
|
||||||
|
if (isok == 2) {
|
||||||
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
|
if (num != 0xFFFF && num != 0x0)
|
||||||
|
Dbprintf(" T55x7................... "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_T55XX_KEYS_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET, keysum, 2);
|
||||||
|
if (isok == 2) {
|
||||||
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
|
if (num != 0xFFFF && num != 0x0)
|
||||||
|
Dbprintf(" iClass.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_ICLASS_KEYS_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
|
||||||
// initialize
|
// initialize
|
||||||
bool FlashInit(void) {
|
bool FlashInit(void) {
|
||||||
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
||||||
|
@ -56,6 +441,52 @@ bool FlashInit(void) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read unique id for chip.
|
||||||
|
void Flash_UniqueID(uint8_t *uid) {
|
||||||
|
|
||||||
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
||||||
|
|
||||||
|
// reading unique serial number
|
||||||
|
FlashSendByte(UNIQUE_ID);
|
||||||
|
FlashSendByte(0xFF);
|
||||||
|
FlashSendByte(0xFF);
|
||||||
|
FlashSendByte(0xFF);
|
||||||
|
FlashSendByte(0xFF);
|
||||||
|
|
||||||
|
uid[7] = FlashSendByte(0xFF);
|
||||||
|
uid[6] = FlashSendByte(0xFF);
|
||||||
|
uid[5] = FlashSendByte(0xFF);
|
||||||
|
uid[4] = FlashSendByte(0xFF);
|
||||||
|
uid[3] = FlashSendByte(0xFF);
|
||||||
|
uid[2] = FlashSendByte(0xFF);
|
||||||
|
uid[1] = FlashSendByte(0xFF);
|
||||||
|
uid[0] = FlashSendLastByte(0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlashStop(void) {
|
||||||
|
//Bof
|
||||||
|
//* Reset all the Chip Select register
|
||||||
|
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
||||||
|
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
||||||
|
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
||||||
|
AT91C_BASE_SPI->SPI_CSR[3] = 0;
|
||||||
|
|
||||||
|
// Reset the SPI mode
|
||||||
|
AT91C_BASE_SPI->SPI_MR = 0;
|
||||||
|
|
||||||
|
// Disable all interrupts
|
||||||
|
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// SPI disable
|
||||||
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
|
if (g_dbglevel > 3) Dbprintf("FlashStop");
|
||||||
|
#endif // AS_BOOTROM
|
||||||
|
|
||||||
|
StopTicks();
|
||||||
|
}
|
||||||
|
|
||||||
void FlashSetup(uint32_t baudrate) {
|
void FlashSetup(uint32_t baudrate) {
|
||||||
//WDT_DISABLE
|
//WDT_DISABLE
|
||||||
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
||||||
|
@ -156,26 +587,28 @@ void FlashSetup(uint32_t baudrate) {
|
||||||
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
|
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlashStop(void) {
|
bool Flash_CheckBusy(uint32_t timeout) {
|
||||||
//Bof
|
WaitUS(WINBOND_WRITE_DELAY);
|
||||||
//* Reset all the Chip Select register
|
StartCountUS();
|
||||||
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
uint32_t _time = GetCountUS();
|
||||||
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
|
||||||
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
|
||||||
AT91C_BASE_SPI->SPI_CSR[3] = 0;
|
|
||||||
|
|
||||||
// Reset the SPI mode
|
do {
|
||||||
AT91C_BASE_SPI->SPI_MR = 0;
|
if (!(Flash_ReadStat1() & BUSY)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} while ((GetCountUS() - _time) < timeout);
|
||||||
|
|
||||||
// Disable all interrupts
|
if (timeout <= (GetCountUS() - _time)) {
|
||||||
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// SPI disable
|
return false;
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
}
|
||||||
|
|
||||||
if (g_dbglevel > 3) Dbprintf("FlashStop");
|
// read state register 1
|
||||||
|
uint8_t Flash_ReadStat1(void) {
|
||||||
StopTicks();
|
FlashSendByte(READSTAT1);
|
||||||
|
return FlashSendLastByte(0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send one byte over SPI
|
// send one byte over SPI
|
||||||
|
@ -201,419 +634,3 @@ uint16_t FlashSendByte(uint32_t data) {
|
||||||
uint16_t FlashSendLastByte(uint32_t data) {
|
uint16_t FlashSendLastByte(uint32_t data) {
|
||||||
return FlashSendByte(data | AT91C_SPI_LASTXFER);
|
return FlashSendByte(data | AT91C_SPI_LASTXFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read state register 1
|
|
||||||
uint8_t Flash_ReadStat1(void) {
|
|
||||||
FlashSendByte(READSTAT1);
|
|
||||||
return FlashSendLastByte(0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Flash_CheckBusy(uint32_t timeout) {
|
|
||||||
WaitUS(WINBOND_WRITE_DELAY);
|
|
||||||
StartCountUS();
|
|
||||||
uint32_t _time = GetCountUS();
|
|
||||||
|
|
||||||
if (g_dbglevel > 3) Dbprintf("Checkbusy in...");
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!(Flash_ReadStat1() & BUSY)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} while ((GetCountUS() - _time) < timeout);
|
|
||||||
|
|
||||||
if (timeout <= (GetCountUS() - _time)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read ID out
|
|
||||||
uint8_t Flash_ReadID(void) {
|
|
||||||
|
|
||||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
|
||||||
|
|
||||||
// Manufacture ID / device ID
|
|
||||||
FlashSendByte(ID);
|
|
||||||
FlashSendByte(0x00);
|
|
||||||
FlashSendByte(0x00);
|
|
||||||
FlashSendByte(0x00);
|
|
||||||
|
|
||||||
uint8_t man_id = FlashSendByte(0xFF);
|
|
||||||
uint8_t dev_id = FlashSendLastByte(0xFF);
|
|
||||||
|
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash ReadID | Man ID %02x | Device ID %02x", man_id, dev_id);
|
|
||||||
|
|
||||||
if ((man_id == WINBOND_MANID) && (dev_id == WINBOND_DEVID))
|
|
||||||
return dev_id;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read unique id for chip.
|
|
||||||
void Flash_UniqueID(uint8_t *uid) {
|
|
||||||
|
|
||||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
|
||||||
|
|
||||||
// reading unique serial number
|
|
||||||
FlashSendByte(UNIQUE_ID);
|
|
||||||
FlashSendByte(0xFF);
|
|
||||||
FlashSendByte(0xFF);
|
|
||||||
FlashSendByte(0xFF);
|
|
||||||
FlashSendByte(0xFF);
|
|
||||||
|
|
||||||
uid[7] = FlashSendByte(0xFF);
|
|
||||||
uid[6] = FlashSendByte(0xFF);
|
|
||||||
uid[5] = FlashSendByte(0xFF);
|
|
||||||
uid[4] = FlashSendByte(0xFF);
|
|
||||||
uid[3] = FlashSendByte(0xFF);
|
|
||||||
uid[2] = FlashSendByte(0xFF);
|
|
||||||
uid[1] = FlashSendByte(0xFF);
|
|
||||||
uid[0] = FlashSendLastByte(0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
|
||||||
|
|
||||||
if (!FlashInit()) return 0;
|
|
||||||
|
|
||||||
// length should never be zero
|
|
||||||
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
|
||||||
|
|
||||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
|
||||||
|
|
||||||
FlashSendByte(cmd);
|
|
||||||
Flash_TransferAdresse(address);
|
|
||||||
|
|
||||||
if (FASTFLASH) {
|
|
||||||
FlashSendByte(DUMMYBYTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t i = 0;
|
|
||||||
for (; i < (len - 1); i++)
|
|
||||||
out[i] = FlashSendByte(0xFF);
|
|
||||||
|
|
||||||
out[i] = FlashSendLastByte(0xFF);
|
|
||||||
FlashStop();
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flash_TransferAdresse(uint32_t address) {
|
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
|
||||||
FlashSendByte((address >> 0) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This ensures we can ReadData without having to cycle through initialization every time */
|
|
||||||
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
|
||||||
|
|
||||||
// length should never be zero
|
|
||||||
if (!len) return 0;
|
|
||||||
|
|
||||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
|
||||||
|
|
||||||
FlashSendByte(cmd);
|
|
||||||
Flash_TransferAdresse(address);
|
|
||||||
|
|
||||||
if (FASTFLASH) {
|
|
||||||
FlashSendByte(DUMMYBYTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t i = 0;
|
|
||||||
for (; i < (len - 1); i++)
|
|
||||||
out[i] = FlashSendByte(0xFF);
|
|
||||||
|
|
||||||
out[i] = FlashSendLastByte(0xFF);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Write data can only program one page. A page has 256 bytes.
|
|
||||||
// if len > 256, it might wrap around and overwrite pos 0.
|
|
||||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
|
||||||
|
|
||||||
// length should never be zero
|
|
||||||
if (!len)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Max 256 bytes write
|
|
||||||
if (((address & 0xFF) + len) > 256) {
|
|
||||||
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// out-of-range
|
|
||||||
if (((address >> 16) & 0xFF) > MAX_BLOCKS) {
|
|
||||||
Dbprintf("Flash_WriteData, block out-of-range");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!FlashInit()) {
|
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
|
|
||||||
Flash_WriteEnable();
|
|
||||||
|
|
||||||
FlashSendByte(PAGEPROG);
|
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
|
||||||
FlashSendByte((address >> 0) & 0xFF);
|
|
||||||
|
|
||||||
uint16_t i = 0;
|
|
||||||
for (; i < (len - 1); i++)
|
|
||||||
FlashSendByte(in[i]);
|
|
||||||
|
|
||||||
FlashSendLastByte(in[i]);
|
|
||||||
|
|
||||||
FlashStop();
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// length should never be zero
|
|
||||||
// Max 256 bytes write
|
|
||||||
// out-of-range
|
|
||||||
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
|
||||||
|
|
||||||
if (!len)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (((address & 0xFF) + len) > 256) {
|
|
||||||
Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF) + len, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((address >> 16) & 0xFF) > MAX_BLOCKS) {
|
|
||||||
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlashSendByte(PAGEPROG);
|
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
|
||||||
FlashSendByte((address >> 0) & 0xFF);
|
|
||||||
|
|
||||||
uint16_t i = 0;
|
|
||||||
for (; i < (len - 1); i++)
|
|
||||||
FlashSendByte(in[i]);
|
|
||||||
|
|
||||||
FlashSendLastByte(in[i]);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assumes valid start 256 based 00 address
|
|
||||||
//
|
|
||||||
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
|
|
||||||
|
|
||||||
bool isok;
|
|
||||||
uint16_t res, bytes_sent = 0, bytes_remaining = len;
|
|
||||||
uint8_t buf[FLASH_MEM_BLOCK_SIZE];
|
|
||||||
while (bytes_remaining > 0) {
|
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
|
|
||||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
|
||||||
|
|
||||||
memcpy(buf, in + bytes_sent, bytes_in_packet);
|
|
||||||
|
|
||||||
res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet);
|
|
||||||
|
|
||||||
bytes_remaining -= bytes_in_packet;
|
|
||||||
bytes_sent += bytes_in_packet;
|
|
||||||
|
|
||||||
isok = (res == bytes_in_packet);
|
|
||||||
|
|
||||||
if (!isok)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
FlashStop();
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Flash_WipeMemoryPage(uint8_t page) {
|
|
||||||
if (!FlashInit()) {
|
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Flash_ReadStat1();
|
|
||||||
|
|
||||||
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(page);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
|
|
||||||
FlashStop();
|
|
||||||
|
|
||||||
// let spiffs check and update its info post flash erase
|
|
||||||
rdv40_spiffs_check();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Wipes flash memory completely, fills with 0xFF
|
|
||||||
bool Flash_WipeMemory(void) {
|
|
||||||
if (!FlashInit()) {
|
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Flash_ReadStat1();
|
|
||||||
|
|
||||||
// Each block is 64Kb. Four blocks
|
|
||||||
// one block erase takes 1s ( 1000ms )
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(0);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(1);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(2);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
Flash_WriteEnable();
|
|
||||||
Flash_Erase64k(3);
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
|
|
||||||
FlashStop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable the flash write
|
|
||||||
void Flash_WriteEnable(void) {
|
|
||||||
FlashSendLastByte(WRITEENABLE);
|
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash Write enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
// erase 4K at one time
|
|
||||||
// execution time: 0.8ms / 800us
|
|
||||||
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
|
||||||
|
|
||||||
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
|
||||||
|
|
||||||
FlashSendByte(SECTORERASE);
|
|
||||||
FlashSendByte(block);
|
|
||||||
FlashSendByte(sector << 4);
|
|
||||||
FlashSendLastByte(00);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// erase 32K at one time
|
|
||||||
// execution time: 0,3s / 300ms
|
|
||||||
bool Flash_Erase32k(uint32_t address) {
|
|
||||||
if (address & (32*1024 - 1)) {
|
|
||||||
if ( g_dbglevel > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
FlashSendByte(BLOCK32ERASE);
|
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
|
||||||
FlashSendLastByte((address >> 0) & 0xFF);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// erase 64k at one time
|
|
||||||
// since a block is 64kb, and there is four blocks.
|
|
||||||
// we only need block number, as MSB
|
|
||||||
// execution time: 1s / 1000ms
|
|
||||||
// 0x00 00 00 -- 0x 00 FF FF == block 0
|
|
||||||
// 0x01 00 00 -- 0x 01 FF FF == block 1
|
|
||||||
// 0x02 00 00 -- 0x 02 FF FF == block 2
|
|
||||||
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
|
||||||
bool Flash_Erase64k(uint8_t block) {
|
|
||||||
|
|
||||||
if (block > MAX_BLOCKS) return false;
|
|
||||||
|
|
||||||
FlashSendByte(BLOCK64ERASE);
|
|
||||||
FlashSendByte(block);
|
|
||||||
FlashSendByte(0x00);
|
|
||||||
FlashSendLastByte(0x00);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Erase chip
|
|
||||||
void Flash_EraseChip(void) {
|
|
||||||
FlashSendLastByte(CHIPERASE);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Flashmem_print_status(void) {
|
|
||||||
DbpString(_CYAN_("Flash memory"));
|
|
||||||
Dbprintf(" Baudrate................ " _GREEN_("%d MHz"), FLASHMEM_SPIBAUDRATE / 1000000);
|
|
||||||
|
|
||||||
if (!FlashInit()) {
|
|
||||||
DbpString(" Init.................... " _RED_("FAILED"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DbpString(" Init.................... " _GREEN_("OK"));
|
|
||||||
|
|
||||||
uint8_t dev_id = Flash_ReadID();
|
|
||||||
switch (dev_id) {
|
|
||||||
case 0x11 :
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb"));
|
|
||||||
break;
|
|
||||||
case 0x10 :
|
|
||||||
DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb"));
|
|
||||||
break;
|
|
||||||
case 0x05 :
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb"));
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
DbpString(" Device ID............... " _YELLOW_(" --> Unknown <--"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
||||||
Flash_UniqueID(uid);
|
|
||||||
Dbprintf(" Unique ID............... 0x%02X%02X%02X%02X%02X%02X%02X%02X",
|
|
||||||
uid[7], uid[6], uid[5], uid[4],
|
|
||||||
uid[3], uid[2], uid[1], uid[0]
|
|
||||||
);
|
|
||||||
|
|
||||||
FlashStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flashmem_print_info(void) {
|
|
||||||
|
|
||||||
if (!FlashInit()) return;
|
|
||||||
|
|
||||||
DbpString(_CYAN_("Flash memory dictionary loaded"));
|
|
||||||
|
|
||||||
// load dictionary offsets.
|
|
||||||
uint8_t keysum[2];
|
|
||||||
uint16_t num;
|
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET, keysum, 2);
|
|
||||||
if (isok == 2) {
|
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
|
||||||
if (num != 0xFFFF && num != 0x0)
|
|
||||||
Dbprintf(" Mifare.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_MF_KEYS_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET, keysum, 2);
|
|
||||||
if (isok == 2) {
|
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
|
||||||
if (num != 0xFFFF && num != 0x0)
|
|
||||||
Dbprintf(" T55x7................... "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_T55XX_KEYS_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
|
||||||
isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET, keysum, 2);
|
|
||||||
if (isok == 2) {
|
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
|
||||||
if (num != 0xFFFF && num != 0x0)
|
|
||||||
Dbprintf(" iClass.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_ICLASS_KEYS_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
FlashStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,10 @@
|
||||||
#define BUSY_TIMEOUT 200000L
|
#define BUSY_TIMEOUT 200000L
|
||||||
|
|
||||||
#define WINBOND_MANID 0xEF
|
#define WINBOND_MANID 0xEF
|
||||||
#define WINBOND_DEVID 0x11
|
#define WINBOND_2MB_DEVID 0x11
|
||||||
|
#define WINBOND_1MB_DEVID 0x10
|
||||||
|
#define WINBOND_512KB_DEVID 0x05
|
||||||
|
|
||||||
#define PAGESIZE 0x100
|
#define PAGESIZE 0x100
|
||||||
#define WINBOND_WRITE_DELAY 0x02
|
#define WINBOND_WRITE_DELAY 0x02
|
||||||
|
|
||||||
|
@ -100,17 +103,21 @@
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
void FlashmemSetSpiBaudrate(uint32_t baudrate);
|
|
||||||
bool FlashInit(void);
|
bool FlashInit(void);
|
||||||
void FlashSetup(uint32_t baudrate);
|
void Flash_UniqueID(uint8_t *uid);
|
||||||
void FlashStop(void);
|
void FlashStop(void);
|
||||||
bool Flash_WaitIdle(void);
|
|
||||||
uint8_t Flash_ReadStat1(void);
|
|
||||||
uint8_t Flash_ReadStat2(void);
|
|
||||||
uint16_t FlashSendByte(uint32_t data);
|
|
||||||
void Flash_TransferAdresse(uint32_t address);
|
|
||||||
|
|
||||||
|
void FlashSetup(uint32_t baudrate);
|
||||||
bool Flash_CheckBusy(uint32_t timeout);
|
bool Flash_CheckBusy(uint32_t timeout);
|
||||||
|
uint8_t Flash_ReadStat1(void);
|
||||||
|
uint16_t FlashSendByte(uint32_t data);
|
||||||
|
uint16_t FlashSendLastByte(uint32_t data);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
|
void FlashmemSetSpiBaudrate(uint32_t baudrate);
|
||||||
|
bool Flash_WaitIdle(void);
|
||||||
|
void Flash_TransferAdresse(uint32_t address);
|
||||||
|
|
||||||
void Flash_WriteEnable(void);
|
void Flash_WriteEnable(void);
|
||||||
bool Flash_WipeMemoryPage(uint8_t page);
|
bool Flash_WipeMemoryPage(uint8_t page);
|
||||||
|
@ -119,8 +126,12 @@ bool Flash_Erase4k(uint8_t block, uint8_t sector);
|
||||||
//bool Flash_Erase32k(uint32_t address);
|
//bool Flash_Erase32k(uint32_t address);
|
||||||
bool Flash_Erase64k(uint8_t block);
|
bool Flash_Erase64k(uint8_t block);
|
||||||
|
|
||||||
void Flash_UniqueID(uint8_t *uid);
|
typedef struct {
|
||||||
uint8_t Flash_ReadID(void);
|
uint8_t manufacturer_id;
|
||||||
|
uint8_t device_id;
|
||||||
|
} flash_device_type_90_t; // to differentiate from JDEC ID via cmd 9F
|
||||||
|
bool Flash_ReadID_90(flash_device_type_90_t *result);
|
||||||
|
|
||||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
||||||
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len);
|
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len);
|
||||||
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len);
|
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
|
@ -128,6 +139,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
void Flashmem_print_status(void);
|
void Flashmem_print_status(void);
|
||||||
void Flashmem_print_info(void);
|
void Flashmem_print_info(void);
|
||||||
uint16_t FlashSendLastByte(uint32_t data);
|
|
||||||
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -19,9 +19,13 @@
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
|
|
||||||
#include "proxmark3_arm.h"
|
#include "proxmark3_arm.h"
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
#include "dbprint.h"
|
#include "dbprint.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM
|
||||||
|
|
||||||
// timer counts in 666ns increments (32/48MHz), rounding applies
|
// timer counts in 666ns increments (32/48MHz), rounding applies
|
||||||
// WARNING: timer can't measure more than 43ms (666ns * 0xFFFF)
|
// WARNING: timer can't measure more than 43ms (666ns * 0xFFFF)
|
||||||
void SpinDelayUsPrecision(int us) {
|
void SpinDelayUsPrecision(int us) {
|
||||||
|
@ -35,11 +39,14 @@ void SpinDelayUsPrecision(int us) {
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register
|
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xFFFF; // Channel Period Register
|
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xFFFF; // Channel Period Register
|
||||||
|
|
||||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t end = AT91C_BASE_PWMC_CH0->PWMC_CCNTR + ticks;
|
||||||
|
if (end == 0) // AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never == 0
|
||||||
|
end++; // so we have to end++ to avoid inivity loop
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||||
if (now == (uint16_t)(start + ticks))
|
|
||||||
|
if (now == end)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -59,13 +66,15 @@ void SpinDelayUs(int us) {
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register
|
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register
|
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register
|
||||||
|
|
||||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t end = AT91C_BASE_PWMC_CH0->PWMC_CCNTR + ticks;
|
||||||
|
if (end == 0) // AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never == 0
|
||||||
|
end++; // so we have to end++ to avoid inivity loop
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||||
if (now == (uint16_t)(start + ticks))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (now == end)
|
||||||
|
return;
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,40 +121,6 @@ uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks) {
|
||||||
return (UINT32_MAX - start_ticks) + stop_ticks;
|
return (UINT32_MAX - start_ticks) + stop_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// microseconds timer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
void StartCountUS(void) {
|
|
||||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
|
||||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
|
||||||
|
|
||||||
// fast clock
|
|
||||||
// tick=1.5mks
|
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
|
||||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
|
||||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR |
|
|
||||||
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
|
|
||||||
AT91C_BASE_TC0->TC_RA = 1;
|
|
||||||
AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000
|
|
||||||
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
|
||||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0
|
|
||||||
|
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
|
||||||
|
|
||||||
// Assert a sync signal. This sets all timers to 0 on next active clock edge
|
|
||||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
|
||||||
|
|
||||||
while (AT91C_BASE_TC1->TC_CV > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t RAMFUNC GetCountUS(void) {
|
|
||||||
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
|
|
||||||
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
|
|
||||||
return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Timer for iso14443 commands. Uses ssp_clk from FPGA
|
// Timer for iso14443 commands. Uses ssp_clk from FPGA
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -241,6 +216,47 @@ uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) {
|
||||||
return (UINT32_MAX - start) + stop;
|
return (UINT32_MAX - start) + stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WaitMS(uint32_t ms) {
|
||||||
|
WaitTicks((ms & 0x1FFFFF) * 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// microseconds timer
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
void StartCountUS(void) {
|
||||||
|
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||||
|
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||||
|
|
||||||
|
// fast clock
|
||||||
|
// tick=1.5mks
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||||
|
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
||||||
|
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR |
|
||||||
|
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
|
||||||
|
AT91C_BASE_TC0->TC_RA = 1;
|
||||||
|
AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000
|
||||||
|
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||||
|
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
|
|
||||||
|
// Assert a sync signal. This sets all timers to 0 on next active clock edge
|
||||||
|
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||||
|
|
||||||
|
while (AT91C_BASE_TC1->TC_CV > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RAMFUNC GetCountUS(void) {
|
||||||
|
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
|
||||||
|
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
|
||||||
|
return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Timer for bitbanging, or LF stuff when you need a very precis timer
|
// Timer for bitbanging, or LF stuff when you need a very precis timer
|
||||||
// 1us = 1.5ticks
|
// 1us = 1.5ticks
|
||||||
|
@ -277,7 +293,6 @@ void StartTicks(void) {
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
while (AT91C_BASE_TC0->TC_CV > 0);
|
while (AT91C_BASE_TC0->TC_CV > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetTicks(void) {
|
uint32_t GetTicks(void) {
|
||||||
uint32_t hi, lo;
|
uint32_t hi, lo;
|
||||||
|
|
||||||
|
@ -302,9 +317,6 @@ void WaitTicks(uint32_t ticks) {
|
||||||
void WaitUS(uint32_t us) {
|
void WaitUS(uint32_t us) {
|
||||||
WaitTicks((us & 0x3FFFFFFF) * 3 / 2);
|
WaitTicks((us & 0x3FFFFFFF) * 3 / 2);
|
||||||
}
|
}
|
||||||
void WaitMS(uint32_t ms) {
|
|
||||||
WaitTicks((ms & 0x1FFFFF) * 1500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop clock
|
// stop clock
|
||||||
void StopTicks(void) {
|
void StopTicks(void) {
|
|
@ -26,6 +26,19 @@
|
||||||
#define GET_TICKS GetTicks()
|
#define GET_TICKS GetTicks()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void StartTicks(void);
|
||||||
|
uint32_t GetTicks(void);
|
||||||
|
void WaitUS(uint32_t us);
|
||||||
|
void WaitTicks(uint32_t ticks);
|
||||||
|
void StartCountUS(void);
|
||||||
|
uint32_t RAMFUNC GetCountUS(void);
|
||||||
|
void StopTicks(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AS_BOOTROM //////////////////////////////////////////////////////////////
|
||||||
|
// Bootrom does not require these functions.
|
||||||
|
// Wrap in #ifndef to avoid accidental bloat of bootrom
|
||||||
|
|
||||||
void SpinDelay(int ms);
|
void SpinDelay(int ms);
|
||||||
void SpinDelayUs(int us);
|
void SpinDelayUs(int us);
|
||||||
void SpinDelayUsPrecision(int us); // precision 0.6us , running for 43ms before
|
void SpinDelayUsPrecision(int us); // precision 0.6us , running for 43ms before
|
||||||
|
@ -34,8 +47,6 @@ void StartTickCount(void);
|
||||||
uint32_t RAMFUNC GetTickCount(void);
|
uint32_t RAMFUNC GetTickCount(void);
|
||||||
uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks);
|
uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks);
|
||||||
|
|
||||||
void StartCountUS(void);
|
|
||||||
uint32_t RAMFUNC GetCountUS(void);
|
|
||||||
void ResetUSClock(void);
|
void ResetUSClock(void);
|
||||||
void SpinDelayCountUs(uint32_t us);
|
void SpinDelayCountUs(uint32_t us);
|
||||||
|
|
||||||
|
@ -44,12 +55,10 @@ void ResetSspClk(void);
|
||||||
uint32_t RAMFUNC GetCountSspClk(void);
|
uint32_t RAMFUNC GetCountSspClk(void);
|
||||||
uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start);
|
uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start);
|
||||||
|
|
||||||
void StartTicks(void);
|
|
||||||
uint32_t GetTicks(void);
|
|
||||||
void WaitTicks(uint32_t ticks);
|
|
||||||
void WaitUS(uint32_t us);
|
|
||||||
void WaitMS(uint32_t ms);
|
void WaitMS(uint32_t ms);
|
||||||
|
|
||||||
void StopTicks(void);
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -366,11 +366,60 @@ static const char StrProduct[] = {
|
||||||
'p', 0, 'r', 0, 'o', 0, 'x', 0, 'm', 0, 'a', 0, 'r', 0, 'k', 0, '3', 0
|
'p', 0, 'r', 0, 'o', 0, 'x', 0, 'm', 0, 'a', 0, 'r', 0, 'k', 0, '3', 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef WITH_FLASH
|
||||||
static const char StrSerialNumber[] = {
|
static const char StrSerialNumber[] = {
|
||||||
14, // Length
|
14, // Length
|
||||||
0x03, // Type is string
|
0x03, // Type is string
|
||||||
'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0
|
'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0
|
||||||
};
|
};
|
||||||
|
#else // WITH_FLASH is defined
|
||||||
|
|
||||||
|
// Manually calculated size of descriptor with unique ID:
|
||||||
|
// offset 0, lengt h 1: total length field
|
||||||
|
// offset 1, length 1: descriptor type field
|
||||||
|
// offset 2, length 12: 6x unicode chars (original string)
|
||||||
|
// offset 14, length 4: 2x unicode chars (underscores) [[ to avoid descriptor being (size % 8) == 0, OS bug workaround ]]
|
||||||
|
// offset 18, length 32: 16x unicode chars (8-byte serial as hex characters)
|
||||||
|
// ============================
|
||||||
|
// total: 50 bytes
|
||||||
|
#define USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH 50
|
||||||
|
char StrSerialNumber[] = {
|
||||||
|
14, // Length is initially identical to non-unique version ... The length updated at boot, if unique serial is available
|
||||||
|
0x03, // Type is string
|
||||||
|
'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0,
|
||||||
|
'_', 0, '_', 0,
|
||||||
|
'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0,
|
||||||
|
'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0,
|
||||||
|
};
|
||||||
|
void usb_update_serial(uint64_t newSerialNumber) {
|
||||||
|
static bool configured = false; // TODO: enable by setting to false here...
|
||||||
|
if (configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// run this only once per boot... even if it fails to find serial number
|
||||||
|
configured = true;
|
||||||
|
// reject serial number if all-zero or all-ones
|
||||||
|
if ((newSerialNumber == 0x0000000000000000) || (newSerialNumber == 0xFFFFFFFFFFFFFFFF)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Descriptor is, effectively, initially identical to non-unique serial
|
||||||
|
// number because it reports the shorter length in the first byte.
|
||||||
|
// Convert uniqueID's eight bytes to 16 unicode characters in the
|
||||||
|
// descriptor and, finally, update the descriptor's length, which
|
||||||
|
// causes the serial number to become visible.
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
// order of nibbles chosen to match display order from `hw status`
|
||||||
|
uint8_t nibble1 = (newSerialNumber >> ((8 * i) + 4)) & 0xFu; // bitmasks [0xF0, 0xF000, 0xF00000, ... 0xF000000000000000]
|
||||||
|
uint8_t nibble2 = (newSerialNumber >> ((8 * i) + 0)) & 0xFu; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000]
|
||||||
|
char c1 = nibble1 < 10 ? '0' + nibble1 : 'A' + (nibble1 - 10);
|
||||||
|
char c2 = nibble2 < 10 ? '0' + nibble2 : 'A' + (nibble2 - 10);
|
||||||
|
StrSerialNumber[18 + (4 * i) + 0] = c1; // [ 18, 22, .., 42, 46 ]
|
||||||
|
StrSerialNumber[18 + (4 * i) + 2] = c2; // [ 20, 24, .., 44, 48 ]
|
||||||
|
}
|
||||||
|
StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// size includes their own field.
|
// size includes their own field.
|
||||||
static const char StrMS_OSDescriptor[] = {
|
static const char StrMS_OSDescriptor[] = {
|
||||||
|
|
|
@ -31,6 +31,7 @@ bool usb_poll_validate_length(void);
|
||||||
uint32_t usb_read(uint8_t *data, size_t len);
|
uint32_t usb_read(uint8_t *data, size_t len);
|
||||||
int usb_write(const uint8_t *data, const size_t len);
|
int usb_write(const uint8_t *data, const size_t len);
|
||||||
uint32_t usb_read_ng(uint8_t *data, size_t len);
|
uint32_t usb_read_ng(uint8_t *data, size_t len);
|
||||||
|
void usb_update_serial(uint64_t newSerialNumber);
|
||||||
|
|
||||||
void SetUSBreconnect(int value);
|
void SetUSBreconnect(int value);
|
||||||
int GetUSBreconnect(void);
|
int GetUSBreconnect(void);
|
||||||
|
|
|
@ -393,8 +393,8 @@ required, please do not proceed.
|
||||||
|
|
||||||
| Hex Data | Binary Data |
|
| Hex Data | Binary Data |
|
||||||
|:--------:|:---------------------------------------|
|
|:--------:|:---------------------------------------|
|
||||||
| 00088040 | 000000000000100010000000111***0***0000 |
|
| 000880E0 | 000000000000100010000000111***0***0000 |
|
||||||
| 00088050 | 000000000000100010000000111***1***0000 |
|
| 000880F0 | 000000000000100010000000111***1***0000 |
|
||||||
|
|
||||||
See how in the above we changed the bit in location 28 from a 0 to 1
|
See how in the above we changed the bit in location 28 from a 0 to 1
|
||||||
0 = No Password, 1 = Use Password
|
0 = No Password, 1 = Use Password
|
||||||
|
@ -533,7 +533,7 @@ required, please do not proceed.
|
||||||
[=] Downlink mode..... default/fixed bit length
|
[=] Downlink mode..... default/fixed bit length
|
||||||
[=] Password set...... No
|
[=] Password set...... No
|
||||||
```
|
```
|
||||||
Yes we can! We can see Block 0 is the correct config 00088040
|
Yes we can! We can see Block 0 is the correct config 000880E0
|
||||||
|
|
||||||
# Part 2 – Configuration Blocks
|
# Part 2 – Configuration Blocks
|
||||||
^[Top](#top)
|
^[Top](#top)
|
||||||
|
|
|
@ -175,13 +175,15 @@
|
||||||
"command": "clear",
|
"command": "clear",
|
||||||
"description": "Clear the Proxmark3 client terminal screen",
|
"description": "Clear the Proxmark3 client terminal screen",
|
||||||
"notes": [
|
"notes": [
|
||||||
"clear"
|
"clear -> clear the terminal screen",
|
||||||
|
"clear -b -> clear the terminal screen and the scrollback buffer"
|
||||||
],
|
],
|
||||||
"offline": true,
|
"offline": true,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help"
|
"-h, --help This help",
|
||||||
|
"-b, --back also clear the scrollback buffer"
|
||||||
],
|
],
|
||||||
"usage": "clear [-h]"
|
"usage": "clear [-hb]"
|
||||||
},
|
},
|
||||||
"data askedgedetect": {
|
"data askedgedetect": {
|
||||||
"command": "data askedgedetect",
|
"command": "data askedgedetect",
|
||||||
|
@ -1101,14 +1103,16 @@
|
||||||
"command": "hf 14a chaining",
|
"command": "hf 14a chaining",
|
||||||
"description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
"description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf 14a chaining disable -> disable chaining",
|
"hf 14a chaining -> show chaining enable/disable state",
|
||||||
"hf 14a chaining -> show chaining enable/disable state"
|
"hf 14a chaining --off -> disable chaining"
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help"
|
"-h, --help This help",
|
||||||
|
"-1, --on enabled chaining",
|
||||||
|
"-0, --off disable chaining"
|
||||||
],
|
],
|
||||||
"usage": "hf 14a chaining [-h] [<enable/disable or 0/1>]"
|
"usage": "hf 14a chaining [-h10]"
|
||||||
},
|
},
|
||||||
"hf 14a config": {
|
"hf 14a config": {
|
||||||
"command": "hf 14a config",
|
"command": "hf 14a config",
|
||||||
|
@ -1654,6 +1658,34 @@
|
||||||
],
|
],
|
||||||
"usage": "hf 15 list [-h1crux] [--frame] [-f <fn>]"
|
"usage": "hf 15 list [-h1crux] [--frame] [-f <fn>]"
|
||||||
},
|
},
|
||||||
|
"hf 15 passprotectafi": {
|
||||||
|
"command": "hf 15 passprotectafi",
|
||||||
|
"description": "This command enables the password protect of AFI. *** OBS! This action can not be undone! ***",
|
||||||
|
"notes": [
|
||||||
|
"hf 15 passprotectafi -p 00000000 --force"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-p, --pwd <hex> EAS/AFI password, 8 hex bytes",
|
||||||
|
"--force Force execution of command (irreversible)"
|
||||||
|
],
|
||||||
|
"usage": "hf 15 passprotectafi [-h] -p <hex> [--force]"
|
||||||
|
},
|
||||||
|
"hf 15 passprotecteas": {
|
||||||
|
"command": "hf 15 passprotecteas",
|
||||||
|
"description": "This command enables the password protect of EAS. *** OBS! This action can not be undone! ***",
|
||||||
|
"notes": [
|
||||||
|
"hf 15 passprotecteas -p 00000000 --force"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-p, --pwd <hex> EAS/AFI password, 8 hex bytes",
|
||||||
|
"--force Force execution of command (irreversible)"
|
||||||
|
],
|
||||||
|
"usage": "hf 15 passprotecteas [-h] -p <hex> [--force]"
|
||||||
|
},
|
||||||
"hf 15 raw": {
|
"hf 15 raw": {
|
||||||
"command": "hf 15 raw",
|
"command": "hf 15 raw",
|
||||||
"description": "Sends raw bytes over ISO-15693 to card",
|
"description": "Sends raw bytes over ISO-15693 to card",
|
||||||
|
@ -1774,8 +1806,34 @@
|
||||||
],
|
],
|
||||||
"usage": "hf 15 sim [-h] -u <8b hex> [-b <dec>]"
|
"usage": "hf 15 sim [-h] -u <8b hex> [-b <dec>]"
|
||||||
},
|
},
|
||||||
"hf 15 slixdisable": {
|
"hf 15 slixeasdisable": {
|
||||||
"command": "hf 15 slixdisable",
|
"command": "hf 15 slixeasdisable",
|
||||||
|
"description": "Disable EAS mode on SLIX ISO-15693 tag",
|
||||||
|
"notes": [
|
||||||
|
"hf 15 slixeasdisable -p 0F0F0F0F"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-p, --pwd <hex> optional password, 8 hex bytes"
|
||||||
|
],
|
||||||
|
"usage": "hf 15 slixeasdisable [-h] [-p <hex>]"
|
||||||
|
},
|
||||||
|
"hf 15 slixeasenable": {
|
||||||
|
"command": "hf 15 slixeasenable",
|
||||||
|
"description": "Enable EAS mode on SLIX ISO-15693 tag",
|
||||||
|
"notes": [
|
||||||
|
"hf 15 slixeasenable -p 0F0F0F0F"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-p, --pwd <hex> optional password, 8 hex bytes"
|
||||||
|
],
|
||||||
|
"usage": "hf 15 slixeasenable [-h] [-p <hex>]"
|
||||||
|
},
|
||||||
|
"hf 15 slixprivacydisable": {
|
||||||
|
"command": "hf 15 slixprivacydisable",
|
||||||
"description": "Disable privacy mode on SLIX ISO-15693 tag",
|
"description": "Disable privacy mode on SLIX ISO-15693 tag",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf 15 slixdisable -p 0F0F0F0F"
|
"hf 15 slixdisable -p 0F0F0F0F"
|
||||||
|
@ -1785,7 +1843,35 @@
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-p, --pwd <hex> password, 8 hex bytes"
|
"-p, --pwd <hex> password, 8 hex bytes"
|
||||||
],
|
],
|
||||||
"usage": "hf 15 slixdisable [-h] -p <hex>"
|
"usage": "hf 15 slixprivacydisable [-h] -p <hex>"
|
||||||
|
},
|
||||||
|
"hf 15 slixprivacyenable": {
|
||||||
|
"command": "hf 15 slixprivacyenable",
|
||||||
|
"description": "Enable privacy mode on SLIX ISO-15693 tag",
|
||||||
|
"notes": [
|
||||||
|
"hf 15 slixenable -p 0F0F0F0F"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-p, --pwd <hex> password, 8 hex bytes"
|
||||||
|
],
|
||||||
|
"usage": "hf 15 slixprivacyenable [-h] -p <hex>"
|
||||||
|
},
|
||||||
|
"hf 15 slixwritepwd": {
|
||||||
|
"command": "hf 15 slixwritepwd",
|
||||||
|
"description": "Write a password on a SLIX family ISO-15693 tag.nSome tags do not support all different password types.",
|
||||||
|
"notes": [
|
||||||
|
"hf 15 slixwritepwd -t READ -o 00000000 -n 12131415"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-t, --type <read|write|privacy|destroy|easafi> which password field to write to",
|
||||||
|
"-o, --old <hex> old password (if present), 8 hex bytes",
|
||||||
|
"-n, --new <hex> new password, 8 hex bytes"
|
||||||
|
],
|
||||||
|
"usage": "hf 15 slixwritepwd [-h] -t <read|write|privacy|destroy|easafi> [-o <hex>] -n <hex>"
|
||||||
},
|
},
|
||||||
"hf 15 sniff": {
|
"hf 15 sniff": {
|
||||||
"command": "hf 15 sniff",
|
"command": "hf 15 sniff",
|
||||||
|
@ -1825,19 +1911,16 @@
|
||||||
"description": "Write AFI on card",
|
"description": "Write AFI on card",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf 15 writeafi -* --afi 12",
|
"hf 15 writeafi -* --afi 12",
|
||||||
"hf 15 writeafi -u E011223344556677 --afi 12"
|
"hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F"
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-u, --uid <hex> full UID, 8 bytes",
|
"-u, --uid <hex> full UID, 8 bytes",
|
||||||
"--ua unaddressed mode",
|
"--afi <dec> AFI number (0-255)",
|
||||||
"-* scan for tag",
|
"-p, --pwd <hex> optional AFI/EAS password"
|
||||||
"-2 use slower '1 out of 256' mode",
|
|
||||||
"-o, --opt set OPTION Flag (needed for TI)",
|
|
||||||
"--afi <dec> AFI number (0-255)"
|
|
||||||
],
|
],
|
||||||
"usage": "hf 15 writeafi [-h*2o] [-u <hex>] [--ua] --afi <dec>"
|
"usage": "hf 15 writeafi [-h] [-u <hex>] --afi <dec> [-p <hex>]"
|
||||||
},
|
},
|
||||||
"hf 15 writedsfid": {
|
"hf 15 writedsfid": {
|
||||||
"command": "hf 15 writedsfid",
|
"command": "hf 15 writedsfid",
|
||||||
|
@ -2881,7 +2964,7 @@
|
||||||
},
|
},
|
||||||
"hf help": {
|
"hf help": {
|
||||||
"command": "hf help",
|
"command": "hf help",
|
||||||
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags",
|
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags",
|
||||||
"notes": [],
|
"notes": [],
|
||||||
"offline": true,
|
"offline": true,
|
||||||
"options": [],
|
"options": [],
|
||||||
|
@ -3016,9 +3099,10 @@
|
||||||
"--fc <dec> facility code",
|
"--fc <dec> facility code",
|
||||||
"--cn <dec> card number",
|
"--cn <dec> card number",
|
||||||
"-w, --wiegand <format> see `wiegand list` for available formats",
|
"-w, --wiegand <format> see `wiegand list` for available formats",
|
||||||
"--shallow use shallow (ASK) reader modulation instead of OOK"
|
"--shallow use shallow (ASK) reader modulation instead of OOK",
|
||||||
|
"-v verbose (print encoded blocks)"
|
||||||
],
|
],
|
||||||
"usage": "hf iclass encode [-h] [--bin <bin>] --ki <dec> [--credit] [--elite] [--raw] [--enckey <hex>] [--fc <dec>] [--cn <dec>] [-w <format>] [--shallow]"
|
"usage": "hf iclass encode [-hv] [--bin <bin>] --ki <dec> [--credit] [--elite] [--raw] [--enckey <hex>] [--fc <dec>] [--cn <dec>] [-w <format>] [--shallow]"
|
||||||
},
|
},
|
||||||
"hf iclass encrypt": {
|
"hf iclass encrypt": {
|
||||||
"command": "hf iclass encrypt",
|
"command": "hf iclass encrypt",
|
||||||
|
@ -6684,6 +6768,47 @@
|
||||||
],
|
],
|
||||||
"usage": "hf st25ta sim [-h] -u <hex>"
|
"usage": "hf st25ta sim [-h] -u <hex>"
|
||||||
},
|
},
|
||||||
|
"hf tesla help": {
|
||||||
|
"command": "hf tesla help",
|
||||||
|
"description": "help This help list List ISO 14443A/7816 history",
|
||||||
|
"notes": [],
|
||||||
|
"offline": true,
|
||||||
|
"options": [],
|
||||||
|
"usage": ""
|
||||||
|
},
|
||||||
|
"hf tesla info": {
|
||||||
|
"command": "hf tesla info",
|
||||||
|
"description": "Get info about TESLA Key tag",
|
||||||
|
"notes": [
|
||||||
|
"hf tesla info"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help"
|
||||||
|
],
|
||||||
|
"usage": "hf telsa info [-h]"
|
||||||
|
},
|
||||||
|
"hf tesla list": {
|
||||||
|
"command": "hf tesla list",
|
||||||
|
"description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
||||||
|
"notes": [
|
||||||
|
"hf tesla list --frame -> show frame delay times",
|
||||||
|
"hf tesla list -1 -> use trace buffer"
|
||||||
|
],
|
||||||
|
"offline": true,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-1, --buffer use data from trace buffer",
|
||||||
|
"--frame show frame delay times",
|
||||||
|
"-c mark CRC bytes",
|
||||||
|
"-r show relative times (gap and duration)",
|
||||||
|
"-u display times in microseconds instead of clock cycles",
|
||||||
|
"-x show hexdump to convert to pcap(ng)",
|
||||||
|
"or to import into Wireshark using encapsulation type \"ISO 14443\"",
|
||||||
|
"-f, --file <fn> filename of dictionary"
|
||||||
|
],
|
||||||
|
"usage": "hf tesla list [-h1crux] [--frame] [-f <fn>]"
|
||||||
|
},
|
||||||
"hf texkom help": {
|
"hf texkom help": {
|
||||||
"command": "hf texkom help",
|
"command": "hf texkom help",
|
||||||
"description": "help This help",
|
"description": "help This help",
|
||||||
|
@ -8068,6 +8193,23 @@
|
||||||
],
|
],
|
||||||
"usage": "lf em 4x70 auth [-h] [--par] --rnd <hex> --frn <hex>"
|
"usage": "lf em 4x70 auth [-h] [--par] --rnd <hex> --frn <hex>"
|
||||||
},
|
},
|
||||||
|
"lf em 4x70 brute": {
|
||||||
|
"command": "lf em 4x70 brute",
|
||||||
|
"description": "Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'",
|
||||||
|
"notes": [
|
||||||
|
"lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"--par Add parity bit when sending commands",
|
||||||
|
"-b, --block <dec> block/word address, dec",
|
||||||
|
"--rnd <hex> Random 56-bit",
|
||||||
|
"--frn <hex> F(RN) 28-bit as 4 hex bytes",
|
||||||
|
"-s, --start <hex> Start bruteforce enumeration from this key value"
|
||||||
|
],
|
||||||
|
"usage": "lf em 4x70 brute [-h] [--par] -b <dec> --rnd <hex> --frn <hex> [-s <hex>]"
|
||||||
|
},
|
||||||
"lf em 4x70 help": {
|
"lf em 4x70 help": {
|
||||||
"command": "lf em 4x70 help",
|
"command": "lf em 4x70 help",
|
||||||
"description": "help This help",
|
"description": "help This help",
|
||||||
|
@ -11760,8 +11902,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 739,
|
"commands_extracted": 749,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2023-01-15T01:24:39"
|
"extracted_on": "2023-02-18T20:20:19"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -236,7 +236,13 @@ Check column "offline" for their availability.
|
||||||
|`hf 15 esave `|N |`Save emulator memory into image file`
|
|`hf 15 esave `|N |`Save emulator memory into image file`
|
||||||
|`hf 15 eview `|N |`View emulator memory`
|
|`hf 15 eview `|N |`View emulator memory`
|
||||||
|`hf 15 sim `|N |`Fake an ISO-15693 tag`
|
|`hf 15 sim `|N |`Fake an ISO-15693 tag`
|
||||||
|`hf 15 slixdisable `|N |`Disable privacy mode on SLIX ISO-15693 tag`
|
|`hf 15 slixwritepwd `|N |`Writes a password on a SLIX ISO-15693 tag`
|
||||||
|
|`hf 15 slixeasdisable `|N |`Disable EAS mode on SLIX ISO-15693 tag`
|
||||||
|
|`hf 15 slixeasenable `|N |`Enable EAS mode on SLIX ISO-15693 tag`
|
||||||
|
|`hf 15 slixprivacydisable`|N |`Disable privacy mode on SLIX ISO-15693 tag`
|
||||||
|
|`hf 15 slixprivacyenable`|N |`Enable privacy mode on SLIX ISO-15693 tag`
|
||||||
|
|`hf 15 passprotectafi `|N |`Password protect AFI - Cannot be undone`
|
||||||
|
|`hf 15 passprotecteas `|N |`Password protect EAS - Cannot be undone`
|
||||||
|`hf 15 wrbl `|N |`Write a block`
|
|`hf 15 wrbl `|N |`Write a block`
|
||||||
|`hf 15 findafi `|N |`Brute force AFI of an ISO-15693 tag`
|
|`hf 15 findafi `|N |`Brute force AFI of an ISO-15693 tag`
|
||||||
|`hf 15 writeafi `|N |`Writes the AFI on an ISO-15693 tag`
|
|`hf 15 writeafi `|N |`Writes the AFI on an ISO-15693 tag`
|
||||||
|
@ -651,6 +657,28 @@ Check column "offline" for their availability.
|
||||||
|`hf st25ta sim `|N |`Fake ISO 14443A/ST tag`
|
|`hf st25ta sim `|N |`Fake ISO 14443A/ST tag`
|
||||||
|
|
||||||
|
|
||||||
|
### hf tesla
|
||||||
|
|
||||||
|
{ TESLA Cards... }
|
||||||
|
|
||||||
|
|command |offline |description
|
||||||
|
|------- |------- |-----------
|
||||||
|
|`hf tesla help `|Y |`This help`
|
||||||
|
|`hf tesla info `|N |`Tag information`
|
||||||
|
|`hf tesla list `|Y |`List ISO 14443A/7816 history`
|
||||||
|
|
||||||
|
|
||||||
|
### hf texkom
|
||||||
|
|
||||||
|
{ Texkom RFIDs... }
|
||||||
|
|
||||||
|
|command |offline |description
|
||||||
|
|------- |------- |-----------
|
||||||
|
|`hf texkom help `|Y |`This help`
|
||||||
|
|`hf texkom reader `|N |`Act like a Texkom reader`
|
||||||
|
|`hf texkom sim `|N |`Simulate a Texkom tag`
|
||||||
|
|
||||||
|
|
||||||
### hf thinfilm
|
### hf thinfilm
|
||||||
|
|
||||||
{ Thinfilm RFIDs... }
|
{ Thinfilm RFIDs... }
|
||||||
|
@ -682,17 +710,6 @@ Check column "offline" for their availability.
|
||||||
|`hf topaz wrbl `|N |`Write block`
|
|`hf topaz wrbl `|N |`Write block`
|
||||||
|
|
||||||
|
|
||||||
### hf texkom
|
|
||||||
|
|
||||||
{ Texkom RFIDs... }
|
|
||||||
|
|
||||||
|command |offline |description
|
|
||||||
|------- |------- |-----------
|
|
||||||
|`hf texkom help `|Y |`This help`
|
|
||||||
|`hf texkom reader `|N |`Act like a Texkom reader`
|
|
||||||
|`hf texkom sim `|N |`Simulate a Texkom tag`
|
|
||||||
|
|
||||||
|
|
||||||
### hf xerox
|
### hf xerox
|
||||||
|
|
||||||
{ Fuji/Xerox cartridge RFIDs... }
|
{ Fuji/Xerox cartridge RFIDs... }
|
||||||
|
@ -876,6 +893,7 @@ Check column "offline" for their availability.
|
||||||
|command |offline |description
|
|command |offline |description
|
||||||
|------- |------- |-----------
|
|------- |------- |-----------
|
||||||
|`lf em 4x70 help `|Y |`This help`
|
|`lf em 4x70 help `|Y |`This help`
|
||||||
|
|`lf em 4x70 brute `|N |`Bruteforce EM4X70 to find partial Crypt Key`
|
||||||
|`lf em 4x70 info `|N |`Tag information EM4x70`
|
|`lf em 4x70 info `|N |`Tag information EM4x70`
|
||||||
|`lf em 4x70 write `|N |`Write EM4x70`
|
|`lf em 4x70 write `|N |`Write EM4x70`
|
||||||
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|
||||||
|
|
|
@ -1086,10 +1086,12 @@ CF <passwd> 35 <2b ATQA><1b SAK> // Configure ATQA/SAK (swap ATQ
|
||||||
CF <passwd> 68 <00-02> // Configure UID length
|
CF <passwd> 68 <00-02> // Configure UID length
|
||||||
CF <passwd> 69 <00-01> // (De)Activate Ultralight mode
|
CF <passwd> 69 <00-01> // (De)Activate Ultralight mode
|
||||||
CF <passwd> 6A <00-03> // Select Ultralight mode
|
CF <passwd> 6A <00-03> // Select Ultralight mode
|
||||||
|
CF <passwd> 6B <1b> // Set Ultralight and M1 maximum read/write sectors
|
||||||
CF <passwd> C6 // Dump configuration
|
CF <passwd> C6 // Dump configuration
|
||||||
CF <passwd> CC // Factory test, returns 6666
|
CF <passwd> CC // Factory test, returns 6666
|
||||||
CF <passwd> CD <1b block number><16b block data> // Backdoor write 16b block
|
CF <passwd> CD <1b block number><16b block data> // Backdoor write 16b block
|
||||||
CF <passwd> CE <1b block number> // Backdoor read 16b block
|
CF <passwd> CE <1b block number> // Backdoor read 16b block
|
||||||
|
CF <passwd> CF <1b param> // Unknown
|
||||||
CF <passwd> F0 <30b configuration data> // Configure all params in one cmd
|
CF <passwd> F0 <30b configuration data> // Configure all params in one cmd
|
||||||
CF <passwd> F1 <30b configuration data> // Configure all params in one cmd and fuse the configuration permanently
|
CF <passwd> F1 <30b configuration data> // Configure all params in one cmd and fuse the configuration permanently
|
||||||
CF <passwd> FE <4b new_password> // change password
|
CF <passwd> FE <4b new_password> // change password
|
||||||
|
@ -1304,6 +1306,19 @@ script run hf_mf_ultimatecard -m 02
|
||||||
```
|
```
|
||||||
|
|
||||||
Now the card supports the 3DES UL-C authentication.
|
Now the card supports the 3DES UL-C authentication.
|
||||||
|
### Set Ultralight and M1 maximum read/write sectors
|
||||||
|
^[Top](#top) ^^[Gen4](#g4top)
|
||||||
|
|
||||||
|
```
|
||||||
|
hf 14a raw -s -c -t 1000 CF<passwd>6B<1b blocks>
|
||||||
|
```
|
||||||
|
Hexadecimal, maximum sector data, default 0xFF, range 0x00-0xFF
|
||||||
|
|
||||||
|
Example: set maximum 63 blocks read/write for Mifare Classic 1K
|
||||||
|
|
||||||
|
```
|
||||||
|
hf 14a raw -s -c -t 1000 CF000000006B3F
|
||||||
|
```
|
||||||
### Set shadow mode (GTU)
|
### Set shadow mode (GTU)
|
||||||
^[Top](#top) ^^[Gen4](#g4top)
|
^[Top](#top) ^^[Gen4](#g4top)
|
||||||
|
|
||||||
|
@ -1365,6 +1380,20 @@ Example: write block0 with factory data, default pwd
|
||||||
hf 14a raw -s -c -t 1000 CF00000000CD00112233441C000011778185BA18000000
|
hf 14a raw -s -c -t 1000 CF00000000CD00112233441C000011778185BA18000000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Unknown command
|
||||||
|
^[Top](#top) ^^[Gen4](#g4top)
|
||||||
|
|
||||||
|
This command modifies one byte in configuration dump, but purpose one is unknown.
|
||||||
|
|
||||||
|
```
|
||||||
|
hf 14a raw -s -c -t 1000 CF<passwd>CF<1b param>
|
||||||
|
```
|
||||||
|
* `<param>`
|
||||||
|
* `??`: ???
|
||||||
|
|
||||||
|
Example:
|
||||||
|
hf 14a raw -s -c -t 1000 CF00000000CF02
|
||||||
|
|
||||||
### Change backdoor password
|
### Change backdoor password
|
||||||
^[Top](#top) ^^[Gen4](#g4top)
|
^[Top](#top) ^^[Gen4](#g4top)
|
||||||
|
|
||||||
|
@ -1391,8 +1420,10 @@ hf 14a raw -s -c -t 1000 CF<passwd>C6
|
||||||
```
|
```
|
||||||
Default configuration:
|
Default configuration:
|
||||||
```
|
```
|
||||||
00000000000002000978009102DABC191010111213141516040008004F6B
|
00000000000002000978009102DABC191010111213141516040008006B024F6B
|
||||||
^^^^ ??
|
^^^^ ??
|
||||||
|
^^ cf cmd cf: ?? this byte set by cmd cf<pwd>cf<param>, factory value 0x02
|
||||||
|
^^ cf cmd 6b: maximum read/write sectors, factory value 0x6b
|
||||||
^^ cf cmd 6a: UL mode
|
^^ cf cmd 6a: UL mode
|
||||||
^^^^^^ cf cmd 35: ATQA/SAK
|
^^^^^^ cf cmd 35: ATQA/SAK
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cf cmd 34: ATS length & content
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cf cmd 34: ATS length & content
|
||||||
|
|
|
@ -135,6 +135,8 @@ See [details here](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)
|
||||||
|
|
||||||
(RDV4 only) Make sure you've the latest SIM firmware according to the [configuration documentation](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md#verify-sim-module-firmware-version).
|
(RDV4 only) Make sure you've the latest SIM firmware according to the [configuration documentation](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md#verify-sim-module-firmware-version).
|
||||||
|
|
||||||
|
Check that the SIM daughterboard is properly seated onto the mainboard. Pressure on the edges of the daughterboard could cause the connector to partially disconnect (especially good to check if problems began after installation of the bluetooth module, for example).
|
||||||
|
|
||||||
## Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries
|
## Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries
|
||||||
^[Top](#top)
|
^[Top](#top)
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ Try running it with
|
||||||
## libQt5Core.so.5 not found
|
## libQt5Core.so.5 not found
|
||||||
^[Top](#top)
|
^[Top](#top)
|
||||||
|
|
||||||
On WSL1 / updated to Ubuntu 20.04, there is a slight chance you experience problems when compiling the repo with QT5.
|
On WSL1 / updated to Ubuntu 20.04 and 22.04, there is a slight chance you experience problems when compiling the repo with QT5.
|
||||||
The following steps is needed to make the development environment happy again.
|
The following steps is needed to make the development environment happy again.
|
||||||
```
|
```
|
||||||
sudo apt reinstall qtbase5-dev
|
sudo apt reinstall qtbase5-dev
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
<a id="top"></a>
|
||||||
|
|
||||||
|
# WSL2 Installation instructions
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
- [WSL2 Installation instructions](#wsl2-installation-instructions)
|
||||||
|
- [Table of Contents](#table-of-contents)
|
||||||
|
- [Requirements](#requirements)
|
||||||
|
- [Install Kali Linux distribution](#install-kali-linux-distribution)
|
||||||
|
- [Driver installation (Windows 11)](#driver-installation-windows-11)
|
||||||
|
- [USBIPD hints](#usbipd-hints)
|
||||||
|
- [WSL2 / Kali Linux Installation](#wsl2--kali-linux-installation)
|
||||||
|
- [X Server Installation](#x-server-installation)
|
||||||
|
- [Clone the Iceman repository](#clone-the-iceman-repository)
|
||||||
|
- [Compile the project](#compile-the-project)
|
||||||
|
- [Install the udev rules](#install-the-udev-rules)
|
||||||
|
- [Inform udev that it really, really should work](#inform-udev-that-it-really-really-should-work)
|
||||||
|
- [Verify Device Exists](#verify-device-exists)
|
||||||
|
- [Using the client...](#using-the-client)
|
||||||
|
- [Done!](#done)
|
||||||
|
|
||||||
|
This provides instructions on how to install, build, and use Proxmark3
|
||||||
|
on Windows 11, using WSL2 (and Kali Linux).
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
This WSL 2 method requires Windows 11 (Build 22000 or later),
|
||||||
|
WSL installed and [set to WSL2](https://learn.microsoft.com/en-us/windows/wsl/basic-commands#set-wsl-version-to-1-or-2),
|
||||||
|
|
||||||
|
While WSL 2 does not itself support passing through USB or
|
||||||
|
serial devices, it can work by using the USB/IP open-source
|
||||||
|
project, [`usbipd-win`](https://github.com/dorssel/usbipd-win).
|
||||||
|
|
||||||
|
|
||||||
|
## Install Kali Linux distribution
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
Open the Windows App Store, and install Kali Linux.
|
||||||
|
|
||||||
|
For WSL configuration, see [Manage and configure Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/wsl-config).
|
||||||
|
|
||||||
|
Start the Kali Linux distribution at least once, to ensure it's fully installed.
|
||||||
|
|
||||||
|
## Driver installation (Windows 11)
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
On the Windows (host) machine, install the
|
||||||
|
[latest release](https://github.com/dorssel/usbipd-win/releases)
|
||||||
|
of `usbpid-win` (typically an `.MSI` file).
|
||||||
|
|
||||||
|
## USBIPD hints
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
This is *NOT* intended to be a full description of how to use USBIPD.
|
||||||
|
Rather, this is intended only to give a starting point, as ***the values
|
||||||
|
shown here are extremely likely to differ per machine***.
|
||||||
|
|
||||||
|
It's presumed that you've already installed USBIPD. Plug the Proxmark
|
||||||
|
device into a USB port. Then, from a `cmd.exe` or `wt.exe` ***launched
|
||||||
|
with administrative permissions***:
|
||||||
|
|
||||||
|
Get a list of attached devices. Example (NOTE: VID/PID for non-proxmark devices redacted)
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
C:\qwert> usbipd list
|
||||||
|
|
||||||
|
Connected:
|
||||||
|
BUSID VID:PID DEVICE STATE
|
||||||
|
1-2 xxxx:xxxx USB Input Device Not shared
|
||||||
|
2-3 xxxx:xxxx USB Mass Storage Device Not shared
|
||||||
|
5-3 9ac4:4b8f USB Serial Device (COM31) Not shared
|
||||||
|
|
||||||
|
Persisted:
|
||||||
|
GUID DEVICE
|
||||||
|
```
|
||||||
|
|
||||||
|
Take note of the `BUSID` for the proxmark device, which should show as a USB Serial Device.
|
||||||
|
|
||||||
|
Setup that bus ID to always be redirected to the WSL distribution named `kali-linux`:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
C:\qwert> usbipd wsl attach --busid 5-3 --distribution kali-linux --auto-attach
|
||||||
|
usbipd: info: Starting endless attach loop; press Ctrl+C to quit.
|
||||||
|
Attached
|
||||||
|
```
|
||||||
|
|
||||||
|
NOTE: You must leave that running in the background, to allow the device to automatically
|
||||||
|
re-attach to the WSL2 instance.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## WSL2 / Kali Linux Installation
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
Start the Kali Linux distribution you installed. First, make sure
|
||||||
|
the distribution is up-to-date:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get upgrade -y
|
||||||
|
sudo apt-get auto-remove -y
|
||||||
|
```
|
||||||
|
|
||||||
|
then, install proxmark dependencies:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt-get install --no-install-recommends \
|
||||||
|
git ca-certificates build-essential pkg-config \
|
||||||
|
libreadline-dev gcc-arm-none-eabi libnewlib-dev \
|
||||||
|
libbz2-dev libpython3-dev qtbase5-dev libssl-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
_note_
|
||||||
|
If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`.
|
||||||
|
If you don't need support for Python3 scripts in the Proxmark3 client, you can skip the installation of `libpython3-dev`.
|
||||||
|
|
||||||
|
## X Server Installation
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
TBD -- Installing [`Win-KeX`](https://www.kali.org/docs/wsl/win-kex/) has worked
|
||||||
|
to provide a fully integrated experience, with three distinct modes.....
|
||||||
|
However, WSL2 may have some functionality already built-in?
|
||||||
|
|
||||||
|
## Clone the Iceman repository
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/
|
||||||
|
git clone https://github.com/RfidResearchGroup/proxmark3.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compile the project
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/proxmark3
|
||||||
|
make clean && make -j
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install the udev rules
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo make accessrights
|
||||||
|
sudo make udev
|
||||||
|
```
|
||||||
|
|
||||||
|
On Kali, the above does two things:
|
||||||
|
1. Ensures the user is a member of the `dialout` group
|
||||||
|
2. Copies the `./driver/77-pm3-usb-device-blacklist.rules` file to the `/etc/udev/rules.d/` directory
|
||||||
|
|
||||||
|
This presumes that the file includes `MODE="660" GROUP="dialout"` at the end of the three match lines.
|
||||||
|
The goal is that Kali Linux will automatically apply the proper permissions when the device is attached.
|
||||||
|
|
||||||
|
However, it may be necessary to give the `udev` service a kind reminder:
|
||||||
|
|
||||||
|
## Inform udev that it really, really should work
|
||||||
|
|
||||||
|
The following workaround appears to work to get udev to apply the permissions
|
||||||
|
appropriately. Note that this may need to be run again, such as when the WSL2
|
||||||
|
distributions have been restarted. I don't know why ... but it's a small hiccup.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo udevadm trigger --action=change
|
||||||
|
```
|
||||||
|
|
||||||
|
General instructions suggested to use `sudo udevadm control --reload-rules`. However,
|
||||||
|
this may simply result in the following cryptic error message:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ sudo udevadm control --reload-rules
|
||||||
|
[sudo] password for root:
|
||||||
|
Failed to send reload request: No such file or directory
|
||||||
|
```
|
||||||
|
|
||||||
|
_Note that the following should **NOT** be required:_
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo service udev restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify Device Exists
|
||||||
|
|
||||||
|
Verify the device exists, and has a symbolic link created:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ls -lFA /dev/ttyACM*
|
||||||
|
ls -lFA /dev/pm3*
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
The first should show the `rw` permissions for both owner
|
||||||
|
and group, and show the group as `dialout`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
┌──(qwert㉿host)-[~]
|
||||||
|
└─$ ls -lFA /dev/ttyACM*
|
||||||
|
crw-rw---- 1 root dialout 166, 0 Jan 22 11:28 /dev/ttyACM0
|
||||||
|
```
|
||||||
|
|
||||||
|
The second command should show that a symbolic link exists
|
||||||
|
from the friendly name `/dev/pm3-0` to the TTY device:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
┌──(qwert㉿host)-[~]
|
||||||
|
└─$ ls -lFA /dev/pm3*
|
||||||
|
lrwxrwxrwx 1 root root 7 Jan 17 19:46 /dev/pm3-0 -> ttyACM0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using the client...
|
||||||
|
|
||||||
|
```sh
|
||||||
|
┌──(qwert㉿host)-[~]
|
||||||
|
└─$ pushd ~/proxmark3
|
||||||
|
|
||||||
|
┌──(qwert㉿host)-[~]
|
||||||
|
└─$ ./pm3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Done!
|
||||||
|
^[Top](#top)
|
||||||
|
|
||||||
|
Full [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md) may be helpful.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
If all went well you should get some information about the firmware and memory usage as well as the prompt, something like this.
|
If all went well you should get some information about the firmware and memory usage as well as the prompt, something like this.
|
||||||
|
|
||||||
```
|
```
|
||||||
[=] Session log /home/iceman/.proxmark3/logs/log_20220213.txt
|
[=] Session log /home/iceman/.proxmark3/logs/log_20230208.txt
|
||||||
[+] loaded from JSON file /home/iceman/.proxmark3/preferences.json
|
[+] loaded from JSON file /home/iceman/.proxmark3/preferences.json
|
||||||
[=] Using UART port /dev/ttyS3
|
[=] Using UART port /dev/ttyS3
|
||||||
[=] Communicating with PM3 over USB-CDC
|
[=] Communicating with PM3 over USB-CDC
|
||||||
|
@ -28,47 +28,18 @@ If all went well you should get some information about the firmware and memory u
|
||||||
8888888P" 888 Y888P 888 "Y8b.
|
8888888P" 888 Y888P 888 "Y8b.
|
||||||
888 888 Y8P 888 888 888
|
888 888 Y8P 888 888 888
|
||||||
888 888 " 888 Y88b d88P
|
888 888 " 888 Y88b d88P
|
||||||
888 888 888 "Y8888P" [ Iceman ❄️ ]
|
888 888 888 "Y8888P" [ ☕ ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[ Proxmark3 RFID instrument ]
|
[ Proxmark3 RFID instrument ]
|
||||||
|
|
||||||
[ CLIENT ]
|
MCU....... AT91SAM7S512 Rev A
|
||||||
RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:08
|
Memory.... 512 Kb ( 66% used )
|
||||||
compiled with............. GCC 10.3.0
|
|
||||||
platform.................. Linux / x86_64
|
|
||||||
Readline support.......... present
|
|
||||||
QT GUI support............ present
|
|
||||||
native BT support......... absent
|
|
||||||
Python script support..... present
|
|
||||||
Lua SWIG support.......... present
|
|
||||||
Python SWIG support....... present
|
|
||||||
|
|
||||||
[ PROXMARK3 ]
|
Client.... Iceman/master/v4.16191 2023-02-08 22:54:30
|
||||||
device.................... RDV4
|
Bootrom... Iceman/master/v4.16191 2023-02-08 22:54:26
|
||||||
firmware.................. RDV4
|
OS........ Iceman/master/v4.16191 2023-02-08 22:54:27
|
||||||
external flash............ present
|
Target.... RDV4
|
||||||
smartcard reader.......... present
|
|
||||||
FPC USART for BT add-on... absent
|
|
||||||
|
|
||||||
[ ARM ]
|
|
||||||
bootrom: RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:55
|
|
||||||
os: RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:49
|
|
||||||
compiled with GCC 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]
|
|
||||||
|
|
||||||
[ FPGA ]
|
|
||||||
LF image 2s30vq100 2022-03-20 09:28:32
|
|
||||||
HF image 2s30vq100 2022-03-20 09:02:07
|
|
||||||
HF FeliCa image 2s30vq100 2022-03-20 09:28:28
|
|
||||||
HF 15 image 2s30vq100 2022-03-20 09:01:59
|
|
||||||
|
|
||||||
[ Hardware ]
|
|
||||||
--= uC: AT91SAM7S512 Rev A
|
|
||||||
--= Embedded Processor: ARM7TDMI
|
|
||||||
--= Internal SRAM size: 64K bytes
|
|
||||||
--= Architecture identifier: AT91SAM7Sxx Series
|
|
||||||
--= Embedded flash memory 512K bytes ( 59% used )
|
|
||||||
|
|
||||||
[usb] pm3 -->
|
[usb] pm3 -->
|
||||||
```
|
```
|
||||||
|
|
|
@ -111,6 +111,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo
|
||||||
| LF_NEDAP_SIM | LF Nedap ID simulator
|
| LF_NEDAP_SIM | LF Nedap ID simulator
|
||||||
| LF_NEXID | Nexwatch credentials detection mode - jrjgjk & Zolorah
|
| LF_NEXID | Nexwatch credentials detection mode - jrjgjk & Zolorah
|
||||||
| LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz
|
| LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz
|
||||||
|
| LF_PROX2BRUTE | HID ProxII bruteforce v2 - Yann Gascuel
|
||||||
| LF_SAMYRUN (def)| HID26 read/clone/sim - Samy Kamkar
|
| LF_SAMYRUN (def)| HID26 read/clone/sim - Samy Kamkar
|
||||||
| LF_SKELETON | standalone mode skeleton - Iceman1001
|
| LF_SKELETON | standalone mode skeleton - Iceman1001
|
||||||
| LF_THAREXDE | LF EM4x50 simulator/read standalone mode - tharexde
|
| LF_THAREXDE | LF EM4x50 simulator/read standalone mode - tharexde
|
||||||
|
@ -119,8 +120,8 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo
|
||||||
| HF_15SNIFF | 15693 sniff storing to flashmem - Glaser
|
| HF_15SNIFF | 15693 sniff storing to flashmem - Glaser
|
||||||
| HF_AVEFUL | MIFARE Ultralight read/simulation - Ave Ozkal
|
| HF_AVEFUL | MIFARE Ultralight read/simulation - Ave Ozkal
|
||||||
| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito
|
| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito
|
||||||
| HF_CRAFTBYTE | UID stealer - Emulates scanned 14a UID - Anze Jensterle
|
|
||||||
| HF_COLIN | Mifare ultra fast sniff/sim/clone - Colin Brigato
|
| HF_COLIN | Mifare ultra fast sniff/sim/clone - Colin Brigato
|
||||||
|
| HF_CRAFTBYTE | UID stealer - Emulates scanned 14a UID - Anze Jensterle
|
||||||
| HF_ICECLASS | iCLASS 4-1 mode sim/read & dump/loclass/glitch & config to flashmem - Iceman1001
|
| HF_ICECLASS | iCLASS 4-1 mode sim/read & dump/loclass/glitch & config to flashmem - Iceman1001
|
||||||
| HF_LEGIC | HF Legic Prime Read/Store/Sim standalone - uhei
|
| HF_LEGIC | HF Legic Prime Read/Store/Sim standalone - uhei
|
||||||
| HF_LEGICSIM | HF Legic Prime Simulate standalone - uhei
|
| HF_LEGICSIM | HF Legic Prime Simulate standalone - uhei
|
||||||
|
|
22
driver/77-pm3-usb-device-blacklist-dialout.rules
Normal file
22
driver/77-pm3-usb-device-blacklist-dialout.rules
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Proxmark3 linux modem-manager de-confliction file
|
||||||
|
#
|
||||||
|
# copy this file to /etc/udev/rules.d (or add the entry to the end of an existing file)
|
||||||
|
# and restart udev hotplug:
|
||||||
|
#
|
||||||
|
# 'sudo udevadm control --reload-rules'
|
||||||
|
#
|
||||||
|
|
||||||
|
# proxmark3
|
||||||
|
ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end"
|
||||||
|
SUBSYSTEM!="tty", GOTO="pm3_ignore"
|
||||||
|
|
||||||
|
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout"
|
||||||
|
ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout"
|
||||||
|
ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout"
|
||||||
|
|
||||||
|
LABEL="pm3_ignore"
|
||||||
|
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||||
|
ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||||
|
ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||||
|
|
||||||
|
LABEL="pm3_usb_device_blacklist_end"
|
|
@ -10,9 +10,9 @@
|
||||||
ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end"
|
ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end"
|
||||||
SUBSYSTEM!="tty", GOTO="pm3_ignore"
|
SUBSYSTEM!="tty", GOTO="pm3_ignore"
|
||||||
|
|
||||||
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp"
|
||||||
ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp"
|
||||||
ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp"
|
||||||
|
|
||||||
LABEL="pm3_ignore"
|
LABEL="pm3_ignore"
|
||||||
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
|
@ -21,17 +21,45 @@
|
||||||
|
|
||||||
#define AEND "\x1b[0m"
|
#define AEND "\x1b[0m"
|
||||||
|
|
||||||
#define _BLUE_(s) "\x1b[34m" s AEND
|
#define _BLACK_(s) "\x1b[30m" s AEND
|
||||||
#define _RED_(s) "\x1b[31m" s AEND
|
#define _RED_(s) "\x1b[31m" s AEND
|
||||||
#define _GREEN_(s) "\x1b[32m" s AEND
|
#define _GREEN_(s) "\x1b[32m" s AEND
|
||||||
#define _YELLOW_(s) "\x1b[33m" s AEND
|
#define _YELLOW_(s) "\x1b[33m" s AEND
|
||||||
|
#define _BLUE_(s) "\x1b[34m" s AEND
|
||||||
#define _MAGENTA_(s) "\x1b[35m" s AEND
|
#define _MAGENTA_(s) "\x1b[35m" s AEND
|
||||||
#define _CYAN_(s) "\x1b[36m" s AEND
|
#define _CYAN_(s) "\x1b[36m" s AEND
|
||||||
#define _WHITE_(s) "\x1b[37m" s AEND
|
#define _WHITE_(s) "\x1b[37m" s AEND
|
||||||
|
|
||||||
#define _CLEAR_ "\x1b[2J"
|
#define _BRIGHT_BLACK_(s) "\x1b[30;1m" s AEND
|
||||||
#define _TOP_ "\x1b[1;1f"
|
#define _BRIGHT_RED_(s) "\x1b[31;1m" s AEND
|
||||||
|
#define _BRIGHT_GREEN_(s) "\x1b[32;1m" s AEND
|
||||||
|
#define _BRIGHT_YELLOW_(s) "\x1b[33;1m" s AEND
|
||||||
|
#define _BRIGHT_BLUE_(s) "\x1b[34;1m" s AEND
|
||||||
|
#define _BRIGHT_MAGENTA_(s) "\x1b[35;1m" s AEND
|
||||||
|
#define _BRIGHT_CYAN_(s) "\x1b[36;1m" s AEND
|
||||||
|
#define _BRIGHT_WHITE_(s) "\x1b[37;1m" s AEND
|
||||||
|
|
||||||
|
#define _BACK_BLACK_(s) "\x1b[40m" s AEND
|
||||||
|
#define _BACK_RED_(s) "\x1b[41m" s AEND
|
||||||
|
#define _BACK_GREEN_(s) "\x1b[42m" s AEND
|
||||||
|
#define _BACK_YELLOW_(s) "\x1b[43m" s AEND
|
||||||
|
#define _BACK_BLUE_(s) "\x1b[44m" s AEND
|
||||||
|
#define _BACK_MAGENTA_(s) "\x1b[45m" s AEND
|
||||||
|
#define _BACK_CYAN_(s) "\x1b[46m" s AEND
|
||||||
|
#define _BACK_WHITE_(s) "\x1b[47m" s AEND
|
||||||
|
|
||||||
|
#define _BACK_BRIGHT_BLACK_(s) "\x1b[40;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_RED_(s) "\x1b[41;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_GREEN_(s) "\x1b[42;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_YELLOW_(s) "\x1b[43;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_BLUE_(s) "\x1b[44;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_MAGENTA_(s) "\x1b[45;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_CYAN_(s) "\x1b[46;1m" s AEND
|
||||||
|
#define _BACK_BRIGHT_WHITE_(s) "\x1b[47;1m" s AEND
|
||||||
|
|
||||||
|
#define _CLEAR_ "\x1b[2J"
|
||||||
|
#define _CLEAR_SCROLLBACK_ "\x1b[3J"
|
||||||
|
#define _TOP_ "\x1b[1;1f"
|
||||||
|
|
||||||
#if defined(HAVE_READLINE)
|
#if defined(HAVE_READLINE)
|
||||||
// https://wiki.hackzine.org/development/misc/readline-color-prompt.html
|
// https://wiki.hackzine.org/development/misc/readline-color-prompt.html
|
||||||
|
|
|
@ -42,6 +42,9 @@ typedef struct {
|
||||||
// Used to write new key
|
// Used to write new key
|
||||||
uint8_t crypt_key[12];
|
uint8_t crypt_key[12];
|
||||||
|
|
||||||
|
// used for bruteforce the partial key
|
||||||
|
uint16_t start_key;
|
||||||
|
|
||||||
} em4x70_data_t;
|
} em4x70_data_t;
|
||||||
|
|
||||||
#endif /* EM4X70_H__ */
|
#endif /* EM4X70_H__ */
|
||||||
|
|
|
@ -205,6 +205,7 @@ typedef struct {
|
||||||
// rdv4
|
// rdv4
|
||||||
bool hw_available_flash : 1;
|
bool hw_available_flash : 1;
|
||||||
bool hw_available_smartcard : 1;
|
bool hw_available_smartcard : 1;
|
||||||
|
bool is_rdv4 : 1;
|
||||||
} PACKED capabilities_t;
|
} PACKED capabilities_t;
|
||||||
#define CAPABILITIES_VERSION 6
|
#define CAPABILITIES_VERSION 6
|
||||||
extern capabilities_t g_pm3_capabilities;
|
extern capabilities_t g_pm3_capabilities;
|
||||||
|
@ -484,6 +485,7 @@ typedef struct {
|
||||||
#define CMD_LF_EM4X70_AUTH 0x0263
|
#define CMD_LF_EM4X70_AUTH 0x0263
|
||||||
#define CMD_LF_EM4X70_WRITEPIN 0x0264
|
#define CMD_LF_EM4X70_WRITEPIN 0x0264
|
||||||
#define CMD_LF_EM4X70_WRITEKEY 0x0265
|
#define CMD_LF_EM4X70_WRITEKEY 0x0265
|
||||||
|
#define CMD_LF_EM4X70_BRUTE 0x0266
|
||||||
// Sampling configuration for LF reader/sniffer
|
// Sampling configuration for LF reader/sniffer
|
||||||
#define CMD_LF_SAMPLING_SET_CONFIG 0x021D
|
#define CMD_LF_SAMPLING_SET_CONFIG 0x021D
|
||||||
#define CMD_LF_FSK_SIMULATE 0x021E
|
#define CMD_LF_FSK_SIMULATE 0x021E
|
||||||
|
@ -519,8 +521,14 @@ typedef struct {
|
||||||
#define CMD_HF_ISO15693_COMMAND 0x0313
|
#define CMD_HF_ISO15693_COMMAND 0x0313
|
||||||
#define CMD_HF_ISO15693_FINDAFI 0x0315
|
#define CMD_HF_ISO15693_FINDAFI 0x0315
|
||||||
#define CMD_HF_ISO15693_CSETUID 0x0316
|
#define CMD_HF_ISO15693_CSETUID 0x0316
|
||||||
#define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317
|
#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0x0867
|
||||||
#define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318
|
#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317
|
||||||
|
#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318
|
||||||
|
#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862
|
||||||
|
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863
|
||||||
|
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864
|
||||||
|
#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865
|
||||||
|
#define CMD_HF_ISO15693_WRITE_AFI 0x0866
|
||||||
#define CMD_HF_TEXKOM_SIMULATE 0x0320
|
#define CMD_HF_TEXKOM_SIMULATE 0x0320
|
||||||
#define CMD_HF_ISO15693_EML_CLEAR 0x0330
|
#define CMD_HF_ISO15693_EML_CLEAR 0x0330
|
||||||
#define CMD_HF_ISO15693_EML_SETMEM 0x0331
|
#define CMD_HF_ISO15693_EML_SETMEM 0x0331
|
||||||
|
|
|
@ -223,6 +223,9 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define NTAG_I2C_SELECT_SECTOR 0xC2
|
#define NTAG_I2C_SELECT_SECTOR 0xC2
|
||||||
#define NTAG_I2C_FASTWRITE 0xA6
|
#define NTAG_I2C_FASTWRITE 0xA6
|
||||||
|
|
||||||
|
//NTAG 213TT (tamper) command
|
||||||
|
#define NTAGTT_CMD_READ_TT 0xA4
|
||||||
|
|
||||||
// mifare 4bit card answers
|
// mifare 4bit card answers
|
||||||
#define CARD_ACK 0x0A // 1010 - ACK
|
#define CARD_ACK 0x0A // 1010 - ACK
|
||||||
#define CARD_NACK_IV 0x00 // 0000 - NACK, invalid argument (invalid page address)
|
#define CARD_NACK_IV 0x00 // 0000 - NACK, invalid argument (invalid page address)
|
||||||
|
|
25
pm3
25
pm3
|
@ -68,13 +68,14 @@ function get_pm3_list_Linux {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# WSL2 with usbipd detection - doesn't report same things as WSL1
|
# WSL2 with usbipd detection - doesn't report same things as WSL1
|
||||||
|
|
||||||
if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then
|
if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then
|
||||||
|
if echo "${PM3LIST[*]}" | grep -qv "${DEV}"; then
|
||||||
PM3LIST+=("$DEV")
|
PM3LIST+=("$DEV")
|
||||||
if [ ${#PM3LIST[*]} -ge "$N" ]; then
|
if [ ${#PM3LIST[*]} -ge "$N" ]; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
if $FINDBTDONGLE; then
|
if $FINDBTDONGLE; then
|
||||||
# check if the HC-06-USB white dongle is present (still, that doesn't tell us if it's paired with a Proxmark3...)
|
# check if the HC-06-USB white dongle is present (still, that doesn't tell us if it's paired with a Proxmark3...)
|
||||||
|
@ -182,7 +183,8 @@ function get_pm3_list_WSL {
|
||||||
PM3LIST=()
|
PM3LIST=()
|
||||||
|
|
||||||
# Normal SERIAL PORTS (COM)
|
# Normal SERIAL PORTS (COM)
|
||||||
for DEV in $($PSHEXE -command "Get-CimInstance -ClassName Win32_serialport | Where-Object {\$_.PNPDeviceID -like '*VID_9AC4&PID_4B8F*' -or \$_.PNPDeviceID -like '*VID_2D2D&PID_504D*'} | Select -expandproperty DeviceID" 2>/dev/null | tr -dc '[:print:]'); do
|
for DEV in $($PSHEXE -command "Get-CimInstance -ClassName Win32_serialport | Where-Object {\$_.PNPDeviceID -like '*VID_9AC4&PID_4B8F*' -or \$_.PNPDeviceID -like '*VID_2D2D&PID_504D*'} | Select -expandproperty DeviceID" 2>/dev/null); do
|
||||||
|
DEV=$(echo $DEV | tr -dc '[:print:]')
|
||||||
_comport=$DEV
|
_comport=$DEV
|
||||||
DEV=$(echo $DEV | sed -nr 's#^COM([0-9]+)\b#/dev/ttyS\1#p')
|
DEV=$(echo $DEV | sed -nr 's#^COM([0-9]+)\b#/dev/ttyS\1#p')
|
||||||
# ttyS counterpart takes some more time to appear
|
# ttyS counterpart takes some more time to appear
|
||||||
|
@ -254,7 +256,7 @@ Quick helper script for proxmark3 client when working with a Proxmark3 device
|
||||||
Description:
|
Description:
|
||||||
The usage is the same as for the proxmark3 client, with the following differences:
|
The usage is the same as for the proxmark3 client, with the following differences:
|
||||||
* the correct port name will be automatically guessed;
|
* the correct port name will be automatically guessed;
|
||||||
* the script will wait for a Proxmark to be connected (same as option -w of the client).
|
* the script will wait for a Proxmark3 to be connected (same as option -w of the client).
|
||||||
You can also specify a first option -n N to access the Nth Proxmark3 connected.
|
You can also specify a first option -n N to access the Nth Proxmark3 connected.
|
||||||
To see a list of available ports, use --list.
|
To see a list of available ports, use --list.
|
||||||
|
|
||||||
|
@ -301,7 +303,7 @@ elif [ "$SCRIPT" = "pm3-flash" ]; then
|
||||||
}
|
}
|
||||||
HELP() {
|
HELP() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
Quick helper script for flashing a Proxmark device via USB
|
Quick helper script for flashing a Proxmark3 device via USB
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed.
|
The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed.
|
||||||
|
@ -339,7 +341,7 @@ elif [ "$SCRIPT" = "pm3-flash-all" ]; then
|
||||||
}
|
}
|
||||||
HELP() {
|
HELP() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
Quick helper script for flashing a Proxmark device via USB
|
Quick helper script for flashing a Proxmark3 device via USB
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed.
|
The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed.
|
||||||
|
@ -369,7 +371,7 @@ elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then
|
||||||
}
|
}
|
||||||
HELP() {
|
HELP() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
Quick helper script for flashing a Proxmark device via USB
|
Quick helper script for flashing a Proxmark3 device via USB
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
The correct port name will be automatically guessed and the stock firmware image will be flashed.
|
The correct port name will be automatically guessed and the stock firmware image will be flashed.
|
||||||
|
@ -399,7 +401,7 @@ elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then
|
||||||
}
|
}
|
||||||
HELP() {
|
HELP() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
Quick helper script for flashing a Proxmark device via USB
|
Quick helper script for flashing a Proxmark3 device via USB
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
The correct port name will be automatically guessed and the stock bootloader will be flashed.
|
The correct port name will be automatically guessed and the stock bootloader will be flashed.
|
||||||
|
@ -441,10 +443,12 @@ done
|
||||||
|
|
||||||
# if a port is already provided, let's just run the command as such
|
# if a port is already provided, let's just run the command as such
|
||||||
for ARG; do
|
for ARG; do
|
||||||
|
shift
|
||||||
if [ "$ARG" == "-p" ]; then
|
if [ "$ARG" == "-p" ]; then
|
||||||
CMD "$@"
|
CMD "$@"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
set -- "$@" "$ARG"
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$1" == "--list" ]; then
|
if [ "$1" == "--list" ]; then
|
||||||
|
@ -456,7 +460,7 @@ if [ "$1" == "--list" ]; then
|
||||||
SHOWLIST=true
|
SHOWLIST=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Number of the proxmark3 we're interested in
|
# Number of the Proxmark3 we're interested in
|
||||||
N=1
|
N=1
|
||||||
if [ "$1" == "-n" ]; then
|
if [ "$1" == "-n" ]; then
|
||||||
shift
|
shift
|
||||||
|
@ -471,7 +475,8 @@ fi
|
||||||
|
|
||||||
HOSTOS=$(uname | awk '{print toupper($0)}')
|
HOSTOS=$(uname | awk '{print toupper($0)}')
|
||||||
if [ "$HOSTOS" = "LINUX" ]; then
|
if [ "$HOSTOS" = "LINUX" ]; then
|
||||||
if uname -a|grep -q Microsoft; then
|
# Detect when running under WSL1 (but exclude WSL2)
|
||||||
|
if uname -a | grep -qi Microsoft && uname -a | grep -qvi WSL2; then
|
||||||
# First try finding it using the PATH environment variable
|
# First try finding it using the PATH environment variable
|
||||||
PSHEXE=$(command -v powershell.exe 2>/dev/null)
|
PSHEXE=$(command -v powershell.exe 2>/dev/null)
|
||||||
|
|
||||||
|
@ -515,7 +520,7 @@ if $SHOWLIST; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Wait till we get at least N proxmark3 devices
|
# Wait till we get at least N Proxmark3 devices
|
||||||
$GETPM3LIST "$N"
|
$GETPM3LIST "$N"
|
||||||
if [ ${#PM3LIST} -lt "$N" ]; then
|
if [ ${#PM3LIST} -lt "$N" ]; then
|
||||||
echo >&2 "[=] Waiting for Proxmark3 to appear..."
|
echo >&2 "[=] Waiting for Proxmark3 to appear..."
|
||||||
|
|
|
@ -22,7 +22,8 @@ echo "Destination: ${DEST:=firmware}"
|
||||||
echo "Produce stats?: ${STATS:=false}"
|
echo "Produce stats?: ${STATS:=false}"
|
||||||
|
|
||||||
# Which parts to skip for the 256kb version?
|
# Which parts to skip for the 256kb version?
|
||||||
SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1"
|
SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1 SKIP_ZX8211=1"
|
||||||
|
|
||||||
|
|
||||||
make $MKFLAGS bootrom || exit 1
|
make $MKFLAGS bootrom || exit 1
|
||||||
chmod 644 bootrom/obj/bootrom.elf
|
chmod 644 bootrom/obj/bootrom.elf
|
||||||
|
@ -30,8 +31,10 @@ mkdir -p "$DEST"
|
||||||
mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf"
|
mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf"
|
||||||
|
|
||||||
# cf armsrc/Standalone/Makefile.hal
|
# cf armsrc/Standalone/Makefile.hal
|
||||||
STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM)
|
STANDALONE_MODES=(LF_SKELETON)
|
||||||
STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI)
|
STANDALONE_MODES+=(LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE)
|
||||||
|
STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG)
|
||||||
|
STANDALONE_MODES+=(DANKARMULTI)
|
||||||
STANDALONE_MODES_REQ_BT=(HF_REBLAY)
|
STANDALONE_MODES_REQ_BT=(HF_REBLAY)
|
||||||
STANDALONE_MODES_REQ_SMARTCARD=()
|
STANDALONE_MODES_REQ_SMARTCARD=()
|
||||||
STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM)
|
STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM)
|
||||||
|
|
|
@ -111,7 +111,8 @@ int main(int argc, char *argv[]) {
|
||||||
uint8_t tag_challenge[16] = {0x00};
|
uint8_t tag_challenge[16] = {0x00};
|
||||||
uint8_t lock_challenge[32] = {0x00};
|
uint8_t lock_challenge[32] = {0x00};
|
||||||
|
|
||||||
uint64_t timestamp = atoi(argv[1]);
|
uint64_t timestamp = 0;
|
||||||
|
sscanf(argv[1], "%"PRIu64, ×tamp);
|
||||||
|
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
printf("\nusage: %s <unix timestamp> <16 byte tag challenge> <32 byte lock challenge>\n\n", argv[0]);
|
printf("\nusage: %s <unix timestamp> <16 byte tag challenge> <32 byte lock challenge>\n\n", argv[0]);
|
||||||
|
@ -124,8 +125,10 @@ int main(int argc, char *argv[]) {
|
||||||
if (hexstr_to_byte_array(argv[3], lock_challenge, sizeof(lock_challenge)))
|
if (hexstr_to_byte_array(argv[3], lock_challenge, sizeof(lock_challenge)))
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
// current time
|
||||||
uint64_t start_time = time(NULL);
|
uint64_t start_time = time(NULL);
|
||||||
|
|
||||||
|
// from a time before up until current time.
|
||||||
for (; timestamp < start_time; timestamp++) {
|
for (; timestamp < start_time; timestamp++) {
|
||||||
|
|
||||||
make_key(timestamp, key);
|
make_key(timestamp, key);
|
||||||
|
|
|
@ -139,10 +139,13 @@ static void print_time(uint64_t at) {
|
||||||
(void)localtime_r(&t, <);
|
(void)localtime_r(&t, <);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char res[32];
|
char res[70];
|
||||||
strftime(res, sizeof(res), "%Y-%m-%d %H:%M:%S", <);
|
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
|
strftime(res, sizeof(res), "('%Y-%m-%d %H:%M:%S')", <);
|
||||||
printf("%u ( '%s' )\n", (unsigned)t, res);
|
#else
|
||||||
|
strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <);
|
||||||
|
#endif
|
||||||
|
printf("%s\n", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *brute_thread(void *arguments) {
|
static void *brute_thread(void *arguments) {
|
||||||
|
@ -233,7 +236,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (argc != 4) return usage(argv[0]);
|
if (argc != 4) return usage(argv[0]);
|
||||||
|
|
||||||
uint64_t start_time = atoi(argv[1]);
|
uint64_t start_time = 0;
|
||||||
|
sscanf(argv[1], "%"PRIu64, &start_time);
|
||||||
|
|
||||||
uint8_t tag_challenge[16] = {0x00};
|
uint8_t tag_challenge[16] = {0x00};
|
||||||
if (hexstr_to_byte_array(argv[2], tag_challenge, sizeof(tag_challenge)))
|
if (hexstr_to_byte_array(argv[2], tag_challenge, sizeof(tag_challenge)))
|
||||||
|
|
|
@ -169,10 +169,13 @@ static void print_time(uint64_t at) {
|
||||||
(void)localtime_r(&t, <);
|
(void)localtime_r(&t, <);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char res[32];
|
char res[70];
|
||||||
strftime(res, sizeof(res), "%Y-%m-%d %H:%M:%S", <);
|
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||||
|
strftime(res, sizeof(res), "('%Y-%m-%d %H:%M:%S')", <);
|
||||||
printf("%u ( '%s' )\n", (unsigned)t, res);
|
#else
|
||||||
|
strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <);
|
||||||
|
#endif
|
||||||
|
printf("%s\n", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *brute_thread(void *arguments) {
|
static void *brute_thread(void *arguments) {
|
||||||
|
@ -378,7 +381,8 @@ int main(int argc, char *argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t start_time = atoi(argv[3]);
|
uint64_t start_time = 0;
|
||||||
|
sscanf(argv[3], "%"PRIu64, &start_time);
|
||||||
|
|
||||||
printf("Crypto algo............ " _GREEN_("%s") "\n", algostr);
|
printf("Crypto algo............ " _GREEN_("%s") "\n", algostr);
|
||||||
printf("LCR Random generator... " _GREEN_("%s") "\n", generators[g_idx].Name);
|
printf("LCR Random generator... " _GREEN_("%s") "\n", generators[g_idx].Name);
|
||||||
|
|
|
@ -428,7 +428,7 @@ while true; do
|
||||||
"GALLAGHER - Region: 1 Facility: 16640 Card No.: 201 Issue Level: 1"; then break; fi
|
"GALLAGHER - Region: 1 Facility: 16640 Card No.: 201 Issue Level: 1"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 gproxii test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf search -1'" "Guardall G-Prox II ID found"; then break; fi
|
if ! CheckExecute slow "lf T55 gproxii test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf search -1'" "Guardall G-Prox II ID found"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 gproxii test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf gproxii demod'" \
|
if ! CheckExecute slow "lf T55 gproxii test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf gproxii demod'" \
|
||||||
"G-Prox-II - len: 26 FC: 123 Card: 11223, Raw: f98c7038c63356c7ac26398c"; then break; fi
|
"G-Prox-II - Len: 26 FC: 123 Card: 11223 xor: 102, Raw: f98c7038c63356c7ac26398c"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 hid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf search -1'" "HID Prox ID found"; then break; fi
|
if ! CheckExecute slow "lf T55 hid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf search -1'" "HID Prox ID found"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 hid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf hid demod'" \
|
if ! CheckExecute slow "lf T55 hid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf hid demod'" \
|
||||||
"FC: 118 CN: 1603"; then break; fi
|
"FC: 118 CN: 1603"; then break; fi
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue